11import re
22import random
33import string
4- import dns .resolver
5- import dns .exception
4+ import socket
65from concurrent .futures import ThreadPoolExecutor , as_completed
76
87
@@ -39,15 +38,25 @@ def filter_valid_subdomains(subdomains, domain):
3938
4039
4140class WildcardDetector :
42- def __init__ (self , dns_resolver ):
43- self .dns_resolver = dns_resolver
41+ def __init__ (self , timeout = 3 ):
4442 self .wildcard_ips = set ()
4543 self .wildcard_detected = False
44+ self .timeout = timeout
4645
4746 def _generate_random_subdomain (self , length = 10 ):
4847 random_string = '' .join (random .choices (string .ascii_lowercase + string .digits , k = length ))
4948 return f"{ random_string } -nonexistent-{ random .randint (10000 , 99999 )} "
5049
50+ def _resolve_domain (self , domain ):
51+ try :
52+ socket .setdefaulttimeout (self .timeout )
53+ ip = socket .gethostbyname (domain )
54+ return True , ip
55+ except (socket .gaierror , socket .timeout ):
56+ return False , None
57+ except Exception :
58+ return False , None
59+
5160 def detect_wildcards (self , domain , test_count = 5 ):
5261 self .wildcard_ips .clear ()
5362 self .wildcard_detected = False
@@ -58,7 +67,7 @@ def detect_wildcards(self, domain, test_count=5):
5867 random_subdomain = self ._generate_random_subdomain ()
5968 test_domain = f"{ random_subdomain } .{ domain } "
6069
61- exists , ip = self .dns_resolver . check_subdomain (test_domain )
70+ exists , ip = self ._resolve_domain (test_domain )
6271 if exists and ip :
6372 ips = [ip ] if isinstance (ip , str ) else ip
6473 for single_ip in ips :
@@ -90,34 +99,22 @@ def get_wildcard_ips(self):
9099
91100
92101class DNSResolver :
93- def __init__ (self , timeout = 3 , nameservers = None ):
94- self .resolver = dns .resolver .Resolver ()
95- self .resolver .timeout = timeout
96- self .resolver .lifetime = timeout
97-
98- if nameservers :
99- self .resolver .nameservers = nameservers
100- else :
101- self .resolver .nameservers = ['8.8.8.8' , '1.1.1.1' , '8.8.4.4' , '1.0.0.1' ]
102-
103- def resolve (self , hostname , record_type = 'A' ):
102+ def __init__ (self , timeout = 3 ):
103+ socket .setdefaulttimeout (timeout )
104+
105+ def resolve (self , hostname ):
104106 try :
105- answers = self .resolver .resolve (hostname , record_type )
106- if record_type == 'A' or record_type == 'AAAA' :
107- ips = [str (answer ) for answer in answers ]
108- return True , ips [0 ] if len (ips ) == 1 else ips
109- else :
110- return True , [str (answer ) for answer in answers ]
111- except (dns .resolver .NXDOMAIN , dns .resolver .NoAnswer ,
112- dns .resolver .NoNameservers , dns .exception .Timeout ,
113- Exception ):
107+
108+ ip = socket .gethostbyname (hostname )
109+ return True , ip
110+ except (socket .gaierror , socket .timeout ):
111+ return False , None
112+ except Exception :
114113 return False , None
115114
116115 def check_subdomain (self , subdomain ):
117116 success , result = self .resolve (subdomain )
118- if success :
119- return True , result if isinstance (result , str ) else result [0 ]
120- return False , None
117+ return success , result
121118
122119
123120class WordlistManager :
@@ -146,10 +143,10 @@ def get_wordlist_size(self):
146143
147144
148145class SubdomainBruteforcer :
149- def __init__ (self , wordlist_path , max_workers = 50 , timeout = 3 , nameservers = None , enable_wildcard_filtering = True ):
146+ def __init__ (self , wordlist_path , max_workers = 50 , timeout = 3 , enable_wildcard_filtering = True ):
150147 self .wordlist_manager = WordlistManager (wordlist_path )
151- self .dns_resolver = DNSResolver (timeout = timeout , nameservers = nameservers )
152- self .wildcard_detector = WildcardDetector (self . dns_resolver )
148+ self .dns_resolver = DNSResolver (timeout = timeout )
149+ self .wildcard_detector = WildcardDetector (timeout = timeout )
153150 self .max_workers = max_workers
154151 self .wordlist = []
155152 self .enable_wildcard_filtering = enable_wildcard_filtering
0 commit comments