First commit
This commit is contained in:
107
server/backend/app/classes/config.py
Normal file
107
server/backend/app/classes/config.py
Normal file
@ -0,0 +1,107 @@
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
import yaml
|
||||
import sys
|
||||
import io
|
||||
import os
|
||||
import re
|
||||
import hashlib
|
||||
from functools import reduce
|
||||
from flask import send_file
|
||||
|
||||
|
||||
class Config(object):
|
||||
def __init__(self):
|
||||
self.dir = "/".join(sys.path[0].split("/")[:-2])
|
||||
return None
|
||||
|
||||
def read_config(self, path):
|
||||
"""
|
||||
Read a single value from the configuration
|
||||
:return: value (it can be any type)
|
||||
"""
|
||||
config = yaml.load(
|
||||
open(os.path.join(self.dir, "config.yaml"), "r"), Loader=yaml.SafeLoader)
|
||||
return reduce(dict.get, path, config)
|
||||
|
||||
def export_config(self):
|
||||
"""
|
||||
Export the configuration
|
||||
:return: dict (configuration content)
|
||||
"""
|
||||
config = yaml.load(
|
||||
open(os.path.join(self.dir, "config.yaml"), "r"), Loader=yaml.SafeLoader)
|
||||
config["interfaces"] = self.get_wireless_interfaces()
|
||||
return config
|
||||
|
||||
def write_config(self, cat, key, value):
|
||||
"""
|
||||
Write a new value in the configuration
|
||||
:return: bool, operation status
|
||||
"""
|
||||
config = yaml.load(
|
||||
open(os.path.join(self.dir, "config.yaml"), "r"), Loader=yaml.SafeLoader)
|
||||
config[cat][key] = value if key != "password" else self.make_password(
|
||||
value)
|
||||
|
||||
if cat == "network" and key == "in":
|
||||
self.edit_configuration_files(value)
|
||||
|
||||
with open(os.path.join(self.dir, "config.yaml"), "w") as yaml_file:
|
||||
yaml_file.write(yaml.dump(config, default_flow_style=False))
|
||||
return True
|
||||
|
||||
def make_password(self, clear_text):
|
||||
"""
|
||||
Make a simple password hash (without salt)
|
||||
"""
|
||||
return hashlib.sha256(clear_text.encode()).hexdigest()
|
||||
|
||||
def export_db(self):
|
||||
"""
|
||||
Export the database.
|
||||
:return: send_file (the database)
|
||||
"""
|
||||
with open(os.path.join(self.dir, "tinycheck.sqlite3"), "rb") as f:
|
||||
return send_file(
|
||||
io.BytesIO(f.read()),
|
||||
mimetype="application/octet-stream",
|
||||
as_attachment=True,
|
||||
attachment_filename='tinycheck-export-db.sqlite')
|
||||
|
||||
def get_wireless_interfaces(self):
|
||||
"""
|
||||
List the Wireless interfaces installed on the box
|
||||
:return: list of the interfaces
|
||||
"""
|
||||
try:
|
||||
return [i for i in os.listdir("/sys/class/net/") if i.startswith("wlan")]
|
||||
except:
|
||||
return ["Fake iface1", "Fake iface 2"]
|
||||
|
||||
def edit_configuration_files(self, iface):
|
||||
"""
|
||||
Edit the DNSMasq and DHCPCD configuration files
|
||||
:return: nothing.
|
||||
"""
|
||||
try:
|
||||
if re.match("^wlan[0-9]{1}$", iface):
|
||||
# Edit of DHCPD.conf
|
||||
with open("/etc/dhcpcd.conf", 'r') as file:
|
||||
content = file.readlines()
|
||||
for i, line in enumerate(content):
|
||||
if line.startswith("interface"):
|
||||
content[i] = "interface {}\n".format(iface)
|
||||
with open("/etc/dhcpcd.conf", 'w') as file:
|
||||
file.writelines(content)
|
||||
# Edit of DNSMASQ.conf
|
||||
with open("/etc/dnsmasq.conf", 'r') as file:
|
||||
content = file.readlines()
|
||||
for i, line in enumerate(content):
|
||||
if line.startswith("interface"):
|
||||
content[i] = "interface={}\n".format(iface)
|
||||
with open("/etc/dnsmasq.conf", 'w') as file:
|
||||
file.writelines(content)
|
||||
except:
|
||||
pass
|
133
server/backend/app/classes/iocs.py
Normal file
133
server/backend/app/classes/iocs.py
Normal file
@ -0,0 +1,133 @@
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
from app import db
|
||||
from app.db.models import Ioc
|
||||
from sqlalchemy.sql import exists
|
||||
from app.definitions import definitions
|
||||
from flask import escape
|
||||
import re
|
||||
import time
|
||||
|
||||
|
||||
class IOCs(object):
|
||||
def __init__(self):
|
||||
return None
|
||||
|
||||
@staticmethod
|
||||
def add(ioc_type, ioc_tag, ioc_tlp, ioc_value, source):
|
||||
"""
|
||||
Parse and add an IOC to the database.
|
||||
:return: status of the operation in JSON
|
||||
"""
|
||||
|
||||
ioc_value = ioc_value.lower() if ioc_type != "snort" else ioc_value
|
||||
ioc_valid = False
|
||||
if db.session.query(exists().where(Ioc.value == ioc_value)).scalar():
|
||||
return {"status": False,
|
||||
"message": "IOC already exists",
|
||||
"ioc": escape(ioc_value)}
|
||||
elif ioc_tlp in ["white", "green", "amber", "red"]:
|
||||
if ioc_type == "unknown":
|
||||
for t in definitions["iocs_types"]:
|
||||
if t["regex"] and t["auto"]:
|
||||
if re.match(t["regex"], ioc_value):
|
||||
ioc_type = t["type"]
|
||||
ioc_valid = True
|
||||
elif ioc_type in [t["type"] for t in definitions["iocs_types"]]:
|
||||
for t in definitions["iocs_types"]:
|
||||
if t["type"] == ioc_type and t["regex"]:
|
||||
if re.match(t["regex"], ioc_value):
|
||||
ioc_valid = True
|
||||
break
|
||||
elif t["type"] == "snort" and ioc_value[0:6] == "alert ":
|
||||
ioc_valid = True
|
||||
break
|
||||
else:
|
||||
return {"status": True,
|
||||
"message": "Wrong IOC type",
|
||||
"ioc": escape(ioc_value),
|
||||
"type": escape(ioc_type)}
|
||||
|
||||
if ioc_valid:
|
||||
added_on = int(time.time())
|
||||
db.session.add(Ioc(ioc_value, ioc_type, ioc_tlp,
|
||||
ioc_tag, source, added_on))
|
||||
db.session.commit()
|
||||
return {"status": True,
|
||||
"message": "IOC added",
|
||||
"ioc": escape(ioc_value)}
|
||||
else:
|
||||
return {"status": False,
|
||||
"message": "Wrong IOC format",
|
||||
"ioc": escape(ioc_value)}
|
||||
else:
|
||||
return {"status": False,
|
||||
"message": "Wrong IOC TLP",
|
||||
"ioc": escape(ioc_value),
|
||||
"type": escape(ioc_tlp)}
|
||||
|
||||
@staticmethod
|
||||
def delete(ioc_id):
|
||||
"""
|
||||
Delete an IOC by its id to the database.
|
||||
:return: status of the operation in JSON
|
||||
"""
|
||||
if db.session.query(exists().where(Ioc.id == ioc_id)).scalar():
|
||||
db.session.query(Ioc).filter_by(id=ioc_id).delete()
|
||||
db.session.commit()
|
||||
return {"status": True,
|
||||
"message": "IOC deleted"}
|
||||
else:
|
||||
return {"status": False,
|
||||
"message": "IOC not found"}
|
||||
|
||||
@staticmethod
|
||||
def search(term):
|
||||
"""
|
||||
Search IOCs in the database.
|
||||
:return: generator of results.
|
||||
"""
|
||||
iocs = db.session.query(Ioc).filter(
|
||||
Ioc.value.like(term.replace("*", "%"))).all()
|
||||
for ioc in iocs:
|
||||
ioc = ioc.__dict__
|
||||
yield {"id": ioc["id"],
|
||||
"type": ioc["type"],
|
||||
"tag": ioc["tag"],
|
||||
"tlp": ioc["tlp"],
|
||||
"value": ioc["value"]}
|
||||
|
||||
@staticmethod
|
||||
def get_types():
|
||||
"""
|
||||
Retreive a list of IOCs types.
|
||||
:return: generator of iocs types.
|
||||
"""
|
||||
for t in definitions["iocs_types"]:
|
||||
yield {"type": t["type"],
|
||||
"name": t["name"]}
|
||||
|
||||
@staticmethod
|
||||
def get_tags():
|
||||
"""
|
||||
Retreive a list of IOCs tags.
|
||||
:return: generator of iocs tags.
|
||||
"""
|
||||
for t in definitions["iocs_tags"]:
|
||||
yield {"tag": t["tag"],
|
||||
"name": t["name"]}
|
||||
|
||||
@staticmethod
|
||||
def get_all():
|
||||
"""
|
||||
Get all IOCs from the database
|
||||
:return: generator of the records.
|
||||
"""
|
||||
for ioc in db.session.query(Ioc).all():
|
||||
ioc = ioc.__dict__
|
||||
yield {"id": ioc["id"],
|
||||
"type": ioc["type"],
|
||||
"tag": ioc["tag"],
|
||||
"tlp": ioc["tlp"],
|
||||
"value": ioc["value"]}
|
102
server/backend/app/classes/whitelist.py
Normal file
102
server/backend/app/classes/whitelist.py
Normal file
@ -0,0 +1,102 @@
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
from app import db
|
||||
from app.db.models import Whitelist
|
||||
from sqlalchemy.sql import exists
|
||||
from app.definitions import definitions
|
||||
from flask import escape
|
||||
import re
|
||||
import time
|
||||
|
||||
|
||||
class WhiteList(object):
|
||||
def __init__(self):
|
||||
return None
|
||||
|
||||
@staticmethod
|
||||
def add(elem_type, elem_value, source):
|
||||
"""
|
||||
Parse and add an element to be whitelisted.
|
||||
:return: status of the operation in a dict
|
||||
"""
|
||||
elem_value = elem_value.lower()
|
||||
elem_valid = False
|
||||
|
||||
if db.session.query(exists().where(Whitelist.element == elem_value)).scalar():
|
||||
return {"status": False,
|
||||
"message": "Element already whitelisted",
|
||||
"element": escape(elem_value)}
|
||||
elif elem_type == "unknown":
|
||||
for t in definitions["whitelist_types"]:
|
||||
if t["regex"] and t["auto"]:
|
||||
if re.match(t["regex"], elem_value):
|
||||
elem_type = t["type"]
|
||||
elem_valid = True
|
||||
break
|
||||
elif elem_type in [t["type"] for t in definitions["whitelist_types"]]:
|
||||
for t in definitions["whitelist_types"]:
|
||||
if t["type"] == elem_type and t["regex"]:
|
||||
if re.match(t["regex"], elem_value):
|
||||
elem_valid = True
|
||||
break
|
||||
if elem_valid:
|
||||
added_on = int(time.time())
|
||||
db.session.add(Whitelist(elem_value, elem_type, source, added_on))
|
||||
db.session.commit()
|
||||
return {"status": True,
|
||||
"message": "Element whitelisted",
|
||||
"element": escape(elem_value)}
|
||||
else:
|
||||
return {"status": False,
|
||||
"message": "Wrong element format",
|
||||
"element": escape(elem_value)}
|
||||
|
||||
@staticmethod
|
||||
def delete(elem_id):
|
||||
"""
|
||||
Delete an element by its id to the database.
|
||||
:return: status of the operation in a dict
|
||||
"""
|
||||
if db.session.query(exists().where(Whitelist.id == elem_id)).scalar():
|
||||
db.session.query(Whitelist).filter_by(id=elem_id).delete()
|
||||
db.session.commit()
|
||||
return {"status": True,
|
||||
"message": "Element deleted"}
|
||||
else:
|
||||
return {"status": False,
|
||||
"message": "Element not found"}
|
||||
|
||||
@staticmethod
|
||||
def search(element):
|
||||
"""
|
||||
Search elements in the database.
|
||||
:return: generator containing elements.
|
||||
"""
|
||||
elems = db.session.query(Whitelist).filter(
|
||||
Whitelist.element.like(element.replace("*", "%"))).all()
|
||||
for elem in elems:
|
||||
elem = elem.__dict__
|
||||
yield {"id": elem["id"],
|
||||
"type": elem["type"],
|
||||
"element": elem["element"]}
|
||||
|
||||
@staticmethod
|
||||
def get_types():
|
||||
"""
|
||||
Get types of whitelisted elements.
|
||||
:return: generator containing types.
|
||||
"""
|
||||
for t in definitions["whitelist_types"]:
|
||||
yield {"type": t["type"], "name": t["name"]}
|
||||
|
||||
@staticmethod
|
||||
def get_all():
|
||||
"""
|
||||
Retrieve all whitelisted elements.
|
||||
:return: generator containing elements.
|
||||
"""
|
||||
for elem in db.session.query(Whitelist).all():
|
||||
elem = elem.__dict__
|
||||
yield {"type": elem["type"],
|
||||
"element": elem["element"]}
|
Reference in New Issue
Block a user