diff --git a/.gitignore b/.gitignore index 6cdd6b7..0708987 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,4 @@ __pycache__ alerts db log +venv diff --git a/CertStreamMonitor.py b/CertStreamMonitor.py index f0a6c56..7cde18c 100755 --- a/CertStreamMonitor.py +++ b/CertStreamMonitor.py @@ -2,6 +2,7 @@ # -*- coding: utf-8 -*- # Copyright (c) 2018 Caisse nationale d'Assurance Maladie +# 2020-2021 Updated by Nicolas BEGUIER (nicolas.beguier@adevinta.com) # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -24,7 +25,7 @@ from utils.utils import TimestampNow, VerifyPath from utils.sqlite import SqliteCmd -VERSION = "0.6.0" +VERSION = "0.7.0" def usage(): """ @@ -136,24 +137,23 @@ def print_callback(message, context): # Data extraction to populate DB Domain = host SAN = "" - Issuer = message['data']['chain'][0]['subject']['aggregated'] + Issuer = message['data']['leaf_cert']['issuer']['aggregated'] Fingerprint = message['data']['leaf_cert']['fingerprint'] Startime = datetime.datetime.utcfromtimestamp( message['data']['leaf_cert']['not_before']).isoformat() FirstSeen = format(datetime.datetime.utcnow( ).replace(microsecond=0).isoformat()) # Test if entry still exist in DB - if SQL.SQLiteVerifyEntry(TABLEname, Domain) is 0: + if SQL.SQLiteVerifyEntry(TABLEname, Domain) == 0: SQL.SQLiteInsert(TABLEname, Domain, SAN, Issuer, Fingerprint, Startime, FirstSeen) - sys.stdout.write(u"[{}] {} (SAN: {}) (Issuer: {}) (Fingerprint: {}) (StartTime: {})\n".format(datetime.datetime.now().replace(microsecond=0).isoformat(), host, "", message['data'] - ['chain'][0]['subject']['aggregated'], message['data']['leaf_cert']['fingerprint'], datetime.datetime.utcfromtimestamp(message['data']['leaf_cert']['not_before']).isoformat())) + sys.stdout.write(u"[{}] {} (SAN: {}) (Issuer: {}) (Fingerprint: {}) (StartTime: {})\n".format(datetime.datetime.now().replace(microsecond=0).isoformat(), host, "", message['data']['leaf_cert']['issuer']['aggregated'], message['data']['leaf_cert']['fingerprint'], datetime.datetime.utcfromtimestamp(message['data']['leaf_cert']['not_before']).isoformat())) sys.stdout.flush() # If just one keyword occurence, put data into debug log file elif FindNb > 0 and FindNb < DetectionThreshold: logging.debug("DETECTION THRESHOLD VALUE NOT REACHED - {} (SAN: {}) (Issuer: {}) (Fingerprint: {}) (StartTime: {})".format(host, "", - message['data']['chain'][0]['subject']['aggregated'], message['data']['leaf_cert']['fingerprint'], datetime.datetime.utcfromtimestamp(message['data']['leaf_cert']['not_before']).isoformat())) + message['data']['leaf_cert']['issuer']['aggregated'], message['data']['leaf_cert']['fingerprint'], datetime.datetime.utcfromtimestamp(message['data']['leaf_cert']['not_before']).isoformat())) # Main diff --git a/requirements.txt b/requirements.txt index 11ead73..90d9957 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,7 +1,7 @@ -certstream==1.10 +certstream==1.11 requests ipwhois PySocks hues -websocket-client==0.48.0 +websocket-client==0.57.0 apprise diff --git a/utils/sqlite.py b/utils/sqlite.py index 9f047f5..671facd 100644 --- a/utils/sqlite.py +++ b/utils/sqlite.py @@ -1,43 +1,51 @@ #!/usr/bin/env python3 # -*- coding: utf-8 -*- - -# This file is a part of CertStreamMonitor +""" +This file is a part of CertStreamMonitor +""" import sqlite3 -import sys class SqliteCmd(object): - '''Sqlite3 DB commands''' - def __init__(self, DBfile): - self.conn = sqlite3.connect(DBfile) - self.cur = self.conn.cursor() + """ + Sqlite3 DB commands + """ + def __init__(self, DBfile): + self.conn = sqlite3.connect(DBfile) + self.cur = self.conn.cursor() + + ## Main DB operations + def SQLiteCreateTable(self, TABLEname): + """ + Creating main Table if not exist + """ + self.cur.execute('CREATE TABLE IF NOT EXISTS '+TABLEname+' (Domain TEXT NOT NULL PRIMARY KEY, SAN TEXT, Issuer TEXT, Fingerprint TEXT, Startime TEXT, FirstSeen TEXT, StillInvestig TEXT)') - ## Main DB operations - def SQLiteCreateTable(self, TABLEname): - '''Creating main Table if not exist''' - self.cur.execute('CREATE TABLE IF NOT EXISTS '+TABLEname+' (Domain TEXT NOT NULL PRIMARY KEY, SAN TEXT, Issuer TEXT, Fingerprint TEXT, Startime TEXT, FirstSeen TEXT, StillInvestig TEXT)') + def SQLiteInsert(self, TABLEname, Domain, SAN, Issuer, Fingerprint, Startime, FirstSeen): + """ + Insert new entry infos + """ + self.cur.execute('INSERT OR IGNORE INTO '+TABLEname+' (Domain, SAN, Issuer, Fingerprint, Startime, FirstSeen) VALUES (?,?,?,?,?,?);', (Domain, SAN, Issuer, Fingerprint, Startime, FirstSeen)) + self.conn.commit() - def SQLiteInsert(self, TABLEname, Domain, SAN, Issuer, Fingerprint, Startime, FirstSeen): - '''Insert new entry infos''' - self.cur.execute('INSERT OR IGNORE INTO '+TABLEname+' (Domain, SAN, Issuer, Fingerprint, Startime, FirstSeen) VALUES (?,?,?,?,?,?);', (Domain, SAN, Issuer, Fingerprint, Startime, FirstSeen)) - self.conn.commit() + def SQLiteVerifyEntry(self, TABLEname, Domain): + """ + Verify if entry still exist + """ + res = self.cur.execute('SELECT EXISTS (SELECT 1 FROM '+TABLEname+' WHERE Domain=? LIMIT 1);', (Domain,)) + fres = res.fetchone()[0] + # 0ô + if fres is not 0: + return 1 + else: + return 0 - def SQLiteVerifyEntry(self, TABLEname, Domain): - '''Verify if entry still exist''' - res = self.cur.execute('SELECT EXISTS (SELECT 1 FROM '+TABLEname+' WHERE Domain='+"\""+Domain+"\""+' LIMIT 1);') - fres = res.fetchone()[0] - # 0ô - if fres is not 0: - return 1 - else: - return 0 + def __del__(self): + try: + self.cur.close() + self.conn.close() + except: + pass - def __del__(self): - try: - self.cur.close() - self.conn.close() - except: - pass - - def SQLiteClose(self): - self.__del__() + def SQLiteClose(self): + self.__del__()