my current main module and modularized input sort, lookup and display functions

This commit is contained in:
Joost Agterhoek 2024-09-02 13:46:07 +02:00
parent 4f36411a50
commit af860ff215
6 changed files with 199 additions and 0 deletions

11
cli_lookup.py Normal file
View File

@ -0,0 +1,11 @@
from src.lookup import lookup
from src.type_hosts import type_hosts
from src.user_input import user_input
from src.display import display
if __name__ == "__main__":
hosts = user_input()
validated_hosts = type_hosts(hosts)
lookedup_hosts = lookup(validated_hosts)
display(lookedup_hosts)

0
src/__init__.py Normal file
View File

25
src/display.py Normal file
View File

@ -0,0 +1,25 @@
from rich.console import Console
from rich.table import Table, errors
def display(lookup_results):
table = Table(title="results", highlight=True, show_lines=True, row_styles=["dim", ""])
# Remember: the dimension/column is not the host type, but the lookup result! So a whois, a DMARC, an SPF, etc. Because for one host, there are multiple lookup results (I guess???)
table.add_column('host')
table.add_column('domain registered')
table.add_column('registrar')
table.add_column('dnssec')
table.add_column('spf')
table.add_column('dmarc')
for lookedup in lookup_results:
try:
table.add_row(str(lookedup.host), str(lookedup.whois['creation_date']), str(lookedup.whois['registrar']), str(lookedup.whois['dnssec']), lookedup.spf, lookedup.dmarc)
except errors.NotRenderableError as error:
print(error.args, lookup_results, lookedup)
table.add_section()
table.add_row("", "", "", "", "*** -all = hard fail ***", "*** p=reject (drop email)***", style="green")
table.add_row("", "", "", "", "*** ~all = hard fail ***", "*** p=quarantine (email in spam)***", style="green")
table.add_row("", "", "", "", "*** all = allow all ***", "*** p=none (ignore email)***", style="green")
console = Console()
console.print(table)

108
src/lookup.py Normal file
View File

@ -0,0 +1,108 @@
from whois import whois
from checkdmarc.spf import get_spf_record, SPFRecordNotFound
from checkdmarc.dmarc import get_dmarc_record, DMARCRecordNotFound
import time
import tldextract
from tqdm import tqdm
import progressbar
def progress_bar():
widgets = ["TESTING A PROGRESS BAR", progressbar.Bar()]
bar = progressbar.ProgressBar(widgets=widgets).start()
return bar
class Lookup(object):
def __init__(self, host):
self.host = host
self.whois = dict(whois(host))
self.dmarc = None
self.spf = None
def lookup(validated_hosts):
bar = progress_bar()
lookups = []
for key, value in validated_hosts.items():
if key == "domains":
print("[Looking up domains...]")
if any(value):
for host in tqdm(value):
lookedup = Lookup(host)
try:
lookedup.dmarc = dict(get_dmarc_record(host))["record"]
except DMARCRecordNotFound as error:
print("DMARC exception. Should start using raise :)")
lookedup.dmarc = error.args[0]
try:
lookedup.spf = dict(get_spf_record(host))["record"]
except SPFRecordNotFound as error:
print(
"SPF exception. Should start using raise :)",
error.args,
type(error.args),
error.args[0],
)
# this 'works', as in, error.args returns some valuable detail (DNS timeout) and the host to look up.
lookedup.spf = error.args[0]
lookups.append(lookedup)
time.sleep(1)
# bar.update()
elif key == "email":
print("[Looking up email addresses...]")
if any(value):
for host in tqdm(value):
domain = str.split(host, "@")[-1]
lookedup = Lookup(domain)
try:
lookedup.dmarc = dict(get_dmarc_record(domain))["record"]
except DMARCRecordNotFound as error:
print("DMARC exception. Should start using raise :)")
try:
lookedup.spf = dict(get_spf_record(domain))["record"]
except SPFRecordNotFound as error:
print("SPF exception. Should start using raise :)",
error.args,
type(error.args),
error.args[0],
)
lookups.append(lookedup)
time.sleep(1)
elif key == "URL":
print("[Looking up URLs...]")
if any(value):
for host in tqdm(value):
domain = tldextract.extract(host).domain
lookedup = Lookup(domain)
lookedup.dmarc = dict(get_dmarc_record(domain))["record"]
lookedup.spf = dict(get_spf_record(domain))["record"]
lookups.append(lookedup)
# TODO add VirusTotal-lookup and return score?
time.sleep(1)
elif key == "hostname":
print("Looking up hostnames...]")
if any(value):
for host in tqdm(value):
pass
elif key == "IP":
print("Looking up IPs...]")
if any(value):
for host in tqdm(value):
lookedup = Lookup(host)
lookups.append(lookup)
time.sleep(1)
else:
print("No hosts to look up in ", key)
bar.update()
return lookups
def lookup_spf(validated_hosts):
pass
def lookup_dmarc(validated_hosts):
pass

43
src/type_hosts.py Normal file
View File

@ -0,0 +1,43 @@
import validators
def normalize(host):
domain_name, tld = "", ""
if host.startswith('www.'):
domain_name, tld = str.split(host,'.')[-2:]
normalized_domain = domain_name + '.' + tld
return normalized_domain
else:
return host
def type_hosts(hosts):
validated_hosts = {
"URLs": [],
"domains": [],
"IPs": [],
"email": [],
"hostnames": [],
}
URLs = []
domains = []
IPs = []
email = []
hostnames = []
for host in hosts:
if validators.url(host):
URLs.append(host)
elif validators.domain(host):
domains.append(normalize(host))
elif validators.ipv4(host) or validators.ipv6(host):
IPs.append(host)
elif validators.email(host):
email.append(host)
elif validators.hostname(host):
hostnames.append(host)
else:
print("This is not a URL, IP, email address or hostname: ", host)
validated_hosts["URLs"].extend([i for i in URLs])
validated_hosts["domains"].extend([i for i in domains])
validated_hosts["IPs"].extend([i for i in IPs])
validated_hosts["email"].extend([i for i in email])
validated_hosts["hostnames"].extend([i for i in hostnames])
return validated_hosts

12
src/user_input.py Normal file
View File

@ -0,0 +1,12 @@
import re
def user_input():
while True:
hosts = str(input("Type in or copy-paste "
"one or more IP addresses, domain names "
"URLs or email addresses: "
))
if hosts.strip() != '':
sanitized = re.split("; |, | ", hosts)
return sanitized
# break