(.*?)', re.S)
656 | link_regex = re.compile('(.*?) ', re.S)
657 | links = []
658 | try:
659 | results_tbl = tbl_regex.findall(resp)[0]
660 | except IndexError:
661 | results_tbl = ''
662 | links_list = link_regex.findall(results_tbl)
663 | links = list(set(links_list))
664 | for link in links:
665 | subdomain = link.strip()
666 | if not subdomain.endswith(self.domain):
667 | continue
668 | if subdomain and subdomain not in self.subdomains and subdomain != self.domain:
669 | self.subdomains.append(subdomain.strip())
670 | return links
671 |
672 |
673 | class Virustotal(enumratorBaseThreaded):
674 | def __init__(self, domain, subdomains=None, q=None, silent=False, verbose=True):
675 | subdomains = subdomains or []
676 | base_url = 'https://www.virustotal.com/en/domain/{domain}/information/'
677 | self.engine_name = "Virustotal"
678 | self.lock = threading.Lock()
679 | self.q = q
680 | super(Virustotal, self).__init__(base_url, self.engine_name, domain, subdomains, q=q, silent=silent, verbose=verbose)
681 | return
682 |
683 | # the main send_req need to be rewritten
684 | def send_req(self, url):
685 | try:
686 | resp = self.session.get(url, headers=self.headers, timeout=self.timeout)
687 | except Exception as e:
688 | self.print_(e)
689 | resp = None
690 |
691 | return self.get_response(resp)
692 |
693 | # once the send_req is rewritten we don't need to call this function, the stock one should be ok
694 | def enumerate(self):
695 | url = self.base_url.format(domain=self.domain)
696 | resp = self.send_req(url)
697 | self.extract_domains(resp)
698 | return self.subdomains
699 |
700 | def extract_domains(self, resp):
701 | link_regx = re.compile('.*? (.*?)', re.S)
702 | try:
703 | links = link_regx.findall(resp)
704 | for link in links:
705 | subdomain = link.strip()
706 | if not subdomain.endswith(self.domain):
707 | continue
708 | if subdomain not in self.subdomains and subdomain != self.domain:
709 | if self.verbose:
710 | self.print_("%s%s: %s%s" % (R, self.engine_name, W, subdomain))
711 | self.subdomains.append(subdomain.strip())
712 | except Exception:
713 | pass
714 |
715 |
716 | class ThreatCrowd(enumratorBaseThreaded):
717 | def __init__(self, domain, subdomains=None, q=None, silent=False, verbose=True):
718 | subdomains = subdomains or []
719 | base_url = 'https://www.threatcrowd.org/searchApi/v2/domain/report/?domain={domain}'
720 | self.engine_name = "ThreatCrowd"
721 | self.lock = threading.Lock()
722 | self.q = q
723 | super(ThreatCrowd, self).__init__(base_url, self.engine_name, domain, subdomains, q=q, silent=silent, verbose=verbose)
724 | return
725 |
726 | def req(self, url):
727 | try:
728 | resp = self.session.get(url, headers=self.headers, timeout=self.timeout)
729 | except Exception:
730 | resp = None
731 |
732 | return self.get_response(resp)
733 |
734 | def enumerate(self):
735 | url = self.base_url.format(domain=self.domain)
736 | resp = self.req(url)
737 | self.extract_domains(resp)
738 | return self.subdomains
739 |
740 | def extract_domains(self, resp):
741 | try:
742 | links = json.loads(resp)['subdomains']
743 | for link in links:
744 | subdomain = link.strip()
745 | if not subdomain.endswith(self.domain):
746 | continue
747 | if subdomain not in self.subdomains and subdomain != self.domain:
748 | if self.verbose:
749 | self.print_("%s%s: %s%s" % (R, self.engine_name, W, subdomain))
750 | self.subdomains.append(subdomain.strip())
751 | except Exception as e:
752 | pass
753 |
754 |
755 | class CrtSearch(enumratorBaseThreaded):
756 | def __init__(self, domain, subdomains=None, q=None, silent=False, verbose=True):
757 | subdomains = subdomains or []
758 | base_url = 'https://crt.sh/?q=%25.{domain}'
759 | self.engine_name = "SSL Certificates"
760 | self.lock = threading.Lock()
761 | self.q = q
762 | super(CrtSearch, self).__init__(base_url, self.engine_name, domain, subdomains, q=q, silent=silent, verbose=verbose)
763 | return
764 |
765 | def req(self, url):
766 | try:
767 | resp = self.session.get(url, headers=self.headers, timeout=self.timeout)
768 | except Exception:
769 | resp = None
770 |
771 | return self.get_response(resp)
772 |
773 | def enumerate(self):
774 | url = self.base_url.format(domain=self.domain)
775 | resp = self.req(url)
776 | if resp:
777 | self.extract_domains(resp)
778 | return self.subdomains
779 |
780 | def extract_domains(self, resp):
781 | link_regx = re.compile(' (.*?) | ')
782 | try:
783 | links = link_regx.findall(resp)
784 | for link in links:
785 | subdomain = link.strip()
786 | if not subdomain.endswith(self.domain) or '*' in subdomain:
787 | continue
788 |
789 | if '@' in subdomain:
790 | subdomain = subdomain[subdomain.find('@')+1:]
791 |
792 | if subdomain not in self.subdomains and subdomain != self.domain:
793 | if self.verbose:
794 | self.print_("%s%s: %s%s" % (R, self.engine_name, W, subdomain))
795 | self.subdomains.append(subdomain.strip())
796 | except Exception as e:
797 | pass
798 |
799 |
800 | class PassiveDNS(enumratorBaseThreaded):
801 | def __init__(self, domain, subdomains=None, q=None, silent=False, verbose=True):
802 | subdomains = subdomains or []
803 | base_url = 'https://api.sublist3r.com/search.php?domain={domain}'
804 | self.engine_name = "PassiveDNS"
805 | self.lock = threading.Lock()
806 | self.q = q
807 | super(PassiveDNS, self).__init__(base_url, self.engine_name, domain, subdomains, q=q, silent=silent, verbose=verbose)
808 | return
809 |
810 | def req(self, url):
811 | try:
812 | resp = self.session.get(url, headers=self.headers, timeout=self.timeout)
813 | except Exception as e:
814 | resp = None
815 |
816 | return self.get_response(resp)
817 |
818 | def enumerate(self):
819 | url = self.base_url.format(domain=self.domain)
820 | resp = self.req(url)
821 | if not resp:
822 | return self.subdomains
823 |
824 | self.extract_domains(resp)
825 | return self.subdomains
826 |
827 | def extract_domains(self, resp):
828 | try:
829 | subdomains = json.loads(resp)
830 | for subdomain in subdomains:
831 | if subdomain not in self.subdomains and subdomain != self.domain:
832 | if self.verbose:
833 | self.print_("%s%s: %s%s" % (R, self.engine_name, W, subdomain))
834 | self.subdomains.append(subdomain.strip())
835 | except Exception as e:
836 | pass
837 |
838 |
839 | class portscan():
840 | def __init__(self, subdomains, ports):
841 | self.subdomains = subdomains
842 | self.ports = ports
843 | self.threads = 20
844 | self.lock = threading.BoundedSemaphore(value=self.threads)
845 |
846 | def port_scan(self, host, ports):
847 | openports = []
848 | self.lock.acquire()
849 | for port in ports:
850 | try:
851 | s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
852 | s.settimeout(2)
853 | result = s.connect_ex((host, int(port)))
854 | if result == 0:
855 | openports.append(port)
856 | s.close()
857 | except Exception:
858 | pass
859 | self.lock.release()
860 | if len(openports) > 0:
861 | print("%s%s%s - %sFound open ports:%s %s%s%s" % (G, host, W, R, W, Y, ', '.join(openports), W))
862 |
863 | def run(self):
864 | for subdomain in self.subdomains:
865 | t = threading.Thread(target=self.port_scan, args=(subdomain, self.ports))
866 | t.start()
867 |
868 |
869 | def main(domain, threads, savefile, ports, silent, verbose, enable_bruteforce, engines):
870 | bruteforce_list = set()
871 | search_list = set()
872 |
873 | if is_windows:
874 | subdomains_queue = list()
875 | else:
876 | subdomains_queue = multiprocessing.Manager().list()
877 |
878 | # Check Bruteforce Status
879 | if enable_bruteforce or enable_bruteforce is None:
880 | enable_bruteforce = True
881 |
882 | # Validate domain
883 | domain_check = re.compile("^(http|https)?[a-zA-Z0-9]+([\-\.]{1}[a-zA-Z0-9]+)*\.[a-zA-Z]{2,}$")
884 | if not domain_check.match(domain):
885 | if not silent:
886 | print(R + "Error: Please enter a valid domain" + W)
887 | return []
888 |
889 | if not domain.startswith('http://') or not domain.startswith('https://'):
890 | domain = 'http://' + domain
891 |
892 | parsed_domain = urlparse.urlparse(domain)
893 |
894 | if not silent:
895 | print(B + "[-] Enumerating subdomains now for %s" % parsed_domain.netloc + W)
896 |
897 | if verbose and not silent:
898 | print(Y + "[-] verbosity is enabled, will show the subdomains results in realtime" + W)
899 |
900 | supported_engines = {'baidu': BaiduEnum,
901 | 'yahoo': YahooEnum,
902 | 'google': GoogleEnum,
903 | 'bing': BingEnum,
904 | 'ask': AskEnum,
905 | 'netcraft': NetcraftEnum,
906 | 'dnsdumpster': DNSdumpster,
907 | 'virustotal': Virustotal,
908 | 'threatcrowd': ThreatCrowd,
909 | 'ssl': CrtSearch,
910 | 'passivedns': PassiveDNS
911 | }
912 |
913 | chosenEnums = []
914 |
915 | if engines is None:
916 | chosenEnums = [
917 | BaiduEnum, YahooEnum, GoogleEnum, BingEnum, AskEnum,
918 | NetcraftEnum, DNSdumpster, Virustotal, ThreatCrowd,
919 | CrtSearch, PassiveDNS
920 | ]
921 | else:
922 | engines = engines.split(',')
923 | for engine in engines:
924 | if engine.lower() in supported_engines:
925 | chosenEnums.append(supported_engines[engine.lower()])
926 |
927 | # Start the engines enumeration
928 | enums = [enum(domain, [], q=subdomains_queue, silent=silent, verbose=verbose) for enum in chosenEnums]
929 | for enum in enums:
930 | enum.start()
931 | for enum in enums:
932 | enum.join()
933 |
934 | subdomains = set(subdomains_queue)
935 | for subdomain in subdomains:
936 | search_list.add(subdomain)
937 |
938 | if enable_bruteforce:
939 | if not silent:
940 | print(G + "[-] Starting bruteforce module now using subbrute.." + W)
941 | record_type = False
942 | path_to_file = os.path.dirname(os.path.realpath(__file__))
943 | subs = os.path.join(path_to_file, 'subbrute', 'names.txt')
944 | resolvers = os.path.join(path_to_file, 'subbrute', 'resolvers.txt')
945 | process_count = threads
946 | output = False
947 | json_output = False
948 | bruteforce_list = subbrute.print_target(parsed_domain.netloc, record_type, subs, resolvers, process_count, output, json_output, search_list, verbose)
949 |
950 | subdomains = search_list.union(bruteforce_list)
951 |
952 | if subdomains:
953 | subdomains = sorted(subdomains, key=subdomain_sorting_key)
954 |
955 | if savefile:
956 | write_file(savefile, subdomains)
957 |
958 | if not silent:
959 | print(Y + "[-] Total Unique Subdomains Found: %s" % len(subdomains) + W)
960 |
961 | if ports:
962 | if not silent:
963 | print(G + "[-] Start port scan now for the following ports: %s%s" % (Y, ports) + W)
964 | ports = ports.split(',')
965 | pscan = portscan(subdomains, ports)
966 | pscan.run()
967 |
968 | elif not silent:
969 | for subdomain in subdomains:
970 | print(G + subdomain + W)
971 | return subdomains
972 |
973 |
974 | def interactive():
975 | args = parse_args()
976 | domain = args.domain
977 | threads = args.threads
978 | savefile = args.output
979 | ports = args.ports
980 | enable_bruteforce = args.bruteforce
981 | verbose = args.verbose
982 | engines = args.engines
983 | if verbose or verbose is None:
984 | verbose = True
985 | banner()
986 | res = main(domain, threads, savefile, ports, silent=False, verbose=verbose, enable_bruteforce=enable_bruteforce, engines=engines)
987 |
988 | if __name__ == "__main__":
989 | interactive()
990 |
--------------------------------------------------------------------------------
/images/ChecksubDomains.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Jewel591/SubDomainFinder/dfd0eee82d901896ecae95913f8d0cfe2dd48e1f/images/ChecksubDomains.png
--------------------------------------------------------------------------------
/input/domains.txt:
--------------------------------------------------------------------------------
1 | huazhu.com
2 | htinns.com
3 | hantinghotels.com
4 | cjia.com
5 | hworld.com.cn
--------------------------------------------------------------------------------
/output/result.txt:
--------------------------------------------------------------------------------
1 | output there!
2 |
--------------------------------------------------------------------------------
/requirements.txt:
--------------------------------------------------------------------------------
1 | dnspython
2 | gevent
3 | argparse
4 | requests
5 |
--------------------------------------------------------------------------------
/subDomainsBrute/.gitignore:
--------------------------------------------------------------------------------
1 | *.py[cod]
2 | .idea/*
3 | tmp/
--------------------------------------------------------------------------------
/subDomainsBrute/dict/dns_servers.txt:
--------------------------------------------------------------------------------
1 | 119.29.29.29
2 | 182.254.116.116
3 | # 223.5.5.5
4 | # 223.6.6.6
5 | 114.114.115.115
6 | 114.114.114.114
7 |
--------------------------------------------------------------------------------
/subDomainsBrute/dict/next_sub.txt:
--------------------------------------------------------------------------------
1 | test
2 | test2
3 | t
4 | dev
5 | 1
6 | 2
7 | 3
8 | s1
9 | s2
10 | s3
11 | admin
12 | adm
13 | a
14 | ht
15 | adminht
16 | webht
17 | web
18 | gm
19 | sys
20 | system
21 | manage
22 | manager
23 | mgr
24 | b
25 | c
26 | passport
27 | bata
28 | wei
29 | weixin
30 | wechat
31 | wx
32 | wiki
33 | upload
34 | ftp
35 | pic
36 | jira
37 | zabbix
38 | nagios
39 | bug
40 | bugzilla
41 | sql
42 | mysql
43 | db
44 | stmp
45 | pop
46 | imap
47 | mail
48 | zimbra
49 | exchange
50 | forum
51 | bbs
52 | list
53 | count
54 | counter
55 | img
56 | img01
57 | img02
58 | img03
59 | img04
60 | api
61 | cache
62 | js
63 | css
64 | app
65 | apps
66 | wap
67 | m
68 | sms
69 | zip
70 | monitor
71 | proxy
72 | update
73 | upgrade
74 | stat
75 | stats
76 | data
77 | portal
78 | blog
79 | autodiscover
80 | en
81 | search
82 | so
83 | oa
84 | database
85 | home
86 | sso
87 | help
88 | vip
89 | s
90 | w
91 | down
92 | download
93 | downloads
94 | dl
95 | svn
96 | git
97 | log
98 | staff
99 | vpn
100 | sslvpn
101 | ssh
102 | scanner
103 | sandbox
104 | ldap
105 | lab
106 | go
107 | demo
108 | console
109 | cms
110 | auth
111 | crm
112 | erp
113 | res
114 | static
115 | old
116 | new
117 | beta
118 | image
119 | service
120 | login
121 | 3g
122 | docs
123 | it
124 | e
125 | live
126 | library
127 | files
128 | i
129 | d
130 | cp
131 | connect
132 | gateway
133 | lib
134 | preview
135 | backup
136 | share
137 | status
138 | assets
139 | user
140 | vote
141 | bugs
142 | cas
143 | feedback
144 | id
145 | edm
146 | survey
147 | union
148 | ceshi
149 | dev1
150 | updates
151 | phpmyadmin
152 | pma
153 | edit
154 | master
155 | xml
156 | control
157 | profile
158 | zhidao
159 | tool
160 | toolbox
161 | boss
162 | activity
163 | www
164 |
--------------------------------------------------------------------------------
/subDomainsBrute/dict/next_sub_full.txt:
--------------------------------------------------------------------------------
1 | test
2 | test2
3 | t
4 | dev
5 | 1
6 | 2
7 | 3
8 | s1
9 | s2
10 | s3
11 | admin
12 | adm
13 | a
14 | ht
15 | adminht
16 | webht
17 | web
18 | gm
19 | sys
20 | system
21 | manage
22 | manager
23 | mgr
24 | b
25 | c
26 | passport
27 | bata
28 | wei
29 | weixin
30 | wechat
31 | wx
32 | wiki
33 | upload
34 | ftp
35 | pic
36 | jira
37 | zabbix
38 | nagios
39 | bug
40 | bugzilla
41 | sql
42 | mysql
43 | db
44 | stmp
45 | pop
46 | imap
47 | mail
48 | zimbra
49 | exchange
50 | forum
51 | bbs
52 | list
53 | count
54 | counter
55 | img
56 | img01
57 | img02
58 | img03
59 | img04
60 | api
61 | cache
62 | js
63 | css
64 | app
65 | apps
66 | wap
67 | m
68 | sms
69 | zip
70 | monitor
71 | proxy
72 | update
73 | upgrade
74 | stat
75 | stats
76 | data
77 | portal
78 | blog
79 | autodiscover
80 | en
81 | search
82 | so
83 | oa
84 | database
85 | home
86 | sso
87 | help
88 | vip
89 | s
90 | w
91 | down
92 | download
93 | downloads
94 | dl
95 | svn
96 | git
97 | log
98 | staff
99 | vpn
100 | sslvpn
101 | ssh
102 | scanner
103 | sandbox
104 | ldap
105 | lab
106 | go
107 | demo
108 | console
109 | cms
110 | auth
111 | crm
112 | erp
113 | res
114 | static
115 | old
116 | new
117 | beta
118 | image
119 | service
120 | login
121 | 3g
122 | docs
123 | it
124 | e
125 | live
126 | library
127 | files
128 | i
129 | d
130 | cp
131 | connect
132 | gateway
133 | lib
134 | preview
135 | backup
136 | share
137 | status
138 | assets
139 | user
140 | vote
141 | bugs
142 | cas
143 | feedback
144 | id
145 | edm
146 | survey
147 | union
148 | ceshi
149 | dev1
150 | updates
151 | phpmyadmin
152 | pma
153 | edit
154 | master
155 | xml
156 | control
157 | profile
158 | zhidao
159 | tool
160 | toolbox
161 | boss
162 | activity
163 | www
164 | smtp
165 | webmail
166 | mx
167 | pop3
168 | ns1
169 | ns2
170 | webdisk
171 | www2
172 | news
173 | cpanel
174 | whm
175 | shop
176 | sip
177 | ns
178 | mobile
179 | www1
180 | email
181 | support
182 | mail2
183 | media
184 | lyncdiscover
185 | secure
186 | video
187 | my
188 | staging
189 | images
190 | dns
191 | info
192 | ns3
193 | mail1
194 | intranet
195 | cdn
196 | lists
197 | dns1
198 | www3
199 | dns2
200 | mobilemail
201 | store
202 | remote
203 | cn
204 | owa
205 | cs
206 | stage
207 | online
208 | jobs
209 | calendar
210 | community
211 | forums
212 | services
213 | dialin
214 | chat
215 | meet
216 | blogs
217 | hr
218 | office
219 | ww
220 | ftp2
221 | legacy
222 | b2b
223 | ns4
224 | v
225 | pda
226 | events
227 | av
228 | edu
229 | ads
230 | health
231 | es
232 | english
233 | ad
234 | extranet
235 | helpdesk
236 | training
237 | photo
238 | finance
239 | tv
240 | fr
241 | sc
242 | job
243 | cloud
244 | im
245 | careers
246 | game
247 | archive
248 | get
249 | gis
250 | access
251 | member
252 | mx1
253 | newsletter
254 | de
255 | qa
256 | direct
257 | alumni
258 | mx2
259 | hk
260 | sp
261 | gw
262 | relay
263 | jp
264 | content
265 | file
266 | citrix
267 | vpn2
268 | soft
269 | ssl
270 | server
271 | club
272 | ws
273 | host
274 | book
275 | www4
276 | sh
277 | tools
278 | mail3
279 | ms
280 | mailhost
281 | ca
282 | ntp
283 | ask
284 | sites
285 | sz
286 | spam
287 | wwww
288 | tw
289 | videos
290 | send
291 | music
292 | project
293 | uk
294 | start
295 | mall
296 | ns5
297 | outlook
298 | reports
299 | us
300 | partner
301 | mssql
302 | bj
303 | sharepoint
304 | link
305 | metrics
306 | partners
307 | smtp2
308 | webproxy
309 | mdm
310 | marketing
311 | ts
312 | security
313 | map
314 | ir
315 | fs
316 | origin
317 | travel
318 | feeds
319 | meeting
320 | u
321 | photos
322 | hq
323 | tj
324 | research
325 | pt
326 | members
327 | ru
328 | bm
329 | business
330 | eq
331 | cc
332 | w3
333 | student
334 | auto
335 | dx
336 | p
337 | rs
338 | dns3
339 | vc
340 | gmail
341 | uc
342 | press
343 | web1
344 | localhost
345 | ent
346 | tuan
347 | dj
348 | web2
349 | ss
350 | cnc
351 | vpn1
352 | pay
353 | time
354 | sx
355 | hd
356 | games
357 | lt
358 | projects
359 | g
360 | sales
361 | stream
362 | gb
363 | forms
364 | www5
365 | wt
366 | abc
367 | weather
368 | zb
369 | smtp1
370 | maps
371 | x
372 | register
373 | design
374 | radio
375 | software
376 | china
377 | math
378 | open
379 | view
380 | fax
381 | event
382 | pm
383 | test1
384 | alpha
385 | irc
386 | sg
387 | cq
388 | ftp1
389 | idc
390 | labs
391 | da
392 | directory
393 | developer
394 | reg
395 | catalog
396 | rss
397 | wh
398 | sd
399 | tg
400 | bb
401 | digital
402 | hb
403 | house
404 | site
405 | conference
406 | rt
407 | temp
408 | fw
409 | tz
410 | tech
411 | education
412 | biz
413 | f
414 | gallery
415 | gh
416 | car
417 | dc
418 | agent
419 | mis
420 | eng
421 | flash
422 | cx
423 | pub
424 | ticket
425 | doc
426 | card
427 | account
428 | code
429 | promo
430 | net
431 | kb
432 | jk
433 | social
434 | sports
435 | ems
436 | tp
437 | public
438 | mm
439 | pms
440 | mrtg
441 | as
442 | jw
443 | corp
444 | tr
445 | investor
446 | dm
447 | sts
448 | th
449 | bi
450 | 123
451 | st
452 | br
453 | wp
454 | art
455 | shopping
456 | global
457 | money
458 | prod
459 | students
460 | cj
461 | iphone
462 | vps
463 | ag
464 | food
465 | sb
466 | ly
467 | local
468 | sj
469 | server1
470 | testing
471 | brand
472 | sy
473 | buy
474 | life
475 | groups
476 | nl
477 | tour
478 | lms
479 | pro
480 | bc
481 | rtx
482 | hao
483 | exam
484 | fb
485 | in
486 | ams
487 | msoid
488 | idp
489 | vod
490 | cm
491 | dk
492 | hs
493 | usa
494 | ww2
495 | jwc
496 | lp
497 | rsc
498 | jd
499 | cf
500 | rms
501 | ec
502 | jabber
503 | streaming
504 | webdev
505 | dms
506 | investors
507 | bookstore
508 | kr
509 | cd
510 | corporate
511 | mail4
512 | fz
513 | order
514 | transfer
515 | hotel
516 | work
517 | bt
518 | au
519 | pages
520 | sm
521 | client
522 | r
523 | y
524 | audio
525 | cz
526 | ci
527 | se
528 | potala
529 | ch
530 | webservices
531 | dy
532 | cvs
533 | ra
534 | apple
535 | barracuda
536 | ip
537 | ja
538 | mkt
539 | archives
540 | www0
541 | intra
542 | gate
543 | youth
544 | internal
545 | mailgw
546 | customer
547 | linux
548 | registration
549 | movie
550 | mailgate
551 | q
552 | xx
553 | mx3
554 | mars
555 | phone
556 | desktop
557 | ds
558 | zz
559 | love
560 | show
561 | nc
562 | redmine
563 | ce
564 | pl
565 | wireless
566 | inside
567 | fx
568 | mp
569 | hz
570 | listserv
571 | analytics
572 | ks
573 | redirect
574 | accounts
575 | report
576 | hermes
577 | ae
578 | mobi
579 | ps
580 | edge
581 | resources
582 | img1
583 | law
584 | pr
585 | international
586 | ml
587 | trac
588 | rd
589 | market
590 | mailer
591 | cert
592 | hg
593 | cl
594 | img2
595 | development
596 | gs
597 | google
598 | space
599 | www6
600 | gd
601 | post
602 | voip
603 | ac
604 | push
605 | m2
606 | sq
607 | fc
608 | ar
609 | asp
610 | dr
611 | seo
612 | mobil
613 | sync
614 | kf
615 | be
616 | about
617 | mail01
618 | sns
619 | board
620 | pc
621 | links
622 | jj
623 | history
624 | mailman
625 | campus
626 | mms
627 | storage
628 | ns0
629 | cdn2
630 | cacti
631 | hy
632 | enterprise
633 | noc
634 | ic
635 | cgi
636 | track
637 | world
638 | act
639 | wl
640 | product
641 | ls
642 | sf
643 | affiliates
644 | android
645 | payment
646 | n
647 | gz
648 | web3
649 | learning
650 | signup
651 | z
652 | tao
653 | top
654 | wifi
655 | yy
656 | password
657 | cw
658 | wm
659 | ess
660 | ex
661 | resource
662 | print
663 | gc
664 | w2
665 | canada
666 | cr
667 | mc
668 | 0
669 | me
670 | keys
671 | sentry
672 | smtp3
673 | journal
674 | mt
675 | team
676 | orion
677 | edi
678 | test3
679 | tc
680 | main
681 | zs
682 | faq
683 | click
684 | hub
685 | tu
686 | golf
687 | phoenix
688 | bd
689 | build
690 | free
691 | ee
692 | int
693 | cdn1
694 | v2
695 | sa
696 | pos
697 | fi
698 | router
699 | rc
700 | mirror
701 | tracker
702 | ct
703 | special
704 | cal
705 | ns6
706 | atlas
707 | ids
708 | affiliate
709 | nj
710 | tt
711 | nz
712 | db1
713 | bg
714 | mercury
715 | family
716 | courses
717 | ipv6
718 | jupiter
719 | no
720 | venus
721 | nb
722 | beijing
723 | summer
724 | ma
725 | yp
726 | ocs
727 | star
728 | traveler
729 | multimedia
730 | fm
731 | study
732 | lb
733 | up
734 | shanghai
735 | bk
736 | www7
737 | join
738 | tfs
739 | feed
740 | h
741 | ns01
742 | php
743 | stock
744 | km
745 | books
746 | eu
747 | md
748 | 2013
749 | whois
750 | sw
751 | mailserver
752 | mb
753 | tms
754 | monitoring
755 | ys
756 | ga
757 | radius
758 | group
759 | mtest
760 | j
761 | www8
762 | wb
763 | m1
764 | billing
765 | aaa
766 | pf
767 | products
768 | faculty
769 | em
770 | opac
771 | cis
772 | xmpp
773 | nanjing
774 | taobao
775 | zp
776 | teacher
777 | co
778 | contact
779 | nt
780 | ky
781 | qq
782 | mp3
783 | gps
784 | hn
785 | users
786 | gl
787 | domain
788 | newsroom
789 | dh
790 | csc
791 | repo
792 | zw
793 | ismart
794 | pp
795 | gg
796 | wms
797 | ims
798 | www9
799 | 2014
800 | solutions
801 | at
802 | bak
803 | sl
804 | cwc
805 | firewall
806 | wordpress
807 | school
808 | nms
809 | developers
810 | pki
811 | pe
812 | v2-ag
813 | devel
814 | hp
815 | titan
816 | pluto
817 | kids
818 | sport
819 | mail5
820 | server2
821 | nas
822 | xh
823 | ap
824 | red
825 | mas
826 | translate
827 | dealer
828 | ipad
829 | demo2
830 | 2012
831 | dns4
832 | hh
833 | green
834 | dz
835 | hybrid
836 | discover
837 | adserver
838 | japan
839 | mi
840 | xf
841 | zeus
842 | am
843 | people
844 | aa
845 | win
846 | sk
847 | db2
848 | jenkins
849 | xb
850 | oss
851 | sdc
852 | wc
853 | its
854 | dw
855 | yun
856 | acs
857 | asia
858 | daj
859 | webadmin
860 | crl
861 | ebook
862 | mag
863 | csg
864 | blue
865 | bank
866 | one
867 | o
868 | horizon
869 | orders
870 | apis
871 | k
872 | l
873 | 4
874 | 5
875 | 6
876 | 7
877 | 8
878 | 9
879 | ab
880 | af
881 | ah
882 | ai
883 | aj
884 | ak
885 | al
886 | an
887 | ao
888 | aq
889 | aw
890 | ax
891 | ay
892 | az
893 | ba
894 | bf
895 | bh
896 | bl
897 | bn
898 | bo
899 | bp
900 | bq
901 | bs
902 | bu
903 | bv
904 | bw
905 | bx
906 | by
907 | bz
908 | cb
909 | cg
910 | ck
911 | cu
912 | cv
913 | cy
914 | dd
915 | df
916 | dg
917 | di
918 | dn
919 | do
920 | dp
921 | dq
922 | dt
923 | du
924 | dv
925 | ea
926 | eb
927 | ed
928 | ef
929 | eg
930 | eh
931 | ei
932 | ej
933 | ek
934 | el
935 | eo
936 | ep
937 | er
938 | et
939 | ev
940 | ew
941 | ey
942 | ez
943 | fa
944 | fd
945 | fe
946 | ff
947 | fg
948 | fh
949 | fj
950 | fk
951 | fl
952 | fn
953 | fo
954 | fp
955 | fq
956 | ft
957 | fu
958 | fv
959 | fy
960 | ge
961 | gf
962 | gi
963 | gj
964 | gk
965 | gn
966 | gp
967 | gq
968 | gr
969 | gt
970 | gu
971 | gv
972 | gx
973 | gy
974 | ha
975 | hc
976 | he
977 | hf
978 | hi
979 | hj
980 | hl
981 | hm
982 | ho
983 | hu
984 | hv
985 | hw
986 | hx
987 | ia
988 | ib
989 | ie
990 | if
991 | ig
992 | ih
993 | ii
994 | ij
995 | ik
996 | il
997 | io
998 | iq
999 | is
1000 | iu
1001 | iv
1002 | iw
1003 | ix
1004 | iy
1005 | iz
1006 | jb
1007 | jc
1008 | je
1009 | jf
1010 | jg
1011 | jh
1012 | ji
1013 | jl
1014 | jm
1015 | jn
1016 | jo
1017 | jq
1018 | jr
1019 | jt
1020 | ju
1021 | jv
1022 | jx
1023 | jy
1024 | jz
1025 | ka
1026 | kc
1027 | kd
1028 | ke
1029 | kg
1030 | kh
1031 | ki
1032 | kj
1033 | kk
1034 | kl
1035 | kn
1036 | ko
1037 | kp
1038 | kq
1039 | kt
1040 | ku
1041 | kv
1042 | kw
1043 | kx
1044 | kz
1045 | la
1046 | lc
1047 | ld
1048 | le
1049 | lf
1050 | lg
1051 | lh
1052 | li
1053 | lj
1054 | lk
1055 | ll
1056 | lm
1057 | ln
1058 | lo
1059 | lq
1060 | lr
1061 | lu
1062 | lv
1063 | lw
1064 | lx
1065 | lz
1066 | mf
1067 | mg
1068 | mh
1069 | mj
1070 | mk
1071 | mn
1072 | mo
1073 | mq
1074 | mr
1075 | mu
1076 | mv
1077 | mw
1078 | mz
1079 | na
1080 | nd
1081 | ne
1082 | nf
1083 | ng
1084 | nh
1085 | ni
1086 | nk
1087 | nm
1088 | nn
1089 | np
1090 | nq
1091 | nr
1092 | nu
1093 | nv
1094 | nw
1095 | nx
1096 | ny
1097 | ob
1098 | oc
1099 | od
1100 | oe
1101 | of
1102 | og
1103 | oh
1104 | oi
1105 | oj
1106 | ok
1107 | ol
1108 | om
1109 | on
1110 | oo
1111 | op
1112 | oq
1113 | or
1114 | os
1115 | ot
1116 | ou
1117 | ov
1118 | ow
1119 | ox
1120 | oy
1121 | oz
1122 | pa
1123 | pb
1124 | pd
1125 | pg
1126 | ph
1127 | pi
1128 | pj
1129 | pk
1130 | pn
1131 | po
1132 | pq
1133 | pu
1134 | pv
1135 | pw
1136 | px
1137 | py
1138 | pz
1139 | qb
1140 | qc
1141 | qd
1142 | qe
1143 | qf
1144 | qg
1145 | qh
1146 | qi
1147 | qj
1148 | qk
1149 | ql
1150 | qm
1151 | qn
1152 | qo
1153 | qp
1154 | qr
1155 | qs
1156 | qt
1157 | qu
1158 | qv
1159 | qw
1160 | qx
1161 | qy
1162 | qz
1163 | rb
1164 | re
1165 | rf
1166 | rg
1167 | rh
1168 | ri
1169 | rj
1170 | rk
1171 | rl
1172 | rm
1173 | rn
1174 | ro
1175 | rp
1176 | rq
1177 | rr
1178 | rv
1179 | rw
1180 | rx
1181 | ry
1182 | rz
1183 | si
1184 | sn
1185 | sr
1186 | su
1187 | sv
1188 | ta
1189 | tb
1190 | td
1191 | te
1192 | tf
1193 | ti
1194 | tk
1195 | tl
1196 | tm
1197 | tn
1198 | to
1199 | tq
1200 | tx
1201 | ty
1202 | ua
1203 | ub
1204 | ud
1205 | ue
1206 | uf
1207 | ug
1208 | uh
1209 | ui
1210 | uj
1211 | ul
1212 | um
1213 | un
1214 | uo
1215 | uq
1216 | ur
1217 | ut
1218 | uu
1219 | uv
1220 | uw
1221 | ux
1222 | uy
1223 | uz
1224 | va
1225 | vb
1226 | vd
1227 | ve
1228 | vf
1229 | vg
1230 | vh
1231 | vi
1232 | vj
1233 | vk
1234 | vl
1235 | vm
1236 | vn
1237 | vo
1238 | vp
1239 | vq
1240 | vr
1241 | vs
1242 | vt
1243 | vu
1244 | vv
1245 | vw
1246 | vx
1247 | vy
1248 | vz
1249 | wa
1250 | wd
1251 | we
1252 | wf
1253 | wg
1254 | wi
1255 | wj
1256 | wk
1257 | wn
1258 | wo
1259 | wq
1260 | wr
1261 | wu
1262 | wv
1263 | wy
1264 | wz
1265 | xa
1266 | xc
1267 | xd
1268 | xe
1269 | xg
1270 | xi
1271 | xj
1272 | xk
1273 | xl
1274 | xm
1275 | xn
1276 | xo
1277 | xp
1278 | xq
1279 | xr
1280 | xs
1281 | xt
1282 | xu
1283 | xv
1284 | xw
1285 | xy
1286 | xz
1287 | ya
1288 | yb
1289 | yc
1290 | yd
1291 | ye
1292 | yf
1293 | yg
1294 | yh
1295 | yi
1296 | yj
1297 | yk
1298 | yl
1299 | ym
1300 | yn
1301 | yo
1302 | yq
1303 | yr
1304 | yt
1305 | yu
1306 | yv
1307 | yw
1308 | yx
1309 | yz
1310 | za
1311 | zc
1312 | zd
1313 | ze
1314 | zf
1315 | zg
1316 | zh
1317 | zi
1318 | zj
1319 | zk
1320 | zl
1321 | zm
1322 | zn
1323 | zo
1324 | zq
1325 | zr
1326 | zt
1327 | zu
1328 | zv
1329 | zx
1330 | zy
--------------------------------------------------------------------------------
/subDomainsBrute/dict/subnames_all_5_letters.txt:
--------------------------------------------------------------------------------
1 | {alphnum}
2 | {alphnum}{alphnum}
3 | {alphnum}{alphnum}{alphnum}
4 | {alphnum}{alphnum}{alphnum}{alphnum}
5 | {alphnum}{alphnum}{alphnum}{alphnum}{alphnum}
--------------------------------------------------------------------------------
/subDomainsBrute/lib/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Jewel591/SubDomainFinder/dfd0eee82d901896ecae95913f8d0cfe2dd48e1f/subDomainsBrute/lib/__init__.py
--------------------------------------------------------------------------------
/subDomainsBrute/lib/cmdline.py:
--------------------------------------------------------------------------------
1 | import optparse
2 | import sys
3 |
4 |
5 | def parse_args():
6 | parser = optparse.OptionParser('usage: %prog [options] target.com',
7 | version="%prog 1.2")
8 | parser.add_option('-f', dest='file', default='subnames.txt',
9 | help='File contains new line delimited subs, default is subnames.txt.')
10 | parser.add_option('--full', dest='full_scan', default=False, action='store_true',
11 | help='Full scan, NAMES FILE subnames_full.txt will be used to brute')
12 | parser.add_option('-i', '--ignore-intranet', dest='i', default=False, action='store_true',
13 | help='Ignore domains pointed to private IPs')
14 | parser.add_option('-t', '--threads', dest='threads', default=200, type=int,
15 | help='Num of scan threads, 200 by default')
16 | parser.add_option('-p', '--process', dest='process', default=6, type=int,
17 | help='Num of scan Process, 6 by default')
18 | parser.add_option('-o', '--output', dest='output', default=None,
19 | type='string', help='Output file name. default is {target}.txt')
20 |
21 | (options, args) = parser.parse_args()
22 | if len(args) < 1:
23 | parser.print_help()
24 | sys.exit(0)
25 | return options, args
26 |
--------------------------------------------------------------------------------
/subDomainsBrute/lib/common.py:
--------------------------------------------------------------------------------
1 | # common functions
2 |
3 | import sys
4 | import os
5 | from gevent.pool import Pool
6 | import dns.resolver
7 | from lib.consle_width import getTerminalSize
8 |
9 | console_width = getTerminalSize()[0] - 2
10 |
11 |
12 | def is_intranet(ip):
13 | ret = ip.split('.')
14 | if len(ret) != 4:
15 | return True
16 | if ret[0] == '10':
17 | return True
18 | if ret[0] == '172' and 16 <= int(ret[1]) <= 31:
19 | return True
20 | if ret[0] == '192' and ret[1] == '168':
21 | return True
22 | return False
23 |
24 |
25 | def print_msg(msg=None, left_align=True, line_feed=False):
26 | if left_align:
27 | sys.stdout.write('\r' + msg + ' ' * (console_width - len(msg)))
28 | else: # right align
29 | sys.stdout.write('\r' + ' ' * (console_width - len(msg)) + msg)
30 | if line_feed:
31 | sys.stdout.write('\n')
32 | sys.stdout.flush()
33 |
34 |
35 | def test_server(server, dns_servers):
36 | resolver = dns.resolver.Resolver(configure=False)
37 | resolver.lifetime = resolver.timeout = 5.0
38 | try:
39 | resolver.nameservers = [server]
40 | answers = resolver.query('public-dns-a.baidu.com') # an existed domain
41 | if answers[0].address != '180.76.76.76':
42 | raise Exception('Incorrect DNS response')
43 | try:
44 | resolver.query('test.bad.dns.lijiejie.com') # non-existed domain
45 | with open('bad_dns_servers.txt', 'a') as f:
46 | f.write(server + '\n')
47 | print_msg('[+] Bad DNS Server found %s' % server)
48 | except Exception as e:
49 | dns_servers.append(server)
50 | print_msg('[+] Server %s < OK > Found %s' % (server.ljust(16), len(dns_servers)))
51 | except Exception as e:
52 | print_msg('[+] Server %s Found %s' % (server.ljust(16), len(dns_servers)))
53 |
54 |
55 | def load_dns_servers():
56 | print_msg('[+] Validate DNS servers', line_feed=True)
57 | dns_servers = []
58 | pool = Pool(5)
59 | for server in open('dict/dns_servers.txt').readlines():
60 | server = server.strip()
61 | if server and not server.startswith('#'):
62 | pool.apply_async(test_server, (server, dns_servers))
63 | pool.join()
64 |
65 | server_count = len(dns_servers)
66 | print_msg('\n[+] %s DNS Servers found' % server_count, line_feed=True)
67 | if server_count == 0:
68 | print_msg('[ERROR] No valid DNS Server !', line_feed=True)
69 | sys.exit(-1)
70 | return dns_servers
71 |
72 |
73 | def load_next_sub(options):
74 | next_subs = []
75 | _file = 'dict/next_sub_full.txt' if options.full_scan else 'dict/next_sub.txt'
76 | with open(_file) as f:
77 | for line in f:
78 | sub = line.strip()
79 | if sub and sub not in next_subs:
80 | tmp_set = {sub}
81 | while tmp_set:
82 | item = tmp_set.pop()
83 | if item.find('{alphnum}') >= 0:
84 | for _letter in 'abcdefghijklmnopqrstuvwxyz0123456789':
85 | tmp_set.add(item.replace('{alphnum}', _letter, 1))
86 | elif item.find('{alpha}') >= 0:
87 | for _letter in 'abcdefghijklmnopqrstuvwxyz':
88 | tmp_set.add(item.replace('{alpha}', _letter, 1))
89 | elif item.find('{num}') >= 0:
90 | for _letter in '0123456789':
91 | tmp_set.add(item.replace('{num}', _letter, 1))
92 | elif item not in next_subs:
93 | next_subs.append(item)
94 | return next_subs
95 |
96 |
97 | def get_out_file_name(target, options):
98 | if options.output:
99 | outfile = options.output
100 | else:
101 | _name = os.path.basename(options.file).replace('subnames', '')
102 | if _name != '.txt':
103 | _name = '_' + _name
104 | outfile = target + _name
105 | return outfile
106 |
107 |
108 | def user_abort(sig, frame):
109 | exit(-1)
110 |
--------------------------------------------------------------------------------
/subDomainsBrute/lib/consle_width.py:
--------------------------------------------------------------------------------
1 | """ getTerminalSize()
2 | - get width and height of console
3 | - works on linux,os x,windows,cygwin(windows)
4 | """
5 |
6 | __all__ = ['getTerminalSize']
7 |
8 |
9 | def getTerminalSize():
10 | import platform
11 | current_os = platform.system()
12 | tuple_xy = None
13 | if current_os == 'Windows':
14 | tuple_xy = _getTerminalSize_windows()
15 | if tuple_xy is None:
16 | tuple_xy = _getTerminalSize_tput()
17 | # needed for window's python in cygwin's xterm!
18 | if current_os == 'Linux' or current_os == 'Darwin' or current_os.startswith('CYGWIN'):
19 | tuple_xy = _getTerminalSize_linux()
20 | if tuple_xy is None:
21 | tuple_xy = (80, 25) # default value
22 | return tuple_xy
23 |
24 |
25 | def _getTerminalSize_windows():
26 | res = None
27 | try:
28 | from ctypes import windll, create_string_buffer
29 |
30 | # stdin handle is -10
31 | # stdout handle is -11
32 | # stderr handle is -12
33 |
34 | h = windll.kernel32.GetStdHandle(-12)
35 | csbi = create_string_buffer(22)
36 | res = windll.kernel32.GetConsoleScreenBufferInfo(h, csbi)
37 | except:
38 | return None
39 | if res:
40 | import struct
41 | (bufx, bufy, curx, cury, wattr,
42 | left, top, right, bottom, maxx, maxy) = struct.unpack("hhhhHhhhhhh", csbi.raw)
43 | sizex = right - left + 1
44 | sizey = bottom - top + 1
45 | return sizex, sizey
46 | else:
47 | return None
48 |
49 |
50 | def _getTerminalSize_tput():
51 | # get terminal width
52 | # src: http://stackoverflow.com/questions/263890/how-do-i-find-the-width-height-of-a-terminal-window
53 | try:
54 | import subprocess
55 | proc = subprocess.Popen(["tput", "cols"], stdin=subprocess.PIPE, stdout=subprocess.PIPE)
56 | output = proc.communicate(input=None)
57 | cols = int(output[0])
58 | proc = subprocess.Popen(["tput", "lines"], stdin=subprocess.PIPE, stdout=subprocess.PIPE)
59 | output = proc.communicate(input=None)
60 | rows = int(output[0])
61 | return (cols, rows)
62 | except:
63 | return None
64 |
65 |
66 | def _getTerminalSize_linux():
67 | def ioctl_GWINSZ(fd):
68 | try:
69 | import fcntl, termios, struct, os
70 | cr = struct.unpack('hh', fcntl.ioctl(fd, termios.TIOCGWINSZ, '1234'))
71 | except:
72 | return None
73 | return cr
74 |
75 | cr = ioctl_GWINSZ(0) or ioctl_GWINSZ(1) or ioctl_GWINSZ(2)
76 | if not cr:
77 | try:
78 | fd = os.open(os.ctermid(), os.O_RDONLY)
79 | cr = ioctl_GWINSZ(fd)
80 | os.close(fd)
81 | except:
82 | pass
83 | if not cr:
84 | try:
85 | env = os.environ
86 | cr = (env['LINES'], env['COLUMNS'])
87 | except:
88 | return None
89 | return int(cr[1]), int(cr[0])
90 |
91 |
92 | if __name__ == "__main__":
93 | sizex, sizey = getTerminalSize()
94 | print 'width =', sizex, 'height =', sizey
95 |
--------------------------------------------------------------------------------
/subDomainsBrute/subDomainsBrute.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # -*- encoding: utf-8 -*-
3 | """
4 | subDomainsBrute 1.2
5 | A simple and fast sub domains brute tool for pentesters
6 | my[at]lijiejie.com (http://www.lijiejie.com)
7 | """
8 |
9 | import multiprocessing
10 | import warnings
11 | warnings.simplefilter("ignore", category=UserWarning)
12 | import gevent
13 | from gevent import monkey
14 | monkey.patch_all()
15 | from gevent.queue import PriorityQueue
16 | from gevent.lock import RLock
17 | import re
18 | import dns.resolver
19 | import time
20 | import signal
21 | import os
22 | import glob
23 | from lib.cmdline import parse_args
24 | from lib.common import is_intranet, load_dns_servers, load_next_sub, print_msg, get_out_file_name, \
25 | user_abort
26 |
27 |
28 | class SubNameBrute(object):
29 | def __init__(self, *params):
30 | self.domain, self.options, self.process_num, self.dns_servers, self.next_subs, \
31 | self.scan_count, self.found_count, self.queue_size_array, tmp_dir = params
32 | self.dns_count = len(self.dns_servers)
33 | self.scan_count_local = 0
34 | self.found_count_local = 0
35 | self.resolvers = [dns.resolver.Resolver(configure=False) for _ in range(self.options.threads)]
36 | for r in self.resolvers:
37 | r.lifetime = r.timeout = 10.0
38 | self.queue = PriorityQueue()
39 | self.priority = 0
40 | self.ip_dict = {}
41 | self.found_subs = set()
42 | self.timeout_subs = {}
43 | self.count_time = time.time()
44 | self.outfile = open('%s/%s_part_%s.txt' % (tmp_dir, self.domain, self.process_num), 'w')
45 | self.normal_names_set = set()
46 | self.load_sub_names()
47 | self.lock = RLock()
48 |
49 | def load_sub_names(self):
50 | normal_lines = []
51 | wildcard_lines = []
52 | wildcard_set = set()
53 | regex_list = []
54 | lines = set()
55 | with open(self.options.file) as inFile:
56 | for line in inFile.xreadlines():
57 | sub = line.strip()
58 | if not sub or sub in lines:
59 | continue
60 | lines.add(sub)
61 |
62 | brace_count = sub.count('{')
63 | if brace_count > 0:
64 | wildcard_lines.append((brace_count, sub))
65 | sub = sub.replace('{alphnum}', '[a-z0-9]')
66 | sub = sub.replace('{alpha}', '[a-z]')
67 | sub = sub.replace('{num}', '[0-9]')
68 | if sub not in wildcard_set:
69 | wildcard_set.add(sub)
70 | regex_list.append('^' + sub + '$')
71 | else:
72 | normal_lines.append(sub)
73 | self.normal_names_set.add(sub)
74 |
75 | if regex_list:
76 | pattern = '|'.join(regex_list)
77 | _regex = re.compile(pattern)
78 | for line in normal_lines:
79 | if _regex.search(line):
80 | normal_lines.remove(line)
81 |
82 | for _ in normal_lines[self.process_num::self.options.process]:
83 | self.queue.put((0, _)) # priority set to 0
84 | for _ in wildcard_lines[self.process_num::self.options.process]:
85 | self.queue.put(_)
86 |
87 | def scan(self, j):
88 | self.resolvers[j].nameservers = [self.dns_servers[j % self.dns_count]] + self.dns_servers
89 |
90 | while True:
91 | try:
92 | self.lock.acquire()
93 | if time.time() - self.count_time > 1.0:
94 | self.scan_count.value += self.scan_count_local
95 | self.scan_count_local = 0
96 | self.queue_size_array[self.process_num] = self.queue.qsize()
97 | if self.found_count_local:
98 | self.found_count.value += self.found_count_local
99 | self.found_count_local = 0
100 | self.count_time = time.time()
101 | self.lock.release()
102 | brace_count, sub = self.queue.get(timeout=3.0)
103 | if brace_count > 0:
104 | brace_count -= 1
105 | if sub.find('{next_sub}') >= 0:
106 | for _ in self.next_subs:
107 | self.queue.put((0, sub.replace('{next_sub}', _)))
108 | if sub.find('{alphnum}') >= 0:
109 | for _ in 'abcdefghijklmnopqrstuvwxyz0123456789':
110 | self.queue.put((brace_count, sub.replace('{alphnum}', _, 1)))
111 | elif sub.find('{alpha}') >= 0:
112 | for _ in 'abcdefghijklmnopqrstuvwxyz':
113 | self.queue.put((brace_count, sub.replace('{alpha}', _, 1)))
114 | elif sub.find('{num}') >= 0:
115 | for _ in '0123456789':
116 | self.queue.put((brace_count, sub.replace('{num}', _, 1)))
117 | continue
118 | except gevent.queue.Empty as e:
119 | break
120 |
121 | try:
122 |
123 | if sub in self.found_subs:
124 | continue
125 |
126 | self.scan_count_local += 1
127 | cur_domain = sub + '.' + self.domain
128 | answers = self.resolvers[j].query(cur_domain)
129 |
130 | if answers:
131 | self.found_subs.add(sub)
132 | ips = ', '.join(sorted([answer.address for answer in answers]))
133 | if ips in ['1.1.1.1', '127.0.0.1', '0.0.0.0', '0.0.0.1']:
134 | continue
135 | if self.options.i and is_intranet(answers[0].address):
136 | continue
137 |
138 | try:
139 | self.scan_count_local += 1
140 | answers = self.resolvers[j].query(cur_domain, 'cname')
141 | cname = answers[0].target.to_unicode().rstrip('.')
142 | if cname.endswith(self.domain) and cname not in self.found_subs:
143 | cname_sub = cname[:len(cname) - len(self.domain) - 1] # new sub
144 | if cname_sub not in self.normal_names_set:
145 | self.found_subs.add(cname)
146 | self.queue.put((0, cname_sub))
147 | except Exception as e:
148 | pass
149 |
150 | first_level_sub = sub.split('.')[-1]
151 | if (first_level_sub, ips) not in self.ip_dict:
152 | self.ip_dict[(first_level_sub, ips)] = 1
153 | else:
154 | self.ip_dict[(first_level_sub, ips)] += 1
155 | if self.ip_dict[(first_level_sub, ips)] > 30:
156 | continue
157 |
158 | self.found_count_local += 1
159 |
160 | self.outfile.write(cur_domain.ljust(30) + '\t' + ips + '\n')
161 | self.outfile.flush()
162 | try:
163 | self.scan_count_local += 1
164 | self.resolvers[j].query('lijiejie-test-not-existed.' + cur_domain)
165 | except (dns.resolver.NXDOMAIN, dns.resolver.NoAnswer) as e:
166 | if self.queue.qsize() < 10000:
167 | for _ in self.next_subs:
168 | self.queue.put((0, _ + '.' + sub))
169 | else:
170 | self.queue.put((1, '{next_sub}.' + sub))
171 | except Exception as e:
172 | pass
173 |
174 | except (dns.resolver.NXDOMAIN, dns.resolver.NoAnswer) as e:
175 | pass
176 | except dns.resolver.NoNameservers as e:
177 | self.queue.put((0, sub)) # Retry
178 | except dns.exception.Timeout as e:
179 | self.timeout_subs[sub] = self.timeout_subs.get(sub, 0) + 1
180 | if self.timeout_subs[sub] <= 2:
181 | self.queue.put((0, sub)) # Retry
182 | except Exception as e:
183 | import traceback
184 | traceback.print_exc()
185 | with open('errors.log', 'a') as errFile:
186 | errFile.write('[%s] %s\n' % (type(e), str(e)))
187 |
188 | def run(self):
189 | threads = [gevent.spawn(self.scan, i) for i in range(self.options.threads)]
190 | gevent.joinall(threads)
191 |
192 |
193 | def run_process(*params):
194 | signal.signal(signal.SIGINT, user_abort)
195 | s = SubNameBrute(*params)
196 | s.run()
197 |
198 |
199 | def wildcard_test(domain, level=1):
200 | try:
201 | r = dns.resolver.Resolver(configure=False)
202 | r.nameservers = dns_servers
203 | answers = r.query('lijiejie-not-existed-test.%s' % domain)
204 | ips = ', '.join(sorted([answer.address for answer in answers]))
205 | if level == 1:
206 | print 'any-sub.%s\t%s' % (domain.ljust(30), ips)
207 | wildcard_test('any-sub.%s' % domain, 2)
208 | elif level == 2:
209 | exit(0)
210 | except Exception as e:
211 | return domain
212 |
213 |
214 | # check file existence
215 | def get_sub_file_path():
216 | if options.full_scan and options.file == 'subnames.txt':
217 | path = 'dict/subnames_full.txt'
218 | else:
219 | if os.path.exists(options.file):
220 | path = options.file
221 | elif os.path.exists('dict/%s' % options.file):
222 | path = 'dict/%s' % options.file
223 | else:
224 | print_msg('[ERROR] Names file not found: %s' % options.file)
225 | exit(-1)
226 | return path
227 |
228 |
229 | if __name__ == '__main__':
230 | options, args = parse_args()
231 | # print ''' SubDomainsBrute v1.2
232 | # https://github.com/lijiejie/subDomainsBrute
233 | # '''
234 | # make tmp dirs
235 | tmp_dir = 'tmp/%s_%s' % (args[0], int(time.time()))
236 | if not os.path.exists(tmp_dir):
237 | os.makedirs(tmp_dir)
238 |
239 | multiprocessing.freeze_support()
240 | dns_servers = load_dns_servers()
241 | next_subs = load_next_sub(options)
242 | scan_count = multiprocessing.Value('i', 0)
243 | found_count = multiprocessing.Value('i', 0)
244 | queue_size_array = multiprocessing.Array('i', options.process)
245 |
246 | try:
247 | print '[+] Run wildcard test'
248 | domain = wildcard_test(args[0])
249 | options.file = get_sub_file_path()
250 | print '[+] Start %s scan process' % options.process
251 | print '[+] Please wait while scanning ... \n'
252 | start_time = time.time()
253 | all_process = []
254 | for process_num in range(options.process):
255 | p = multiprocessing.Process(target=run_process,
256 | args=(domain, options, process_num, dns_servers, next_subs,
257 | scan_count, found_count, queue_size_array, tmp_dir)
258 | )
259 | all_process.append(p)
260 | p.start()
261 |
262 | char_set = ['\\', '|', '/', '-']
263 | count = 0
264 | while all_process:
265 | for p in all_process:
266 | if not p.is_alive():
267 | all_process.remove(p)
268 | groups_count = 0
269 | for c in queue_size_array:
270 | groups_count += c
271 | msg = '[%s] %s found, %s scanned in %.1f seconds, %s groups left' % (
272 | char_set[count % 4], found_count.value, scan_count.value, time.time() - start_time, groups_count)
273 | print_msg(msg)
274 | count += 1
275 | time.sleep(0.3)
276 | except KeyboardInterrupt as e:
277 | print '[ERROR] User aborted the scan!'
278 | for p in all_process:
279 | p.terminate()
280 | except Exception as e:
281 | print '[ERROR] %s' % str(e)
282 |
283 | out_file_name = get_out_file_name(domain, options)
284 | all_domains = set()
285 | domain_count = 0
286 | with open(out_file_name, 'w') as f:
287 | for _file in glob.glob(tmp_dir + '/*.txt'):
288 | with open(_file, 'r') as tmp_f:
289 | for domain in tmp_f:
290 | if domain not in all_domains:
291 | domain_count += 1
292 | all_domains.add(domain) # cname query can result in duplicated domains
293 | f.write(domain)
294 |
295 | msg = 'All Done. %s found, %s scanned in %.1f seconds.' % (
296 | domain_count, scan_count.value, time.time() - start_time)
297 | print_msg(msg, line_feed=True)
298 | print 'Output file is %s' % out_file_name
299 |
--------------------------------------------------------------------------------
/tmp/tmp.txt:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
|