-
Notifications
You must be signed in to change notification settings - Fork 167
/
main.py
executable file
·135 lines (101 loc) · 3.44 KB
/
main.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
#!/usr/bin/env python3
from scan import scan_domain
import signatures
import output
import detection_enums
import providers
from os import linesep
from domain import Domain
from resolver import Resolver
from functools import partial
import logging
from sys import stderr, exit, argv
import argparsing
import colorama
import time
import asyncio
import dns.resolver
start_time = time.time()
if "--nocolour" in argv:
print(argparsing.banner, file=stderr)
else:
colorama.init()
print(argparsing.banner_with_colour, file=stderr)
args = argparsing.parse_args()
###### verbosity
if args.verbose == 0:
verbosity_level = logging.WARN
if args.verbose == 1:
verbosity_level = logging.INFO
if args.verbose > 1:
verbosity_level = logging.DEBUG
logging.basicConfig(format="%(message)s", level=verbosity_level)
logging.StreamHandler(stderr)
if not args.verbose > 2:
for module in ["boto", "requests"]:
logger = logging.getLogger(module)
logger.setLevel(logging.CRITICAL)
###### signatures
signatures = [getattr(signatures, signature) for signature in signatures.__all__]
# replace name for each signature
for signature in signatures:
signature.__name__ = signature.__name__.replace("signatures.", "")
if args.signature:
signatures = [s for s in signatures if s.__name__ in args.signature]
if args.exclude_signature:
signatures = [s for s in signatures if s.__name__ not in args.exclude_signature]
if not args.enable_unlikely:
signatures = [
s
for s in signatures
if s.test.CONFIDENCE != detection_enums.CONFIDENCE.UNLIKELY
]
if args.disable_probable:
signatures = [
s
for s in signatures
if s.test.CONFIDENCE != detection_enums.CONFIDENCE.POTENTIAL
]
logging.warning(f"Testing with {len(signatures)} signatures")
###### scanning
findings = []
if "--out" not in argv:
# using default out location, need to append our format
args.out = f"{args.out}.{args.out_format}"
async def main():
###### domain ingestion
nameservers = (
dns.resolver.Resolver().nameservers
if args.resolver == ""
else args.resolver.replace(" ", "").split(",")
)
Domain.resolver = Resolver(nameservers=nameservers, parallelism=args.parallelism)
provider = getattr(providers, args.provider)
domains = list(provider.fetch_domains(**args.__dict__))
if len(domains) == 0:
logging.error("ERROR: No domains to scan")
exit(-1)
with output.Output(args.out_format, args.out) as o:
scan = partial(
scan_domain,
signatures=signatures,
output_handler=o,
findings=findings,
)
await asyncio.gather(*[asyncio.create_task(scan(domain)) for domain in domains])
###### exit
logging.warning(f"\n\nWe found {len(findings)} takeovers ☠️")
for finding in findings:
msg = f"-- DOMAIN '{finding.domain}' :: SIGNATURE '{finding.signature}' :: CONFIDENCE '{finding.confidence}'"
msg += f"{linesep}{finding.populated_records()}"
if args.nocolour == False:
msg = colorama.Fore.RED + msg + colorama.Fore.RESET
logging.warning(msg)
logging.warning(
f"\n⏱️ We completed in {round(time.time() - start_time, 2)} seconds"
)
logging.warning(f"...Thats all folks!")
if args.pipeline:
logging.debug(f"Pipeline flag set - Exit code: {len(findings)}")
exit(len(findings))
asyncio.run(main())