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'
}
#DNS_QUERIES_TYPE = ('A', 'MX', 'TXT')
DNS_QUERIES_TYPE = {
'A': 'address',
'MX': ['exchange', 'preference'],

@ -20,37 +20,35 @@ class DNSInformations:
report['updated_date'] = w.updated_date
report['ns'] = w.name_servers
report['admin_name'] = w.admin_name
report['registrar'] = w.registrar
return report
def resolver(self):
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():
report[t] = self._resolving(self._fqdn, t, DNS_QUERIES_TYPE[t])
return report
def _resolving(self, fqdn, t, attr):
report = list()
res_query = dns.resolver.resolve(fqdn, t)
for rdata in res_query:
if isinstance(attr, list):
data = dict()
for a in attr:
data[a] = getattr(rdata, a)
report.append(data)
else:
report.append({
attr: getattr(rdata, attr)
})
try:
res_query = dns.resolver.resolve(fqdn, t)
for rdata in res_query:
if isinstance(attr, list):
data = dict()
for a in attr:
data[a] = getattr(rdata, a)
report.append(data)
else:
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

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 -*-
from argparse import ArgumentParser
import requests
import re
from config import VT_ATTRIBUTES_MAPPING
from vt import VT
from dnsinformations import DNSInformations as DNS
import ipaddress
from datetime import datetime
from hashing import Hash
from os.path import exists
def checkArguments():
parser = ArgumentParser(description="baoSOC")
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')
parser.add_argument('--dns', help='Get domain name information', action="store_true")
# For dns command
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()
def usage():
@ -25,8 +39,20 @@ def usage():
print("Usage: main.py [COMMAND]")
print("-c PATH, --config PATH\t\tConfig file - mandatory")
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("--dnsattacks FILE\t\t\tParse the DNS pcap file and identify some DNS attacks")
print("--dns \t\t\t\tGet information regarding the domain with whois and VirusTotal")
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():
print("\n baoSOC ")
@ -74,35 +100,151 @@ def main():
print("Failed to read the config file")
exit(0)
#vt = VT(config['api_key'])
#report = list()
#print(vt.getIPVirusTotal("1.1.1.1", report))
report = dict()
# Analyse 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")
report = dns.resolver()
for key in report.keys():
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}")
res = "6548eec09f4d8bc6514bee3e5452541c"
if args.scanvt:
_parsingHash(config, res, report)
print("\nReport with Whois:\n")
report = dns.whois()
for key in report.keys():
if isinstance(report[key], list):
print(f"{key}:")
for value in report[key]:
print(f"\t{value}")
else:
print(f"{key}: {report[key]}")
def _parsingHash(config, h, report):
report = dict()
vt = VT(config['api_key'])
vt.getRateFromHash(h, report)
print("\n----------------------")
print("| VirusTotal |")
print("----------------------")
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__":
main()

76
vt.py

@ -1,16 +1,18 @@
#!/ur/bin/env python3
import requests
from config import VT_ATTRIBUTES_MAPPING
from datetime import datetime
class VT:
def __init__(self, api_key):
self._url = "https://www.virustotal.com/api/v3"
self._headers = {
'x-apki-key': api_key,
'x-apikey': api_key,
}
def getIPVirusTotal(self, ip, report):
def getIPVirusTotal(self, ip):
res = requests.get(
f"{self._url}/ip_addresses/{ip}",
headers=self._headers
@ -33,16 +35,76 @@ class VT:
data[entry] = vt[entry]
except KeyError:
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):
headers = self._headers
headers['resource'] = h
res = requests.get(
f"{self._url}/file/report",
headers=headers
f"{self._url}/files/{h}",
headers=self._headers
).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