Merge pull request #52 from KasperskyLab/dev

Adding WHOIS record / active analysis
This commit is contained in:
Félix Aimé 2021-02-16 18:52:20 +01:00 committed by GitHub
commit 42c7254cc6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 132 additions and 46 deletions

View File

@ -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):
"""

View File

@ -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 {}",

View File

@ -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 {}",

View File

@ -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 {}",

View File

@ -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."

View File

@ -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">

View File

@ -13,4 +13,5 @@ pyudev
wifi
qrcode
netifaces
weasyprint
weasyprint
python-whois

File diff suppressed because one or more lines are too long

View File

@ -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

View File

@ -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

View File

@ -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):
"""

View File

@ -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):
"""

View File

@ -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: