-
Notifications
You must be signed in to change notification settings - Fork 1
/
reconizer.py
192 lines (167 loc) · 6.88 KB
/
reconizer.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
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
import requests
import json
import copy
import tldextract
import re, dns.resolver
from shodan import Shodan
import argparse
from tqdm import tqdm # Import tqdm for the progress bar
import csv # Import the csv module
dns_server = '1.1.1.1'
parser = argparse.ArgumentParser("prscan.py")
parser.add_argument("--hostfile", metavar='<file>', help="A txt file with hosts per newline", type=str, required=True)
parser.add_argument("--ipinfo-token", metavar='<token>', help="API token for ipinfo.com", type=str, required=True)
parser.add_argument("--output", metavar='<output>', help="Output CSV filename", type=str, default="reconizer-results.csv") # Add a default filename
args = parser.parse_args()
hostfile = args.hostfile
apitoken = args.ipinfo_token
output_filename = args.output # Get the specified output filename from the command line argument
def prscan(hostfile):
domains = []
with open(hostfile,'r') as fin:
lines = fin.readlines()
for line in lines:
domains.append(str(line).rstrip("\n"))
# get unique hosts by converting to set and back
domains = list(set(domains))
ips = domains.copy()
print("[~] DNS resolving hostnames to IP")
for i in tqdm(range(len(ips))): # Use tqdm for the progress bar
try:
dnsresolver = dns.resolver.Resolver()
dnsresolver.nameservers = [dns_server]
dnsresolver = list(dnsresolver.resolve(domains[i], 'A'))
ips[i] = str(dnsresolver.pop())
except Exception as e:
ips[i] = ""
print()
openPortsShodan = ips.copy()
vulnsShodan = ips.copy()
ipinfo = ips.copy()
existingShodanRequest = {}
print("[~] Analyzing ports, CVEs and IP information")
openPortsShodan = [] # Initialize openPortsShodan outside the loop
vulnsShodan = [] # Initialize vulnsShodan outside the loop
for i in tqdm(range(len(ips))): # Use tqdm for the progress bar
if ips[i] in existingShodanRequest:
openPortsShodan.append(existingShodanRequest[ips[i]][0])
vulnsShodan.append(existingShodanRequest[ips[i]][1])
ipinfo[i] = existingShodanRequest[ips[i]][2]
else:
if ips[i] != "":
try:
# query InternetDB by shodan for CVE and port information
apirequest = requests.get("https://internetdb.shodan.io/{0}".format(ips[i])).json()
openPortsShodan.append(apirequest.get('ports', []))
vulnsShodan.append(apirequest.get('vulns', []))
except:
openPortsShodan.append([])
vulnsShodan.append([])
try:
# query ipinfo.com API for IP information
ipinforequest = requests.get("https://ipinfo.io/{0}?token={1}".format(ips[i],apitoken)).json()
ipinfo[i] = ipinforequest
except:
ipinfo[i] = ""
existingShodanRequest[ips[i]] = [openPortsShodan[-1], vulnsShodan[-1], ipinfo[i]]
else:
openPortsShodan.append([])
vulnsShodan.append([])
ipinfo[i] = ""
crtscan = {
"domains": domains,
"ips": ips,
"openPortsShodan": openPortsShodan,
"vulnsShodan": vulnsShodan,
"ipinfo" : ipinfo,
}
print()
print('ID;ROOT;DOMAIN;IP;PORTS;CVE;ASN;ORG;CITY;REGION;COUNTRY')
for i in range(len(crtscan['domains'])):
domain = crtscan['domains'][i]
ip = crtscan['ips'][i]
ports = crtscan['openPortsShodan'][i]
cves = crtscan['vulnsShodan'][i]
ipinfo = crtscan['ipinfo'][i]
failstr = "N/A"
if len(ports) == 0:
ports = failstr
else:
ports = str(ports)[1:-1].replace(' ','')
if len(ip) == 0:
ip = failstr
if len(ipinfo) == 0:
asn = failstr
organization = failstr
city = failstr
region = failstr
country = failstr
else:
try:
if ipinfo['org'].startswith('AS'):
asn = ipinfo['org'].split(" ", 1)[0]
organization = ipinfo['org'].split(" ", 1)[1]
else:
asn = "N/A"
organization = ipinfo['org']
city = ipinfo['city']
region = ipinfo['region']
country = ipinfo['country']
except:
asn = failstr
organization = failstr
city = failstr
region = failstr
country = failstr
if len(cves) == 0:
cves = failstr
else:
cves = str(cves)[1:-1].replace(' ','')
print(f'HOST-{i};{tldextract.extract(domain.strip()).registered_domain};{domain};{ip};{ports};{cves};{asn};{organization};{city};{region};{country}')
# Write the results to the specified CSV file
with open(output_filename, mode='w', newline='') as csv_file:
csv_writer = csv.writer(csv_file)
csv_writer.writerow(['ID', 'ROOT', 'DOMAIN', 'IP', 'PORTS', 'CVE', 'ASN', 'ORG', 'CITY', 'REGION', 'COUNTRY'])
for i in range(len(crtscan['domains'])):
domain = crtscan['domains'][i]
ip = crtscan['ips'][i]
ports = crtscan['openPortsShodan'][i]
cves = crtscan['vulnsShodan'][i]
ipinfo = crtscan['ipinfo'][i]
failstr = "N/A"
if len(ports) == 0:
ports = failstr
else:
ports = str(ports)[1:-1].replace(' ','')
if len(ip) == 0:
ip = failstr
if len(ipinfo) == 0:
asn = failstr
organization = failstr
city = failstr
region = failstr
country = failstr
else:
try:
if ipinfo['org'].startswith('AS'):
asn = ipinfo['org'].split(" ", 1)[0]
organization = ipinfo['org'].split(" ", 1)[1]
else:
asn = "N/A"
organization = ipinfo['org']
city = ipinfo['city']
region = ipinfo['region']
country = ipinfo['country']
except:
asn = failstr
organization = failstr
city = failstr
region = failstr
country = failstr
if len(cves) == 0:
cves = failstr
else:
cves = str(cves)[1:-1].replace(' ','')
csv_writer.writerow([f'HOST-{i}', tldextract.extract(domain.strip()).registered_domain, domain, ip, ports, cves, asn, organization, city, region, country])
if __name__ == '__main__':
prscan(hostfile)