-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- New "-sdo" functionality. This subdomain enumeration function uses multiple free online tools to scrape the subdomains of your target. This enumeration technique is very fast and should be used over the "-sd" argument. - Improved code logic - Improved exception handling.
- Loading branch information
Showing
8 changed files
with
274 additions
and
135 deletions.
There are no files selected for viewing
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,93 @@ | ||
import dns.resolver | ||
import dns.zone | ||
import dns.reversename | ||
|
||
class bcolors: | ||
HEADER = '\033[95m' | ||
OKBLUE = '\033[94m' | ||
OKCYAN = '\033[96m' | ||
OKGREEN = '\033[92m' | ||
WARNING = '\033[93m' | ||
FAIL = '\033[91m' | ||
ENDC = '\033[0m' | ||
BOLD = '\033[1m' | ||
UNDERLINE = '\033[4m' | ||
|
||
#----------------- Record Enumeration -----------------# | ||
|
||
class dnsEnumeration: | ||
|
||
def findAllDnsRecords(domain): | ||
dnsRecordTypes = ['A', 'AAAA', 'NS', 'CNAME', 'TXT', 'SOA', 'PTR', 'MX', 'SRV'] | ||
server = [] | ||
serverOutput = [] | ||
|
||
try: | ||
for dnsRecords in dnsRecordTypes: | ||
try: | ||
resolve = dns.resolver.resolve(domain, dnsRecords) | ||
for answers in resolve: | ||
server.append(f'{bcolors.OKGREEN}{bcolors.BOLD}{dnsRecords}: ' + answers.to_text() + bcolors.ENDC + '\n') | ||
serverOutput.append(f'{dnsRecords}: {answers.to_text()}\n') | ||
except dns.resolver.NoAnswer: | ||
server.append(f'{bcolors.FAIL}{bcolors.BOLD}{dnsRecords}: Record not existing{bcolors.ENDC}\n') | ||
except dns.resolver.NXDOMAIN: | ||
print(f'{bcolors.FAIL}{bcolors.BOLD}{domain} does not exist.{bcolors.ENDC}\n') | ||
except dns.resolver.NoResolverConfiguration: | ||
print(f'{bcolors.FAIL}{bcolors.BOLD}No NS found or no internet connection.{bcolors.ENDC}') | ||
|
||
print(bcolors.OKGREEN + bcolors.BOLD + ''.join(server) + bcolors.ENDC) | ||
|
||
return serverOutput | ||
|
||
|
||
def findSpecificRecord(domain, record): | ||
response = [] | ||
responseOutput = [] | ||
|
||
try: | ||
for recordType in record: | ||
try: | ||
resolve = dns.resolver.resolve(domain, recordType) | ||
for answers in resolve: | ||
response.append(f'{bcolors.OKGREEN}{bcolors.BOLD}{recordType} Record: {answers.to_text()}{bcolors.ENDC}\n') | ||
responseOutput.append(f'{recordType} Record: {answers.to_text()}\n') | ||
except dns.resolver.NoAnswer: | ||
response.append(f'{bcolors.FAIL}{bcolors.BOLD}{recordType} Record not existing.{bcolors.ENDC}\n') | ||
responseOutput.append(f'{recordType} Record not existing.\n') | ||
|
||
except dns.resolver.NXDOMAIN: | ||
print(f'{bcolors.FAIL}{bcolors.BOLD}{domain} does not existing.{bcolors.ENDC}') | ||
except dns.rdatatype.UnknownRdatatype: | ||
print(f'{bcolors.FAIL}{bcolors.BOLD}Error in your record statement.{bcolors.ENDC}') | ||
except dns.resolver.NoResolverConfiguration: | ||
print(f'{bcolors.FAIL}{bcolors.BOLD}No NS found or no internet connection.{bcolors.ENDC}') | ||
|
||
|
||
print(bcolors.OKGREEN + bcolors.BOLD + ''.join(response) + bcolors.ENDC) | ||
|
||
return responseOutput | ||
|
||
|
||
def reverseLookup(ipAddress): | ||
dnsNames = [] | ||
dnsNamesOutput = [] | ||
|
||
try: | ||
for ips in ipAddress: | ||
names = dns.reversename.from_address(ips) | ||
dnsNames.append(f'{bcolors.OKGREEN}{bcolors.BOLD}Reverse Lookup: {str(dns.resolver.resolve(names, "PTR")[0])}{bcolors.ENDC}\n') | ||
dnsNamesOutput.append(f'Reverse DNS Lookup: {str(dns.resolver.resolve(names, "PTR")[0])}\n') | ||
except dns.resolver.NXDOMAIN: | ||
print(f'{bcolors.FAIL}{bcolors.BOLD}{names} does not existing.{bcolors.ENDC}') | ||
dnsNamesOutput.append(f'{names} does not existing.\n') | ||
|
||
|
||
print(''.join(dnsNames)) | ||
|
||
return dnsNamesOutput | ||
|
||
#---------------------------------------------------------# | ||
|
||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,125 @@ | ||
from bs4 import BeautifulSoup | ||
import requests | ||
from random import randint | ||
import re | ||
import dns.resolver | ||
import dns.zone | ||
import dns.reversename | ||
import os | ||
import concurrent.futures | ||
|
||
|
||
class bcolors: | ||
HEADER = '\033[95m' | ||
OKBLUE = '\033[94m' | ||
OKCYAN = '\033[96m' | ||
OKGREEN = '\033[92m' | ||
WARNING = '\033[93m' | ||
FAIL = '\033[91m' | ||
ENDC = '\033[0m' | ||
BOLD = '\033[1m' | ||
UNDERLINE = '\033[4m' | ||
|
||
#----------------- "Online" Subdomain Enumeration -----------------# | ||
|
||
class onlineSubdomains: | ||
|
||
def suipEnumeration(domain): | ||
|
||
def randBoundary(): | ||
start = 10**(29-1) | ||
end = (10**29)-1 | ||
return str(randint(start, end)) | ||
|
||
hosts = [] | ||
|
||
url = 'https://suip.biz/?act=subfinder' | ||
boundary = randBoundary() | ||
headers = { | ||
|
||
'Host': 'suip.biz', | ||
'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/115.0', | ||
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8', | ||
'Accept-Language': 'en-US,en;q=0.5', | ||
'Accept-Encoding': 'gzip, deflate, br', | ||
'Content-Type': f'multipart/form-data; boundary=---------------------------{boundary}', | ||
'Content-Length': '237' | ||
|
||
} | ||
|
||
body = f'-----------------------------{boundary}\n' + 'Content-Disposition: form-data; name="url"\n\n' + f'{domain}\n' + f'-----------------------------{boundary}\n' + 'Content-Disposition: form-data; name="Submit1"\n\n' + 'Submit' | ||
|
||
soup = BeautifulSoup(requests.post(url, headers=headers, data=body).content, 'html.parser') | ||
for content in soup.find('pre'): | ||
hosts.append(content) | ||
|
||
return hosts | ||
|
||
|
||
def crtSh(domain): | ||
|
||
hosts = [] | ||
|
||
url = f'https://crt.sh/?q={domain}' | ||
soup = BeautifulSoup(requests.get(url).content, 'html.parser') | ||
matches = soup.find_all(string=re.compile(f'{domain}')) | ||
|
||
for match in matches: | ||
hosts.append(match) | ||
|
||
return hosts | ||
|
||
def main(domain): | ||
|
||
duplicates = [] | ||
|
||
subdomains = onlineSubdomains.suipEnumeration(f'{domain}') + onlineSubdomains.crtSh(f'{domain}') | ||
for subds in subdomains: | ||
if subds not in duplicates: | ||
duplicates.append(subds) | ||
print(bcolors.OKGREEN + bcolors.BOLD + subds + bcolors.ENDC) | ||
return subds | ||
|
||
#---------------------------------------------------------# | ||
|
||
#----------------- Brute Force Subdomain Enumeration -----------------# | ||
|
||
class bruteForceSubdomains: | ||
|
||
def subdomainEnumeration(targetDomain): | ||
print(f'\n{bcolors.WARNING}[+] Subdomain brute force started...{bcolors.ENDC}') | ||
list = [] | ||
newList = [] | ||
|
||
with open(f'{os.getcwd()}/../lists/subdomains.txt', 'r') as file: | ||
name = file.read() | ||
subDomains = name.splitlines() | ||
|
||
def enumeration(subdomains): | ||
try: | ||
ipValue = dns.resolver.resolve(f'{subdomains.lower()}.{targetDomain}', 'A') | ||
if ipValue: | ||
list.append(f'{subdomains.lower()}.{targetDomain}') | ||
for x in list: | ||
if x not in newList: #We check for duplicates | ||
newList.append(x) | ||
print(f'{bcolors.OKGREEN}{bcolors.BOLD}{subdomains.lower()}.{targetDomain}{bcolors.ENDC}') | ||
|
||
else: | ||
pass | ||
except (dns.resolver.NXDOMAIN, dns.resolver.NoAnswer, dns.resolver.NoNameservers, dns.name.EmptyLabel): | ||
pass | ||
except KeyboardInterrupt: | ||
print(f'{bcolors.FAIL}{bcolors.BOLD}\nEnumeration canceled.{bcolors.ENDC}') | ||
executor.shutdown() | ||
|
||
with concurrent.futures.ThreadPoolExecutor() as executor: | ||
try: | ||
executor.map(enumeration, subDomains) | ||
except KeyboardInterrupt: | ||
executor.shutdown() | ||
|
||
return newList | ||
|
||
#---------------------------------------------------------# | ||
|
Oops, something went wrong.