Merge branch 'aboul3la:master' into master

This commit is contained in:
҉αkα x⠠⠵ 2023-07-26 17:59:25 -05:00 committed by GitHub
commit 04ec27937b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 1046 additions and 2053 deletions

View File

@ -1,6 +1,6 @@
## About Sublist3r ## About Sublist3r
Sublist3r is a python tool designed to enumerate subdomains of websites using OSINT. It helps penetration testers and bug hunters collect and gather subdomains for the domain they are targeting. Sublist3r enumerates subdomains using many search engines such as Google, Yahoo, Bing, Baidu, and Ask. Sublist3r also enumerates subdomains using Netcraft, Virustotal, ThreatCrowd, DNSdumpster, and ReverseDNS. Sublist3r is a python tool designed to enumerate subdomains of websites using OSINT. It helps penetration testers and bug hunters collect and gather subdomains for the domain they are targeting. Sublist3r enumerates subdomains using many search engines such as Google, Yahoo, Bing, Baidu and Ask. Sublist3r also enumerates subdomains using Netcraft, Virustotal, ThreatCrowd, DNSdumpster and ReverseDNS.
[subbrute](https://github.com/TheRook/subbrute) was integrated with Sublist3r to increase the possibility of finding more subdomains using bruteforce with an improved wordlist. The credit goes to TheRook who is the author of subbrute. [subbrute](https://github.com/TheRook/subbrute) was integrated with Sublist3r to increase the possibility of finding more subdomains using bruteforce with an improved wordlist. The credit goes to TheRook who is the author of subbrute.
@ -26,11 +26,11 @@ sublist3r -b -d yourdomain.com -t 37 -v -o /root/sublist3r_yourdomain_com
Sublist3r currently supports **Python 2** and **Python 3**. Sublist3r currently supports **Python 2** and **Python 3**.
* The recommended version for Python 2 is **2.7.x** * The recommended version for Python 2 is **2.7.x**
* The recommened version for Python 3 is **3.4.x** * The recommended version for Python 3 is **3.4.x**
## Dependencies: ## Dependencies:
Sublist3r depends on the `requests`, `dnspython`, and `argparse` python modules. Sublist3r depends on the `requests`, `dnspython` and `argparse` python modules.
These dependencies can be installed using the requirements file: These dependencies can be installed using the requirements file:

File diff suppressed because it is too large Load Diff

View File

@ -66,6 +66,10 @@ else:
R = '\033[91m' # red R = '\033[91m' # red
W = '\033[0m' # white W = '\033[0m' # white
def no_color():
global G, Y, B, R, W
G = Y = B = R = W = ''
def banner(): def banner():
print("""%s print("""%s
@ -98,6 +102,7 @@ def parse_args():
parser.add_argument('-t', '--threads', help='Number of threads to use for subbrute bruteforce', type=int, default=30) parser.add_argument('-t', '--threads', help='Number of threads to use for subbrute bruteforce', type=int, default=30)
parser.add_argument('-e', '--engines', help='Specify a comma-separated list of search engines') parser.add_argument('-e', '--engines', help='Specify a comma-separated list of search engines')
parser.add_argument('-o', '--output', help='Save the results to text file') parser.add_argument('-o', '--output', help='Save the results to text file')
parser.add_argument('-n', '--no-color', help='Output without color', default=False, action='store_true')
return parser.parse_args() return parser.parse_args()
@ -252,11 +257,10 @@ class enumratorBase(object):
class enumratorBaseThreaded(multiprocessing.Process, enumratorBase): class enumratorBaseThreaded(multiprocessing.Process, enumratorBase):
def __init__(self, base_url, engine_name, domain, subdomains=None, q=None, lock=threading.Lock(), silent=False, verbose=True): def __init__(self, base_url, engine_name, domain, subdomains=None, q=None, silent=False, verbose=True):
subdomains = subdomains or [] subdomains = subdomains or []
enumratorBase.__init__(self, base_url, engine_name, domain, subdomains, silent=silent, verbose=verbose) enumratorBase.__init__(self, base_url, engine_name, domain, subdomains, silent=silent, verbose=verbose)
multiprocessing.Process.__init__(self) multiprocessing.Process.__init__(self)
self.lock = lock
self.q = q self.q = q
return return
@ -520,7 +524,6 @@ class NetcraftEnum(enumratorBaseThreaded):
subdomains = subdomains or [] subdomains = subdomains or []
self.base_url = 'https://searchdns.netcraft.com/?restriction=site+ends+with&host={domain}' self.base_url = 'https://searchdns.netcraft.com/?restriction=site+ends+with&host={domain}'
self.engine_name = "Netcraft" self.engine_name = "Netcraft"
self.lock = threading.Lock()
super(NetcraftEnum, self).__init__(self.base_url, self.engine_name, domain, subdomains, q=q, silent=silent, verbose=verbose) super(NetcraftEnum, self).__init__(self.base_url, self.engine_name, domain, subdomains, q=q, silent=silent, verbose=verbose)
self.q = q self.q = q
return return
@ -534,11 +537,14 @@ class NetcraftEnum(enumratorBaseThreaded):
resp = None resp = None
return resp return resp
def should_sleep(self):
time.sleep(random.randint(1, 2))
return
def get_next(self, resp): def get_next(self, resp):
link_regx = re.compile('<A href="(.*?)"><b>Next page</b></a>') link_regx = re.compile('<a.*?href="(.*?)">Next Page')
link = link_regx.findall(resp) link = link_regx.findall(resp)
link = re.sub('host=.*?%s' % self.domain, 'host=%s' % self.domain, link[0]) url = 'http://searchdns.netcraft.com' + link[0]
url = 'http://searchdns.netcraft.com' + link
return url return url
def create_cookies(self, cookie): def create_cookies(self, cookie):
@ -564,14 +570,15 @@ class NetcraftEnum(enumratorBaseThreaded):
while True: while True:
resp = self.get_response(self.req(url, cookies)) resp = self.get_response(self.req(url, cookies))
self.extract_domains(resp) self.extract_domains(resp)
if 'Next page' not in resp: if 'Next Page' not in resp:
return self.subdomains return self.subdomains
break break
url = self.get_next(resp) url = self.get_next(resp)
self.should_sleep()
def extract_domains(self, resp): def extract_domains(self, resp):
links_list = list() links_list = list()
link_regx = re.compile('<a href="http://toolbar.netcraft.com/site_report\?url=(.*)">') link_regx = re.compile('<a class="results-table__host" href="(.*?)"')
try: try:
links_list = link_regx.findall(resp) links_list = link_regx.findall(resp)
for link in links_list: for link in links_list:
@ -593,9 +600,8 @@ class DNSdumpster(enumratorBaseThreaded):
base_url = 'https://dnsdumpster.com/' base_url = 'https://dnsdumpster.com/'
self.live_subdomains = [] self.live_subdomains = []
self.engine_name = "DNSdumpster" self.engine_name = "DNSdumpster"
self.threads = 70
self.lock = threading.BoundedSemaphore(value=self.threads)
self.q = q self.q = q
self.lock = None
super(DNSdumpster, self).__init__(base_url, self.engine_name, domain, subdomains, q=q, silent=silent, verbose=verbose) super(DNSdumpster, self).__init__(base_url, self.engine_name, domain, subdomains, q=q, silent=silent, verbose=verbose)
return return
@ -631,11 +637,12 @@ class DNSdumpster(enumratorBaseThreaded):
return self.get_response(resp) return self.get_response(resp)
def get_csrftoken(self, resp): def get_csrftoken(self, resp):
csrf_regex = re.compile("<input type='hidden' name='csrfmiddlewaretoken' value='(.*?)' />", re.S) csrf_regex = re.compile('<input type="hidden" name="csrfmiddlewaretoken" value="(.*?)">', re.S)
token = csrf_regex.findall(resp)[0] token = csrf_regex.findall(resp)[0]
return token.strip() return token.strip()
def enumerate(self): def enumerate(self):
self.lock = threading.BoundedSemaphore(value=70)
resp = self.req('GET', self.base_url) resp = self.req('GET', self.base_url)
token = self.get_csrftoken(resp) token = self.get_csrftoken(resp)
params = {'csrfmiddlewaretoken': token, 'targetip': self.domain} params = {'csrfmiddlewaretoken': token, 'targetip': self.domain}
@ -669,11 +676,11 @@ class DNSdumpster(enumratorBaseThreaded):
class Virustotal(enumratorBaseThreaded): class Virustotal(enumratorBaseThreaded):
def __init__(self, domain, subdomains=None, q=None, silent=False, verbose=True): def __init__(self, domain, subdomains=None, q=None, silent=False, verbose=True):
subdomains = subdomains or [] subdomains = subdomains or []
base_url = 'https://www.virustotal.com/en/domain/{domain}/information/' base_url = 'https://www.virustotal.com/ui/domains/{domain}/subdomains'
self.engine_name = "Virustotal" self.engine_name = "Virustotal"
self.lock = threading.Lock()
self.q = q self.q = q
super(Virustotal, self).__init__(base_url, self.engine_name, domain, subdomains, q=q, silent=silent, verbose=verbose) super(Virustotal, self).__init__(base_url, self.engine_name, domain, subdomains, q=q, silent=silent, verbose=verbose)
self.url = self.base_url.format(domain=self.domain)
return return
# the main send_req need to be rewritten # the main send_req need to be rewritten
@ -688,17 +695,25 @@ class Virustotal(enumratorBaseThreaded):
# once the send_req is rewritten we don't need to call this function, the stock one should be ok # once the send_req is rewritten we don't need to call this function, the stock one should be ok
def enumerate(self): def enumerate(self):
url = self.base_url.format(domain=self.domain) while self.url != '':
resp = self.send_req(url) resp = self.send_req(self.url)
resp = json.loads(resp)
if 'error' in resp:
self.print_(R + "[!] Error: Virustotal probably now is blocking our requests" + W)
break
if 'links' in resp and 'next' in resp['links']:
self.url = resp['links']['next']
else:
self.url = ''
self.extract_domains(resp) self.extract_domains(resp)
return self.subdomains return self.subdomains
def extract_domains(self, resp): def extract_domains(self, resp):
link_regx = re.compile('<div class="enum.*?">.*?<a target="_blank" href=".*?">(.*?)</a>', re.S) #resp is already parsed as json
try: try:
links = link_regx.findall(resp) for i in resp['data']:
for link in links: if i['type'] == 'domain':
subdomain = link.strip() subdomain = i['id']
if not subdomain.endswith(self.domain): if not subdomain.endswith(self.domain):
continue continue
if subdomain not in self.subdomains and subdomain != self.domain: if subdomain not in self.subdomains and subdomain != self.domain:
@ -714,7 +729,6 @@ class ThreatCrowd(enumratorBaseThreaded):
subdomains = subdomains or [] subdomains = subdomains or []
base_url = 'https://www.threatcrowd.org/searchApi/v2/domain/report/?domain={domain}' base_url = 'https://www.threatcrowd.org/searchApi/v2/domain/report/?domain={domain}'
self.engine_name = "ThreatCrowd" self.engine_name = "ThreatCrowd"
self.lock = threading.Lock()
self.q = q self.q = q
super(ThreatCrowd, self).__init__(base_url, self.engine_name, domain, subdomains, q=q, silent=silent, verbose=verbose) super(ThreatCrowd, self).__init__(base_url, self.engine_name, domain, subdomains, q=q, silent=silent, verbose=verbose)
return return
@ -753,7 +767,6 @@ class CrtSearch(enumratorBaseThreaded):
subdomains = subdomains or [] subdomains = subdomains or []
base_url = 'https://crt.sh/?q=%25.{domain}' base_url = 'https://crt.sh/?q=%25.{domain}'
self.engine_name = "SSL Certificates" self.engine_name = "SSL Certificates"
self.lock = threading.Lock()
self.q = q self.q = q
super(CrtSearch, self).__init__(base_url, self.engine_name, domain, subdomains, q=q, silent=silent, verbose=verbose) super(CrtSearch, self).__init__(base_url, self.engine_name, domain, subdomains, q=q, silent=silent, verbose=verbose)
return return
@ -778,7 +791,14 @@ class CrtSearch(enumratorBaseThreaded):
try: try:
links = link_regx.findall(resp) links = link_regx.findall(resp)
for link in links: for link in links:
subdomain = link.strip() link = link.strip()
subdomains = []
if '<BR>' in link:
subdomains = link.split('<BR>')
else:
subdomains.append(link)
for subdomain in subdomains:
if not subdomain.endswith(self.domain) or '*' in subdomain: if not subdomain.endswith(self.domain) or '*' in subdomain:
continue continue
@ -790,15 +810,14 @@ class CrtSearch(enumratorBaseThreaded):
self.print_("%s%s: %s%s" % (R, self.engine_name, W, subdomain)) self.print_("%s%s: %s%s" % (R, self.engine_name, W, subdomain))
self.subdomains.append(subdomain.strip()) self.subdomains.append(subdomain.strip())
except Exception as e: except Exception as e:
print(e)
pass pass
class PassiveDNS(enumratorBaseThreaded): class PassiveDNS(enumratorBaseThreaded):
def __init__(self, domain, subdomains=None, q=None, silent=False, verbose=True): def __init__(self, domain, subdomains=None, q=None, silent=False, verbose=True):
subdomains = subdomains or [] subdomains = subdomains or []
base_url = 'https://api.sublist3r.com/search.php?domain={domain}' base_url = 'https://api.sublist3r.com/search.php?domain={domain}'
self.engine_name = "PassiveDNS" self.engine_name = "PassiveDNS"
self.lock = threading.Lock()
self.q = q self.q = q
super(PassiveDNS, self).__init__(base_url, self.engine_name, domain, subdomains, q=q, silent=silent, verbose=verbose) super(PassiveDNS, self).__init__(base_url, self.engine_name, domain, subdomains, q=q, silent=silent, verbose=verbose)
return return
@ -836,8 +855,7 @@ class portscan():
def __init__(self, subdomains, ports): def __init__(self, subdomains, ports):
self.subdomains = subdomains self.subdomains = subdomains
self.ports = ports self.ports = ports
self.threads = 20 self.lock = None
self.lock = threading.BoundedSemaphore(value=self.threads)
def port_scan(self, host, ports): def port_scan(self, host, ports):
openports = [] openports = []
@ -857,6 +875,7 @@ class portscan():
print("%s%s%s - %sFound open ports:%s %s%s%s" % (G, host, W, R, W, Y, ', '.join(openports), W)) print("%s%s%s - %sFound open ports:%s %s%s%s" % (G, host, W, R, W, Y, ', '.join(openports), W))
def run(self): def run(self):
self.lock = threading.BoundedSemaphore(value=20)
for subdomain in self.subdomains: for subdomain in self.subdomains:
t = threading.Thread(target=self.port_scan, args=(subdomain, self.ports)) t = threading.Thread(target=self.port_scan, args=(subdomain, self.ports))
t.start() t.start()
@ -978,6 +997,8 @@ def interactive():
engines = args.engines engines = args.engines
if verbose or verbose is None: if verbose or verbose is None:
verbose = True verbose = True
if args.no_color:
no_color()
banner() banner()
res = main(domain, threads, savefile, ports, silent=False, verbose=verbose, enable_bruteforce=enable_bruteforce, engines=engines) res = main(domain, threads, savefile, ports, silent=False, verbose=verbose, enable_bruteforce=enable_bruteforce, engines=engines)