-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathdomain_in_scope.py
More file actions
148 lines (133 loc) · 4.51 KB
/
domain_in_scope.py
File metadata and controls
148 lines (133 loc) · 4.51 KB
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
136
137
138
139
140
141
142
143
144
145
146
147
148
import ipaddress
import socket
import sys
import logging
import threading
import argparse
# Color output
COLORS = {
"grey": 30,
"red": 31,
"green": 32,
"yellow": 33,
"blue": 34,
"magenta": 35,
"cyan": 36,
"white": 37
}
def colored(text: str, color: str) -> str:
"""Colorize text with ANSI escape sequences."""
return f"\033[{COLORS[color]}m{text}\033[0m"
def IPs_from_octet_range(ip: str) -> list[str]:
res = []
ip_octet = [[0, 0], [0, 0], [0, 0], [0, 0]]
octets = ip.split(".")
for i, octet in enumerate(octets):
if "-" in octet:
ip_octet[i][0] = int(octet.split("-")[0])
ip_octet[i][1] = int(octet.split("-")[1])
else:
ip_octet[i][0] = int(octet)
ip_octet[i][1] = int(octet)
for i in range (ip_octet[0][0], ip_octet[0][1] + 1):
for j in range (ip_octet[1][0], ip_octet[1][1] + 1):
for k in range (ip_octet[2][0], ip_octet[2][1] + 1):
for l in range (ip_octet[3][0], ip_octet[3][1] + 1):
res.append(f"{i}.{j}.{k}.{l}")
return res
class LookupThread(threading.Thread):
def __init__(self, domain, result):
self.domain = domain
self.result = result
threading.Thread.__init__(self)
def run(self):
with semaphore:
self.lookup(self.domain, ips_list)
def lookup(self, domain, ips_list):
"""Try to find the IPs of a domain
Returns a dict:
{domain: {"ips": [ip1, ip2], "error": ""}
If host is not found, then the dict will hold:
{domain: {"ips": [], "error": "error message"}
"""
try:
hostname, aliaslist, ipaddrlist = socket.gethostbyname_ex(domain)
except Exception as e:
self.result[domain] = {"ips": [], "error": str(e)}
if IS_SILENT:
pass
else:
print(f"{colored('[!]', 'yellow')} {domain}: {colored(str(e), 'yellow')}")
else:
self.result[domain] = {"ips": ipaddrlist, "error": ""}
intersection = ips_list.intersection(set(ipaddrlist))
if intersection:
res_ipaddrlist = ipaddrlist.copy()
for i in range(len(res_ipaddrlist)):
if res_ipaddrlist[i] in intersection:
res_ipaddrlist[i] = colored(res_ipaddrlist[i], "green")
if IS_SILENT:
print(domain)
else:
print(f"{colored('[+]', 'green')} {domain}: {', '.join(res_ipaddrlist)}")
else:
if IS_SILENT:
pass
else:
print(f"{colored('[-]', 'red')} {domain}: {', '.join(ipaddrlist)}")
if __name__ == '__main__':
parser = argparse.ArgumentParser(
prog="domain_in_scope",
description="Return domains in IP addresses scope",
allow_abbrev=False
)
parser.add_argument(
'--domains',
nargs='?',
type=argparse.FileType('r'),
default=(None if sys.stdin.isatty() else sys.stdin),
help='path to domains list')
parser.add_argument(
'--ips',
nargs='?',
type=argparse.FileType('r'),
required=True,
help='path to IP addresses list')
parser.add_argument(
'--silent',
help="be silent and return only domains in scope",
action="store_true"
)
parser.add_argument(
'-t', '--threads',
nargs="?",
type=int,
help="number of threads (default 25)",
default=25
)
args = parser.parse_args()
ips_file = args.ips
domains_file = args.domains
if not args.domains:
sys.exit("Please provide an input file, or pipe it via stdin")
IS_SILENT = args.silent
MAX_CONCURRENT_THREADS = args.threads
semaphore = threading.Semaphore(value=MAX_CONCURRENT_THREADS)
# List IP address from ips_file
ips_list = set()
lines = ips_file.read().splitlines()
# import pdb; pdb.set_trace()
for line in lines:
if "-" in line:
ips_list.update(IPs_from_octet_range(line))
else:
ips_list.update([str(ip) for ip in ipaddress.IPv4Network(line)])
# Check if domains is in IP address list
domains_lookup_res = {}
lookup_threads = []
lines = domains_file.read().splitlines()
for line in lines:
lookup_threads.append(LookupThread(line, domains_lookup_res))
# Start the threads
for t in lookup_threads:
t.start()