Merge pull request #52 from KasperskyLab/dev
Adding WHOIS record / active analysis
This commit is contained in:
commit
42c7254cc6
@ -5,13 +5,14 @@
|
||||
from classes.parsezeeklogs import ParseZeekLogs
|
||||
from netaddr import IPNetwork, IPAddress
|
||||
from utils import get_iocs, get_config, get_whitelist
|
||||
from ipwhois import IPWhois
|
||||
from datetime import datetime
|
||||
import subprocess as sp
|
||||
import json
|
||||
import pydig
|
||||
import os
|
||||
import re
|
||||
import sys
|
||||
import whois
|
||||
|
||||
|
||||
class ZeekEngine(object):
|
||||
@ -30,6 +31,7 @@ class ZeekEngine(object):
|
||||
self.heuristics_analysis = get_config(("analysis", "heuristics"))
|
||||
self.iocs_analysis = get_config(("analysis", "iocs"))
|
||||
self.whitelist_analysis = get_config(("analysis", "whitelist"))
|
||||
self.active_analysis = get_config(("analysis", "active"))
|
||||
self.userlang = get_config(("frontend", "user_lang"))
|
||||
|
||||
# Load template language
|
||||
@ -213,22 +215,36 @@ class ZeekEngine(object):
|
||||
"host": c["resolution"],
|
||||
"level": "Low",
|
||||
"id": "IOC-06"})
|
||||
|
||||
# Check for use of suspect nameservers.
|
||||
try:
|
||||
if self.active_analysis:
|
||||
for c in self.conns:
|
||||
try: # Domain nameservers check.
|
||||
name_servers = pydig.query(c["resolution"], "NS")
|
||||
if len(name_servers):
|
||||
for ns in bl_nameservers:
|
||||
if name_servers[0].endswith(".{}.".format(ns[0])):
|
||||
c["alert_tiggered"] = True
|
||||
self.alerts.append({"title": self.template["ACT-01"]["title"].format(c["resolution"], name_servers[0]),
|
||||
"description": self.template["ACT-01"]["description"].format(c["resolution"]),
|
||||
"host": c["resolution"],
|
||||
"level": "Moderate",
|
||||
"id": "ACT-01"})
|
||||
except:
|
||||
name_servers = []
|
||||
pass
|
||||
|
||||
if len(name_servers):
|
||||
for ns in bl_nameservers:
|
||||
if name_servers[0].endswith(".{}.".format(ns[0])):
|
||||
c["alert_tiggered"] = True
|
||||
self.alerts.append({"title": self.template["IOC-07"]["title"].format(c["resolution"], name_servers[0]),
|
||||
"description": self.template["IOC-07"]["description"].format(c["resolution"]),
|
||||
"host": c["resolution"],
|
||||
"level": "Moderate",
|
||||
"id": "IOC-07"})
|
||||
try: # Domain history check.
|
||||
whois_record = whois.whois(c["resolution"])
|
||||
creation_date = whois_record.creation_date if type(
|
||||
whois_record.creation_date) is not list else whois_record.creation_date[0]
|
||||
creation_days = abs((datetime.now() - creation_date).days)
|
||||
if creation_days < 365:
|
||||
c["alert_tiggered"] = True
|
||||
self.alerts.append({"title": self.template["ACT-02"]["title"].format(c["resolution"], creation_days),
|
||||
"description": self.template["ACT-02"]["description"].format(c["resolution"]),
|
||||
"host": c["resolution"],
|
||||
"level": "Moderate",
|
||||
"id": "ACT-02"})
|
||||
except:
|
||||
pass
|
||||
|
||||
def files_check(self, dir):
|
||||
"""
|
||||
@ -260,11 +276,11 @@ class ZeekEngine(object):
|
||||
if f["sha1"] == cert[0]:
|
||||
host = self.resolve(f["ip_dst"])
|
||||
c["alert_tiggered"] = True
|
||||
self.alerts.append({"title": self.template["IOC-08"]["title"].format(cert[1].upper(), host),
|
||||
"description": self.template["IOC-08"]["description"].format(f["sha1"], 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),
|
||||
"host": host,
|
||||
"level": "High",
|
||||
"id": "IOC-08"})
|
||||
"id": "IOC-07"})
|
||||
|
||||
def ssl_check(self, dir):
|
||||
"""
|
||||
|
@ -45,12 +45,16 @@
|
||||
"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. "
|
||||
},
|
||||
"IOC-07": {
|
||||
"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."
|
||||
},
|
||||
"ACT-01": {
|
||||
"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. "
|
||||
},
|
||||
"IOC-08": {
|
||||
"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."
|
||||
"ACT-02": {
|
||||
"title": "El domini {} es va crear recentment (fa {} dies).",
|
||||
"description": "El nom de domini {}és nou. Fins i tot això no és intrínsecament maliciós, és força habitual que els atacants configurin una nova infraestructura per a cada campanya, que pot conduir a l’ús de noms de domini registrats recentment. "
|
||||
},
|
||||
"SSL-01": {
|
||||
"title": "Connexió SSL realitzada mitjançant un port no estàndard ({}) a {}",
|
||||
|
@ -45,12 +45,16 @@
|
||||
"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."
|
||||
},
|
||||
"IOC-07": {
|
||||
"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."
|
||||
},
|
||||
"ACT-01": {
|
||||
"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."
|
||||
},
|
||||
"IOC-08": {
|
||||
"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."
|
||||
"ACT-02": {
|
||||
"title": "The domain {} have been created quite recently ({} days ago).",
|
||||
"description": "The domain name {} is quite new. Even this is not malicious by itself, its quite common for attackers to set up new infrastructure for each campaign which can lead to the use of recently registered domain names."
|
||||
},
|
||||
"SSL-01": {
|
||||
"title": "SSL connection done on a non standard port ({}) to {}",
|
||||
|
@ -45,12 +45,16 @@
|
||||
"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."
|
||||
},
|
||||
"IOC-07": {
|
||||
"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."
|
||||
},
|
||||
"ACT-01": {
|
||||
"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."
|
||||
},
|
||||
"IOC-08": {
|
||||
"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."
|
||||
"ACT-02": {
|
||||
"title": "El dominio {} se creó recientemente (hay {} días).",
|
||||
"description": "El nombre de dominio {} es nuevo. Incluso esto no es intrínsecamente malicioso, es bastante común que los atacantes configuren una nueva infraestructura para cada campaña, lo que puede llevar al uso de nombres de dominio recién registrados."
|
||||
},
|
||||
"SSL-01": {
|
||||
"title": "Conexión SSL realizada mediante un puerto no standard ({}) a {}",
|
||||
|
@ -45,13 +45,17 @@
|
||||
"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."
|
||||
},
|
||||
"IOC-07": {
|
||||
"title": "Le domaine {} utilise un serveur de noms suspect ({}).",
|
||||
"description": "Le nom de domaine {} utilise un server de nom 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é."
|
||||
},
|
||||
"IOC-08": {
|
||||
"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."
|
||||
},
|
||||
"ACT-01": {
|
||||
"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é."
|
||||
},
|
||||
"ACT-02": {
|
||||
"title": "Le domaine {} a été créé récemment (il y a {} jours).",
|
||||
"description": "Le nom de domaine {} est nouveau. Même ce n'est pas malveillant en soi, il est assez courant pour les attaquants de mettre en place une nouvelle infrastructure pour chaque campagne, ce qui peut conduire à l'utilisation de noms de domaine récemment enregistrés."
|
||||
},
|
||||
"SSL-01": {
|
||||
"title": "Connexion SSL utilisant un port non standard ({}) vers {}",
|
||||
"description": "Il n'est pas commun de voir des connexions SSL issues de smartphones utiliser des ports non standards. Même si cela peut être totalement légitime, il est recommandé d'évaluer la réputation du serveur {}, en regardant son enregistrement WHOIS, son système autonome, sa date de création et en le recherchant sur Internet."
|
||||
|
@ -86,6 +86,10 @@
|
||||
<input type="checkbox" @change="local_analysis('analysis', 'whitelist')" v-model="config.analysis.whitelist">
|
||||
<i class="form-icon"></i> Use whitelist to prevent false positives.
|
||||
</label>
|
||||
<label class="form-switch">
|
||||
<input type="checkbox" @change="local_analysis('analysis', 'active')" v-model="config.analysis.active">
|
||||
<i class="form-icon"></i> Use active analysis (Dig, Whois).
|
||||
</label>
|
||||
</div>
|
||||
<h5 class="s-subtitle">User credentials</h5>
|
||||
<div class="form-group">
|
||||
|
@ -13,4 +13,5 @@ pyudev
|
||||
wifi
|
||||
qrcode
|
||||
netifaces
|
||||
weasyprint
|
||||
weasyprint
|
||||
python-whois
|
File diff suppressed because one or more lines are too long
@ -9,6 +9,7 @@ analysis:
|
||||
- CN=ZeroSSL RSA Domain Secure Site CA,O=ZeroSSL,C=AT
|
||||
- CN=R3,O=Let's Encrypt,C=US
|
||||
heuristics: true
|
||||
active: true
|
||||
http_default_port: 80
|
||||
iocs: true
|
||||
max_alerts: 3
|
||||
|
@ -81,7 +81,7 @@ set_credentials() {
|
||||
}
|
||||
|
||||
set_kioskmode() {
|
||||
echo -n " [?] Do you want to start TinyCheck in fullscreen during the system startup (aka. Kiosk mode)? [Yes/No] "
|
||||
echo -n "[?] Do you want to start TinyCheck in fullscreen during the system startup (aka. Kiosk mode)? [Yes/No] "
|
||||
read answer
|
||||
if [[ "$answer" =~ ^([yY][eE][sS]|[yY])$ ]]
|
||||
then
|
||||
@ -347,7 +347,7 @@ check_interfaces(){
|
||||
|
||||
# Setup of iface_out which can be any interface,
|
||||
# but needs to be connected now or in the future.
|
||||
echo -n " [?] The interface $ciface is connected. Do you want to use it as a bridge to Internet (network/out) ? [Yes/No] "
|
||||
echo -n "[?] The interface $ciface is connected. Do you want to use it as a bridge to Internet (network/out) ? [Yes/No] "
|
||||
read answer
|
||||
if [[ "$answer" =~ ^([yY][eE][sS]|[yY])$ ]]
|
||||
then
|
||||
@ -359,7 +359,7 @@ check_interfaces(){
|
||||
for iface in $IFACES;
|
||||
do
|
||||
config="$(ifconfig $iface)"
|
||||
echo -n " [?] Do you want to use $iface as a bridge to Internet (network/out) ? [Y/n] "
|
||||
echo -n "[?] Do you want to use $iface as a bridge to Internet (network/out) ? [Y/n] "
|
||||
read answer
|
||||
if [[ "$answer" =~ ^([yY][eE][sS]|[yY])$ ]]
|
||||
then
|
||||
@ -381,7 +381,7 @@ check_interfaces(){
|
||||
hw="$(iw $iface info | grep wiphy | cut -d" " -f2)" # Get the iface hardware id.
|
||||
info="$(iw phy$hw info)" # Get the iface hardware infos.
|
||||
if echo "$info" | grep -qE "* AP$"; then # Know if the iface has the AP mode available.
|
||||
echo -n " [?] The interface $iface can be used for the Wi-Fi Access Point. Do you want to use it for the TinyCheck Access Point ? [Yes/No] "
|
||||
echo -n "[?] The interface $iface can be used for the Wi-Fi Access Point. Do you want to use it for the TinyCheck Access Point ? [Yes/No] "
|
||||
read answer
|
||||
if [[ "$answer" =~ ^([yY][eE][sS]|[yY])$ ]]
|
||||
then
|
||||
|
@ -70,7 +70,7 @@ class IOCs(object):
|
||||
@staticmethod
|
||||
def delete(ioc_id):
|
||||
"""
|
||||
Delete an IOC by its id to the database.
|
||||
Delete an IOC by its id in the database.
|
||||
:return: status of the operation in JSON
|
||||
"""
|
||||
if db.session.query(exists().where(Ioc.id == ioc_id)).scalar():
|
||||
@ -82,6 +82,21 @@ class IOCs(object):
|
||||
return {"status": False,
|
||||
"message": "IOC not found"}
|
||||
|
||||
@staticmethod
|
||||
def delete_by_value(ioc_value):
|
||||
"""
|
||||
Delete an IOC by its value in the database.
|
||||
:return: status of the operation in JSON
|
||||
"""
|
||||
if db.session.query(exists().where(Ioc.value == ioc_value)).scalar():
|
||||
db.session.query(Ioc).filter_by(value=ioc_value).delete()
|
||||
db.session.commit()
|
||||
return {"status": True,
|
||||
"message": "IOC deleted"}
|
||||
else:
|
||||
return {"status": False,
|
||||
"message": "IOC not found"}
|
||||
|
||||
@staticmethod
|
||||
def search(term):
|
||||
"""
|
||||
|
@ -55,7 +55,7 @@ class WhiteList(object):
|
||||
@staticmethod
|
||||
def delete(elem_id):
|
||||
"""
|
||||
Delete an element by its id to the database.
|
||||
Delete an element by its id in the database.
|
||||
:return: status of the operation in a dict
|
||||
"""
|
||||
if db.session.query(exists().where(Whitelist.id == elem_id)).scalar():
|
||||
@ -67,6 +67,21 @@ class WhiteList(object):
|
||||
return {"status": False,
|
||||
"message": "Element not found"}
|
||||
|
||||
@staticmethod
|
||||
def delete_by_value(elem_value):
|
||||
"""
|
||||
Delete an element by its value in the database.
|
||||
:return: status of the operation in a dict
|
||||
"""
|
||||
if db.session.query(exists().where(Whitelist.element == elem_value)).scalar():
|
||||
db.session.query(Whitelist).filter_by(element=elem_value).delete()
|
||||
db.session.commit()
|
||||
return {"status": True,
|
||||
"message": "Element deleted"}
|
||||
else:
|
||||
return {"status": False,
|
||||
"message": "Element not found"}
|
||||
|
||||
@staticmethod
|
||||
def search(element):
|
||||
"""
|
||||
|
@ -12,12 +12,12 @@ import time
|
||||
from multiprocessing import Process
|
||||
|
||||
"""
|
||||
This file is parsing the watchers present
|
||||
in the configuration file. This in order to get
|
||||
automatically new iocs / elements from remote
|
||||
This file is parsing the watchers present
|
||||
in the configuration file. This in order to get
|
||||
automatically new iocs / elements from remote
|
||||
sources without user interaction.
|
||||
|
||||
As of today the default export JSON format from
|
||||
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 ;)
|
||||
@ -44,7 +44,9 @@ def watch_iocs():
|
||||
try:
|
||||
res = requests.get(w["url"], verify=False)
|
||||
if res.status_code == 200:
|
||||
iocs_list = json.loads(res.content)["iocs"]
|
||||
content = json.loads(res.content)
|
||||
iocs_list = content["iocs"] if "iocs" in content else []
|
||||
to_delete = content["to_delete"] if "to_delete" in content else []
|
||||
else:
|
||||
w["status"] = False
|
||||
except:
|
||||
@ -58,6 +60,13 @@ def watch_iocs():
|
||||
except:
|
||||
continue
|
||||
|
||||
for ioc in to_delete:
|
||||
try:
|
||||
iocs.delete_by_value(ioc["value"])
|
||||
w["status"] = True
|
||||
except:
|
||||
continue
|
||||
|
||||
# If at least one URL haven't be parsed, let's retry in 1min.
|
||||
if False in [w["status"] for w in watchers]:
|
||||
time.sleep(60)
|
||||
@ -67,8 +76,8 @@ def watch_iocs():
|
||||
|
||||
def watch_whitelists():
|
||||
"""
|
||||
Retrieve whitelist elements from the remote URLs
|
||||
defined in config/watchers. For each (new ?) element,
|
||||
Retrieve whitelist elements from the remote URLs
|
||||
defined in config/watchers. For each (new ?) element,
|
||||
add it to the DB.
|
||||
"""
|
||||
|
||||
@ -83,7 +92,9 @@ def watch_whitelists():
|
||||
try:
|
||||
res = requests.get(w["url"], verify=False)
|
||||
if res.status_code == 200:
|
||||
elements = json.loads(res.content)["elements"]
|
||||
content = json.loads(res.content)
|
||||
elements = content["elements"] if "elements" in content else []
|
||||
to_delete = content["to_delete"] if "to_delete" in content else []
|
||||
else:
|
||||
w["status"] = False
|
||||
except:
|
||||
@ -96,6 +107,13 @@ def watch_whitelists():
|
||||
except:
|
||||
continue
|
||||
|
||||
for elem in to_delete:
|
||||
try:
|
||||
whitelist.delete_by_value(elem["element"])
|
||||
w["status"] = True
|
||||
except:
|
||||
continue
|
||||
|
||||
if False in [w["status"] for w in watchers]:
|
||||
time.sleep(60)
|
||||
else:
|
||||
|
Loading…
Reference in New Issue
Block a user