-
Notifications
You must be signed in to change notification settings - Fork 31
/
Recon.py
executable file
·266 lines (244 loc) · 15.8 KB
/
Recon.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
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
from SubDomainCollector import *
import os
import sys
import argparse
from FindJenkins import *
class Recon(object):
"""docstring for Recon"""
def __init__(self):
super(Recon, self).__init__()
def createVariables(self, domain):
self.globalVariables=GlobalVariables()
self.outSubDomainPath="{}{}/{}".format(self.globalVariables.outputDir, domain, "all_output.txt")
self.outSubDomainFilePath="{}{}/{}".format(self.globalVariables.outputDir, domain, "all_domains.txt")
self.outResolveDomain="{}{}/{}".format(self.globalVariables.outputDir, domain, "resolve.txt")
self.outResolveUniqDomain="{}{}/{}".format(self.globalVariables.outputDir, domain, "resolve_uniq.txt")
self.outUpHosts="{}{}/{}".format(self.globalVariables.outputDir, domain, "uphosts.txt")
self.outUniqUpHostsAll="{}{}/{}".format(self.globalVariables.outputDir, domain, "uphosts_uniq_all.txt")
self.outUniqUpHosts="{}{}/{}".format(self.globalVariables.outputDir, domain, "uphosts_uniq.txt")
self.outUniqUpHostsIP="{}{}/{}".format(self.globalVariables.outputDir, domain, "uphosts_ip.txt")
self.outUniqUpHostsUniqIP="{}{}/{}".format(self.globalVariables.outputDir, domain, "uphosts_ip_uniq.txt")
self.outHostToIPMapping="{}{}/{}".format(self.globalVariables.outputDir, domain, "host_to_ip_mapping.txt")
self.outCURLRequestOutput="{}{}/{}".format(self.globalVariables.outputDir, domain, "check_for_internalIP.txt")
self.outCRLFInjectionOutput="{}{}/{}".format(self.globalVariables.outputDir, domain, "check_for_CRLFInjection.txt")
self.outOpenRedirectionOutput="{}{}/{}".format(self.globalVariables.outputDir, domain, "check_for_OpenRedirection.txt")
self.outToolAndTechOutput="{}{}/{}".format(self.globalVariables.outputDir, domain, "tools_and_tech.txt")
self.outWelknownDirGoBuster="{}{}/{}".format(self.globalVariables.outputDir, domain, "WellKnownDir_Gobuster.txt")
self.outSSLScanResult="{}{}/{}".format(self.globalVariables.outputDir, domain, "sslscan_results.xml")
self.s3scannerOutput="{}{}/{}".format(self.globalVariables.outputDir, domain, "s3scanner.txt")
self.massDNSOutput="{}{}/{}".format(self.globalVariables.outputDir, domain, "massDNS.txt")
self.outCNAMEs="{}{}/{}".format(self.globalVariables.outputDir, domain, "cnames.txt")
self.webScreenShotReportDir="{}{}/{}".format(self.globalVariables.outputDir, domain, "WebScreenShot")
self.massScanOutputDir="{}{}/{}".format(self.globalVariables.outputDir, domain, "MassScan")
def WebScreenshotOnUpHost(self):
print ("WebScreenShot process running..")
self.globalVariables.CommandExecutor("webscreenshot -i {} -o {}".format(self.outUniqUpHosts, self.webScreenShotReportDir))
def SSLScanOnUpHost(self):
print ("SSLScan process running.." )
self.globalVariables.CommandExecutor("sslscan --targets={} --ssl2 --ssl3 --xml={}".format(self.outUniqUpHosts, self.outSSLScanResult))
def S3ScannerUpHosts(self):
print ("S3Scanner process running..")
self.globalVariables.CommandExecutor("python {} {} --out-file {}".format(self.globalVariables.S3ScannerPath, self.outUniqUpHosts, self.s3scannerOutput))
def WellKnownFilesDirGoBuster(self):
print ("GoBuster process running..")
upHostFile = open(self.outUniqUpHosts, "r")
for host in upHostFile:
try:
output=self.globalVariables.CommandExecutor("gobuster dir -u https://{} -w {} -s \"200,204,301,302,307\" -k".format(host.strip(), self.globalVariables.goBusterCommonWordlist))
self.globalVariables.WriteTextToFile(self.outWelknownDirGoBuster, output)
except:
print ("Gobuster error")
def ToolAndTechOutput(self):
print ("Webtech process running..")
output=''
tmpFileName='temp.txt'
if os.path.exists(tmpFileName):
os.remove(tmpFileName)
tempFile = open(self.outUniqUpHosts)
line = tempFile.readline()
while line:
output+='https://'+line
line = tempFile.readline()
tempFile.close()
self.globalVariables.WriteTextToFile(tmpFileName, output)
self.globalVariables.CommandExecutor("webtech --ul={} | tee {}".format(tmpFileName, self.outToolAndTechOutput))
os.remove(tmpFileName)
def MassScanOnUpHost(self, specificPort="", topPort=True):
print ("MassScan process running..")
upHostFile = open(self.outUniqUpHosts, "r")
for host in upHostFile:
try:
output="\n"+host
textToWrite=self.globalVariables.CommandExecutor("dig +short {} | grep -oE '\\b([0-9]{{1,3}}\\.){{3}}[0-9]{{1,3}}\\b'".format(host.strip()))
output+=textToWrite
self.globalVariables.WriteTextToFile(self.outHostToIPMapping, output)
self.globalVariables.WriteTextToFile(self.outUniqUpHostsIP, textToWrite)
self.globalVariables.CommandExecutor("sed -i '/^$/d' {} | sort {} | uniq > {}".format(self.outUniqUpHostsIP, self.outUniqUpHostsIP, self.outUniqUpHostsUniqIP))
except:
"MassScan Error"
if not specificPort:
if topPort:
self.globalVariables.CommandExecutor("sudo masscan -p{} -iL {} --max-rate 10000 -oG {}".format(self.globalVariables.topNMapPort, self.outUniqUpHostsUniqIP, self.massScanOutputDir))
else:
self.globalVariables.CommandExecutor("sudo masscan -p1-65535 -iL {} --max-rate 10000 -oG {}".format(self.outUniqUpHostsUniqIP, self.massScanOutputDir))
else:
self.globalVariables.CommandExecutor("sudo masscan -p{} -iL {} --max-rate 10000 -oG {}".format(specificPort, self.outUniqUpHostsUniqIP, self.massScanOutputDir))
def CheckForOpenRedirection(self):
print ("Open redirection script running..")
upHostFile = open(self.outUniqUpHosts, "r")
for host in upHostFile:
output="\n\nHTTP Request\n"+host
status, rawOutput = self.globalVariables.CommandExecutor("curl -v --connect-timeout 5 --expect100-timeout 5 https://{}//attacker.com".format(host.strip()))
output+=rawOutput
status, rawOutput = self.globalVariables.CommandExecutor("curl -v --connect-timeout 5 --expect100-timeout 5 http://{}//attacker.com".format(host.strip()))
output+=rawOutput
self.globalVariables.WriteTextToFile(self.outOpenRedirectionOutput, output)
#cat check_for_OpenRedirection.txt | grep Location:
def CheckForInternalIPDisclosure(self):
print ("Check for internal IP script running..")
upHostFile = open(self.outUniqUpHosts, "r")
for host in upHostFile:
output="\n\nHTTP Request\n"+host
status, rawOutput = self.globalVariables.CommandExecutor("curl -v -H \"Host:\" --http1.0 --connect-timeout 5 --expect100-timeout 5 http://{}".format(host.strip()))
output+=rawOutput
self.globalVariables.WriteTextToFile(self.outCURLRequestOutput, output)
def CheckForCRLFInjection(self):
print ("CRLF Injection script running..")
upHostFile = open(self.outUniqUpHosts, "r")
for host in upHostFile:
output="\n\nHTTP Request\n"+host
status, rawOutput = self.globalVariables.CommandExecutor("curl -v --connect-timeout 5 --expect100-timeout 5 http://{}/%0d%0a%09CRLFInjection:%20CRLFInjection".format(host.strip()))
output+=rawOutput
self.globalVariables.WriteTextToFile(self.outCRLFInjectionOutput, output)
#cat check_for_CRLFInjection.txt | grep " CRLFInjection"
def FindJenkinsIntance(self, domain):
findJenkins=FindJenkins()
findJenkins.EnumerateIPToFindJenkins(domain)
def create_cli_parser(self):
self.parser = argparse.ArgumentParser(add_help=False, description="Domain recon is a tool to gather information about target")
self.parser.add_argument('-h', '-?', '--h', '-help', '--help', action="store_true", help=argparse.SUPPRESS)
input_options = self.parser.add_argument_group('Usage')
input_options.add_argument('--domain', metavar='DomainName', default="", help='Website domain name')
input_options.add_argument('--organization', metavar='OrganizationName', default="", help='Website organization name')
input_options.add_argument('--bgpipspace', default=False, action='store_true', help='collect organization ip ranges from bgp.he.net')
input_options.add_argument('--bgpamass', default=False, action='store_true', help='collect domains from bgp.he.net + amass')
input_options.add_argument('--censys', default=False, action='store_true', help='collect domains from censys')
input_options.add_argument('--assetfinder', default=False, action='store_true', help='collect domains from assetfinder')
input_options.add_argument('--gitlab', default=False, action='store_true', help='collect domains from gitlabs')
input_options.add_argument('--github', default=False, action='store_true', help='collect domains from github')
input_options.add_argument('--finddomain', default=False, action='store_true', help='collect domains from FindDomain')
#input_options.add_argument('--certdomain', default=False, action='store_true', help='collect domain using cert domain finder')
input_options.add_argument('--amassactive', default=False, action='store_true', help='collect domain using amass active scan')
input_options.add_argument('--amasspassive', default=False, action='store_true', help='collect domain using amass passive scan')
input_options.add_argument('--subfinder', default=False, action='store_true', help='collect domain using subfinder')
input_options.add_argument('--ctfr', default=False, action='store_true', help='collect domain using CTFR')
input_options.add_argument('--ctexposer', default=False, action='store_true', help='collect domain using CTFRExposer')
input_options.add_argument('--certgraph', default=False, action='store_true', help='collect domain using certgraph')
input_options.add_argument('--certspotter', default=False, action='store_true', help='collect domain using certspotter')
input_options.add_argument('--fdnsr7', default=False, action='store_true', help='collect domain using fdns rapid7 project sonar opendata')
input_options.add_argument('--commonspeak', default=False, action='store_true', help='collect domain using commonspeak wordlist')
input_options.add_argument('--cnames', default=False, action='store_true', help='Collect CNAMEs of all the collected domains')
input_options.add_argument('--s3scanner', default=False, action='store_true', help='Run s3scanner on all the collected domains')
input_options.add_argument('--webscreenshot', default=False, action='store_true', help='Capture screenshot of all the collected domains')
input_options.add_argument('--sslscan', default=False, action='store_true', help='Run sslscan on all collected domains')
input_options.add_argument('--webtech', default=False, action='store_true', help='Run webtech on all collected domains')
input_options.add_argument('--internalip', default=False, action='store_true', help='Run internal ip script on all collected domains')
input_options.add_argument('--crlfinjection', default=False, action='store_true', help='Run crlf injection script on all collected domains')
input_options.add_argument('--gobuster', default=False, action='store_true', help='Run gobuster module for common files and directory')
input_options.add_argument('--openredirection', default=False, action='store_true', help='Run open redirection on all collected domains')
input_options.add_argument('--masscan', default=False, action='store_true', help='Run masscan on all collected domains')
input_options.add_argument('--jenkins', default=False, action='store_true', help='Run jenkins on all collected IP ranges collected using bgp.he.net')
args = self.parser.parse_args()
return args
def GeDomainRecon(self, domain, organization, bgpipspace, bgpamass, censys, assetfinder, github, gitlab, finddomain, certdomain, amassactive, amasspassive, subfinder, ctfr, ctexposer, certgraph, certspotter, fdnsr7, commonspeak, cnames, s3scanner, webscreenshot, sslscan, webtech, internalip, crlfinjection, gobuster, openredirection, masscan, jenkins):
self.createVariables(domain)
self.subDomainCollector=SubDomainCollector()
outputDir="{}{}".format(self.globalVariables.outputDir, domain)
print (outputDir)
if not os.path.exists(outputDir):
os.makedirs(outputDir)
self.subDomainCollector.GetAllDomains(domain, organization, bgpipspace, bgpamass, censys, assetfinder, github, gitlab, finddomain, certdomain, amassactive, amasspassive, subfinder, ctfr, ctexposer, certgraph, certspotter, fdnsr7, commonspeak, self.outSubDomainPath)
self.subDomainCollector.ExtractDomainOnly(self.outSubDomainPath, self.outSubDomainFilePath)
self.subDomainCollector.checkForResolvedDomain(self.outSubDomainFilePath, self.outResolveDomain, self.outResolveUniqDomain)
self.subDomainCollector.checkForUpHostUsingHttpProbe(self.outSubDomainFilePath, self.outUpHosts)
self.globalVariables.CommandExecutor("sed -i '/^$/d' {} | sort {} | uniq > {}".format(self.outUpHosts, self.outUpHosts, self.outUniqUpHostsAll))
self.globalVariables.CommandExecutor("cat {} | grep {} > {}".format(self.outUniqUpHostsAll, domain, self.outUniqUpHosts))
#Can be call in individual thread as they can be run as parallel
#cat cnames.txt | grep -P '(?<!tomtom\.com\.)$'
if cnames:
self.subDomainCollector.checkForCNAMEUsingMassDNS(self.outUniqUpHosts, self.massDNSOutput, self.outCNAMEs)
if s3scanner:
self.S3ScannerUpHosts()
if webscreenshot:
self.WebScreenshotOnUpHost()
if sslscan:
self.SSLScanOnUpHost()
if webtech:
self.ToolAndTechOutput()
if internalip:
self.CheckForInternalIPDisclosure()
if crlfinjection:
self.CheckForCRLFInjection()
if gobuster:
self.WellKnownFilesDirGoBuster()
if openredirection:
self.CheckForOpenRedirection()
if masscan:
self.MassScanOnUpHost()
if jenkins:
self.FindJenkinsIntance(domain)
def print_banner():
banner= (" ____ _ ____ \n"+
"| _ \\ ___ _ __ ___ __ _(_)_ __ | _ \\ ___ ___ ___ _ __ \n"+
"| | | |/ _ \\| '_ ` _ \\ / _` | | '_ \\ | |_) / _ \\/ __/ _ \\| '_ \\ \n"+
"| |_| | (_) | | | | | | (_| | | | | | | _ < __/ (_| (_) | | | |\n"+
"|____/ \\___/|_| |_| |_|\\__,_|_|_| |_| |_| \\_\\___|\\___\\___/|_| |_|\n")
print (banner)
if __name__ == "__main__":
'''file = open('domains.txt', "r")
lines = file.readlines()
for line in lines:
data=(line.strip()).split(",")
recon=Recon(data[1])
recon.GeDomainRecon(data[0], data[1])
file.close() '''
print_banner()
recon=Recon()
cli_parsed = recon.create_cli_parser()
if cli_parsed.h:
recon.parser.print_help()
sys.exit()
if cli_parsed.domain == "" and cli_parsed.organization == "" or (cli_parsed.bgpipspace is False and cli_parsed.bgpamass is False and cli_parsed.censys is False and cli_parsed.assetfinder is False and cli_parsed.github is False and cli_parsed.gitlab is False and cli_parsed.finddomain is False and cli_parsed.amassactive is False and cli_parsed.amasspassive is False and cli_parsed.subfinder is False and cli_parsed.ctfr is False and cli_parsed.ctexposer is False and cli_parsed.certgraph is False and cli_parsed.certspotter is False and cli_parsed.fdnsr7 is False and cli_parsed.commonspeak is False and cli_parsed.cnames is False and cli_parsed.s3scanner is False and cli_parsed.webscreenshot is False and cli_parsed.sslscan is False and cli_parsed.webtech is False and cli_parsed.internalip is False and cli_parsed.crlfinjection is False and cli_parsed.gobuster is False and cli_parsed.openredirection is False and cli_parsed.masscan is False and cli_parsed.jenkins is False):
recon.parser.print_help()
sys.exit()
else:
recon.GeDomainRecon(cli_parsed.domain,
cli_parsed.organization,
cli_parsed.bgpipspace,
cli_parsed.bgpamass,
cli_parsed.censys,
cli_parsed.assetfinder,
cli_parsed.github,
cli_parsed.gitlab,
cli_parsed.finddomain,
False,#cli_parsed.certdomain,
cli_parsed.amassactive,
cli_parsed.amasspassive,
cli_parsed.subfinder,
cli_parsed.ctfr,
cli_parsed.ctexposer,
cli_parsed.certgraph,
cli_parsed.certspotter,
cli_parsed.fdnsr7,
cli_parsed.commonspeak,
cli_parsed.cnames,
cli_parsed.s3scanner,
cli_parsed.webscreenshot,
cli_parsed.sslscan,
cli_parsed.webtech,
cli_parsed.internalip,
cli_parsed.crlfinjection,
cli_parsed.gobuster,
cli_parsed.openredirection,
cli_parsed.masscan,
cli_parsed.jenkins)