Analyse hash and dns

This commit is contained in:
geoffrey 2024-06-21 17:13:51 +02:00
parent 926678c6ee
commit 1e36568e44
5 changed files with 298 additions and 59 deletions

@ -12,7 +12,6 @@ VT_ATTRIBUTES_MAPPING = {
'ip': 'str' 'ip': 'str'
} }
#DNS_QUERIES_TYPE = ('A', 'MX', 'TXT')
DNS_QUERIES_TYPE = { DNS_QUERIES_TYPE = {
'A': 'address', 'A': 'address',
'MX': ['exchange', 'preference'], 'MX': ['exchange', 'preference'],

@ -20,37 +20,35 @@ class DNSInformations:
report['updated_date'] = w.updated_date report['updated_date'] = w.updated_date
report['ns'] = w.name_servers report['ns'] = w.name_servers
report['admin_name'] = w.admin_name report['admin_name'] = w.admin_name
report['registrar'] = w.registrar
return report return report
def resolver(self): def resolver(self):
report = dict() report = dict()
n = dns.name.from_text(self._fqdn)
s = self._fqdn.split(".")
l = len(s)
fqdn = f"{s[l - 2]}.{s[l - 1]}"
print(fqdn)
o = dns.name.from_text(fqdn)
if n.relativize(o):
print(True)
for t in DNS_QUERIES_TYPE.keys(): for t in DNS_QUERIES_TYPE.keys():
report[t] = self._resolving(self._fqdn, t, DNS_QUERIES_TYPE[t]) report[t] = self._resolving(self._fqdn, t, DNS_QUERIES_TYPE[t])
return report return report
def _resolving(self, fqdn, t, attr): def _resolving(self, fqdn, t, attr):
report = list() report = list()
res_query = dns.resolver.resolve(fqdn, t) try:
for rdata in res_query: res_query = dns.resolver.resolve(fqdn, t)
if isinstance(attr, list): for rdata in res_query:
data = dict() if isinstance(attr, list):
for a in attr: data = dict()
data[a] = getattr(rdata, a) for a in attr:
report.append(data) data[a] = getattr(rdata, a)
else: report.append(data)
report.append({ else:
attr: getattr(rdata, attr) report.append({
}) attr: getattr(rdata, attr)
})
except dns.resolver.NoAnswer:
pass
except dns.resolver.NXDOMAIN:
report.append({'error': 'Domain not exist'})
except dns.resolver.NoNameservers:
report.append({'error': 'Domain not exist'})
return report return report

38
hashing.py Normal file

@ -0,0 +1,38 @@
#!/usr/bin/env python3
import hashlib
class Hash:
def __init__(self):
pass
def hashMd5(self, f):
md5 = hashlib.md5()
with open(f, "rb") as data:
md5.update(data.read())
return md5.hexdigest()
def hashSha1(self, f):
sha1 = hashlib.sha1()
with open(f, "rb") as data:
sha1.update(data.read())
return sha1.hexdigest()
def hashSha256(self, f):
sha256 = hashlib.sha256()
with open(f, "rb") as data:
sha256.update(data.read())
return sha256.hexdigest()
def hashSha384(self, f):
sha384 = hashlib.sha384()
with open(f, "rb") as data:
sha384.update(data.read())
return sha384.hexdigest()
def hashSha512(self, f):
sha512 = hashlib.sha512()
with open(f, "rb") as data:
sha512.update(data.read())
return sha512.hexdigest()

202
main.py

@ -2,19 +2,33 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from argparse import ArgumentParser from argparse import ArgumentParser
import requests
import re
from config import VT_ATTRIBUTES_MAPPING from config import VT_ATTRIBUTES_MAPPING
from vt import VT from vt import VT
from dnsinformations import DNSInformations as DNS from dnsinformations import DNSInformations as DNS
import ipaddress
from datetime import datetime
from hashing import Hash
from os.path import exists
def checkArguments(): def checkArguments():
parser = ArgumentParser(description="baoSOC") parser = ArgumentParser(description="baoSOC")
parser.add_argument('-c', '--config', help='Config file') parser.add_argument('-c', '--config', help='Config file')
parser.add_argument('--hash', help='Hash file', action='store_true') parser.add_argument('--dns', help='Get domain name information', action="store_true")
parser.add_argument('--dns', help='Get domain name information') # For dns command
parser.add_argument('--dnsattacks', help='Parse DNS pcap file') parser.add_argument('--dnsattacks', help='Parse DNS pcap file')
parser.add_argument('--domain', help='Get domain name information')
parser.add_argument('--host', help='Get domain name information')
parser.add_argument('--ip', help='Get IP information')
# For hash command
parser.add_argument('--hash', help='Hash file', action='store_true')
parser.add_argument('--scanvt', help='If specified, scan the hash with VirusTotal', action='store_true')
parser.add_argument('--md5', help='Hash file')
parser.add_argument('--sha1', help='Hash file')
parser.add_argument('--sha256', help='Hash file')
parser.add_argument('--sha384', help='Hash file')
parser.add_argument('--sha512', help='Hash file')
return parser.parse_args() return parser.parse_args()
def usage(): def usage():
@ -25,8 +39,20 @@ def usage():
print("Usage: main.py [COMMAND]") print("Usage: main.py [COMMAND]")
print("-c PATH, --config PATH\t\tConfig file - mandatory") print("-c PATH, --config PATH\t\tConfig file - mandatory")
print("--hash FILE\t\t\tHash the file and check in VirusTotal") print("--hash FILE\t\t\tHash the file and check in VirusTotal")
print("--dns FQDN\t\t\tGet information regarding the domain with whois and VirusTotal") print("--dns \t\t\t\tGet information regarding the domain with whois and VirusTotal")
print("--dnsattacks FILE\t\t\tParse the DNS pcap file and identify some DNS attacks") print("--dnsattacks FILE\t\tParse the DNS pcap file and identify some DNS attacks")
print("\n--dns command:")
print("\t --domain FQDN\t\tScan and get domain information")
print("\t --host HOST\t\tScan and get host information")
print("\t --ip IP\t\tScan and get IP information")
print("\n--hash command:")
print("\t --md5 FILE\t\tGet the MD5 hash of the file")
print("\t --sha1 FILE\t\tGet the SHA256 of the file")
print("\t --sha256 FILE\t\tGet the SHA256 of the file")
print("\t --sha384 FILE\t\tGet the SHA384 of the file")
print("\t --sha512 FILE\t\tGet the SHA512 of the file")
def mainMenu(): def mainMenu():
print("\n baoSOC ") print("\n baoSOC ")
@ -74,35 +100,151 @@ def main():
print("Failed to read the config file") print("Failed to read the config file")
exit(0) exit(0)
#vt = VT(config['api_key']) report = dict()
#report = list()
#print(vt.getIPVirusTotal("1.1.1.1", report))
# Analyse DNS
if args.dns: if args.dns:
dns = DNS(config['api_key'], args.dns) if args.domain:
_parsingDomain(config, args.domain, report)
if args.host:
pass
if args.ip:
_parsingIP(config, args.ip, report)
# Analyse hash
if args.hash:
h = Hash()
dispatcher = {
"MD5": h.hashMd5,
"SHA1": h.hashSha1,
"SHA256": h.hashSha256,
"SHA384": h.hashSha384,
"SHA512": h.hashSha512,
}
if args.md5:
hashType = "MD5"
filename = args.md5
if args.sha1:
hashType = "SHA1"
filename = args.sha1
if args.sha256:
hashType = "SHA256"
filename = args.sha256
if args.sha384:
hashType = "SHA384"
filename = args.sha384
if args.sha512:
hashType = "SHA512"
filename = args.sha512
if not exists(filename):
print(f"File {filename} do not exist")
else:
res = dispatcher[hashType](filename)
print(f"{hashType} hash: {res}")
print("IP Informations:\n") res = "6548eec09f4d8bc6514bee3e5452541c"
report = dns.resolver() if args.scanvt:
for key in report.keys(): _parsingHash(config, res, report)
print(f"{key}: ")
for entry in report[key]:
for subkey in entry.keys():
value = entry[subkey]
if isinstance(value, bytes):
value = value.decode()
print(f"\t{subkey}: {value}")
print("\nReport with Whois:\n") def _parsingHash(config, h, report):
report = dns.whois() report = dict()
for key in report.keys(): vt = VT(config['api_key'])
if isinstance(report[key], list):
print(f"{key}:") vt.getRateFromHash(h, report)
for value in report[key]: print("\n----------------------")
print(f"\t{value}") print("| VirusTotal |")
else: print("----------------------")
print(f"{key}: {report[key]}")
if 'error' in report:
print("Error, can not find any informations")
return
# File
print("\nFile information:")
f = report['results']['file']
print(f"\tMD5: {f['md5']}")
print(f"\tSHA1: {f['sha1']}")
print(f"\tMagic: {f['magic']}")
print(f"\tFile type: {f['filetype']}")
print(f"\tSize: {f['size']}")
print(f"\tExtension: {f['extension']}")
print(f"\tFirst seen: {f['first_seen']}")
print(f"\tLast analysis: {f['last_analysis']}")
# Vendors
vendors = report['results']['vendors']
print("\nVendors:")
print(f"\tTotal vendors: {vendors['total_vendors']}")
print(f"\tCategorized as malicious: {vendors['total_malicious']}\n")
for key in vendors['result']:
print(f"\t{key}: {vendors['result'][key]}")
def _parsingIP(config, ip, report):
# Check if it's an IP address
vt = VT(config['api_key'])
try:
ip_obj = ipaddress.ip_address(ip)
except ValueError:
print("The IP is not valid")
return
report['ip'] = dict()
report['ip'] = vt.getIPVirusTotal(ip)
if 'error' not in report['ip']:
print("----------------------------")
print("| IP Informations |")
print("----------------------------")
for vt in VT_ATTRIBUTES_MAPPING.keys():
try:
vtAttributes = VT_ATTRIBUTES_MAPPING[vt]
if 'date' in vtAttributes:
value = datetime.fromtimestamp(int(report['ip'][vt]))
else:
value = report['ip'][vt]
print(f"{vt}: {value}")
except KeyError:
print(f"Cannot find the key {vt}")
def _parsingDomain(config, fqdn, report):
vt = VT(config['api_key'])
dns = DNS(config['api_key'], fqdn)
print("----------------------")
print("| resolving |")
print("----------------------")
report['resolving'] = dns.resolver()
for key in report['resolving'].keys():
print(f"{key}: ")
for entry in report['resolving'][key]:
for subkey in entry.keys():
value = entry[subkey]
if isinstance(value, bytes):
value = value.decode()
print(f"\t{subkey}: {value}")
print("\n----------------------")
print("| whois |")
print("----------------------")
report['whois'] = dns.whois()
report_whois = report['whois']
for key in report_whois.keys():
if isinstance(report_whois[key], list):
print(f"{key}:")
for value in report_whois[key]:
print(f"\t{value}")
else:
print(f"{key}: {report_whois[key]}")
print("\n----------------------")
print("| VirusTotal |")
print("----------------------")
report['vt'] = dict()
vt.getDomainReport(fqdn, report['vt'])
report_vt = report['vt']
for key in report_vt:
print(f"{key}: {report_vt[key]}")
print("\nReport with VirusTotal:\n")
if __name__ == "__main__": if __name__ == "__main__":
main() main()

76
vt.py

@ -1,16 +1,18 @@
#!/ur/bin/env python3 #!/ur/bin/env python3
import requests import requests
from config import VT_ATTRIBUTES_MAPPING
from datetime import datetime
class VT: class VT:
def __init__(self, api_key): def __init__(self, api_key):
self._url = "https://www.virustotal.com/api/v3" self._url = "https://www.virustotal.com/api/v3"
self._headers = { self._headers = {
'x-apki-key': api_key, 'x-apikey': api_key,
} }
def getIPVirusTotal(self, ip, report): def getIPVirusTotal(self, ip):
res = requests.get( res = requests.get(
f"{self._url}/ip_addresses/{ip}", f"{self._url}/ip_addresses/{ip}",
headers=self._headers headers=self._headers
@ -33,16 +35,76 @@ class VT:
data[entry] = vt[entry] data[entry] = vt[entry]
except KeyError: except KeyError:
data[entry] = 'Unknown' data[entry] = 'Unknown'
return data
report.append(data) def getDomainReport(self, fqdn, report):
res = requests.get(
f"{self._url}/domains/{fqdn}",
headers=self._headers
)
js = res.json()
report['reputation'] = js['data']['attributes']['reputation']
report['last_update'] = \
datetime.fromtimestamp(js['data']['attributes']['last_update_date'])
# Get number of security vendors
report['total_vendors'] = 0
report['clean'] = 0
report['unrated'] = 0
report['malicious'] = 0
vendors = js['data']['attributes']['last_analysis_results']
for entry in vendors:
report['total_vendors'] += 1
if vendors[entry]['result'] == 'clean':
report['clean'] += 1
elif vendors[entry]['result'] == 'unrated':
report['unrated'] += 1
elif vendors[entry]['result'] == 'malicious':
report['malicious'] += 1
def getRateFromHash(self, h, report): def getRateFromHash(self, h, report):
headers = self._headers headers = self._headers
headers['resource'] = h
res = requests.get( res = requests.get(
f"{self._url}/file/report", f"{self._url}/files/{h}",
headers=headers headers=self._headers
).json() ).json()
data = dict() if 'error' in res:
report["error"] = "Can not find the result"
return
attributes = res['data']['attributes']
report['results'] = dict()
report['results']['file'] = dict()
report['results']['file']['magic'] = attributes['magic']
report['results']['file']['sha1'] = attributes['sha1']
report['results']['file']['md5'] = attributes['md5']
report['results']['file']['filetype'] = attributes['detectiteasy']['filetype']
report['results']['file']['size'] = attributes['size']
report['results']['file']['extension'] = attributes['type_extension']
report['results']['file']['first_seen'] = \
datetime.fromtimestamp(attributes['first_seen_itw_date'])
report['results']['file']['last_analysis'] = \
datetime.fromtimestamp(attributes['last_analysis_date'])
# Identify vendors
report['results']['vendors'] = dict()
report['results']['vendors']['total_vendors'] = 0
report['results']['vendors']['total_malicious'] = 0
report['results']['vendors']['result'] = dict()
report['results']['vendors']['result']['undetected'] = 0
results = res['data']['attributes']['last_analysis_results']
for entry in results:
report['results']['vendors']['total_vendors'] += 1
if results[entry]['category'] == 'undetected':
report['results']['vendors']['result']['undetected'] += 1
else:
result = results[entry]['result']
if result not in report['results']['vendors']['result']:
report['results']['vendors']['result'][result] = 0
report['results']['vendors']['result'][result] += 1
report['results']['vendors']['total_malicious'] += 1