Compare commits
61 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 2e9f86d333 | |||
| 74770b75e7 | |||
| a1c0f12f21 | |||
| 2c9c4096ee | |||
| 11781dd0a0 | |||
| 08a4f26de4 | |||
| 793a97b530 | |||
| 920bd6785c | |||
| bbfbfc2e84 | |||
| 6f5fd11a26 | |||
| 22315277f3 | |||
| 601450d9fd | |||
| b8bed722dc | |||
| 940d5954a3 | |||
| cb0742d440 | |||
| 436870960d | |||
| 772ff95108 | |||
| 926daf3e34 | |||
| 73946c27e2 | |||
| 8e09d4e1c8 | |||
| f189f2e100 | |||
| a481e88251 | |||
| 1d1c217258 | |||
| 93e164d7c2 | |||
| 50baeaa9e5 | |||
| 691a413bfb | |||
| 73ee7a280b | |||
| e0c79fa5d6 | |||
| 61de73d989 | |||
| 9f75d339da | |||
| c1b8f4a447 | |||
| 1d8c2387ca | |||
| fd66d2274e | |||
| fa8393cba5 | |||
| 8ea52b1a4f | |||
| 2968d6fcb6 | |||
| cb7aeb2721 | |||
| 24be446598 | |||
| e04ef547c2 | |||
| 033d751e31 | |||
| d41ad28c25 | |||
| bf8edb0283 | |||
| f00a6d67b9 | |||
| 056f8b0b64 | |||
| bf848cd224 | |||
| 79b597de8e | |||
| c3f132fc26 | |||
| 0a00cc1b08 | |||
| 6bca89630e | |||
| 27942c224b | |||
| c69f2a3d6e | |||
| d5ff62590a | |||
| 1923348538 | |||
| 022f23be1c | |||
| 8f006e4ecc | |||
| 24e35d9ef5 | |||
| 53271bbb33 | |||
| d9fed1a558 | |||
| e2f5801a99 | |||
| 8ac1beba9d | |||
| 16a4a3675a |
@@ -34,6 +34,22 @@ class ZeekEngine(object):
|
|||||||
self.active_analysis = get_config(("analysis", "active"))
|
self.active_analysis = get_config(("analysis", "active"))
|
||||||
self.userlang = get_config(("frontend", "user_lang"))
|
self.userlang = get_config(("frontend", "user_lang"))
|
||||||
|
|
||||||
|
# Retreive IOCs.
|
||||||
|
if self.iocs_analysis:
|
||||||
|
self.bl_cidrs = [[IPNetwork(cidr[0]), cidr[1]]
|
||||||
|
for cidr in get_iocs("cidr")]
|
||||||
|
self.bl_hosts = get_iocs("ip4addr") + get_iocs("ip6addr")
|
||||||
|
self.bl_domains = get_iocs("domain")
|
||||||
|
self.bl_freedns = get_iocs("freedns")
|
||||||
|
self.bl_nameservers = get_iocs("ns")
|
||||||
|
self.bl_tlds = get_iocs("tld")
|
||||||
|
|
||||||
|
# Retreive whitelisted items.
|
||||||
|
if self.whitelist_analysis:
|
||||||
|
self.wl_cidrs = [IPNetwork(cidr) for cidr in get_whitelist("cidr")]
|
||||||
|
self.wl_hosts = get_whitelist("ip4addr") + get_whitelist("ip6addr")
|
||||||
|
self.wl_domains = get_whitelist("domain")
|
||||||
|
|
||||||
# Load template language
|
# Load template language
|
||||||
if not re.match("^[a-z]{2,3}$", self.userlang):
|
if not re.match("^[a-z]{2,3}$", self.userlang):
|
||||||
self.userlang = "en"
|
self.userlang = "en"
|
||||||
@@ -84,21 +100,17 @@ class ZeekEngine(object):
|
|||||||
# Check for whitelisted assets, if any, delete the record.
|
# Check for whitelisted assets, if any, delete the record.
|
||||||
if self.whitelist_analysis:
|
if self.whitelist_analysis:
|
||||||
|
|
||||||
wl_cidrs = [IPNetwork(cidr) for cidr in get_whitelist("cidr")]
|
|
||||||
wl_hosts = get_whitelist("ip4addr") + get_whitelist("ip6addr")
|
|
||||||
wl_domains = get_whitelist("domain")
|
|
||||||
|
|
||||||
for i, c in enumerate(self.conns):
|
for i, c in enumerate(self.conns):
|
||||||
if c["ip_dst"] in [ip for ip in wl_hosts]:
|
if c["ip_dst"] in [ip for ip in self.wl_hosts]:
|
||||||
self.whitelist.append(self.conns[i])
|
self.whitelist.append(self.conns[i])
|
||||||
self.conns[i] = False
|
self.conns[i] = False
|
||||||
elif c["resolution"] in wl_domains:
|
elif c["resolution"] in self.wl_domains:
|
||||||
self.whitelist.append(self.conns[i])
|
self.whitelist.append(self.conns[i])
|
||||||
self.conns[i] = False
|
self.conns[i] = False
|
||||||
elif True in [c["resolution"].endswith("." + dom) for dom in wl_domains]:
|
elif True in [c["resolution"].endswith("." + dom) for dom in self.wl_domains]:
|
||||||
self.whitelist.append(self.conns[i])
|
self.whitelist.append(self.conns[i])
|
||||||
self.conns[i] = False
|
self.conns[i] = False
|
||||||
elif True in [IPAddress(c["ip_dst"]) in cidr for cidr in wl_cidrs]:
|
elif True in [IPAddress(c["ip_dst"]) in cidr for cidr in self.wl_cidrs]:
|
||||||
self.whitelist.append(self.conns[i])
|
self.whitelist.append(self.conns[i])
|
||||||
self.conns[i] = False
|
self.conns[i] = False
|
||||||
|
|
||||||
@@ -151,17 +163,9 @@ class ZeekEngine(object):
|
|||||||
|
|
||||||
if self.iocs_analysis:
|
if self.iocs_analysis:
|
||||||
|
|
||||||
bl_cidrs = [[IPNetwork(cidr[0]), cidr[1]]
|
|
||||||
for cidr in get_iocs("cidr")]
|
|
||||||
bl_hosts = get_iocs("ip4addr") + get_iocs("ip6addr")
|
|
||||||
bl_domains = get_iocs("domain")
|
|
||||||
bl_freedns = get_iocs("freedns")
|
|
||||||
bl_nameservers = get_iocs("ns")
|
|
||||||
bl_tlds = get_iocs("tld")
|
|
||||||
|
|
||||||
for c in self.conns:
|
for c in self.conns:
|
||||||
# Check for blacklisted IP address.
|
# Check for blacklisted IP address.
|
||||||
for host in bl_hosts:
|
for host in self.bl_hosts:
|
||||||
if c["ip_dst"] == host[0]:
|
if c["ip_dst"] == host[0]:
|
||||||
c["alert_tiggered"] = True
|
c["alert_tiggered"] = True
|
||||||
self.alerts.append({"title": self.template["IOC-01"]["title"].format(c["resolution"], c["ip_dst"], host[1].upper()),
|
self.alerts.append({"title": self.template["IOC-01"]["title"].format(c["resolution"], c["ip_dst"], host[1].upper()),
|
||||||
@@ -171,7 +175,7 @@ class ZeekEngine(object):
|
|||||||
"id": "IOC-01"})
|
"id": "IOC-01"})
|
||||||
break
|
break
|
||||||
# Check for blacklisted CIDR.
|
# Check for blacklisted CIDR.
|
||||||
for cidr in bl_cidrs:
|
for cidr in self.bl_cidrs:
|
||||||
if IPAddress(c["ip_dst"]) in cidr[0]:
|
if IPAddress(c["ip_dst"]) in cidr[0]:
|
||||||
c["alert_tiggered"] = True
|
c["alert_tiggered"] = True
|
||||||
self.alerts.append({"title": self.template["IOC-02"]["title"].format(c["resolution"], cidr[0], cidr[1].upper()),
|
self.alerts.append({"title": self.template["IOC-02"]["title"].format(c["resolution"], cidr[0], cidr[1].upper()),
|
||||||
@@ -180,7 +184,7 @@ class ZeekEngine(object):
|
|||||||
"level": "Moderate",
|
"level": "Moderate",
|
||||||
"id": "IOC-02"})
|
"id": "IOC-02"})
|
||||||
# Check for blacklisted domain.
|
# Check for blacklisted domain.
|
||||||
for domain in bl_domains:
|
for domain in self.bl_domains:
|
||||||
if c["resolution"].endswith(domain[0]):
|
if c["resolution"].endswith(domain[0]):
|
||||||
if domain[1] != "tracker":
|
if domain[1] != "tracker":
|
||||||
c["alert_tiggered"] = True
|
c["alert_tiggered"] = True
|
||||||
@@ -197,7 +201,7 @@ class ZeekEngine(object):
|
|||||||
"level": "Moderate",
|
"level": "Moderate",
|
||||||
"id": "IOC-04"})
|
"id": "IOC-04"})
|
||||||
# Check for blacklisted FreeDNS.
|
# Check for blacklisted FreeDNS.
|
||||||
for domain in bl_freedns:
|
for domain in self.bl_freedns:
|
||||||
if c["resolution"].endswith("." + domain[0]):
|
if c["resolution"].endswith("." + domain[0]):
|
||||||
c["alert_tiggered"] = True
|
c["alert_tiggered"] = True
|
||||||
self.alerts.append({"title": self.template["IOC-05"]["title"].format(c["resolution"]),
|
self.alerts.append({"title": self.template["IOC-05"]["title"].format(c["resolution"]),
|
||||||
@@ -207,7 +211,7 @@ class ZeekEngine(object):
|
|||||||
"id": "IOC-05"})
|
"id": "IOC-05"})
|
||||||
|
|
||||||
# Check for suspect tlds.
|
# Check for suspect tlds.
|
||||||
for tld in bl_tlds:
|
for tld in self.bl_tlds:
|
||||||
if c["resolution"].endswith(tld[0]):
|
if c["resolution"].endswith(tld[0]):
|
||||||
c["alert_tiggered"] = True
|
c["alert_tiggered"] = True
|
||||||
self.alerts.append({"title": self.template["IOC-06"]["title"].format(c["resolution"]),
|
self.alerts.append({"title": self.template["IOC-06"]["title"].format(c["resolution"]),
|
||||||
@@ -220,7 +224,7 @@ class ZeekEngine(object):
|
|||||||
try: # Domain nameservers check.
|
try: # Domain nameservers check.
|
||||||
name_servers = pydig.query(c["resolution"], "NS")
|
name_servers = pydig.query(c["resolution"], "NS")
|
||||||
if len(name_servers):
|
if len(name_servers):
|
||||||
for ns in bl_nameservers:
|
for ns in self.bl_nameservers:
|
||||||
if name_servers[0].endswith(".{}.".format(ns[0])):
|
if name_servers[0].endswith(".{}.".format(ns[0])):
|
||||||
c["alert_tiggered"] = True
|
c["alert_tiggered"] = True
|
||||||
self.alerts.append({"title": self.template["ACT-01"]["title"].format(c["resolution"], name_servers[0]),
|
self.alerts.append({"title": self.template["ACT-01"]["title"].format(c["resolution"], name_servers[0]),
|
||||||
@@ -271,23 +275,71 @@ class ZeekEngine(object):
|
|||||||
self.files.append(f)
|
self.files.append(f)
|
||||||
|
|
||||||
for f in self.files:
|
for f in self.files:
|
||||||
if f["mime_type"] == "application/x-x509-ca-cert":
|
if f["mime_type"] == "application/x-x509-user-cert":
|
||||||
for cert in bl_certs: # Check for blacklisted certificate.
|
for cert in bl_certs: # Check for blacklisted certificate.
|
||||||
if f["sha1"] == cert[0]:
|
if f["sha1"] == cert[0]:
|
||||||
host = self.resolve(f["ip_dst"])
|
host = self.resolve(f["ip_src"])
|
||||||
c["alert_tiggered"] = True
|
|
||||||
self.alerts.append({"title": self.template["IOC-07"]["title"].format(cert[1].upper(), host),
|
self.alerts.append({"title": self.template["IOC-07"]["title"].format(cert[1].upper(), host),
|
||||||
"description": self.template["IOC-07"]["description"].format(f["sha1"], host),
|
"description": self.template["IOC-07"]["description"].format(f["sha1"], host),
|
||||||
"host": host,
|
"host": host,
|
||||||
"level": "High",
|
"level": "High",
|
||||||
"id": "IOC-07"})
|
"id": "IOC-07"})
|
||||||
|
|
||||||
|
def http_check(self, dir):
|
||||||
|
"""
|
||||||
|
Check on the http.log:
|
||||||
|
* Blacklisted domain/tld from the Host header field.
|
||||||
|
Can be used when no DNS query have been done during the session (already cached by the device.)
|
||||||
|
:return: nothing - all stuff appended to self.alerts
|
||||||
|
"""
|
||||||
|
|
||||||
|
if os.path.isfile(os.path.join(dir, "http.log")):
|
||||||
|
for record in ParseZeekLogs(os.path.join(dir, "http.log"), output_format="json", safe_headers=False):
|
||||||
|
if record is not None:
|
||||||
|
c = {"host": record['host']}
|
||||||
|
if c not in self.http:
|
||||||
|
self.http.append(c)
|
||||||
|
|
||||||
|
if self.iocs_analysis:
|
||||||
|
for c in self.http:
|
||||||
|
|
||||||
|
# If we already know the host form DNS, let's continue.
|
||||||
|
if c["host"] in [r["domain"] for r in self.dns]:
|
||||||
|
continue
|
||||||
|
|
||||||
|
# Check for blacklisted domain.
|
||||||
|
for h in self.bl_domains:
|
||||||
|
if h[1] != "tracker":
|
||||||
|
if c["host"].endswith(h[0]):
|
||||||
|
self.alerts.append({"title": self.template["IOC-08"]["title"].format(c["host"], h[1].upper()),
|
||||||
|
"description": self.template["IOC-08"]["description"].format(c["host"]),
|
||||||
|
"host": c["host"],
|
||||||
|
"level": "High",
|
||||||
|
"id": "IOC-08"})
|
||||||
|
# Check for freedns.
|
||||||
|
for h in self.bl_freedns:
|
||||||
|
if c["host"].endswith(h[0]):
|
||||||
|
self.alerts.append({"title": self.template["IOC-09"]["title"].format(c["host"]),
|
||||||
|
"description": self.template["IOC-09"]["description"].format(c["host"]),
|
||||||
|
"host": c["host"],
|
||||||
|
"level": "Moderate",
|
||||||
|
"id": "IOC-09"})
|
||||||
|
# Check for fancy TLD.
|
||||||
|
for h in self.bl_tlds:
|
||||||
|
if c["host"].endswith(h[0]):
|
||||||
|
self.alerts.append({"title": self.template["IOC-10"]["title"].format(c["host"]),
|
||||||
|
"description": self.template["IOC-10"]["description"].format(c["host"], h[0]),
|
||||||
|
"host": c["host"],
|
||||||
|
"level": "Low",
|
||||||
|
"id": "IOC-10"})
|
||||||
|
|
||||||
def ssl_check(self, dir):
|
def ssl_check(self, dir):
|
||||||
"""
|
"""
|
||||||
Check on the ssl.log:
|
Check on the ssl.log:
|
||||||
* SSL connections which doesn't use the 443.
|
* SSL connections which doesn't use the 443.
|
||||||
* "Free" certificate issuer (taken from the config).
|
* "Free" certificate issuer (taken from the config).
|
||||||
* Self-signed certificates.
|
* Self-signed certificates.
|
||||||
|
* Blacklisted domain in the CN
|
||||||
:return: nothing - all stuff appended to self.alerts
|
:return: nothing - all stuff appended to self.alerts
|
||||||
"""
|
"""
|
||||||
ssl_default_ports = get_config(("analysis", "ssl_default_ports"))
|
ssl_default_ports = get_config(("analysis", "ssl_default_ports"))
|
||||||
@@ -298,8 +350,9 @@ class ZeekEngine(object):
|
|||||||
if record is not None:
|
if record is not None:
|
||||||
c = {"host": record['id.resp_h'],
|
c = {"host": record['id.resp_h'],
|
||||||
"port": record['id.resp_p'],
|
"port": record['id.resp_p'],
|
||||||
"issuer": record["issuer"],
|
"issuer": record["issuer"] if "issuer" in record else "",
|
||||||
"validation_status": record["validation_status"]}
|
"validation_status": record["validation_status"],
|
||||||
|
"cn": record["server_name"] if "server_name" in record else ""}
|
||||||
if c not in self.ssl:
|
if c not in self.ssl:
|
||||||
self.ssl.append(c)
|
self.ssl.append(c)
|
||||||
|
|
||||||
@@ -335,6 +388,24 @@ class ZeekEngine(object):
|
|||||||
"level": "Moderate",
|
"level": "Moderate",
|
||||||
"id": "SSL-03"})
|
"id": "SSL-03"})
|
||||||
|
|
||||||
|
if self.iocs_analysis:
|
||||||
|
for cert in self.ssl:
|
||||||
|
# Check if the domain in the certificate haven't been blacklisted
|
||||||
|
# This check can be good if the domain has already been cached by
|
||||||
|
# the device so it wont appear in self.dns.
|
||||||
|
|
||||||
|
if any([cert["cn"].endswith(r["domain"]) for r in self.dns]):
|
||||||
|
continue
|
||||||
|
|
||||||
|
for domain in self.bl_domains:
|
||||||
|
if domain[1] != "tracker":
|
||||||
|
if cert["cn"].endswith(domain[0]):
|
||||||
|
self.alerts.append({"title": self.template["SSL-04"]["title"].format(domain[0], domain[1].upper()),
|
||||||
|
"description": self.template["SSL-04"]["description"].format(domain[0]),
|
||||||
|
"host": domain[0],
|
||||||
|
"level": "High",
|
||||||
|
"id": "SSL-04"})
|
||||||
|
|
||||||
def alerts_check(self):
|
def alerts_check(self):
|
||||||
"""
|
"""
|
||||||
Leverage an advice to the user based on the trigered hosts
|
Leverage an advice to the user based on the trigered hosts
|
||||||
@@ -380,6 +451,7 @@ class ZeekEngine(object):
|
|||||||
self.fill_dns(self.working_dir + "/assets/")
|
self.fill_dns(self.working_dir + "/assets/")
|
||||||
self.netflow_check(self.working_dir + "/assets/")
|
self.netflow_check(self.working_dir + "/assets/")
|
||||||
self.ssl_check(self.working_dir + "/assets/")
|
self.ssl_check(self.working_dir + "/assets/")
|
||||||
|
self.http_check(self.working_dir + "/assets/")
|
||||||
self.files_check(self.working_dir + "/assets/")
|
self.files_check(self.working_dir + "/assets/")
|
||||||
self.alerts_check()
|
self.alerts_check()
|
||||||
|
|
||||||
|
|||||||
@@ -48,6 +48,18 @@
|
|||||||
"title": "Un certificat associat a activitats {} ha estat identificat en una comunicació cap a {}.",
|
"title": "Un certificat associat a activitats {} ha estat identificat en una comunicació cap a {}.",
|
||||||
"description": "El certificat ({}) associat a {} ha estat explícitament etiquetat com a maliciós. Això indica que el seu dispositiu està probablement compromès i necessita ser analitzat en profunditat per un especialista forense."
|
"description": "El certificat ({}) associat a {} ha estat explícitament etiquetat com a maliciós. Això indica que el seu dispositiu està probablement compromès i necessita ser analitzat en profunditat per un especialista forense."
|
||||||
},
|
},
|
||||||
|
"IOC-08": {
|
||||||
|
"title": "S'ha fet una petició HTTP a {} que està etiquetada com {}.",
|
||||||
|
"description": "El domini {} identificat en la captura ha estat explícitament etiquetat com a maliciós. Això indica que el dispositiu està probablement compromès i ha de ser investigat en profunditat."
|
||||||
|
},
|
||||||
|
"IOC-09": {
|
||||||
|
"title": "S'ha fet una petició HTTP a el domini {} que és un DNS gratuït.",
|
||||||
|
"description": "El domini {} està utilitzant un servei DNS gratuït. Aquest tipus de serveis és utilitzat per cibercriminals i altres actors d'amenaces de manera comú. És força sospitós que una aplicació en segon pla utilitzi aquest tipus de serveis.Per favor investigui. "
|
||||||
|
},
|
||||||
|
"IOC-10": {
|
||||||
|
"title": "S'ha fet una petició HTTP a el domini {} que conté un TLD sospitós.",
|
||||||
|
"description": "El domini {} està utilitzant un domini de primer nivell -TLD- ({}). Encara que no sigui maliciós, aquest TLP no-genèric és usat per cibercriminals i altres actors d'amenaces amb regularitat. Comproveu aquest domini mitjançant la seva cerca a Internet. Si hi ha altres alertes relacionades amb aquest host, considereu-lo com a molt sospitós. "
|
||||||
|
},
|
||||||
"ACT-01": {
|
"ACT-01": {
|
||||||
"title": "El domini {} està utilitzant un servidor de noms sospitós ({}).",
|
"title": "El domini {} està utilitzant un servidor de noms sospitós ({}).",
|
||||||
"description": "El nom de domini {} utilitza un servidor de noms que ha estat explícitament etiquetat i associat a activitat maliciosa. Molts ciberdelinqüents i altres actors d'amenaces utilitzen aquest tipus de registradors ja que accepten criptomonedes i pagaments anònims. Es recomana investigar aquest domini i l'aplicació en execució associada mitjançant un anàlisi forense de el dispositiu. "
|
"description": "El nom de domini {} utilitza un servidor de noms que ha estat explícitament etiquetat i associat a activitat maliciosa. Molts ciberdelinqüents i altres actors d'amenaces utilitzen aquest tipus de registradors ja que accepten criptomonedes i pagaments anònims. Es recomana investigar aquest domini i l'aplicació en execució associada mitjançant un anàlisi forense de el dispositiu. "
|
||||||
@@ -68,6 +80,10 @@
|
|||||||
"title": "El certificat associat a {} és autosignat.",
|
"title": "El certificat associat a {} és autosignat.",
|
||||||
"description": "L'ús de certificats autosignats és un element comú en infrastructures utilitzades per atacants. Recomanem comprovar el host {} que està associat a aquest certificat, especialment el seu nom de domini (en cas d'existir), el seu registre WHOIS, la seva data de creació i verificant la seva reputació a Internet. "
|
"description": "L'ús de certificats autosignats és un element comú en infrastructures utilitzades per atacants. Recomanem comprovar el host {} que està associat a aquest certificat, especialment el seu nom de domini (en cas d'existir), el seu registre WHOIS, la seva data de creació i verificant la seva reputació a Internet. "
|
||||||
},
|
},
|
||||||
|
"SSL-04": {
|
||||||
|
"title": "Un certificat conté el nom de domini {}, classificat com a {}",
|
||||||
|
"description": "Un dels certificats intercanviats conté el nom de domini {}. Aquest nom de domini s’ha classificat explícitament com a maliciós. El vostre dispositiu està compromès i hauria de ser investigat amb més detall per un equip professional."
|
||||||
|
},
|
||||||
"ADV-01": {
|
"ADV-01": {
|
||||||
"title": "Comprovi les alertes per {}",
|
"title": "Comprovi les alertes per {}",
|
||||||
"description": "Si us plau, verifiqui la reputació del sistema {}, ja que sembla ser maliciós per aparèixer en {} alertes durant la sessió."
|
"description": "Si us plau, verifiqui la reputació del sistema {}, ja que sembla ser maliciós per aparèixer en {} alertes durant la sessió."
|
||||||
|
|||||||
@@ -48,6 +48,18 @@
|
|||||||
"title": "Ein Zertifikat, das mit {} Aktivitäten verknüpft ist, wurde in der Kommunikationsverbindung zu {} gefunden.",
|
"title": "Ein Zertifikat, das mit {} Aktivitäten verknüpft ist, wurde in der Kommunikationsverbindung zu {} gefunden.",
|
||||||
"description": "Das Zertifikat ({}), das mit {} verknüpft ist, wurde explizit als bösartig gekennzeichnet. Dies weist darauf hin, dass Ihr Gerät wahrscheinlich kompromittiert ist und eine forensische Analyse benötigt."
|
"description": "Das Zertifikat ({}), das mit {} verknüpft ist, wurde explizit als bösartig gekennzeichnet. Dies weist darauf hin, dass Ihr Gerät wahrscheinlich kompromittiert ist und eine forensische Analyse benötigt."
|
||||||
},
|
},
|
||||||
|
"IOC-08": {
|
||||||
|
"title": "Es wurde eine HTTP-Abfrage zu {} ausgeführt, was als {} gekennzeichnet ist.",
|
||||||
|
"description": "Der in der Aufnahme vorkommende Domain-Name {} wurde explizit als bösartig gekennzeichnet. Dies weist darauf hin, dass Ihr Gerät wahrscheinlich kompromittiert ist und eingehend untersucht werden muss."
|
||||||
|
},
|
||||||
|
"IOC-09": {
|
||||||
|
"title": "Es wurde eine HTTP-Abfrage zur Domain {} ausgeführt, die einen Free-DNS-Dienst nutzt.",
|
||||||
|
"description": "Der Domain-Name {} nutzt einen Free-DNS-Dienst. Dienste dieser Art werden häufig von Cyberkriminellen oder staatlich unterstützten Angreifern bei ihren Operationen genutzt. Es ist sehr verdächtig, dass eine im Hintergrund laufende Anwendung einen solchen Dienst verwendet. Bitte untersuchen Sie das näher."
|
||||||
|
},
|
||||||
|
"IOC-10": {
|
||||||
|
"title": "Es wurde eine HTTP-Abfrage zur Domain {} ausgeführt, die eine verdächtige TLD enthält.",
|
||||||
|
"description": "Der Domain-Name {} nutzt eine verdächtige Top-Level-Domain ({}). Diese nicht-generische TLD ist zwar selbst nicht bösartig, wird aber häufig von Cyberkriminellen und bei staatlich unterstützten Operationen verwendet. Bitte überprüfen Sie diese Domain anhand einer Internetsuche. Wenn dieser Host in anderen Warnungen erwähnt wird, können Sie ihn als sehr verdächtig betrachten."
|
||||||
|
},
|
||||||
"ACT-01": {
|
"ACT-01": {
|
||||||
"title": "Die Domain {} nutzt einen verdächtigen Nameserver ({}).",
|
"title": "Die Domain {} nutzt einen verdächtigen Nameserver ({}).",
|
||||||
"description": "Der Domain-Name {} nutzt einen Nameserver, der explizit mit bösartigen Aktivitäten in Verbindung gebracht wird. Viele Cyberkriminelle und staatlich unterstützte Angreifer nutzen Registrare dieser Art, weil sie Kryptowährungen und anonyme Zahlungen zulassen. Es wird empfohlen, diese Domain und die damit verknüpfte laufende Anwendung mithilfe einer forensischen Analyse des Telefons näher zu untersuchen."
|
"description": "Der Domain-Name {} nutzt einen Nameserver, der explizit mit bösartigen Aktivitäten in Verbindung gebracht wird. Viele Cyberkriminelle und staatlich unterstützte Angreifer nutzen Registrare dieser Art, weil sie Kryptowährungen und anonyme Zahlungen zulassen. Es wird empfohlen, diese Domain und die damit verknüpfte laufende Anwendung mithilfe einer forensischen Analyse des Telefons näher zu untersuchen."
|
||||||
@@ -68,6 +80,10 @@
|
|||||||
"title": "Das mit {} verknüpfte Zertifikat ist selbstsigniert.",
|
"title": "Das mit {} verknüpfte Zertifikat ist selbstsigniert.",
|
||||||
"description": "Die Verwendung von selbstsignierten Zertifikaten ist in der Infrastruktur von Angreifern weit verbreitet. Wir empfehlen, den mit diesem Zertifikat verknüpften Host {} zu überprüfen. Sehen Sie sich dazu seinen Domain-Namen (falls vorhanden), den WHOIS-Eintrag und das Erstellungsdatum an und überprüfen Sie die Reputation des Hosts im Internet."
|
"description": "Die Verwendung von selbstsignierten Zertifikaten ist in der Infrastruktur von Angreifern weit verbreitet. Wir empfehlen, den mit diesem Zertifikat verknüpften Host {} zu überprüfen. Sehen Sie sich dazu seinen Domain-Namen (falls vorhanden), den WHOIS-Eintrag und das Erstellungsdatum an und überprüfen Sie die Reputation des Hosts im Internet."
|
||||||
},
|
},
|
||||||
|
"SSL-04": {
|
||||||
|
"title": "Ein Zertifikat enthält den Domainnamen {}, der als {} kategorisiert ist",
|
||||||
|
"description": "Eines der ausgetauschten Zertifikate enthält den Domainnamen {}. Dieser Domainname wurde explizit als bösartig eingestuft. Ihr Gerät ist sicherlich kompromittiert und sollte von einem professionellen Team genauer untersucht werden."
|
||||||
|
},
|
||||||
"ADV-01": {
|
"ADV-01": {
|
||||||
"title": "Überprüfen Sie die Warnungen für {}",
|
"title": "Überprüfen Sie die Warnungen für {}",
|
||||||
"description": "Bitte überprüfen Sie die Reputation des Hosts {}. Dieser scheint bösartig zu sein, da er während der Sitzung {} Warnungen verursacht hat."
|
"description": "Bitte überprüfen Sie die Reputation des Hosts {}. Dieser scheint bösartig zu sein, da er während der Sitzung {} Warnungen verursacht hat."
|
||||||
|
|||||||
@@ -48,6 +48,18 @@
|
|||||||
"title": "A certificate associated to {} activities have been found in the communication to {}.",
|
"title": "A certificate associated to {} activities have been found in the communication to {}.",
|
||||||
"description": "The certificate ({}) associated to {} has been explicitly tagged as malicious. This indicates that your device is likely compromised and need a forensic analysis."
|
"description": "The certificate ({}) associated to {} has been explicitly tagged as malicious. This indicates that your device is likely compromised and need a forensic analysis."
|
||||||
},
|
},
|
||||||
|
"IOC-08": {
|
||||||
|
"title": "An HTTP request have been done to {} which is tagged as {}.",
|
||||||
|
"description": "The domain name {} seen in the capture has been explicitly tagged as malicious. This indicates that your device is likely compromised and needs to be investigated deeply."
|
||||||
|
},
|
||||||
|
"IOC-09": {
|
||||||
|
"title": "An HTTP request have been done to the domain {} which is a Free DNS.",
|
||||||
|
"description": "The domain name {} is using a Free DNS service. This kind of service is commonly used by cybercriminals or state-sponsored threat actors during their operations. It is very suspicious that an application running in background use this kind of service, please investigate."
|
||||||
|
},
|
||||||
|
"IOC-10": {
|
||||||
|
"title": "An HTTP request have been done to the domain {} which contains a suspect TLD.",
|
||||||
|
"description": "The domain name {} is using a suspect Top Level Domain ({}). Even not malicious, this non-generic TLD is used regularly by cybercrime or state-sponsored operations. Please check this domain by searching it on an internet search engine. If other alerts are related to this host, please consider it as very suspicious."
|
||||||
|
},
|
||||||
"ACT-01": {
|
"ACT-01": {
|
||||||
"title": "The domain {} is using a suspect nameserver ({}).",
|
"title": "The domain {} is using a suspect nameserver ({}).",
|
||||||
"description": "The domain name {} is using a nameserver that has been explicitly tagged to be associated to malicious activities. Many cybercriminals and state-sponsored threat actors are using this kind of registrars because they allow cryptocurrencies and anonymous payments. It is adviced to investigate on this domain and the associated running application by doing a forensic analysis of the phone."
|
"description": "The domain name {} is using a nameserver that has been explicitly tagged to be associated to malicious activities. Many cybercriminals and state-sponsored threat actors are using this kind of registrars because they allow cryptocurrencies and anonymous payments. It is adviced to investigate on this domain and the associated running application by doing a forensic analysis of the phone."
|
||||||
@@ -68,6 +80,10 @@
|
|||||||
"title": "The certificate associated to {} is self-signed.",
|
"title": "The certificate associated to {} is self-signed.",
|
||||||
"description": "The use of self-signed certificates is a common thing for attacker infrastructure. We recommend to check the host {} which is associated to this certificate, by looking at the domain name (if any), its WHOIS record, its creation date, and by checking its reputation on the internet."
|
"description": "The use of self-signed certificates is a common thing for attacker infrastructure. We recommend to check the host {} which is associated to this certificate, by looking at the domain name (if any), its WHOIS record, its creation date, and by checking its reputation on the internet."
|
||||||
},
|
},
|
||||||
|
"SSL-04": {
|
||||||
|
"title": "A certificate contains the domain name {}, categorized as {}",
|
||||||
|
"description": "One of the certificates exchanged contains the domain name {}. This domain name has been explicitly classified as malicious. Your device is definitely compromised and should be investigated further by a professional team."
|
||||||
|
},
|
||||||
"ADV-01": {
|
"ADV-01": {
|
||||||
"title": "Check the alerts for {}",
|
"title": "Check the alerts for {}",
|
||||||
"description": "Please, check the reputation of the host {}, this one seems to be malicious as it leveraged {} alerts during the session."
|
"description": "Please, check the reputation of the host {}, this one seems to be malicious as it leveraged {} alerts during the session."
|
||||||
|
|||||||
@@ -48,6 +48,18 @@
|
|||||||
"title": "Un certificado asociado a actividades {} ha sido identificado en una comunicación hacia {}.",
|
"title": "Un certificado asociado a actividades {} ha sido identificado en una comunicación hacia {}.",
|
||||||
"description": "El certificado ({}) asociado a {} ha sido explícitamente etiquetado como malicioso. Esto indica que su dispositivo está probablemente comprometido y necesita ser analizado en profundidad por un especialista forense."
|
"description": "El certificado ({}) asociado a {} ha sido explícitamente etiquetado como malicioso. Esto indica que su dispositivo está probablemente comprometido y necesita ser analizado en profundidad por un especialista forense."
|
||||||
},
|
},
|
||||||
|
"IOC-08": {
|
||||||
|
"title": "Se ha realizado una petición HTTP a {} que está etiquetada como {}.",
|
||||||
|
"description": "El dominio {} identificado en la captura ha sido explícitamente etiquetado como malicioso. Esto indica que su dispositivo está probablemente comprometido y debe ser investigado en profundidad."
|
||||||
|
},
|
||||||
|
"IOC-09": {
|
||||||
|
"title": "Se ha realizado una petición HTTP al dominio {} que es un DNS gratuito.",
|
||||||
|
"description": "El dominio {} está usando un servicio DNS gratuito. Este tipo de servicios es comúnmente utilizado por cibercriminales y otros actores de amenazas. Es altamente sospechoso que una aplicación ejecutándose en segundo plano use este tipo de servicios. Por favor investigue."
|
||||||
|
},
|
||||||
|
"IOC-10": {
|
||||||
|
"title": "Se ha realizado una petición HTTP al dominio {} que contiene un TLD sospechoso.",
|
||||||
|
"description": "El dominio {} está usando un dominio de primero nivel -TLD- ({}). Aunque no sea malicioso, este TLP no-genérico es usado por cibercriminales y otros actores de amenazas con regularidad. Verifique este dominio mediante su búsqueda en Internet. Si hay otras alertas relacionadas con este host, por favor considérelo como muy sospechoso."
|
||||||
|
},
|
||||||
"ACT-01": {
|
"ACT-01": {
|
||||||
"title": "El dominio {} está usando un servidor de nombres sospechoso ({}).",
|
"title": "El dominio {} está usando un servidor de nombres sospechoso ({}).",
|
||||||
"description": "El nombre de dominio {} usa un servidor de nombres que ha sido explícitamente etiquetado como asociado a actividad maliciosa. Muchos ciberdelincuentes y otros actores de amenazas utilizan este tipo de registradores ya que aceptan criptomonedas y pagos anónimos. Se recomienda investigar este dominio y la aplicación en ejecución asociada mediante un análisis forense del dispositivo."
|
"description": "El nombre de dominio {} usa un servidor de nombres que ha sido explícitamente etiquetado como asociado a actividad maliciosa. Muchos ciberdelincuentes y otros actores de amenazas utilizan este tipo de registradores ya que aceptan criptomonedas y pagos anónimos. Se recomienda investigar este dominio y la aplicación en ejecución asociada mediante un análisis forense del dispositivo."
|
||||||
@@ -68,6 +80,10 @@
|
|||||||
"title": "El certificado asociado a {} es autofirmado.",
|
"title": "El certificado asociado a {} es autofirmado.",
|
||||||
"description": "El uso de certificados autofirmados es un elemento común en infraestructuras utilizadas por atacantes. Recomendamos comprobar el host {} que está asociado a este certificado, especialmente su nombre de dominio (en caso de existir), su registro WHOIS, su fecha de creación y verificando su reputación en Internet."
|
"description": "El uso de certificados autofirmados es un elemento común en infraestructuras utilizadas por atacantes. Recomendamos comprobar el host {} que está asociado a este certificado, especialmente su nombre de dominio (en caso de existir), su registro WHOIS, su fecha de creación y verificando su reputación en Internet."
|
||||||
},
|
},
|
||||||
|
"SSL-04": {
|
||||||
|
"title": "Un certificado contiene el nombre de dominio {}, categorizado como {}",
|
||||||
|
"description": "Uno de los certificados intercambiados contiene el nombre de dominio {}. Este nombre de dominio se ha clasificado explícitamente como malicioso. Su dispositivo está definitivamente comprometido y debe ser investigado más a fondo por un equipo profesional."
|
||||||
|
},
|
||||||
"ADV-01": {
|
"ADV-01": {
|
||||||
"title": "Compruebe las alertas para {}",
|
"title": "Compruebe las alertas para {}",
|
||||||
"description": "Por favor, verifique la reputación del host {}, ya que parece ser malicioso por aparecer en {} alertas durante la sesión."
|
"description": "Por favor, verifique la reputación del host {}, ya que parece ser malicioso por aparecer en {} alertas durante la sesión."
|
||||||
|
|||||||
@@ -48,6 +48,18 @@
|
|||||||
"title": "Un certificat associé à des activités de {} a été vu lors de communications vers {}.",
|
"title": "Un certificat associé à des activités de {} a été vu lors de communications vers {}.",
|
||||||
"description": "Le certificat ({}) associé au serveur {} a été explicitement catégorisé comme malveillant. Votre appareil est sûrement compromis et doit être investigué plus en détails par une équipe professionnelle."
|
"description": "Le certificat ({}) associé au serveur {} a été explicitement catégorisé comme malveillant. Votre appareil est sûrement compromis et doit être investigué plus en détails par une équipe professionnelle."
|
||||||
},
|
},
|
||||||
|
"IOC-08": {
|
||||||
|
"title": "Requête HTTP vers le domaine {} qui est tagué en tant que {}.",
|
||||||
|
"description": "Le serveur {} vers lequel communique votre appareil a été explicitement catégorisé en tant que malveillant. Votre appareil est sûrement compromis et doit être investigué plus en détails par une équipe professionnelle."
|
||||||
|
},
|
||||||
|
"IOC-09": {
|
||||||
|
"title": "Requête HTTP vers le domaine {} qui est un domaine gratuit.",
|
||||||
|
"description": "Le nom de domaine {} utilise un service de noms de domaine gratuits. Ce type de service est couramment utilisé par les cybercriminels ou des acteurs associés à des États au cours de leurs opérations d'espionnage. Il est très suspect qu'une application exécutée en arrière-plan utilise ce type de service, veuillez enquêter."
|
||||||
|
},
|
||||||
|
"IOC-10": {
|
||||||
|
"title": "Requête HTTP vers le domaine {} contenant une extension suspecte.",
|
||||||
|
"description": "Le nom de domaine {} utilise une extension suspecte ({}). Même si cela n'est pas malveillant en-soi, l'utilisation d'une extension non générique est l'apanage d'acteurs cybercriminels et étatiques durant leurs opérations. Veuillez vérifier la pertinance de ce domaine en le recherchant sur un moteur de recherche Internet. Si d'autres alertes sont liées à ce dernier, veuillez le considérer comme très suspect."
|
||||||
|
},
|
||||||
"ACT-01": {
|
"ACT-01": {
|
||||||
"title": "Le domaine {} utilise un serveur de noms suspect ({}).",
|
"title": "Le domaine {} utilise un serveur de noms suspect ({}).",
|
||||||
"description": "Le nom de domaine {} utilise un serveur de noms qui a été explicitement catégorisé comme associé à des activités malveillantes. Plusieurs cybercriminels et acteurs étatiques utilisent ce type de serveurs de noms car ils autorisent les paiements anonymes grâce aux cryptomonnaies. Il est conseillé d'investiguer sur ce domaine et l'application s'y connectant en réalisant une analyse post-mortem de l'appareil analysé."
|
"description": "Le nom de domaine {} utilise un serveur de noms qui a été explicitement catégorisé comme associé à des activités malveillantes. Plusieurs cybercriminels et acteurs étatiques utilisent ce type de serveurs de noms car ils autorisent les paiements anonymes grâce aux cryptomonnaies. Il est conseillé d'investiguer sur ce domaine et l'application s'y connectant en réalisant une analyse post-mortem de l'appareil analysé."
|
||||||
@@ -68,6 +80,10 @@
|
|||||||
"title": "Le certificat associé à {} est auto-signé.",
|
"title": "Le certificat associé à {} est auto-signé.",
|
||||||
"description": "L'utilisation de certificats auto-signés est une chose courante pour des infrastructures d'attaque associées à des activités malveillantes. Nous vous recommandons de vérifier le serveur {} qui est associé à ce certificat, en regardant le nom de domaine (le cas échéant), son enregistrement WHOIS, sa date de création, et en vérifiant sa réputation sur Internet."
|
"description": "L'utilisation de certificats auto-signés est une chose courante pour des infrastructures d'attaque associées à des activités malveillantes. Nous vous recommandons de vérifier le serveur {} qui est associé à ce certificat, en regardant le nom de domaine (le cas échéant), son enregistrement WHOIS, sa date de création, et en vérifiant sa réputation sur Internet."
|
||||||
},
|
},
|
||||||
|
"SSL-04": {
|
||||||
|
"title": "Un certificat contient le nom de domaine {}, catégorisé en tant que {}",
|
||||||
|
"description": "Un des certificats échangés contient le nom de domaine {}. Ce nom de domaine a été explicitement catégorisé en tant que malveillant. Votre appareil est sûrement compromis et doit être investigué plus en détails par une équipe professionnelle."
|
||||||
|
},
|
||||||
"ADV-01": {
|
"ADV-01": {
|
||||||
"title": "Vérifiez les alertes liées au serveur {}",
|
"title": "Vérifiez les alertes liées au serveur {}",
|
||||||
"description": "Merci de vérifier la réputation et les alertes liées au serveur {}, ce dernier semble malveillant, ayant engendré {} alertes durant la session de capture."
|
"description": "Merci de vérifier la réputation et les alertes liées au serveur {}, ce dernier semble malveillant, ayant engendré {} alertes durant la session de capture."
|
||||||
|
|||||||
@@ -48,6 +48,18 @@
|
|||||||
"title": "Nella comunicazione a {} è stato rilevato un certificato associato ad attività {}.",
|
"title": "Nella comunicazione a {} è stato rilevato un certificato associato ad attività {}.",
|
||||||
"description": "Il certificato ({}) associato a {} è stato esplicitamente contrassegnato come dannoso. Questo indica che il dispositivo è potenzialmente compromesso e necessita di un'analisi forense."
|
"description": "Il certificato ({}) associato a {} è stato esplicitamente contrassegnato come dannoso. Questo indica che il dispositivo è potenzialmente compromesso e necessita di un'analisi forense."
|
||||||
},
|
},
|
||||||
|
"IOC-08": {
|
||||||
|
"title": "È stata effettuata una richiesta HTTP a {} con contrassegno {}.",
|
||||||
|
"description": "Il nome di dominio {} visualizzato nell'acquisizione è stato esplicitamente contrassegnato come dannoso. Questo indica che il dispositivo è potenzialmente compromesso e deve essere esaminato a fondo."
|
||||||
|
},
|
||||||
|
"IOC-09": {
|
||||||
|
"title": "È stata effettuata una richiesta HTTP al dominio {} che è un servizio Free DNS.",
|
||||||
|
"description": "Il nome di dominio {} utilizza un servizio Free DNS. Questo tipo di servizio è comunemente utilizzato durante le operazioni di criminali informatici o autori di attacchi commissionati da stati esteri. L'utilizzo di questo tipo di servizio da parte di un'applicazione in esecuzione in background è molto sospetto e richiede ulteriori indagini."
|
||||||
|
},
|
||||||
|
"IOC-10": {
|
||||||
|
"title": "È stata effettuata una richiesta HTTP al dominio {} contenente un dominio di primo livello sospetto.",
|
||||||
|
"description": "Il nome di dominio {} utilizza un dominio di primo livello sospetto ({}). Anche se non dannoso, questo dominio di primo livello non generico viene utilizzato regolarmente durante le operazioni di criminali informatici o autori di attacchi commissionati da stati esteri. Controllare questo dominio effettuando una ricerca tramite un motore di ricerca Internet. Se altri avvisi sono correlati all'host, è necessario considerare questo elemento molto sospetto."
|
||||||
|
},
|
||||||
"ACT-01": {
|
"ACT-01": {
|
||||||
"title": "Il dominio {} utilizza un server dei nomi sospetto ({}).",
|
"title": "Il dominio {} utilizza un server dei nomi sospetto ({}).",
|
||||||
"description": "Il nome di dominio {} utilizza un server dei nomi che è stato esplicitamente contrassegnato come associato ad attività dannose. Molti criminali informatici e autori di attacchi commissionati da stati esteri utilizzano questo tipo di registrar poiché sono ammessi criptovalute e pagamenti anonimi. È consigliabile indagare su questo dominio e sull'applicazione in esecuzione associata eseguendo un'analisi forense del telefono."
|
"description": "Il nome di dominio {} utilizza un server dei nomi che è stato esplicitamente contrassegnato come associato ad attività dannose. Molti criminali informatici e autori di attacchi commissionati da stati esteri utilizzano questo tipo di registrar poiché sono ammessi criptovalute e pagamenti anonimi. È consigliabile indagare su questo dominio e sull'applicazione in esecuzione associata eseguendo un'analisi forense del telefono."
|
||||||
@@ -68,6 +80,10 @@
|
|||||||
"title": "Il certificato associato a {} è autofirmato.",
|
"title": "Il certificato associato a {} è autofirmato.",
|
||||||
"description": "L'utilizzo di certificati autofirmati è una consuetudine per l'infrastruttura degli autori degli attacchi. È consigliabile controllare l'host {} associato a questo certificato, prestando attenzione all'eventuale nome di dominio, al record WHOIS e alla data di creazione, nonché verificandone la reputazione in Internet."
|
"description": "L'utilizzo di certificati autofirmati è una consuetudine per l'infrastruttura degli autori degli attacchi. È consigliabile controllare l'host {} associato a questo certificato, prestando attenzione all'eventuale nome di dominio, al record WHOIS e alla data di creazione, nonché verificandone la reputazione in Internet."
|
||||||
},
|
},
|
||||||
|
"SSL-04": {
|
||||||
|
"title": "Un certificato contiene il nome di dominio {}, classificato come {}",
|
||||||
|
"description": "Uno dei certificati scambiati contiene il nome di dominio {}. Questo nome di dominio è stato esplicitamente classificato come dannoso. Il tuo dispositivo è decisamente compromesso e dovrebbe essere esaminato ulteriormente da un team di professionisti."
|
||||||
|
},
|
||||||
"ADV-01": {
|
"ADV-01": {
|
||||||
"title": "Controllare gli avvisi per {}",
|
"title": "Controllare gli avvisi per {}",
|
||||||
"description": "Controllare la reputazione dell'host {}, che sembra di natura dannosa poiché ha sfruttato {} avvisi durante la sessione."
|
"description": "Controllare la reputazione dell'host {}, che sembra di natura dannosa poiché ha sfruttato {} avvisi durante la sessione."
|
||||||
|
|||||||
@@ -48,6 +48,18 @@
|
|||||||
"title": "Um certificado associado a atividades de {} foi encontrado na comunicação para {}.",
|
"title": "Um certificado associado a atividades de {} foi encontrado na comunicação para {}.",
|
||||||
"description": "O certificado ({}) associado a {} foi explicitamente marcado como malicioso. Isso indica que o dispositivo provavelmente foi comprometido e precisa de uma análise forense."
|
"description": "O certificado ({}) associado a {} foi explicitamente marcado como malicioso. Isso indica que o dispositivo provavelmente foi comprometido e precisa de uma análise forense."
|
||||||
},
|
},
|
||||||
|
"IOC-08": {
|
||||||
|
"title": "Uma solicitação de HTTP foi feita para {}, marcado como {}.",
|
||||||
|
"description": "O nome de domínio {} visto na captura foi explicitamente marcado como malicioso. Isso indica que o dispositivo provavelmente foi comprometido e precisa ser analisado com cuidado."
|
||||||
|
},
|
||||||
|
"IOC-09": {
|
||||||
|
"title": "Uma solicitação de HTTP foi feita para o domínio {}, que é um DNS gratuito.",
|
||||||
|
"description": "O nome de domínio {} está usando um serviço de DNS gratuito. Esse tipo de serviço é comumente usado por cibercriminosos ou agências de inteligência estatais no exercício de suas funções. É muito suspeito que aplicativos em execução em segundo plano usem esse tipo de serviço e isso deve ser analisado com cuidado."
|
||||||
|
},
|
||||||
|
"IOC-10": {
|
||||||
|
"title": "Uma solicitação de HTTP foi feita para o domínio {}, que contém um TLD (domínio de nível superior) suspeito.",
|
||||||
|
"description": "O nome de domínio {} está usando um TLD suspeito ({}). Mesmo não sendo malicioso, esse TLD não genérico é frequentemente usado por cibercriminosos ou agências de inteligência estatais. Analise a reputação do domínio pesquisando-o na internet. Se outros alertas forem observados, considere esse host como muito suspeito."
|
||||||
|
},
|
||||||
"ACT-01": {
|
"ACT-01": {
|
||||||
"title": "O domínio {} está usando um servidor de nomes suspeito ({}).",
|
"title": "O domínio {} está usando um servidor de nomes suspeito ({}).",
|
||||||
"description": "O nome de domínio {} está usando um servidor de nomes explicitamente marcado como associado a atividades maliciosas. Muitos cibercriminosos e agentes de inteligência estatais usam esse tipo de registradores porque isso permite pagamentos com criptomoedas e anônimos. É recomendável investigar esse domínio e o aplicativo em execução por meio de uma análise forense do telefone."
|
"description": "O nome de domínio {} está usando um servidor de nomes explicitamente marcado como associado a atividades maliciosas. Muitos cibercriminosos e agentes de inteligência estatais usam esse tipo de registradores porque isso permite pagamentos com criptomoedas e anônimos. É recomendável investigar esse domínio e o aplicativo em execução por meio de uma análise forense do telefone."
|
||||||
@@ -68,6 +80,10 @@
|
|||||||
"title": "O certificado associado a {} é autoassinado.",
|
"title": "O certificado associado a {} é autoassinado.",
|
||||||
"description": "O uso de certificados autoassinados é comum na infraestrutura de invasores. É recomendável analisar o host {} que está associado a esse certificado verificando o nome e o registro de domínio (se houver), a data de criação e sua reputação na internet."
|
"description": "O uso de certificados autoassinados é comum na infraestrutura de invasores. É recomendável analisar o host {} que está associado a esse certificado verificando o nome e o registro de domínio (se houver), a data de criação e sua reputação na internet."
|
||||||
},
|
},
|
||||||
|
"SSL-04": {
|
||||||
|
"title": "Um certificado contém o nome de domínio {}, categorizado como {}",
|
||||||
|
"description": "Um dos certificados trocados contém o nome de domínio {}. Este nome de domínio foi explicitamente classificado como malicioso. Seu dispositivo está definitivamente comprometido e deve ser investigado por uma equipe profissional."
|
||||||
|
},
|
||||||
"ADV-01": {
|
"ADV-01": {
|
||||||
"title": "Verifique os alertas para {}",
|
"title": "Verifique os alertas para {}",
|
||||||
"description": "Verifique a reputação do host {}, este parece ser malicioso, pois acionou alertas para {} durante a sessão."
|
"description": "Verifique a reputação do host {}, este parece ser malicioso, pois acionou alertas para {} durante a sessão."
|
||||||
|
|||||||
@@ -48,6 +48,18 @@
|
|||||||
"title": "Сертификат, связанный с действиями {}, был обнаружен при взаимодействии с {}.",
|
"title": "Сертификат, связанный с действиями {}, был обнаружен при взаимодействии с {}.",
|
||||||
"description": "Сертификат ({}), связанный с {}, явно отмечен как вредоносный. Это указывает на то, что ваше устройство, вероятно, взломано и требуется провести экспертный анализ."
|
"description": "Сертификат ({}), связанный с {}, явно отмечен как вредоносный. Это указывает на то, что ваше устройство, вероятно, взломано и требуется провести экспертный анализ."
|
||||||
},
|
},
|
||||||
|
"IOC-08": {
|
||||||
|
"title": "Выполнен HTTP-запрос к {}, отмеченному как {}.",
|
||||||
|
"description": "Доменное имя {}, обнаруженное при сборе данных, явно отмечено как вредоносное. Это указывает на то, что ваше устройство, вероятно, взломано и требуется тщательное расследование."
|
||||||
|
},
|
||||||
|
"IOC-09": {
|
||||||
|
"title": "Выполнен HTTP-запрос к домену {}, использующему бесплатную службу DNS.",
|
||||||
|
"description": "Доменное имя {} использует бесплатную службу DNS. Такие службы обычно используются киберпреступниками или спонсируемыми государством злоумышленниками для атак. Очень подозрительно, что приложение, работающее в фоновом режиме, использует такую службу. Требуется расследование."
|
||||||
|
},
|
||||||
|
"IOC-10": {
|
||||||
|
"title": "Выполнен HTTP-запрос к домену {}, содержащему подозрительный домен верхнего уровня.",
|
||||||
|
"description": "Доменное имя {} использует подозрительный домен верхнего уровня ({}). Даже не являясь вредоносным, этот не универсальный домен верхнего уровня регулярно используется киберпреступниками или спонсируемыми государством злоумышленниками. Проверьте этот домен, выполнив поиск в интернете. Если с этим устройством связаны другие предупреждения, это очень подозрительно."
|
||||||
|
},
|
||||||
"ACT-01": {
|
"ACT-01": {
|
||||||
"title": "Домен {} использует подозрительный сервер имен ({}).",
|
"title": "Домен {} использует подозрительный сервер имен ({}).",
|
||||||
"description": "Доменное имя {} использует сервер имен, который явно отмечен как связанный с вредоносными действиями. Многие киберпреступники и спонсируемые государством злоумышленники пользуются такими регистраторами, поскольку они позволяют использовать криптовалюту и анонимные платежи. Рекомендуется исследовать этот домен и связанные с ним работающие приложения, выполнив экспертный анализ телефона."
|
"description": "Доменное имя {} использует сервер имен, который явно отмечен как связанный с вредоносными действиями. Многие киберпреступники и спонсируемые государством злоумышленники пользуются такими регистраторами, поскольку они позволяют использовать криптовалюту и анонимные платежи. Рекомендуется исследовать этот домен и связанные с ним работающие приложения, выполнив экспертный анализ телефона."
|
||||||
@@ -68,6 +80,10 @@
|
|||||||
"title": "Сертификат, связанный с {}, является самоподписанным.",
|
"title": "Сертификат, связанный с {}, является самоподписанным.",
|
||||||
"description": "Использование самоподписанных сертификатов типично для инфраструктуры злоумышленников. Рекомендуется проверить устройство {}, связанное с этим сертификатом, изучив его доменное имя (если имеется), запись WHOIS, дату создания и репутацию в интернете."
|
"description": "Использование самоподписанных сертификатов типично для инфраструктуры злоумышленников. Рекомендуется проверить устройство {}, связанное с этим сертификатом, изучив его доменное имя (если имеется), запись WHOIS, дату создания и репутацию в интернете."
|
||||||
},
|
},
|
||||||
|
"SSL-04": {
|
||||||
|
"title": "Сертификат содержит доменное имя {}, относящееся к категории {}",
|
||||||
|
"description": "Один из обмениваемых сертификатов содержит доменное имя {}. Это доменное имя явно классифицировано как вредоносное. Ваше устройство определенно взломано и должно быть исследовано профессиональной группой."
|
||||||
|
},
|
||||||
"ADV-01": {
|
"ADV-01": {
|
||||||
"title": "Проверьте предупреждения для {}",
|
"title": "Проверьте предупреждения для {}",
|
||||||
"description": "Проверьте репутацию устройства {}. Оно кажется вредоносным, поскольку для него сработало {} предупрежд. во время сеанса."
|
"description": "Проверьте репутацию устройства {}. Оно кажется вредоносным, поскольку для него сработало {} предупрежд. во время сеанса."
|
||||||
|
|||||||
@@ -25,9 +25,6 @@
|
|||||||
<li class="menu-item">
|
<li class="menu-item">
|
||||||
<span @click="$router.push('/device/db')">Manage database</span>
|
<span @click="$router.push('/device/db')">Manage database</span>
|
||||||
</li>
|
</li>
|
||||||
<!-- <li class="menu-item">
|
|
||||||
<span @click="$router.push('/device/user')">User configuration</a>
|
|
||||||
</li> -->
|
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -42,6 +39,12 @@
|
|||||||
<li class="menu-item">
|
<li class="menu-item">
|
||||||
<span @click="$router.push('/iocs/search')">Search IOCs</span>
|
<span @click="$router.push('/iocs/search')">Search IOCs</span>
|
||||||
</li>
|
</li>
|
||||||
|
<li class="menu-item">
|
||||||
|
<span @click="$router.push('/iocs/misp')">MISP Instances</span>
|
||||||
|
</li>
|
||||||
|
<li class="menu-item">
|
||||||
|
<span @click="$router.push('/iocs/opencti')">OpenCTI Instances</span>
|
||||||
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -651,3 +651,127 @@ h4, h5 {
|
|||||||
.upper {
|
.upper {
|
||||||
text-transform: uppercase;
|
text-transform: uppercase;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*** MISP CSS ***/
|
||||||
|
|
||||||
|
.misp-form {
|
||||||
|
/* Using CSS Grid to lay out the elements in two-dimensions: */
|
||||||
|
display: grid;
|
||||||
|
/* specifying a 0.2em gutter/gap between adjacent elements: */
|
||||||
|
gap: 0.4em;
|
||||||
|
overflow:auto;
|
||||||
|
grid-template-columns: 10em 0.5em 1fr;
|
||||||
|
width: 100%;
|
||||||
|
border-radius:.1rem;
|
||||||
|
margin-bottom: .8rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.misp-label {
|
||||||
|
/* placing all <label> elements in the grid column 1 (the first): */
|
||||||
|
grid-column: 1;
|
||||||
|
text-align: left;
|
||||||
|
padding-top: .3em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.misp-offline {
|
||||||
|
background-color: #e85600;
|
||||||
|
color: #FFF;
|
||||||
|
font-size: 11px;
|
||||||
|
border-radius: 3px;
|
||||||
|
padding:3px 6px 3px 6px;
|
||||||
|
cursor: help;
|
||||||
|
}
|
||||||
|
|
||||||
|
.misp-online {
|
||||||
|
background-color: #64c800;
|
||||||
|
color: #FFF;
|
||||||
|
font-size: 11px;
|
||||||
|
border-radius: 3px;
|
||||||
|
padding:3px 6px 3px 6px;
|
||||||
|
cursor: help;
|
||||||
|
}
|
||||||
|
.misp-name {
|
||||||
|
font-size: 1rem;
|
||||||
|
font-family: "Roboto-Bold";
|
||||||
|
color: #484848;
|
||||||
|
}
|
||||||
|
|
||||||
|
.misp-name:disabled {
|
||||||
|
border-style: none;
|
||||||
|
color:inherit;
|
||||||
|
background-color: inherit;
|
||||||
|
padding: unset;
|
||||||
|
}
|
||||||
|
|
||||||
|
.misp-input {
|
||||||
|
grid-column: 3;
|
||||||
|
align-self: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.misp-input:disabled {
|
||||||
|
border-style: none;
|
||||||
|
color:inherit;
|
||||||
|
background-color: inherit;
|
||||||
|
padding: unset;
|
||||||
|
}
|
||||||
|
|
||||||
|
.misp-button {
|
||||||
|
/* positioning the <button> element in the grid-area identified
|
||||||
|
by the name of 'submit': */
|
||||||
|
grid-area: submit;
|
||||||
|
}
|
||||||
|
|
||||||
|
.loading {
|
||||||
|
margin-bottom: 12px;
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.loading::after {
|
||||||
|
animation: loading .5s infinite linear;
|
||||||
|
background: 0 0;
|
||||||
|
border: .1rem solid #66758c;
|
||||||
|
border-radius: 50%;
|
||||||
|
border-right-color: transparent;
|
||||||
|
border-top-color: transparent;
|
||||||
|
content: "";
|
||||||
|
display: block;
|
||||||
|
height: .8rem;
|
||||||
|
left: 50%;
|
||||||
|
margin-left: -.4rem;
|
||||||
|
margin-top: -.4rem;
|
||||||
|
opacity: 1;
|
||||||
|
padding: 0;
|
||||||
|
position: absolute;
|
||||||
|
top: 50%;
|
||||||
|
width: .8rem;
|
||||||
|
z-index: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.loading.loading-lg::after {
|
||||||
|
height: 1.6rem;
|
||||||
|
margin-left: -.8rem;
|
||||||
|
margin-top: -.8rem;
|
||||||
|
width: 1.6rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tooltip::after{
|
||||||
|
background:rgba(48,55,66,.95);
|
||||||
|
border-radius:3px;
|
||||||
|
bottom:100%;
|
||||||
|
color:#fff;
|
||||||
|
content:attr(data-tooltip);
|
||||||
|
display:block;
|
||||||
|
font-size: 11px;
|
||||||
|
left:50%;
|
||||||
|
max-width:320px;
|
||||||
|
opacity:0;
|
||||||
|
overflow:hidden;
|
||||||
|
padding:3px 6px 3px 6px;
|
||||||
|
pointer-events:none;
|
||||||
|
position:absolute;
|
||||||
|
text-overflow:ellipsis;
|
||||||
|
transform:translate(-50%,.4rem);
|
||||||
|
transition:opacity .2s,transform .2s;
|
||||||
|
white-space:pre;
|
||||||
|
z-index:300
|
||||||
|
}
|
||||||
@@ -34,6 +34,18 @@ const routes = [
|
|||||||
component: () => import('../views/iocs-manage.vue'),
|
component: () => import('../views/iocs-manage.vue'),
|
||||||
props: true
|
props: true
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
path: '/iocs/misp',
|
||||||
|
name: 'iocs-manage',
|
||||||
|
component: () => import('../views/iocs-misp.vue'),
|
||||||
|
props: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: '/iocs/opencti',
|
||||||
|
name: 'iocs-opencti',
|
||||||
|
component: () => import('../views/iocs-opencti.vue'),
|
||||||
|
props: true
|
||||||
|
},
|
||||||
{
|
{
|
||||||
path: '/iocs/search',
|
path: '/iocs/search',
|
||||||
name: 'iocs-search',
|
name: 'iocs-search',
|
||||||
|
|||||||
@@ -35,6 +35,10 @@
|
|||||||
<input type="checkbox" @change="switch_config('frontend', 'virtual_keyboard')" v-model="config.frontend.virtual_keyboard">
|
<input type="checkbox" @change="switch_config('frontend', 'virtual_keyboard')" v-model="config.frontend.virtual_keyboard">
|
||||||
<i class="form-icon"></i> Use virtual keyboard (for touch screen)
|
<i class="form-icon"></i> Use virtual keyboard (for touch screen)
|
||||||
</label>
|
</label>
|
||||||
|
<label class="form-switch">
|
||||||
|
<input type="checkbox" @change="switch_config('frontend', 'choose_net')" v-model="config.frontend.choose_net">
|
||||||
|
<i class="form-icon"></i> Allow the end-user to choose the network even if connected.
|
||||||
|
</label>
|
||||||
<label class="form-switch">
|
<label class="form-switch">
|
||||||
<input type="checkbox" @change="switch_config('frontend', 'reboot_option')" v-model="config.frontend.reboot_option">
|
<input type="checkbox" @change="switch_config('frontend', 'reboot_option')" v-model="config.frontend.reboot_option">
|
||||||
<i class="form-icon"></i> Allow the end-user to reboot the device from the interface.
|
<i class="form-icon"></i> Allow the end-user to reboot the device from the interface.
|
||||||
|
|||||||
@@ -0,0 +1,174 @@
|
|||||||
|
<template>
|
||||||
|
<div class="backend-content" id="content">
|
||||||
|
<div class="column col-8 col-xs-12">
|
||||||
|
<h3 class="s-title">Manage MISP instances</h3>
|
||||||
|
<ul class="tab tab-block">
|
||||||
|
<li class="tab-item">
|
||||||
|
<a href="#" v-on:click="switch_tab('addmisp')" v-bind:class="{ active: tabs.addmisp }">Add instance</a>
|
||||||
|
</li>
|
||||||
|
<li class="tab-item">
|
||||||
|
<a href="#" v-on:click="switch_tab('instances')" v-bind:class="{ active: tabs.instances }">Existing instances</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
<div v-if="tabs.addmisp">
|
||||||
|
<div class="misp-form">
|
||||||
|
<label class="misp-label">Instance name</label><span></span>
|
||||||
|
<input class="form-input" type="text" ref="misp_name" placeholder="CYBERACME MISP" v-model="mispinst.name" required>
|
||||||
|
<label class="misp-label">Instance URL</label><span></span>
|
||||||
|
<input class="form-input" type="text" ref="misp_url" placeholder="https://misp.cyberacme.com" v-model="mispinst.url" required>
|
||||||
|
<label class="misp-label">Authentication key</label><span></span>
|
||||||
|
<input class="form-input" type="text" ref="misp_key" placeholder="OqHSMyAuth3ntic4t10nK3y0MyAuth3ntic4t10nK3y3iiH" v-model="mispinst.key" required>
|
||||||
|
<label class="misp-label" v-if="mispinst.url.startsWith('https://')">Verify certificate? </label><span v-if="mispinst.url.startsWith('https://')"></span>
|
||||||
|
<div style="flex:50%" v-if="mispinst.url.startsWith('https://')"><label class="form-switch">
|
||||||
|
<input type="checkbox" v-model="mispinst.ssl">
|
||||||
|
<i class="form-icon"></i>
|
||||||
|
</label></div>
|
||||||
|
</div>
|
||||||
|
<button class="btn-primary btn col-12" v-on:click="add_instance()">Add MISP instance</button>
|
||||||
|
<div class="form-group" v-if="added">
|
||||||
|
<div class="toast toast-success">
|
||||||
|
✓ MISP instance added successfully. Redirecting to instances in 2 seconds.
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group" v-if="error">
|
||||||
|
<div class="toast toast-error">
|
||||||
|
✗ MISP instance not added. {{error}}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group" v-if="tabs.instances">
|
||||||
|
<div v-if="instances.length">
|
||||||
|
<table class="table table-striped table-hover">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>Name</th>
|
||||||
|
<th>Server</th>
|
||||||
|
<th>Authkey</th>
|
||||||
|
<th>Status</th>
|
||||||
|
<th>Action</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<tr v-for="i in instances" v-bind:key="i.id">
|
||||||
|
<td>{{ i.name }}</td>
|
||||||
|
<td>{{ i.url.replace('https://', '') .replace('http://', '') }}</td>
|
||||||
|
<td>{{ i.apikey.slice(0,5) }} [...] {{ i.apikey.slice(35,40) }}</td>
|
||||||
|
<td>
|
||||||
|
<span v-if="i.connected" class="misp-online tooltip" :data-tooltip="i.lastsync">✓ ONLINE</span>
|
||||||
|
<span v-else class="misp-offline tooltip" :data-tooltip="i.lastsync">⚠ OFFLINE</span>
|
||||||
|
</td>
|
||||||
|
<td><button class="btn btn-sm" v-on:click="delete_instance(i)">Delete</button></td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
<div v-else>
|
||||||
|
<div class="empty">
|
||||||
|
<div v-if="loading">
|
||||||
|
<p class="empty-title h5">
|
||||||
|
<span class="loading loading-lg"></span>
|
||||||
|
</p>
|
||||||
|
<p class="empty-subtitle">Testing and loading your MISP instances.</p>
|
||||||
|
</div>
|
||||||
|
<div v-else>
|
||||||
|
<p class="empty-title h5">No MISP instance found.</p>
|
||||||
|
<p class="empty-subtitle">Do not hesitate to add a MISP instance.</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<script>
|
||||||
|
|
||||||
|
import axios from 'axios'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'managemisp',
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
error:false,
|
||||||
|
loading:false,
|
||||||
|
added:false,
|
||||||
|
mispinst:{ name:'', url:'',key:'', ssl:false },
|
||||||
|
instances:[],
|
||||||
|
tabs: { "addmisp" : true, "instances" : false },
|
||||||
|
jwt:""
|
||||||
|
}
|
||||||
|
},
|
||||||
|
props: { },
|
||||||
|
methods: {
|
||||||
|
add_instance: function()
|
||||||
|
{
|
||||||
|
this.added = false;
|
||||||
|
this.error = false;
|
||||||
|
if (this.mispinst.name && this.mispinst.url && this.mispinst.key)
|
||||||
|
{
|
||||||
|
axios.post(`/api/misp/add`, { data: { instance: this.mispinst } }, { headers: {'X-Token': this.jwt} }).then(response => {
|
||||||
|
if(response.data.status){
|
||||||
|
this.added = true;
|
||||||
|
setTimeout(function (){
|
||||||
|
this.switch_tab('instances')
|
||||||
|
this.mispinst = { name:'', url:'',key:'', ssl:false }
|
||||||
|
}.bind(this), 2000);
|
||||||
|
} else {
|
||||||
|
this.error = response.data.message;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch(err => (console.log(err)))
|
||||||
|
}
|
||||||
|
},
|
||||||
|
delete_instance(elem)
|
||||||
|
{
|
||||||
|
axios.get(`/api/misp/delete/${elem.id}`, { timeout: 10000, headers: {'X-Token': this.jwt} })
|
||||||
|
.then(response => {
|
||||||
|
if(response.data.status){
|
||||||
|
this.instances = this.instances.filter(function(el) { return el != elem; });
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch(err => (console.log(err)))
|
||||||
|
},
|
||||||
|
get_misp_instances()
|
||||||
|
{
|
||||||
|
this.loading = true;
|
||||||
|
this.instances = []
|
||||||
|
axios.get(`/api/misp/get_all`, { timeout: 10000, headers: {'X-Token': this.jwt} })
|
||||||
|
.then(response => {
|
||||||
|
if(response.data.results){
|
||||||
|
this.instances = response.data.results;
|
||||||
|
this.instances.forEach(e => {
|
||||||
|
var lastsync = parseInt((Date.now()/1000 - e.lastsync) / 86400)
|
||||||
|
e.lastsync = (!lastsync)? "Synchronized today" : `Synchronized ${lastsync} day(s) ago`
|
||||||
|
} )
|
||||||
|
}
|
||||||
|
this.loading = false
|
||||||
|
})
|
||||||
|
.catch(err => (console.log(err)))
|
||||||
|
},
|
||||||
|
switch_tab: function(tab) {
|
||||||
|
|
||||||
|
Object.keys(this.tabs).forEach(key => {
|
||||||
|
if( key == tab ){
|
||||||
|
this.tabs[key] = true
|
||||||
|
if (key == "instances") this.get_misp_instances();
|
||||||
|
} else {
|
||||||
|
this.tabs[key] = false
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
get_jwt(){
|
||||||
|
axios.get(`/api/get-token`, { timeout: 10000 })
|
||||||
|
.then(response => {
|
||||||
|
if(response.data.token){
|
||||||
|
this.jwt = response.data.token
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch(err => (console.log(err)))
|
||||||
|
}
|
||||||
|
},
|
||||||
|
created: function() {
|
||||||
|
this.get_jwt();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
@@ -0,0 +1,170 @@
|
|||||||
|
<template>
|
||||||
|
<div class="backend-content" id="content">
|
||||||
|
<div class="column col-8 col-xs-12">
|
||||||
|
<h3 class="s-title">Manage OpenCTI instances</h3>
|
||||||
|
<ul class="tab tab-block">
|
||||||
|
<li class="tab-item">
|
||||||
|
<a href="#" v-on:click="switch_tab('addopencti')" v-bind:class="{ active: tabs.addopencti }">Add instance</a>
|
||||||
|
</li>
|
||||||
|
<li class="tab-item">
|
||||||
|
<a href="#" v-on:click="switch_tab('instances')" v-bind:class="{ active: tabs.instances }">Existing instances</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
<div v-if="tabs.addopencti">
|
||||||
|
<div class="misp-form">
|
||||||
|
<label class="misp-label">Instance name</label><span></span>
|
||||||
|
<input class="form-input" type="text" placeholder="CYBERACME OpenCTI" v-model="openctiinst.name" required>
|
||||||
|
<label class="misp-label">Instance URL</label><span></span>
|
||||||
|
<input class="form-input" type="text" placeholder="https://opencti.cyberacme.com" v-model="openctiinst.url" required>
|
||||||
|
<label class="misp-label">Authentication key</label><span></span>
|
||||||
|
<input class="form-input" type="text" placeholder="83114ab2-3570-493b-8caa-14ef1bcf8e9a" v-model="openctiinst.key" required>
|
||||||
|
<label class="misp-label">Verify certificate? </label><span></span>
|
||||||
|
<div style="flex:50%"><label class="form-switch">
|
||||||
|
<input type="checkbox" v-model="openctiinst.ssl">
|
||||||
|
<i class="form-icon"></i>
|
||||||
|
</label></div>
|
||||||
|
</div>
|
||||||
|
<button class="btn-primary btn col-12" v-on:click="add_instance()">Add OpenCTI instance</button>
|
||||||
|
<div class="form-group" v-if="added">
|
||||||
|
<div class="toast toast-success">
|
||||||
|
✓ OpenCTI instance added successfully.
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group" v-if="error">
|
||||||
|
<div class="toast toast-error">
|
||||||
|
✗ OpenCTI instance not added. {{error}}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group" v-if="tabs.instances">
|
||||||
|
<div v-if="instances.length">
|
||||||
|
<table class="table table-striped table-hover">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>Name</th>
|
||||||
|
<th>Server</th>
|
||||||
|
<th>Authkey</th>
|
||||||
|
<th>Status</th>
|
||||||
|
<th>Action</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<tr v-for="i in instances" v-bind:key="i.id">
|
||||||
|
<td>{{ i.name }}</td>
|
||||||
|
<td>{{ i.url.replace('https://', '') .replace('http://', '') }}</td>
|
||||||
|
<td>{{ i.apikey.slice(0,5) }} [...] {{ i.apikey.slice(35,40) }}</td>
|
||||||
|
<td>
|
||||||
|
<span v-if="i.connected" class="misp-online tooltip" :data-tooltip="i.lastsync">✓ ONLINE</span>
|
||||||
|
<span v-else class="misp-offline tooltip" :data-tooltip="i.lastsync">⚠ OFFLINE</span>
|
||||||
|
</td>
|
||||||
|
<td><button class="btn btn-sm" v-on:click="delete_instance(i)">Delete</button></td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
<div v-else>
|
||||||
|
<div class="empty">
|
||||||
|
<div v-if="loading">
|
||||||
|
<p class="empty-title h5">
|
||||||
|
<span class="loading loading-lg"></span>
|
||||||
|
</p>
|
||||||
|
<p class="empty-subtitle">Testing and loading your OpenCTI instances.</p>
|
||||||
|
</div>
|
||||||
|
<div v-else>
|
||||||
|
<p class="empty-title h5">No OpenCTI instance found.</p>
|
||||||
|
<p class="empty-subtitle">Do not hesitate to add a OpenCTI instance.</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<script>
|
||||||
|
|
||||||
|
import axios from 'axios'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'manageopencti',
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
error:false,
|
||||||
|
loading:false,
|
||||||
|
added:false,
|
||||||
|
openctiinst:{ name:'', url:'',key:'', ssl:false },
|
||||||
|
instances:[],
|
||||||
|
tabs: { "addopencti" : true, "instances" : false },
|
||||||
|
jwt:""
|
||||||
|
}
|
||||||
|
},
|
||||||
|
props: { },
|
||||||
|
methods: {
|
||||||
|
add_instance: function()
|
||||||
|
{
|
||||||
|
this.added = false;
|
||||||
|
this.error = false;
|
||||||
|
if (this.openctiinst.name && this.openctiinst.url && this.openctiinst.key)
|
||||||
|
{
|
||||||
|
axios.post(`/api/opencti/add`, { data: { instance: this.openctiinst } }, { headers: {'X-Token': this.jwt} }).then(response => {
|
||||||
|
if(response.data.status){
|
||||||
|
this.added = true;
|
||||||
|
} else {
|
||||||
|
this.error = response.data.message;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch(err => (console.log(err)))
|
||||||
|
}
|
||||||
|
},
|
||||||
|
delete_instance(elem)
|
||||||
|
{
|
||||||
|
axios.get(`/api/opencti/delete/${elem.id}`, { timeout: 10000, headers: {'X-Token': this.jwt} })
|
||||||
|
.then(response => {
|
||||||
|
if(response.data.status){
|
||||||
|
this.instances = this.instances.filter(function(el) { return el != elem; });
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch(err => (console.log(err)))
|
||||||
|
},
|
||||||
|
get_opencti_instances()
|
||||||
|
{
|
||||||
|
this.loading = true;
|
||||||
|
this.instances = []
|
||||||
|
axios.get(`/api/opencti/get_all`, { timeout: 10000, headers: {'X-Token': this.jwt} })
|
||||||
|
.then(response => {
|
||||||
|
if(response.data.results){
|
||||||
|
this.instances = response.data.results;
|
||||||
|
this.instances.forEach(e => {
|
||||||
|
var lastsync = parseInt((Date.now()/1000 - e.lastsync) / 86400)
|
||||||
|
e.lastsync = (!lastsync)? "Synchronized today" : `Synchronized ${lastsync} day(s) ago`
|
||||||
|
} )
|
||||||
|
}
|
||||||
|
this.loading = false
|
||||||
|
})
|
||||||
|
.catch(err => (console.log(err)))
|
||||||
|
},
|
||||||
|
switch_tab: function(tab) {
|
||||||
|
|
||||||
|
Object.keys(this.tabs).forEach(key => {
|
||||||
|
if( key == tab ){
|
||||||
|
this.tabs[key] = true
|
||||||
|
if (key == "instances") this.get_opencti_instances();
|
||||||
|
} else {
|
||||||
|
this.tabs[key] = false
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
get_jwt(){
|
||||||
|
axios.get(`/api/get-token`, { timeout: 10000 })
|
||||||
|
.then(response => {
|
||||||
|
if(response.data.token){
|
||||||
|
this.jwt = response.data.token
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch(err => (console.log(err)))
|
||||||
|
}
|
||||||
|
},
|
||||||
|
created: function() {
|
||||||
|
this.get_jwt();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
@@ -13,27 +13,37 @@
|
|||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th>Indicator</th>
|
<th>Indicator</th>
|
||||||
<th>Type</th>
|
|
||||||
<th>Tag</th>
|
<th>Tag</th>
|
||||||
<th>TLP</th>
|
<th>TLP</th>
|
||||||
<th> </th>
|
<th>Source</th>
|
||||||
|
<th>Action</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
<tr v-for="r in results" :key="r.tlp">
|
<tr v-for="r in results" :key="r.tlp">
|
||||||
<td>{{ r.value }}</td>
|
<td>{{ r.value }}</td>
|
||||||
<td class="capi">{{ r.type }}</td>
|
|
||||||
<td class="upper">{{ r.tag }}</td>
|
<td class="upper">{{ r.tag }}</td>
|
||||||
<td><label :class="['tlp-' + r.tlp]">{{ r.tlp }}</label></td>
|
<td><label :class="['tlp-' + r.tlp]">{{ r.tlp }}</label></td>
|
||||||
|
<td class="capi">{{ r.source }}</td>
|
||||||
<td><button class="btn btn-sm" v-on:click="remove(r)">Delete</button></td>
|
<td><button class="btn btn-sm" v-on:click="remove(r)">Delete</button></td>
|
||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
<div v-else-if="first_search==false">
|
<div v-else-if="first_search==false">
|
||||||
<div class="empty">
|
<div v-if="loading">
|
||||||
<p class="empty-title h5">IOC<span v-if="this.iocs.match(/[^\r\n]+/g).length>1">s</span> not found.</p>
|
<div class="empty">
|
||||||
<p class="empty-subtitle">Try wildcard search to expend your search.</p>
|
<p class="empty-title h5">
|
||||||
|
<span class="loading loading-lg"></span>
|
||||||
|
</p>
|
||||||
|
<p class="empty-subtitle">Finding your IOC(s)...</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div v-else>
|
||||||
|
<div class="empty">
|
||||||
|
<p class="empty-title h5">IOC<span v-if="this.iocs.match(/[^\r\n]+/g).length>1">s</span> not found.</p>
|
||||||
|
<p class="empty-subtitle">Try wildcard search to expend your search.</p>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -49,7 +59,8 @@ export default {
|
|||||||
return {
|
return {
|
||||||
results: [],
|
results: [],
|
||||||
first_search: true,
|
first_search: true,
|
||||||
jwt:""
|
jwt:"",
|
||||||
|
loading:false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
props: { },
|
props: { },
|
||||||
@@ -57,6 +68,7 @@ export default {
|
|||||||
search_iocs: function() {
|
search_iocs: function() {
|
||||||
this.results = []
|
this.results = []
|
||||||
this.first_search = false
|
this.first_search = false
|
||||||
|
this.loading = true;
|
||||||
this.iocs.match(/[^\r\n]+/g).forEach(ioc => {
|
this.iocs.match(/[^\r\n]+/g).forEach(ioc => {
|
||||||
ioc = ioc.trim()
|
ioc = ioc.trim()
|
||||||
if("alert " != ioc.slice(0,6)) {
|
if("alert " != ioc.slice(0,6)) {
|
||||||
@@ -72,6 +84,7 @@ export default {
|
|||||||
if(response.data.results.length>0){
|
if(response.data.results.length>0){
|
||||||
this.results = [].concat(this.results, response.data.results);
|
this.results = [].concat(this.results, response.data.results);
|
||||||
}
|
}
|
||||||
|
this.loading = false;
|
||||||
})
|
})
|
||||||
.catch(err => (console.log(err)))
|
.catch(err => (console.log(err)))
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -128,8 +128,8 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.report-wrapper {
|
.report-wrapper {
|
||||||
width:90%;
|
|
||||||
margin:auto;
|
margin:auto;
|
||||||
|
padding-bottom:1px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.device-ctx {
|
.device-ctx {
|
||||||
@@ -212,10 +212,11 @@
|
|||||||
.report-wrapper {
|
.report-wrapper {
|
||||||
width:60%;
|
width:60%;
|
||||||
margin:auto;
|
margin:auto;
|
||||||
|
padding-bottom: 1px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.device-ctx {
|
.device-ctx {
|
||||||
padding:15px;
|
padding:15px 0px 15px 0px;
|
||||||
margin:auto;
|
margin:auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -303,6 +304,17 @@ footer {
|
|||||||
padding-left:40px;
|
padding-left:40px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.device-ctx-legend {
|
||||||
|
font-size: 14px;
|
||||||
|
color: #a6a6a6;
|
||||||
|
margin-top: 10px;
|
||||||
|
padding-top: 10px;
|
||||||
|
background-color: #fbfbfb;
|
||||||
|
padding: 10px;
|
||||||
|
border-radius: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
.group-title {
|
.group-title {
|
||||||
text-transform: uppercase;
|
text-transform: uppercase;
|
||||||
color : #999;
|
color : #999;
|
||||||
|
|||||||
@@ -53,7 +53,7 @@ export default {
|
|||||||
load_config: function() {
|
load_config: function() {
|
||||||
axios.get(`/api/misc/config`, { timeout: 60000 })
|
axios.get(`/api/misc/config`, { timeout: 60000 })
|
||||||
.then(response => {
|
.then(response => {
|
||||||
this.quit_available = response.data.quit_option
|
this.quit_available = (response.data.quit_option && (["localhost", "127.0.0.1"].some(h => window.location.host.includes(h) )))
|
||||||
this.off_available = response.data.shutdown_option
|
this.off_available = response.data.shutdown_option
|
||||||
})
|
})
|
||||||
.catch(error => { console.log(error) });
|
.catch(error => { console.log(error) });
|
||||||
|
|||||||
@@ -50,8 +50,11 @@
|
|||||||
"low_msg": "Només teniu {nb} alertes baixes, <br /> Si us plau comproveu-les.",
|
"low_msg": "Només teniu {nb} alertes baixes, <br /> Si us plau comproveu-les.",
|
||||||
"save_report": "Desa l'informe",
|
"save_report": "Desa l'informe",
|
||||||
"report_of": "Informe de",
|
"report_of": "Informe de",
|
||||||
"ip_address": "Adreça IP",
|
"ip_address": "Adreça IP:",
|
||||||
"mac_address": "Adreça MAC",
|
"mac_address": "Adreça MAC:",
|
||||||
|
"pcap_sha1": "SHA1:",
|
||||||
|
"capture_started": "La captura va començar a:",
|
||||||
|
"capture_ended": "La captura va acabar el:",
|
||||||
"high": "alt",
|
"high": "alt",
|
||||||
"moderat": "moderat",
|
"moderat": "moderat",
|
||||||
"low": "baix"
|
"low": "baix"
|
||||||
|
|||||||
@@ -50,8 +50,11 @@
|
|||||||
"low_msg": "Sie haben nur {nb} Warnungen der Stufe \"Niedrig\":<br> Überprüfen Sie sie gerne.",
|
"low_msg": "Sie haben nur {nb} Warnungen der Stufe \"Niedrig\":<br> Überprüfen Sie sie gerne.",
|
||||||
"save_report": "Bericht speichern",
|
"save_report": "Bericht speichern",
|
||||||
"report_of": "Bericht zu",
|
"report_of": "Bericht zu",
|
||||||
"ip_address": "IP-Adresse",
|
"ip_address": "IP-Adresse:",
|
||||||
"mac_address": "MAC-Adresse",
|
"mac_address": "MAC-Adresse:",
|
||||||
|
"pcap_sha1": "SHA1:",
|
||||||
|
"capture_started": "Capture begann mit:",
|
||||||
|
"capture_ended": "Capture endete an:",
|
||||||
"high": "Hoch",
|
"high": "Hoch",
|
||||||
"moderate": "Mittel",
|
"moderate": "Mittel",
|
||||||
"low": "Niedrig"
|
"low": "Niedrig"
|
||||||
|
|||||||
@@ -50,8 +50,11 @@
|
|||||||
"low_msg": "You have only {nb} low alerts,<br /> don't hesitate to check them.",
|
"low_msg": "You have only {nb} low alerts,<br /> don't hesitate to check them.",
|
||||||
"save_report": "Save the report",
|
"save_report": "Save the report",
|
||||||
"report_of": "Report of",
|
"report_of": "Report of",
|
||||||
"ip_address": "IP address",
|
"ip_address": "IP address:",
|
||||||
"mac_address": "MAC address",
|
"mac_address": "MAC address:",
|
||||||
|
"pcap_sha1": "SHA1:",
|
||||||
|
"capture_started": "Capture started on:",
|
||||||
|
"capture_ended": "Capture ended on:",
|
||||||
"high": "high",
|
"high": "high",
|
||||||
"moderate": "moderate",
|
"moderate": "moderate",
|
||||||
"low": "low"
|
"low": "low"
|
||||||
|
|||||||
@@ -50,8 +50,11 @@
|
|||||||
"low_msg": "Solo tiene {nb} alertas bajas, <br /> por favor revíselas",
|
"low_msg": "Solo tiene {nb} alertas bajas, <br /> por favor revíselas",
|
||||||
"save_report": "Guardar el informe",
|
"save_report": "Guardar el informe",
|
||||||
"report_of": "Informe de",
|
"report_of": "Informe de",
|
||||||
"ip_address": "dirección IP",
|
"ip_address": "Dirección IP:",
|
||||||
"mac_address": "dirección MAC",
|
"mac_address": "Dirección MAC:",
|
||||||
|
"pcap_sha1": "SHA1:",
|
||||||
|
"capture_started": "Captura comenzó a:",
|
||||||
|
"capture_ended": "Captura terminó a:",
|
||||||
"high": "alta",
|
"high": "alta",
|
||||||
"moderate": "moderada",
|
"moderate": "moderada",
|
||||||
"low": "bajo"
|
"low": "bajo"
|
||||||
|
|||||||
@@ -52,6 +52,9 @@
|
|||||||
"report_of": "Rapport de",
|
"report_of": "Rapport de",
|
||||||
"ip_address": "Adresse IP :",
|
"ip_address": "Adresse IP :",
|
||||||
"mac_address": "Adresse MAC :",
|
"mac_address": "Adresse MAC :",
|
||||||
|
"pcap_sha1": "SHA1 :",
|
||||||
|
"capture_started": "Capture débutée le :",
|
||||||
|
"capture_ended": "Capture finie le :",
|
||||||
"high": "elevee",
|
"high": "elevee",
|
||||||
"moderate": "moyenne",
|
"moderate": "moyenne",
|
||||||
"low": "basse"
|
"low": "basse"
|
||||||
|
|||||||
@@ -50,8 +50,11 @@
|
|||||||
"low_msg": "Sono presenti solo {nb} avvisi con priorità bassa<br /> da controllare.",
|
"low_msg": "Sono presenti solo {nb} avvisi con priorità bassa<br /> da controllare.",
|
||||||
"save_report": "Salva il rapporto",
|
"save_report": "Salva il rapporto",
|
||||||
"report_of": "Rapporto di",
|
"report_of": "Rapporto di",
|
||||||
"ip_address": "Indirizzo IP",
|
"ip_address": "Indirizzo IP:",
|
||||||
"mac_address": "Indirizzo MAC",
|
"mac_address": "Indirizzo MAC:",
|
||||||
|
"pcap_sha1": "SHA1:",
|
||||||
|
"capture_started": "Cattura è iniziata su:",
|
||||||
|
"capture_ended": "Cattura terminata su:",
|
||||||
"high": "elevata",
|
"high": "elevata",
|
||||||
"moderate": "moderata",
|
"moderate": "moderata",
|
||||||
"low": "bassa"
|
"low": "bassa"
|
||||||
|
|||||||
@@ -50,8 +50,11 @@
|
|||||||
"low_msg": "Você tem apenas {nb} alertas leves,<br /> não deixe de verificá-los.",
|
"low_msg": "Você tem apenas {nb} alertas leves,<br /> não deixe de verificá-los.",
|
||||||
"save_report": "Salvar o relatório",
|
"save_report": "Salvar o relatório",
|
||||||
"report_of": "Relatório de",
|
"report_of": "Relatório de",
|
||||||
"ip_address": "Endereço IP",
|
"ip_address": "Endereço IP:",
|
||||||
"mac_address": "Endereço MAC",
|
"mac_address": "Endereço MAC:",
|
||||||
|
"pcap_sha1": "SHA1:",
|
||||||
|
"capture_started": "Captura iniciada em:",
|
||||||
|
"capture_ended": "Captura terminou em:",
|
||||||
"high": "crítico",
|
"high": "crítico",
|
||||||
"moderate": "moderado",
|
"moderate": "moderado",
|
||||||
"low": "leve"
|
"low": "leve"
|
||||||
|
|||||||
@@ -50,8 +50,11 @@
|
|||||||
"low_msg": "У вас {nb} предупреждение низкого уровня<br />, проверьте их.",
|
"low_msg": "У вас {nb} предупреждение низкого уровня<br />, проверьте их.",
|
||||||
"save_report": "Сохранить отчет",
|
"save_report": "Сохранить отчет",
|
||||||
"report_of": "Отчет",
|
"report_of": "Отчет",
|
||||||
"ip_address": "IP-адрес",
|
"ip_address": "IP-адрес:",
|
||||||
"mac_address": "MAC-адрес",
|
"mac_address": "MAC-адрес:",
|
||||||
|
"pcap_sha1": " SHA1:",
|
||||||
|
"capture_started": "Захват начался:",
|
||||||
|
"capture_ended": "захват закончился:",
|
||||||
"high": "высокий",
|
"high": "высокий",
|
||||||
"moderate": "средний",
|
"moderate": "средний",
|
||||||
"low": "низкий"
|
"low": "низкий"
|
||||||
|
|||||||
@@ -55,6 +55,7 @@ export default {
|
|||||||
router.replace({ name: 'report',
|
router.replace({ name: 'report',
|
||||||
params: { alerts : response.data.alerts,
|
params: { alerts : response.data.alerts,
|
||||||
device : response.data.device,
|
device : response.data.device,
|
||||||
|
pcap : response.data.pcap,
|
||||||
capture_token : this.capture_token } });
|
capture_token : this.capture_token } });
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -24,6 +24,8 @@ export default {
|
|||||||
var internet = this.internet
|
var internet = this.internet
|
||||||
if (window.config.iface_out.charAt(0) == 'e'){
|
if (window.config.iface_out.charAt(0) == 'e'){
|
||||||
router.push({ name: 'generate-ap' });
|
router.push({ name: 'generate-ap' });
|
||||||
|
} else if (!window.config.choose_net && this.internet){
|
||||||
|
router.push({ name: 'generate-ap' });
|
||||||
} else {
|
} else {
|
||||||
router.push({ name: 'wifi-select',
|
router.push({ name: 'wifi-select',
|
||||||
params: { saved_ssid: saved_ssid,
|
params: { saved_ssid: saved_ssid,
|
||||||
|
|||||||
@@ -46,8 +46,14 @@
|
|||||||
</div>
|
</div>
|
||||||
<div v-else-if="show_report" class="report-wrapper">
|
<div v-else-if="show_report" class="report-wrapper">
|
||||||
<div class="device-ctx">
|
<div class="device-ctx">
|
||||||
<h3 style="margin: 0;">{{ $t("report.report_of") }} {{device.name}}</h3>
|
<h3 style="margin: 0; padding-left:10px;">{{ $t("report.report_of") }} {{device.name}}</h3>
|
||||||
{{ $t("report.ip_address") }} {{device.ip_address}}<br />{{ $t("report.mac_address") }} {{device.mac_address}}
|
<div class="device-ctx-legend">
|
||||||
|
{{ $t("report.pcap_sha1") }} {{ pcap.SHA1 }}<br />
|
||||||
|
{{ $t("report.capture_started") }} {{ pcap["First packet time"].split(",")[0] }}<br />
|
||||||
|
{{ $t("report.capture_ended") }} {{ pcap["Last packet time"].split(",")[0] }}<br />
|
||||||
|
<!-- {{ $t("report.ip_address") }} {{device.ip_address}}<br /> -->
|
||||||
|
{{ $t("report.mac_address") }} {{device.mac_address}}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<ul class="alerts">
|
<ul class="alerts">
|
||||||
<li class="alert" v-for="alert in alerts.high" :key="alert.message">
|
<li class="alert" v-for="alert in alerts.high" :key="alert.message">
|
||||||
@@ -94,6 +100,7 @@
|
|||||||
|
|
||||||
<script>
|
<script>
|
||||||
import router from '../router'
|
import router from '../router'
|
||||||
|
import axios from 'axios'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'report',
|
name: 'report',
|
||||||
@@ -104,6 +111,7 @@ export default {
|
|||||||
},
|
},
|
||||||
props: {
|
props: {
|
||||||
device: Object,
|
device: Object,
|
||||||
|
pcap: Object,
|
||||||
alerts: Array,
|
alerts: Array,
|
||||||
capture_token: String
|
capture_token: String
|
||||||
},
|
},
|
||||||
@@ -113,7 +121,11 @@ export default {
|
|||||||
router.replace({ name: 'save-capture', params: { capture_token: capture_token } });
|
router.replace({ name: 'save-capture', params: { capture_token: capture_token } });
|
||||||
},
|
},
|
||||||
new_capture: function() {
|
new_capture: function() {
|
||||||
router.push({ name: 'generate-ap' })
|
axios.get('/api/misc/delete-captures', { timeout: 30000 })
|
||||||
|
.then(() => {
|
||||||
|
router.push({ name: 'generate-ap' })
|
||||||
|
})
|
||||||
|
.catch(err => (console.log(err)))
|
||||||
},
|
},
|
||||||
grep_keyword: function(kw, level){
|
grep_keyword: function(kw, level){
|
||||||
try {
|
try {
|
||||||
|
|||||||
@@ -39,6 +39,10 @@
|
|||||||
})
|
})
|
||||||
.catch(err => (console.log(err)))
|
.catch(err => (console.log(err)))
|
||||||
},
|
},
|
||||||
|
delete_captures: function() {
|
||||||
|
axios.get('/api/misc/delete-captures', { timeout: 30000 })
|
||||||
|
.catch(err => (console.log(err)))
|
||||||
|
},
|
||||||
goto_home: function() {
|
goto_home: function() {
|
||||||
var list_ssids = this.list_ssids
|
var list_ssids = this.list_ssids
|
||||||
var internet = this.internet
|
var internet = this.internet
|
||||||
@@ -46,6 +50,7 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
created: function() {
|
created: function() {
|
||||||
|
this.delete_captures();
|
||||||
setTimeout(function () { this.internet_check(); }.bind(this), 5000);
|
setTimeout(function () { this.internet_check(); }.bind(this), 5000);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
File diff suppressed because one or more lines are too long
@@ -2,6 +2,8 @@ ipwhois
|
|||||||
M2Crypto
|
M2Crypto
|
||||||
pyOpenSSL
|
pyOpenSSL
|
||||||
pydig
|
pydig
|
||||||
|
pymisp
|
||||||
|
pycti
|
||||||
netaddr
|
netaddr
|
||||||
pyyaml
|
pyyaml
|
||||||
flask
|
flask
|
||||||
|
|||||||
@@ -17,3 +17,25 @@ CREATE TABLE "whitelist" (
|
|||||||
"added_on" INTEGER NOT NULL,
|
"added_on" INTEGER NOT NULL,
|
||||||
PRIMARY KEY("id" AUTOINCREMENT)
|
PRIMARY KEY("id" AUTOINCREMENT)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
CREATE TABLE "misp" (
|
||||||
|
"id" INTEGER UNIQUE,
|
||||||
|
"name" TEXT,
|
||||||
|
"url" TEXT NOT NULL,
|
||||||
|
"apikey" TEXT NOT NULL,
|
||||||
|
"verifycert" INTEGER NOT NULL DEFAULT 0,
|
||||||
|
"added_on" NUMERIC NOT NULL,
|
||||||
|
"last_sync" NUMERIC NOT NULL DEFAULT 0,
|
||||||
|
PRIMARY KEY("id" AUTOINCREMENT)
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE TABLE "octi" (
|
||||||
|
"id" INTEGER UNIQUE,
|
||||||
|
"name" TEXT,
|
||||||
|
"url" TEXT NOT NULL,
|
||||||
|
"apikey" TEXT NOT NULL,
|
||||||
|
"verifycert" INTEGER NOT NULL DEFAULT 0,
|
||||||
|
"added_on" NUMERIC NOT NULL,
|
||||||
|
"last_sync" NUMERIC NOT NULL DEFAULT 0,
|
||||||
|
PRIMARY KEY("id" AUTOINCREMENT)
|
||||||
|
);
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
+2
-1
@@ -51,6 +51,7 @@ frontend:
|
|||||||
virtual_keyboard: true
|
virtual_keyboard: true
|
||||||
user_lang: userlang
|
user_lang: userlang
|
||||||
update: updateoption
|
update: updateoption
|
||||||
|
choose_net: false
|
||||||
|
|
||||||
# NETWORK -
|
# NETWORK -
|
||||||
# Some elements related to the network configuration, such as
|
# Some elements related to the network configuration, such as
|
||||||
@@ -59,7 +60,7 @@ frontend:
|
|||||||
#
|
#
|
||||||
network:
|
network:
|
||||||
in: iface_in
|
in: iface_in
|
||||||
internet_check: http://example.com
|
internet_check: https://1.1.1.1
|
||||||
out: iface_out
|
out: iface_out
|
||||||
ssids:
|
ssids:
|
||||||
- wireless
|
- wireless
|
||||||
|
|||||||
+4
-4
@@ -303,8 +303,7 @@ check_dependencies() {
|
|||||||
"/usr/bin/suricata"
|
"/usr/bin/suricata"
|
||||||
"/usr/bin/unclutter"
|
"/usr/bin/unclutter"
|
||||||
"/usr/bin/sqlite3"
|
"/usr/bin/sqlite3"
|
||||||
"/usr/bin/pip"
|
"/usr/bin/pip")
|
||||||
"/usr/bin/node")
|
|
||||||
|
|
||||||
echo -e "\e[39m[+] Checking dependencies...\e[39m"
|
echo -e "\e[39m[+] Checking dependencies...\e[39m"
|
||||||
for bin in "${bins[@]}"
|
for bin in "${bins[@]}"
|
||||||
@@ -316,6 +315,7 @@ check_dependencies() {
|
|||||||
install_package ${bin##*/}
|
install_package ${bin##*/}
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
|
install_package node
|
||||||
echo -e "\e[39m[+] Install Python packages...\e[39m"
|
echo -e "\e[39m[+] Install Python packages...\e[39m"
|
||||||
python3 -m pip install -r "$SCRIPT_PATH/assets/requirements.txt"
|
python3 -m pip install -r "$SCRIPT_PATH/assets/requirements.txt"
|
||||||
}
|
}
|
||||||
@@ -338,7 +338,7 @@ create_desktop() {
|
|||||||
Version=1.0
|
Version=1.0
|
||||||
Type=Application
|
Type=Application
|
||||||
Terminal=false
|
Terminal=false
|
||||||
Exec=chromium-browser http://localhost
|
Exec=bash /usr/share/tinycheck/kiosk.sh
|
||||||
Name=TinyCheck
|
Name=TinyCheck
|
||||||
Comment=Launcher for the TinyCheck frontend
|
Comment=Launcher for the TinyCheck frontend
|
||||||
Icon=/usr/share/tinycheck/app/frontend/src/assets/icon.png
|
Icon=/usr/share/tinycheck/app/frontend/src/assets/icon.png
|
||||||
@@ -441,7 +441,7 @@ change_configs() {
|
|||||||
|
|
||||||
feeding_iocs() {
|
feeding_iocs() {
|
||||||
echo -e "\e[39m[+] Feeding your TinyCheck instance with fresh IOCs and whitelist, please wait."
|
echo -e "\e[39m[+] Feeding your TinyCheck instance with fresh IOCs and whitelist, please wait."
|
||||||
python3 /usr/share/tinycheck/server/backend/watchers.py
|
python3 /usr/share/tinycheck/server/backend/watchers.py 2>/dev/null
|
||||||
}
|
}
|
||||||
|
|
||||||
reboot_box() {
|
reboot_box() {
|
||||||
|
|||||||
@@ -1,11 +1,12 @@
|
|||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
from flask import Blueprint, jsonify, Response
|
from flask import Blueprint, jsonify, Response, request
|
||||||
from app.decorators import require_header_token, require_get_token
|
from app.decorators import require_header_token, require_get_token
|
||||||
from app.classes.iocs import IOCs
|
from app.classes.iocs import IOCs
|
||||||
|
|
||||||
import json
|
import json
|
||||||
|
from urllib.parse import unquote
|
||||||
|
|
||||||
ioc_bp = Blueprint("ioc", __name__)
|
ioc_bp = Blueprint("ioc", __name__)
|
||||||
ioc = IOCs()
|
ioc = IOCs()
|
||||||
@@ -19,10 +20,26 @@ def add(ioc_type, ioc_tag, ioc_tlp, ioc_value):
|
|||||||
:return: status of the operation in JSON
|
:return: status of the operation in JSON
|
||||||
"""
|
"""
|
||||||
source = "backend"
|
source = "backend"
|
||||||
|
if ioc_type == "snort":
|
||||||
|
ioc_value = unquote("/".join(request.full_path.split("/")[7:]))
|
||||||
res = IOCs.add(ioc_type, ioc_tag, ioc_tlp, ioc_value, source)
|
res = IOCs.add(ioc_type, ioc_tag, ioc_tlp, ioc_value, source)
|
||||||
return jsonify(res)
|
return jsonify(res)
|
||||||
|
|
||||||
|
|
||||||
|
@ioc_bp.route('/add_post', methods=['POST'])
|
||||||
|
@require_header_token
|
||||||
|
def add_post():
|
||||||
|
"""
|
||||||
|
Parse and add an IOC to the database using the post method.
|
||||||
|
:return: status of the operation in JSON
|
||||||
|
"""
|
||||||
|
|
||||||
|
data = json.loads(request.data)
|
||||||
|
ioc = data["data"]["ioc"]
|
||||||
|
res = IOCs.add(ioc["ioc_type"], ioc["ioc_tag"], ioc["ioc_tlp"], ioc["ioc_value"], ioc["ioc_source"])
|
||||||
|
return jsonify(res)
|
||||||
|
|
||||||
|
|
||||||
@ioc_bp.route('/delete/<ioc_id>', methods=['GET'])
|
@ioc_bp.route('/delete/<ioc_id>', methods=['GET'])
|
||||||
@require_header_token
|
@require_header_token
|
||||||
def delete(ioc_id):
|
def delete(ioc_id):
|
||||||
|
|||||||
@@ -0,0 +1,44 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
from flask import Blueprint, jsonify, Response, request
|
||||||
|
from app.decorators import require_header_token, require_get_token
|
||||||
|
from app.classes.misp import MISP
|
||||||
|
|
||||||
|
import json
|
||||||
|
|
||||||
|
misp_bp = Blueprint("misp", __name__)
|
||||||
|
misp = MISP()
|
||||||
|
|
||||||
|
|
||||||
|
@misp_bp.route('/add', methods=['POST'])
|
||||||
|
@require_header_token
|
||||||
|
def add_instance():
|
||||||
|
"""
|
||||||
|
Parse and add a MISP instance to the database.
|
||||||
|
:return: status of the operation in JSON
|
||||||
|
"""
|
||||||
|
data = json.loads(request.data)
|
||||||
|
res = misp.add_instance(data["data"]["instance"])
|
||||||
|
return jsonify(res)
|
||||||
|
|
||||||
|
@misp_bp.route('/delete/<misp_id>', methods=['GET'])
|
||||||
|
@require_header_token
|
||||||
|
def delete_instance(misp_id):
|
||||||
|
"""
|
||||||
|
Delete a MISP instance by its id to the database.
|
||||||
|
:return: status of the operation in JSON
|
||||||
|
"""
|
||||||
|
res = misp.delete_instance(misp_id)
|
||||||
|
return jsonify(res)
|
||||||
|
|
||||||
|
|
||||||
|
@misp_bp.route('/get_all', methods=['GET'])
|
||||||
|
@require_header_token
|
||||||
|
def get_all():
|
||||||
|
"""
|
||||||
|
Retreive a list of all MISP instances.
|
||||||
|
:return: list of MISP instances in JSON.
|
||||||
|
"""
|
||||||
|
res = misp.get_instances()
|
||||||
|
return jsonify({"results": [i for i in res]})
|
||||||
@@ -0,0 +1,45 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
from flask import Blueprint, jsonify, Response, request
|
||||||
|
from app.decorators import require_header_token, require_get_token
|
||||||
|
from app.classes.octi import OCTI
|
||||||
|
|
||||||
|
import json
|
||||||
|
|
||||||
|
octi_bp = Blueprint("octi", __name__)
|
||||||
|
octi = OCTI()
|
||||||
|
|
||||||
|
|
||||||
|
@octi_bp.route('/add', methods=['POST'])
|
||||||
|
@require_header_token
|
||||||
|
def add_instance():
|
||||||
|
"""
|
||||||
|
Parse and add a OpenCTI instance to the database.
|
||||||
|
:return: status of the operation in JSON
|
||||||
|
"""
|
||||||
|
data = json.loads(request.data)
|
||||||
|
res = octi.add_instance(data["data"]["instance"])
|
||||||
|
return jsonify(res)
|
||||||
|
|
||||||
|
|
||||||
|
@octi_bp.route('/delete/<octi_id>', methods=['GET'])
|
||||||
|
@require_header_token
|
||||||
|
def delete_instance(octi_id):
|
||||||
|
"""
|
||||||
|
Delete a OpenCTI instance by its id to the database.
|
||||||
|
:return: status of the operation in JSON
|
||||||
|
"""
|
||||||
|
res = octi.delete_instance(octi_id)
|
||||||
|
return jsonify(res)
|
||||||
|
|
||||||
|
|
||||||
|
@octi_bp.route('/get_all', methods=['GET'])
|
||||||
|
@require_header_token
|
||||||
|
def get_all():
|
||||||
|
"""
|
||||||
|
Retreive a list of all OpenCTI instances.
|
||||||
|
:return: list of OpenCTI instances in JSON.
|
||||||
|
"""
|
||||||
|
res = octi.get_instances()
|
||||||
|
return jsonify({"results": [i for i in res]})
|
||||||
@@ -56,7 +56,12 @@ class IOCs(object):
|
|||||||
db.session.commit()
|
db.session.commit()
|
||||||
return {"status": True,
|
return {"status": True,
|
||||||
"message": "IOC added",
|
"message": "IOC added",
|
||||||
"ioc": escape(ioc_value)}
|
"ioc": escape(ioc_value),
|
||||||
|
"type": escape(ioc_type),
|
||||||
|
"tlp": escape(ioc_tlp),
|
||||||
|
"tag": escape(ioc_tag),
|
||||||
|
"source": escape(source),
|
||||||
|
"added_on": escape(added_on)}
|
||||||
else:
|
else:
|
||||||
return {"status": False,
|
return {"status": False,
|
||||||
"message": "Wrong IOC format",
|
"message": "Wrong IOC format",
|
||||||
@@ -111,7 +116,8 @@ class IOCs(object):
|
|||||||
"type": ioc["type"],
|
"type": ioc["type"],
|
||||||
"tag": ioc["tag"],
|
"tag": ioc["tag"],
|
||||||
"tlp": ioc["tlp"],
|
"tlp": ioc["tlp"],
|
||||||
"value": ioc["value"]}
|
"value": ioc["value"],
|
||||||
|
"source": ioc["source"]}
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def get_types():
|
def get_types():
|
||||||
|
|||||||
@@ -0,0 +1,159 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
from app import db
|
||||||
|
from app.db.models import MISPInst
|
||||||
|
from app.definitions import definitions as defs
|
||||||
|
|
||||||
|
from sqlalchemy.sql import exists
|
||||||
|
from urllib.parse import unquote
|
||||||
|
from flask import escape
|
||||||
|
from pymisp import PyMISP
|
||||||
|
import re
|
||||||
|
import time
|
||||||
|
import sys
|
||||||
|
|
||||||
|
|
||||||
|
class MISP(object):
|
||||||
|
def __init__(self):
|
||||||
|
return None
|
||||||
|
|
||||||
|
def add_instance(self, instance):
|
||||||
|
"""
|
||||||
|
Parse and add a MISP instance to the database.
|
||||||
|
:return: status of the operation in JSON
|
||||||
|
"""
|
||||||
|
|
||||||
|
url = instance["url"]
|
||||||
|
name = instance["name"]
|
||||||
|
apikey = instance["key"]
|
||||||
|
verify = instance["ssl"]
|
||||||
|
last_sync = int(time.time()-31536000) # One year
|
||||||
|
|
||||||
|
sameinstances = db.session.query(MISPInst).filter(
|
||||||
|
MISPInst.url == url, MISPInst.apikey == apikey)
|
||||||
|
if sameinstances.count():
|
||||||
|
return {"status": False,
|
||||||
|
"message": "This MISP instance already exists"}
|
||||||
|
if name:
|
||||||
|
if self.test_instance(url, apikey, verify):
|
||||||
|
added_on = int(time.time())
|
||||||
|
db.session.add(MISPInst(name, escape(
|
||||||
|
url), apikey, verify, added_on, last_sync))
|
||||||
|
db.session.commit()
|
||||||
|
return {"status": True,
|
||||||
|
"message": "MISP instance added"}
|
||||||
|
else:
|
||||||
|
return {"status": False,
|
||||||
|
"message": "Please verify the connection to the MISP instance"}
|
||||||
|
else:
|
||||||
|
return {"status": False,
|
||||||
|
"message": "Please provide a name for your instance"}
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def delete_instance(misp_id):
|
||||||
|
"""
|
||||||
|
Delete a MISP instance by its id in the database.
|
||||||
|
:return: status of the operation in JSON
|
||||||
|
"""
|
||||||
|
if db.session.query(exists().where(MISPInst.id == misp_id)).scalar():
|
||||||
|
db.session.query(MISPInst).filter_by(id=misp_id).delete()
|
||||||
|
db.session.commit()
|
||||||
|
return {"status": True,
|
||||||
|
"message": "MISP instance deleted"}
|
||||||
|
else:
|
||||||
|
return {"status": False,
|
||||||
|
"message": "MISP instance not found"}
|
||||||
|
|
||||||
|
def get_instances(self):
|
||||||
|
"""
|
||||||
|
Get MISP instances from the database
|
||||||
|
:return: generator of the records.
|
||||||
|
"""
|
||||||
|
for misp in db.session.query(MISPInst).all():
|
||||||
|
misp = misp.__dict__
|
||||||
|
yield {"id": misp["id"],
|
||||||
|
"name": misp["name"],
|
||||||
|
"url": misp["url"],
|
||||||
|
"apikey": misp["apikey"],
|
||||||
|
"verifycert": True if misp["verifycert"] else False,
|
||||||
|
"connected": self.test_instance(misp["url"], misp["apikey"], misp["verifycert"]),
|
||||||
|
"lastsync": misp["last_sync"]}
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def test_instance(url, apikey, verify):
|
||||||
|
"""
|
||||||
|
Test the connection of the MISP instance.
|
||||||
|
:return: generator of the records.
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
PyMISP(url, apikey, verify)
|
||||||
|
return True
|
||||||
|
except:
|
||||||
|
return False
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def update_sync(misp_id):
|
||||||
|
"""
|
||||||
|
Update the last synchronization date by the actual date.
|
||||||
|
:return: bool, True if updated.
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
misp = MISPInst.query.get(int(misp_id))
|
||||||
|
misp.last_sync = int(time.time())
|
||||||
|
db.session.commit()
|
||||||
|
return True
|
||||||
|
except:
|
||||||
|
return False
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def get_iocs(misp_id):
|
||||||
|
"""
|
||||||
|
Get all IOCs from specific MISP instance
|
||||||
|
:return: generator containing the IOCs.
|
||||||
|
"""
|
||||||
|
misp = MISPInst.query.get(int(misp_id))
|
||||||
|
if misp is not None:
|
||||||
|
if misp.url and misp.apikey:
|
||||||
|
try:
|
||||||
|
# Connect to MISP instance and get network activity attributes.
|
||||||
|
m = PyMISP(misp.url, misp.apikey, misp.verifycert)
|
||||||
|
r = m.search("attributes", category="Network activity", date_from=int(misp.last_sync))
|
||||||
|
except:
|
||||||
|
print("Unable to connect to the MISP instance ({}/{}).".format(misp.url, misp.apikey))
|
||||||
|
return []
|
||||||
|
|
||||||
|
for attr in r["Attribute"]:
|
||||||
|
if attr["type"] in ["ip-dst", "domain", "snort", "x509-fingerprint-sha1"]:
|
||||||
|
|
||||||
|
ioc = {"value": attr["value"],
|
||||||
|
"type": None,
|
||||||
|
"tag": "suspect",
|
||||||
|
"tlp": "white"}
|
||||||
|
|
||||||
|
# Deduce the IOC type.
|
||||||
|
if re.match(defs["iocs_types"][0]["regex"], attr["value"]):
|
||||||
|
ioc["type"] = "ip4addr"
|
||||||
|
elif re.match(defs["iocs_types"][1]["regex"], attr["value"]):
|
||||||
|
ioc["type"] = "ip6addr"
|
||||||
|
elif re.match(defs["iocs_types"][2]["regex"], attr["value"]):
|
||||||
|
ioc["type"] = "cidr"
|
||||||
|
elif re.match(defs["iocs_types"][3]["regex"], attr["value"]):
|
||||||
|
ioc["type"] = "domain"
|
||||||
|
elif re.match(defs["iocs_types"][4]["regex"], attr["value"]):
|
||||||
|
ioc["type"] = "sha1cert"
|
||||||
|
elif "alert " in attr["value"][0:6]:
|
||||||
|
ioc["type"] = "snort"
|
||||||
|
else:
|
||||||
|
continue
|
||||||
|
|
||||||
|
if "Tag" in attr:
|
||||||
|
for tag in attr["Tag"]:
|
||||||
|
# Add a TLP to the IOC if defined in tags.
|
||||||
|
tlp = re.search(r"^(?:tlp:)(red|green|amber|white)", tag['name'].lower())
|
||||||
|
if tlp: ioc["tlp"] = tlp.group(1)
|
||||||
|
|
||||||
|
# Add possible tag (need to match TinyCheck tags)
|
||||||
|
if tag["name"].lower() in [t["tag"] for t in defs["iocs_tags"]]:
|
||||||
|
ioc["tag"] = tag["name"].lower()
|
||||||
|
yield ioc
|
||||||
@@ -0,0 +1,164 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
from app import db
|
||||||
|
from app.db.models import OCTIInst
|
||||||
|
from app.definitions import definitions as defs
|
||||||
|
|
||||||
|
from sqlalchemy.sql import exists
|
||||||
|
from urllib.parse import unquote
|
||||||
|
from flask import escape
|
||||||
|
from pycti import OpenCTIApiClient, Infrastructure
|
||||||
|
import re
|
||||||
|
import time
|
||||||
|
import sys
|
||||||
|
|
||||||
|
|
||||||
|
class OCTI(object):
|
||||||
|
def __init__(self):
|
||||||
|
return None
|
||||||
|
|
||||||
|
def add_instance(self, instance):
|
||||||
|
"""
|
||||||
|
Parse and add a OpenCTI instance to the database.
|
||||||
|
:return: status of the operation in JSON
|
||||||
|
"""
|
||||||
|
|
||||||
|
url = instance["url"]
|
||||||
|
name = instance["name"]
|
||||||
|
apikey = instance["key"]
|
||||||
|
verify = instance["ssl"]
|
||||||
|
last_sync = int(time.time()-31536000) # One year
|
||||||
|
|
||||||
|
sameinstances = db.session.query(OCTIInst).filter(
|
||||||
|
OCTIInst.url == url, OCTIInst.apikey == apikey)
|
||||||
|
if sameinstances.count():
|
||||||
|
return {"status": False,
|
||||||
|
"message": "This OpenCTI instance already exists"}
|
||||||
|
if name:
|
||||||
|
if self.test_instance(url, apikey, verify):
|
||||||
|
added_on = int(time.time())
|
||||||
|
db.session.add(OCTIInst(name, escape(
|
||||||
|
url), apikey, verify, added_on, last_sync))
|
||||||
|
db.session.commit()
|
||||||
|
return {"status": True,
|
||||||
|
"message": "OpenCTI instance added"}
|
||||||
|
else:
|
||||||
|
return {"status": False,
|
||||||
|
"message": "Please verify the connection to the OpenCTI instance"}
|
||||||
|
else:
|
||||||
|
return {"status": False,
|
||||||
|
"message": "Please provide a name for your instance"}
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def delete_instance(opencti_id):
|
||||||
|
"""
|
||||||
|
Delete a OpenCTI instance by its id in the database.
|
||||||
|
:return: status of the operation in JSON
|
||||||
|
"""
|
||||||
|
if db.session.query(exists().where(OCTIInst.id == opencti_id)).scalar():
|
||||||
|
db.session.query(OCTIInst).filter_by(id=opencti_id).delete()
|
||||||
|
db.session.commit()
|
||||||
|
return {"status": True,
|
||||||
|
"message": "OpenCTI instance deleted"}
|
||||||
|
else:
|
||||||
|
return {"status": False,
|
||||||
|
"message": "OpenCTI instance not found"}
|
||||||
|
|
||||||
|
def get_instances(self):
|
||||||
|
"""
|
||||||
|
Get OpenCTI instances from the database
|
||||||
|
:return: generator of the records.
|
||||||
|
"""
|
||||||
|
for opencti in db.session.query(OCTIInst).all():
|
||||||
|
opencti = opencti.__dict__
|
||||||
|
yield {"id": opencti["id"],
|
||||||
|
"name": opencti["name"],
|
||||||
|
"url": opencti["url"],
|
||||||
|
"apikey": opencti["apikey"],
|
||||||
|
"verifycert": True if opencti["verifycert"] else False,
|
||||||
|
"connected": self.test_instance(opencti["url"], opencti["apikey"], opencti["verifycert"]),
|
||||||
|
"lastsync": opencti["last_sync"]}
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def test_instance(url, apikey, verify):
|
||||||
|
"""
|
||||||
|
Test the connection of the OpenCTI instance.
|
||||||
|
:return: generator of the records.
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
OpenCTIApiClient(url, token=apikey, ssl_verify=verify)
|
||||||
|
return True
|
||||||
|
except:
|
||||||
|
return False
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def update_sync(opencti_id):
|
||||||
|
"""
|
||||||
|
Update the last synchronization date by the actual date.
|
||||||
|
:return: bool, True if updated.
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
misp = OCTIInst.query.get(int(opencti_id))
|
||||||
|
misp.last_sync = int(time.time())
|
||||||
|
db.session.commit()
|
||||||
|
return True
|
||||||
|
except:
|
||||||
|
return False
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def get_iocs(opencti_id):
|
||||||
|
"""
|
||||||
|
Get all IOCs from specific OpenCTI instance
|
||||||
|
:return: generator containing the IOCs.
|
||||||
|
"""
|
||||||
|
opencti = OCTIInst.query.get(int(opencti_id))
|
||||||
|
if opencti is not None:
|
||||||
|
if opencti.url and opencti.apikey:
|
||||||
|
try:
|
||||||
|
# Connect to OpenCTI instance and get network activity attributes.
|
||||||
|
i = OpenCTIApiClient(
|
||||||
|
opencti.url, opencti.apikey, opencti.verifycert)
|
||||||
|
r = Infrastructure(i).list(getAll=True)
|
||||||
|
except:
|
||||||
|
print(
|
||||||
|
"Unable to connect to the OpenCTI instance ({}/{}).".format(opencti.url, opencti.apikey))
|
||||||
|
return []
|
||||||
|
"""
|
||||||
|
for attr in r["Attribute"]:
|
||||||
|
if attr["type"] in ["ip-dst", "domain", "snort", "x509-fingerprint-sha1"]:
|
||||||
|
|
||||||
|
ioc = {"value": attr["value"],
|
||||||
|
"type": None,
|
||||||
|
"tag": "suspect",
|
||||||
|
"tlp": "white"}
|
||||||
|
|
||||||
|
# Deduce the IOC type.
|
||||||
|
if re.match(defs["iocs_types"][0]["regex"], attr["value"]):
|
||||||
|
ioc["type"] = "ip4addr"
|
||||||
|
elif re.match(defs["iocs_types"][1]["regex"], attr["value"]):
|
||||||
|
ioc["type"] = "ip6addr"
|
||||||
|
elif re.match(defs["iocs_types"][2]["regex"], attr["value"]):
|
||||||
|
ioc["type"] = "cidr"
|
||||||
|
elif re.match(defs["iocs_types"][3]["regex"], attr["value"]):
|
||||||
|
ioc["type"] = "domain"
|
||||||
|
elif re.match(defs["iocs_types"][4]["regex"], attr["value"]):
|
||||||
|
ioc["type"] = "sha1cert"
|
||||||
|
elif "alert " in attr["value"][0:6]:
|
||||||
|
ioc["type"] = "snort"
|
||||||
|
else:
|
||||||
|
continue
|
||||||
|
|
||||||
|
if "Tag" in attr:
|
||||||
|
for tag in attr["Tag"]:
|
||||||
|
# Add a TLP to the IOC if defined in tags.
|
||||||
|
tlp = re.search(
|
||||||
|
r"^(?:tlp:)(red|green|amber|white)", tag['name'].lower())
|
||||||
|
if tlp:
|
||||||
|
ioc["tlp"] = tlp.group(1)
|
||||||
|
|
||||||
|
# Add possible tag (need to match TinyCheck tags)
|
||||||
|
if tag["name"].lower() in [t["tag"] for t in defs["iocs_tags"]]:
|
||||||
|
ioc["tag"] = tag["name"].lower()
|
||||||
|
yield ioc
|
||||||
|
"""
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
from app import db
|
from app import db
|
||||||
|
|
||||||
|
|
||||||
class Ioc(db.Model):
|
class Ioc(db.Model):
|
||||||
def __init__(self, value, type, tlp, tag, source, added_on):
|
def __init__(self, value, type, tlp, tag, source, added_on):
|
||||||
self.value = value
|
self.value = value
|
||||||
@@ -9,6 +10,7 @@ class Ioc(db.Model):
|
|||||||
self.source = source
|
self.source = source
|
||||||
self.added_on = added_on
|
self.added_on = added_on
|
||||||
|
|
||||||
|
|
||||||
class Whitelist(db.Model):
|
class Whitelist(db.Model):
|
||||||
def __init__(self, element, type, source, added_on):
|
def __init__(self, element, type, source, added_on):
|
||||||
self.element = element
|
self.element = element
|
||||||
@@ -16,5 +18,28 @@ class Whitelist(db.Model):
|
|||||||
self.source = source
|
self.source = source
|
||||||
self.added_on = added_on
|
self.added_on = added_on
|
||||||
|
|
||||||
|
|
||||||
|
class MISPInst(db.Model):
|
||||||
|
def __init__(self, name, url, key, ssl, added_on, last_sync):
|
||||||
|
self.name = name
|
||||||
|
self.url = url
|
||||||
|
self.apikey = key
|
||||||
|
self.verifycert = ssl
|
||||||
|
self.added_on = added_on
|
||||||
|
self.last_sync = last_sync
|
||||||
|
|
||||||
|
|
||||||
|
class OCTIInst(db.Model):
|
||||||
|
def __init__(self, name, url, key, ssl, added_on, last_sync):
|
||||||
|
self.name = name
|
||||||
|
self.url = url
|
||||||
|
self.apikey = key
|
||||||
|
self.verifycert = ssl
|
||||||
|
self.added_on = added_on
|
||||||
|
self.last_sync = last_sync
|
||||||
|
|
||||||
|
|
||||||
db.mapper(Whitelist, db.Table('whitelist', db.metadata, autoload=True))
|
db.mapper(Whitelist, db.Table('whitelist', db.metadata, autoload=True))
|
||||||
db.mapper(Ioc, db.Table('iocs', db.metadata, autoload=True))
|
db.mapper(Ioc, db.Table('iocs', db.metadata, autoload=True))
|
||||||
|
db.mapper(MISPInst, db.Table('misp', db.metadata, autoload=True))
|
||||||
|
db.mapper(OCTIInst, db.Table('octi', db.metadata, autoload=True))
|
||||||
|
|||||||
@@ -6,6 +6,8 @@ from app.decorators import auth
|
|||||||
from app.blueprints.ioc import ioc_bp
|
from app.blueprints.ioc import ioc_bp
|
||||||
from app.blueprints.whitelist import whitelist_bp
|
from app.blueprints.whitelist import whitelist_bp
|
||||||
from app.blueprints.config import config_bp
|
from app.blueprints.config import config_bp
|
||||||
|
from app.blueprints.misp import misp_bp
|
||||||
|
from app.blueprints.octi import octi_bp
|
||||||
import datetime
|
import datetime
|
||||||
import secrets
|
import secrets
|
||||||
import jwt
|
import jwt
|
||||||
@@ -56,6 +58,8 @@ def page_not_found(e):
|
|||||||
app.register_blueprint(ioc_bp, url_prefix='/api/ioc')
|
app.register_blueprint(ioc_bp, url_prefix='/api/ioc')
|
||||||
app.register_blueprint(whitelist_bp, url_prefix='/api/whitelist')
|
app.register_blueprint(whitelist_bp, url_prefix='/api/whitelist')
|
||||||
app.register_blueprint(config_bp, url_prefix='/api/config')
|
app.register_blueprint(config_bp, url_prefix='/api/config')
|
||||||
|
app.register_blueprint(misp_bp, url_prefix='/api/misp')
|
||||||
|
app.register_blueprint(octi_bp, url_prefix='/api/opencti')
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
ssl_cert = "{}/{}".format(path[0], 'cert.pem')
|
ssl_cert = "{}/{}".format(path[0], 'cert.pem')
|
||||||
|
|||||||
+62
-10
@@ -4,6 +4,8 @@
|
|||||||
from app.utils import read_config
|
from app.utils import read_config
|
||||||
from app.classes.iocs import IOCs
|
from app.classes.iocs import IOCs
|
||||||
from app.classes.whitelist import WhiteList
|
from app.classes.whitelist import WhiteList
|
||||||
|
from app.classes.misp import MISP
|
||||||
|
from app.classes.octi import OCTI
|
||||||
|
|
||||||
import requests
|
import requests
|
||||||
import json
|
import json
|
||||||
@@ -16,11 +18,6 @@ from multiprocessing import Process
|
|||||||
in the configuration file. This in order to get
|
in the configuration file. This in order to get
|
||||||
automatically new iocs / elements from remote
|
automatically new iocs / elements from remote
|
||||||
sources without user interaction.
|
sources without user interaction.
|
||||||
|
|
||||||
As of today the default export JSON format from
|
|
||||||
the backend and unauthenticated HTTP requests
|
|
||||||
are accepted. The code is little awkward, it'll
|
|
||||||
be better in a next version ;)
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
|
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
|
||||||
@@ -29,7 +26,7 @@ urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
|
|||||||
def watch_iocs():
|
def watch_iocs():
|
||||||
"""
|
"""
|
||||||
Retrieve IOCs from the remote URLs defined in config/watchers.
|
Retrieve IOCs from the remote URLs defined in config/watchers.
|
||||||
For each (new ?) IOC, add it to the DB.
|
For each IOC, add it to the DB.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# Retrieve the URLs from the configuration
|
# Retrieve the URLs from the configuration
|
||||||
@@ -45,8 +42,10 @@ def watch_iocs():
|
|||||||
res = requests.get(w["url"], verify=False)
|
res = requests.get(w["url"], verify=False)
|
||||||
if res.status_code == 200:
|
if res.status_code == 200:
|
||||||
content = json.loads(res.content)
|
content = json.loads(res.content)
|
||||||
iocs_list = content["iocs"] if "iocs" in content else []
|
iocs_list = content["iocs"] if "iocs" in content else [
|
||||||
to_delete = content["to_delete"] if "to_delete" in content else []
|
]
|
||||||
|
to_delete = content["to_delete"] if "to_delete" in content else [
|
||||||
|
]
|
||||||
else:
|
else:
|
||||||
w["status"] = False
|
w["status"] = False
|
||||||
except:
|
except:
|
||||||
@@ -93,8 +92,10 @@ def watch_whitelists():
|
|||||||
res = requests.get(w["url"], verify=False)
|
res = requests.get(w["url"], verify=False)
|
||||||
if res.status_code == 200:
|
if res.status_code == 200:
|
||||||
content = json.loads(res.content)
|
content = json.loads(res.content)
|
||||||
elements = content["elements"] if "elements" in content else []
|
elements = content["elements"] if "elements" in content else [
|
||||||
to_delete = content["to_delete"] if "to_delete" in content else []
|
]
|
||||||
|
to_delete = content["to_delete"] if "to_delete" in content else [
|
||||||
|
]
|
||||||
else:
|
else:
|
||||||
w["status"] = False
|
w["status"] = False
|
||||||
except:
|
except:
|
||||||
@@ -120,8 +121,59 @@ def watch_whitelists():
|
|||||||
break
|
break
|
||||||
|
|
||||||
|
|
||||||
|
def watch_misp():
|
||||||
|
"""
|
||||||
|
Retrieve IOCs from misp instances. Each new element is
|
||||||
|
tested and then added to the database.
|
||||||
|
"""
|
||||||
|
iocs, misp = IOCs(), MISP()
|
||||||
|
instances = [i for i in misp.get_instances()]
|
||||||
|
|
||||||
|
while instances:
|
||||||
|
for i, ist in enumerate(instances):
|
||||||
|
status = misp.test_instance(ist["url"],
|
||||||
|
ist["apikey"],
|
||||||
|
ist["verifycert"])
|
||||||
|
if status:
|
||||||
|
for ioc in misp.get_iocs(ist["id"]):
|
||||||
|
iocs.add(ioc["type"], ioc["tag"], ioc["tlp"],
|
||||||
|
ioc["value"], "misp-{}".format(ist["id"]))
|
||||||
|
misp.update_sync(ist["id"])
|
||||||
|
instances.pop(i)
|
||||||
|
if instances:
|
||||||
|
time.sleep(60)
|
||||||
|
|
||||||
|
|
||||||
|
def watch_opencti():
|
||||||
|
"""
|
||||||
|
Retrieve IOCs from OpenCTI instances. Each new element is
|
||||||
|
tested and then added to the database.
|
||||||
|
"""
|
||||||
|
iocs, octi = IOCs(), OCTI()
|
||||||
|
instances = [i for i in octi.get_instances()]
|
||||||
|
|
||||||
|
while instances:
|
||||||
|
for i, ist in enumerate(instances):
|
||||||
|
status = octi.test_instance(ist["url"],
|
||||||
|
ist["apikey"],
|
||||||
|
ist["verifycert"])
|
||||||
|
if status:
|
||||||
|
print("Testing...")
|
||||||
|
# for ioc in octi.get_iocs(ist["id"]):
|
||||||
|
# iocs.add(ioc["type"], ioc["tag"], ioc["tlp"],
|
||||||
|
# ioc["value"], "octi-{}".format(ist["id"]))
|
||||||
|
# octi.update_sync(ist["id"])
|
||||||
|
instances.pop(i)
|
||||||
|
if instances:
|
||||||
|
time.sleep(60)
|
||||||
|
|
||||||
|
|
||||||
p1 = Process(target=watch_iocs)
|
p1 = Process(target=watch_iocs)
|
||||||
p2 = Process(target=watch_whitelists)
|
p2 = Process(target=watch_whitelists)
|
||||||
|
p3 = Process(target=watch_misp)
|
||||||
|
p4 = Process(target=watch_octi)
|
||||||
|
|
||||||
p1.start()
|
p1.start()
|
||||||
p2.start()
|
p2.start()
|
||||||
|
p3.start()
|
||||||
|
p4.start()
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
|
|
||||||
import subprocess as sp
|
import subprocess as sp
|
||||||
from flask import Blueprint, jsonify
|
from flask import Blueprint, jsonify
|
||||||
from app.utils import read_config
|
from app.utils import read_config, delete_captures
|
||||||
import re
|
import re
|
||||||
import sys
|
import sys
|
||||||
import os
|
import os
|
||||||
@@ -11,6 +11,17 @@ import os
|
|||||||
misc_bp = Blueprint("misc", __name__)
|
misc_bp = Blueprint("misc", __name__)
|
||||||
|
|
||||||
|
|
||||||
|
@misc_bp.route("/delete-captures", methods=["GET"])
|
||||||
|
def api_delete_captures():
|
||||||
|
"""
|
||||||
|
Delete the zombies capture folders (if any)
|
||||||
|
"""
|
||||||
|
if delete_captures():
|
||||||
|
return jsonify({"message": "Captures deleted", "status": True})
|
||||||
|
else:
|
||||||
|
return jsonify({"message": "Issue while removing captures", "status": False})
|
||||||
|
|
||||||
|
|
||||||
@misc_bp.route("/reboot", methods=["GET"])
|
@misc_bp.route("/reboot", methods=["GET"])
|
||||||
def api_reboot():
|
def api_reboot():
|
||||||
"""
|
"""
|
||||||
@@ -61,5 +72,6 @@ def get_config():
|
|||||||
"shutdown_option": read_config(("frontend", "shutdown_option")),
|
"shutdown_option": read_config(("frontend", "shutdown_option")),
|
||||||
"reboot_option": read_config(("frontend", "reboot_option")),
|
"reboot_option": read_config(("frontend", "reboot_option")),
|
||||||
"iface_out": read_config(("network", "out")),
|
"iface_out": read_config(("network", "out")),
|
||||||
"user_lang": read_config(("frontend", "user_lang"))
|
"user_lang": read_config(("frontend", "user_lang")),
|
||||||
|
"choose_net": read_config(("frontend", "choose_net"))
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -41,13 +41,18 @@ class Analysis(object):
|
|||||||
:return: dict containing the report or error message.
|
:return: dict containing the report or error message.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
device, alerts = {}, {}
|
device, alerts, pcap = {}, {}, {}
|
||||||
|
|
||||||
# Getting device configuration.
|
# Getting device configuration.
|
||||||
if os.path.isfile("/tmp/{}/assets/device.json".format(self.token)):
|
if os.path.isfile("/tmp/{}/assets/device.json".format(self.token)):
|
||||||
with open("/tmp/{}/assets/device.json".format(self.token), "r") as f:
|
with open("/tmp/{}/assets/device.json".format(self.token), "r") as f:
|
||||||
device = json.load(f)
|
device = json.load(f)
|
||||||
|
|
||||||
|
# Getting pcap infos.
|
||||||
|
if os.path.isfile("/tmp/{}/assets/capinfos.json".format(self.token)):
|
||||||
|
with open("/tmp/{}/assets/capinfos.json".format(self.token), "r") as f:
|
||||||
|
pcap = json.load(f)
|
||||||
|
|
||||||
# Getting alerts configuration.
|
# Getting alerts configuration.
|
||||||
if os.path.isfile("/tmp/{}/assets/alerts.json".format(self.token)):
|
if os.path.isfile("/tmp/{}/assets/alerts.json".format(self.token)):
|
||||||
with open("/tmp/{}/assets/alerts.json".format(self.token), "r") as f:
|
with open("/tmp/{}/assets/alerts.json".format(self.token), "r") as f:
|
||||||
@@ -55,6 +60,7 @@ class Analysis(object):
|
|||||||
|
|
||||||
if device != {} and alerts != {}:
|
if device != {} and alerts != {}:
|
||||||
return {"alerts": alerts,
|
return {"alerts": alerts,
|
||||||
"device": device}
|
"device": device,
|
||||||
|
"pcap": pcap}
|
||||||
else:
|
else:
|
||||||
return {"message": "No report yet"}
|
return {"message": "No report yet"}
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
import subprocess as sp
|
import subprocess as sp
|
||||||
import netifaces as ni
|
import netifaces as ni
|
||||||
import requests as rq
|
import requests as rq
|
||||||
|
import re
|
||||||
import sys
|
import sys
|
||||||
import time
|
import time
|
||||||
import qrcode
|
import qrcode
|
||||||
@@ -214,11 +215,13 @@ class Network(object):
|
|||||||
:return: bool - if hostapd configuration file created
|
:return: bool - if hostapd configuration file created
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
|
chan = self.set_ap_channel()
|
||||||
with open("{}/app/assets/hostapd.conf".format(sys.path[0]), "r") as f:
|
with open("{}/app/assets/hostapd.conf".format(sys.path[0]), "r") as f:
|
||||||
conf = f.read()
|
conf = f.read()
|
||||||
conf = conf.replace("{IFACE}", self.iface_in)
|
conf = conf.replace("{IFACE}", self.iface_in)
|
||||||
conf = conf.replace("{SSID}", self.AP_SSID)
|
conf = conf.replace("{SSID}", self.AP_SSID)
|
||||||
conf = conf.replace("{PASS}", self.AP_PASS)
|
conf = conf.replace("{PASS}", self.AP_PASS)
|
||||||
|
conf = conf.replace("{CHAN}", chan)
|
||||||
with open("/tmp/hostapd.conf", "w") as c:
|
with open("/tmp/hostapd.conf", "w") as c:
|
||||||
c.write(conf)
|
c.write(conf)
|
||||||
return True
|
return True
|
||||||
@@ -335,3 +338,18 @@ class Network(object):
|
|||||||
return True
|
return True
|
||||||
except:
|
except:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
def set_ap_channel(self):
|
||||||
|
"""
|
||||||
|
Deduce the channel to have for the AP in order to prevent
|
||||||
|
kind of jamming between the two wifi interfaces.
|
||||||
|
"""
|
||||||
|
|
||||||
|
# Get the channel of the connected interface
|
||||||
|
sh = sp.Popen(["iw", self.iface_out, "info"],
|
||||||
|
stdout=sp.PIPE, stderr=sp.PIPE).communicate()
|
||||||
|
res = re.search("channel ([0-9]{1,2})", sh[0].decode('utf8'))
|
||||||
|
chn = res.group(1)
|
||||||
|
|
||||||
|
# Return a good candidate.
|
||||||
|
return "11" if int(chn) < 7 else "1"
|
||||||
|
|||||||
@@ -7,6 +7,8 @@ import yaml
|
|||||||
import sys
|
import sys
|
||||||
import os
|
import os
|
||||||
from functools import reduce
|
from functools import reduce
|
||||||
|
import shutil
|
||||||
|
import re
|
||||||
|
|
||||||
|
|
||||||
def terminate_process(process):
|
def terminate_process(process):
|
||||||
@@ -33,3 +35,16 @@ def read_config(path):
|
|||||||
config = yaml.load(open(os.path.join(dir, "config.yaml"), "r"),
|
config = yaml.load(open(os.path.join(dir, "config.yaml"), "r"),
|
||||||
Loader=yaml.SafeLoader)
|
Loader=yaml.SafeLoader)
|
||||||
return reduce(dict.get, path, config)
|
return reduce(dict.get, path, config)
|
||||||
|
|
||||||
|
|
||||||
|
def delete_captures():
|
||||||
|
"""
|
||||||
|
Delete potential zombies capture directories
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
for d in os.listdir("/tmp/"):
|
||||||
|
if re.match("[A-F0-9]{8}", d):
|
||||||
|
shutil.rmtree(os.path.join("/tmp/", d))
|
||||||
|
return True
|
||||||
|
except:
|
||||||
|
return False
|
||||||
|
|||||||
@@ -37,16 +37,20 @@ elif [ $PWD = "/tmp/tinycheck" ]; then
|
|||||||
python3 -m pip install -r assets/requirements.txt
|
python3 -m pip install -r assets/requirements.txt
|
||||||
|
|
||||||
echo "[+] Building new interfaces..."
|
echo "[+] Building new interfaces..."
|
||||||
cd /usr/share/tinycheck/app/frontend/ && npm install && npm run build
|
cd /usr/share/tinycheck/app/frontend/ && npm install && npm audit fix && npm run build
|
||||||
cd /usr/share/tinycheck/app/backend/ && npm install && npm run build
|
cd /usr/share/tinycheck/app/backend/ && npm install && npm audit fix && npm run build
|
||||||
|
|
||||||
|
echo "[+] Updating the database scheme..."
|
||||||
|
cd /usr/share/tinycheck/
|
||||||
|
sqlite3 tinycheck.sqlite3 < /tmp/tinycheck/assets/scheme.sql 2>/dev/null
|
||||||
|
|
||||||
echo "[+] Updating current configuration with new values."
|
echo "[+] Updating current configuration with new values."
|
||||||
if ! grep -q reboot_option /usr/share/tinycheck/config.yaml; then
|
if ! grep -q reboot_option /usr/share/tinycheck/config.yaml; then
|
||||||
sed -i 's/frontend:/frontend:\n reboot_option: true/g' /usr/share/tinycheck/config.yaml
|
sed -i 's/frontend:/frontend:\n reboot_option: true/g' /usr/share/tinycheck/config.yaml
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if ! grep -q user_lang /usr/share/tinycheck/config.yaml; then
|
if ! grep -q choose_net /usr/share/tinycheck/config.yaml; then
|
||||||
sed -i 's/frontend:/frontend:\n user_lang: en/g' /usr/share/tinycheck/config.yaml
|
sed -i 's/frontend:/frontend:\n choose_net: false/g' /usr/share/tinycheck/config.yaml
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if ! grep -q shutdown_option /usr/share/tinycheck/config.yaml; then
|
if ! grep -q shutdown_option /usr/share/tinycheck/config.yaml; then
|
||||||
@@ -65,6 +69,10 @@ elif [ $PWD = "/tmp/tinycheck" ]; then
|
|||||||
sed -i 's/frontend:/frontend:\n update: true/g' /usr/share/tinycheck/config.yaml
|
sed -i 's/frontend:/frontend:\n update: true/g' /usr/share/tinycheck/config.yaml
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
if ! grep -q user_lang /usr/share/tinycheck/config.yaml; then
|
||||||
|
sed -i 's/frontend:/frontend:\n user_lang: en/g' /usr/share/tinycheck/config.yaml
|
||||||
|
fi
|
||||||
|
|
||||||
if ! grep -q "CN=R3,O=Let's Encrypt,C=US" /usr/share/tinycheck/config.yaml; then
|
if ! grep -q "CN=R3,O=Let's Encrypt,C=US" /usr/share/tinycheck/config.yaml; then
|
||||||
sed -i "s/free_issuers:/free_issuers:\n - CN=R3,O=Let's Encrypt,C=US/g" /usr/share/tinycheck/config.yaml
|
sed -i "s/free_issuers:/free_issuers:\n - CN=R3,O=Let's Encrypt,C=US/g" /usr/share/tinycheck/config.yaml
|
||||||
fi
|
fi
|
||||||
|
|||||||
Reference in New Issue
Block a user