baoSOC/tunneling.py
2024-06-18 21:46:23 +02:00

83 lines
2.6 KiB
Python

#!/usr/bin/venv python
# -*- coding: utf-8 -*-
def tunnelingDNSAttacks(report, queries, dnsbl):
"""
This function identify if we have a DNS tunneling
We can identify the payload size (512 bytes) and for a specific domain, how many occurs it appear.
For the payload size, according to the RFC 1035: https://datatracker.ietf.org/doc/html/rfc1035#section-2.3.4
The maximum UDP message is 512 or less.
If we detect a lot of request to a specific domain, that can be a DNS tunneling
"""
report['blackDomain'] = _blackDomain(queries, dnsbl)
report['oversized'] = _oversized(queries)
def _blackDomain(queries, dnsbl) -> list:
""""
This function identify if a dns domain is in a blacklist
Return the report
"""
report = dict()
# Read the black domain list
dataDnsbl = list()
with open(dnsbl, 'r') as f:
for line in f:
dataDnsbl.append(line.replace("\n", ""))
for query in queries:
domain = _splitDomain(query['query'])
# Check if in dns blacklist
if domain in dataDnsbl:
if domain not in report:
report[domain] = list()
report[domain].append(query['src'])
else:
if query['src'] not in report[domain]:
report[domain].append(query['src'])
return report
def _oversized(queries) -> dict:
"""
This function analyzed the payload size and if it's oversize, that can be a DNS tunneling
"""
report = dict()
for query in queries:
if query['len'] > 220:
domain = _splitDomain(query['query'])
if domain not in report:
report[domain] = list()
report[domain].append({
'source': query['src'],
'len': query['len'],
})
else:
if query['src'] not in report[domain]:
report[domain].append({
'source': query['src'],
'len': query['len'],
})
return report
def _splitDomain(query) -> str:
"""
This function split the query for identifying the domain
"""
# Split to get the country code and the TLD
domainSplitted = str(query).split(".")
l = len(domainSplitted)
tld = domainSplitted[l - 3:l - 2]
cc = domainSplitted[l - 2 :l - 1]
try:
domain = f"{tld[0]}.{cc[0]}"
except IndexError:
print(f"Failed to parse the domain {query}")
domain = None
return domain