ronin-recon 0.1.0.rc1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (119) hide show
  1. checksums.yaml +7 -0
  2. data/.document +4 -0
  3. data/.github/workflows/ruby.yml +46 -0
  4. data/.gitignore +20 -0
  5. data/.rspec +1 -0
  6. data/.rubocop.yml +44 -0
  7. data/.ruby-version +1 -0
  8. data/.yardopts +1 -0
  9. data/COPYING.txt +165 -0
  10. data/ChangeLog.md +36 -0
  11. data/Gemfile +62 -0
  12. data/README.md +391 -0
  13. data/Rakefile +74 -0
  14. data/bin/ronin-recon +16 -0
  15. data/data/completions/ronin-recon +95 -0
  16. data/data/templates/worker.rb.erb +67 -0
  17. data/data/wordlists/raft-small-directories.txt.gz +0 -0
  18. data/data/wordlists/subdomains-1000.txt.gz +0 -0
  19. data/examples/recon.rb +24 -0
  20. data/gemspec.yml +57 -0
  21. data/lib/ronin/recon/builtin/dns/lookup.rb +65 -0
  22. data/lib/ronin/recon/builtin/dns/mailservers.rb +64 -0
  23. data/lib/ronin/recon/builtin/dns/nameservers.rb +61 -0
  24. data/lib/ronin/recon/builtin/dns/reverse_lookup.rb +63 -0
  25. data/lib/ronin/recon/builtin/dns/srv_enum.rb +178 -0
  26. data/lib/ronin/recon/builtin/dns/subdomain_enum.rb +105 -0
  27. data/lib/ronin/recon/builtin/dns/suffix_enum.rb +168 -0
  28. data/lib/ronin/recon/builtin/net/ip_range_enum.rb +65 -0
  29. data/lib/ronin/recon/builtin/net/port_scan.rb +84 -0
  30. data/lib/ronin/recon/builtin/net/service_id.rb +75 -0
  31. data/lib/ronin/recon/builtin/ssl/cert_enum.rb +109 -0
  32. data/lib/ronin/recon/builtin/ssl/cert_grab.rb +76 -0
  33. data/lib/ronin/recon/builtin/ssl/cert_sh.rb +77 -0
  34. data/lib/ronin/recon/builtin/web/dir_enum.rb +121 -0
  35. data/lib/ronin/recon/builtin/web/email_addresses.rb +70 -0
  36. data/lib/ronin/recon/builtin/web/spider.rb +93 -0
  37. data/lib/ronin/recon/builtin.rb +34 -0
  38. data/lib/ronin/recon/cli/command.rb +40 -0
  39. data/lib/ronin/recon/cli/commands/completion.rb +61 -0
  40. data/lib/ronin/recon/cli/commands/irb.rb +57 -0
  41. data/lib/ronin/recon/cli/commands/new.rb +203 -0
  42. data/lib/ronin/recon/cli/commands/run.rb +420 -0
  43. data/lib/ronin/recon/cli/commands/test.rb +99 -0
  44. data/lib/ronin/recon/cli/commands/worker.rb +114 -0
  45. data/lib/ronin/recon/cli/commands/workers.rb +80 -0
  46. data/lib/ronin/recon/cli/debug_option.rb +45 -0
  47. data/lib/ronin/recon/cli/printing.rb +122 -0
  48. data/lib/ronin/recon/cli/ruby_shell.rb +51 -0
  49. data/lib/ronin/recon/cli/worker_command.rb +105 -0
  50. data/lib/ronin/recon/cli.rb +50 -0
  51. data/lib/ronin/recon/config.rb +371 -0
  52. data/lib/ronin/recon/dns_worker.rb +41 -0
  53. data/lib/ronin/recon/engine.rb +639 -0
  54. data/lib/ronin/recon/exceptions.rb +45 -0
  55. data/lib/ronin/recon/graph.rb +127 -0
  56. data/lib/ronin/recon/importer.rb +224 -0
  57. data/lib/ronin/recon/input_file.rb +81 -0
  58. data/lib/ronin/recon/message/job_completed.rb +60 -0
  59. data/lib/ronin/recon/message/job_failed.rb +69 -0
  60. data/lib/ronin/recon/message/job_started.rb +60 -0
  61. data/lib/ronin/recon/message/shutdown.rb +38 -0
  62. data/lib/ronin/recon/message/value.rb +76 -0
  63. data/lib/ronin/recon/message/worker_started.rb +51 -0
  64. data/lib/ronin/recon/message/worker_stopped.rb +51 -0
  65. data/lib/ronin/recon/mixins/dns.rb +639 -0
  66. data/lib/ronin/recon/mixins/http.rb +58 -0
  67. data/lib/ronin/recon/mixins.rb +21 -0
  68. data/lib/ronin/recon/output_formats/dir.rb +94 -0
  69. data/lib/ronin/recon/output_formats/dot.rb +155 -0
  70. data/lib/ronin/recon/output_formats/graph_format.rb +48 -0
  71. data/lib/ronin/recon/output_formats/graphviz_format.rb +115 -0
  72. data/lib/ronin/recon/output_formats/pdf.rb +43 -0
  73. data/lib/ronin/recon/output_formats/png.rb +43 -0
  74. data/lib/ronin/recon/output_formats/svg.rb +43 -0
  75. data/lib/ronin/recon/output_formats.rb +48 -0
  76. data/lib/ronin/recon/registry.rb +35 -0
  77. data/lib/ronin/recon/root.rb +33 -0
  78. data/lib/ronin/recon/scope.rb +112 -0
  79. data/lib/ronin/recon/value/parser.rb +113 -0
  80. data/lib/ronin/recon/value.rb +110 -0
  81. data/lib/ronin/recon/value_status.rb +87 -0
  82. data/lib/ronin/recon/values/cert.rb +168 -0
  83. data/lib/ronin/recon/values/domain.rb +88 -0
  84. data/lib/ronin/recon/values/email_address.rb +114 -0
  85. data/lib/ronin/recon/values/host.rb +137 -0
  86. data/lib/ronin/recon/values/ip.rb +123 -0
  87. data/lib/ronin/recon/values/ip_range.rb +155 -0
  88. data/lib/ronin/recon/values/mailserver.rb +61 -0
  89. data/lib/ronin/recon/values/nameserver.rb +61 -0
  90. data/lib/ronin/recon/values/open_port.rb +190 -0
  91. data/lib/ronin/recon/values/url.rb +218 -0
  92. data/lib/ronin/recon/values/website.rb +200 -0
  93. data/lib/ronin/recon/values/wildcard.rb +140 -0
  94. data/lib/ronin/recon/values.rb +32 -0
  95. data/lib/ronin/recon/version.rb +26 -0
  96. data/lib/ronin/recon/web_worker.rb +35 -0
  97. data/lib/ronin/recon/worker.rb +433 -0
  98. data/lib/ronin/recon/worker_pool.rb +203 -0
  99. data/lib/ronin/recon/workers.rb +260 -0
  100. data/lib/ronin/recon.rb +22 -0
  101. data/man/ronin-recon-completion.1 +76 -0
  102. data/man/ronin-recon-completion.1.md +78 -0
  103. data/man/ronin-recon-irb.1 +27 -0
  104. data/man/ronin-recon-irb.1.md +26 -0
  105. data/man/ronin-recon-new.1 +58 -0
  106. data/man/ronin-recon-new.1.md +59 -0
  107. data/man/ronin-recon-run.1 +137 -0
  108. data/man/ronin-recon-run.1.md +115 -0
  109. data/man/ronin-recon-test.1 +53 -0
  110. data/man/ronin-recon-test.1.md +55 -0
  111. data/man/ronin-recon-worker.1 +32 -0
  112. data/man/ronin-recon-worker.1.md +34 -0
  113. data/man/ronin-recon-workers.1 +29 -0
  114. data/man/ronin-recon-workers.1.md +31 -0
  115. data/man/ronin-recon.1 +57 -0
  116. data/man/ronin-recon.1.md +57 -0
  117. data/ronin-recon.gemspec +62 -0
  118. data/scripts/setup +58 -0
  119. metadata +364 -0
data/gemspec.yml ADDED
@@ -0,0 +1,57 @@
1
+ name: ronin-recon
2
+ summary: A micro-framework and tool for performing reconnaissance.
3
+ description: |
4
+ ronin-recon is a micro-framework and tool for performing reconnaissance.
5
+ ronin-recon uses multiple workers which process different data types
6
+ (IP, host, URL, etc) and produce new values. ronin-recon contains built-in
7
+ recon workers and supports loading additional 3rd-party workers from Ruby
8
+ files or 3rd-party git repositories. ronin-recon has a unique queue design
9
+ and uses asynchronous I/O to maximize efficiency. ronin-recon can lookup
10
+ IPs addresses, nameservers, mailservers, bruteforce sub-domains, port scan
11
+ IPs, discover services, and spider websites.
12
+
13
+ license: LGPL-3.0
14
+ authors: Postmodern
15
+ email: postmodern.mod3@gmail.com
16
+ homepage: https://ronin-rb.dev/
17
+ has_yard: true
18
+
19
+ metadata:
20
+ documentation_uri: https://ronin-rb.dev/docs/ronin-recon
21
+ source_code_uri: https://github.com/ronin-rb/ronin-recon
22
+ bug_tracker_uri: https://github.com/ronin-rb/ronin-recon/issues
23
+ changelog_uri: https://github.com/ronin-rb/ronin-recon/blob/main/ChangeLog.md
24
+ rubygems_mfa_required: 'true'
25
+
26
+ generated_files:
27
+ - data/completions/ronin-recon
28
+ - man/ronin-recon.1
29
+ - man/ronin-recon-completion.1
30
+ - man/ronin-recon-irb.1
31
+ - man/ronin-recon-new.1
32
+ - man/ronin-recon-workers.1
33
+ - man/ronin-recon-worker.1
34
+ - man/ronin-recon-test.1
35
+ - man/ronin-recon-run.1
36
+ - data/wordlists/subdomains-1000.txt.gz
37
+ - data/wordlists/raft-small-directories.txt.gz
38
+
39
+ required_ruby_version: ">= 3.1.0"
40
+
41
+ dependencies:
42
+ thread-local: ~> 1.0
43
+ async-io: ~> 1.0
44
+ async-dns: ~> 1.0
45
+ async-http: ~> 0.60
46
+ wordlist: ~> 1.0, >= 1.0.3
47
+ # Ronin dependencies:
48
+ ronin-support: ~> 1.1.0.rc1
49
+ ronin-core: ~> 0.2.0.rc1
50
+ ronin-db: ~> 0.2.0.rc1
51
+ ronin-repos: ~> 0.1
52
+ ronin-masscan: ~> 0.1.0.rc1
53
+ ronin-nmap: ~> 0.1.0.rc1
54
+ ronin-web-spider: ~> 0.2.0.rc1
55
+
56
+ development_dependencies:
57
+ bundler: ~> 2.0
@@ -0,0 +1,65 @@
1
+ # frozen_string_literal: true
2
+ #
3
+ # ronin-recon - A micro-framework and tool for performing reconnaissance.
4
+ #
5
+ # Copyright (c) 2023-2024 Hal Brodigan (postmodern.mod3@gmail.com)
6
+ #
7
+ # ronin-recon is free software: you can redistribute it and/or modify
8
+ # it under the terms of the GNU Lesser General Public License as published
9
+ # by the Free Software Foundation, either version 3 of the License, or
10
+ # (at your option) any later version.
11
+ #
12
+ # ronin-recon is distributed in the hope that it will be useful,
13
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
14
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
+ # GNU Lesser General Public License for more details.
16
+ #
17
+ # You should have received a copy of the GNU Lesser General Public License
18
+ # along with ronin-recon. If not, see <https://www.gnu.org/licenses/>.
19
+ #
20
+
21
+ require 'ronin/recon/dns_worker'
22
+
23
+ module Ronin
24
+ module Recon
25
+ module DNS
26
+ #
27
+ # Looks up the IP address of a host name, domain, nameserver, or
28
+ # mailserver.
29
+ #
30
+ class Lookup < DNSWorker
31
+
32
+ register 'dns/lookup'
33
+
34
+ summary 'Looks up the IPs of a host-name'
35
+ description <<~DESC
36
+ Resolves the IP addresses of domains, host names, nameservers,
37
+ and mailservers.
38
+ DESC
39
+
40
+ accepts Domain, Host, Nameserver, Mailserver
41
+ outputs IP
42
+
43
+ #
44
+ # Resolves the IP address for the given host.
45
+ #
46
+ # @param [Values::Host, Values::Domain, Values::Nameserver, Values::Mailserver] host
47
+ # The host name to resolve.
48
+ #
49
+ # @yield [ip]
50
+ #
51
+ # @yieldparam [Values::IP] ip
52
+ # An IP address for the host.
53
+ #
54
+ def process(host)
55
+ addresses = dns_get_addresses(host.name)
56
+
57
+ addresses.each do |address|
58
+ yield IP.new(address, host: host.name)
59
+ end
60
+ end
61
+
62
+ end
63
+ end
64
+ end
65
+ end
@@ -0,0 +1,64 @@
1
+ # frozen_string_literal: true
2
+ #
3
+ # ronin-recon - A micro-framework and tool for performing reconnaissance.
4
+ #
5
+ # Copyright (c) 2023-2024 Hal Brodigan (postmodern.mod3@gmail.com)
6
+ #
7
+ # ronin-recon is free software: you can redistribute it and/or modify
8
+ # it under the terms of the GNU Lesser General Public License as published
9
+ # by the Free Software Foundation, either version 3 of the License, or
10
+ # (at your option) any later version.
11
+ #
12
+ # ronin-recon is distributed in the hope that it will be useful,
13
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
14
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
+ # GNU Lesser General Public License for more details.
16
+ #
17
+ # You should have received a copy of the GNU Lesser General Public License
18
+ # along with ronin-recon. If not, see <https://www.gnu.org/licenses/>.
19
+ #
20
+
21
+ require 'ronin/recon/dns_worker'
22
+
23
+ module Ronin
24
+ module Recon
25
+ module DNS
26
+ #
27
+ # Finds the mailservers for the domain.
28
+ #
29
+ class Mailservers < DNSWorker
30
+
31
+ register 'dns/mailservers'
32
+
33
+ summary 'Looks up the mailservers of a domain'
34
+ description <<~DESC
35
+ Queries the mailservers (MX records) for a domain name.
36
+ DESC
37
+
38
+ accepts Domain
39
+ outputs Mailserver
40
+
41
+ #
42
+ # Finds the mailservers for the given domain.
43
+ #
44
+ # @param [Values::Domain] domain
45
+ # The given domain value.
46
+ #
47
+ # @yield [mailserver]
48
+ # Each discovered mailserver will be yielded.
49
+ #
50
+ # @yieldparam [Values::Mailserver] mailserver
51
+ # A discovered mailserver.
52
+ #
53
+ def process(domain)
54
+ dns_get_mailservers(domain.name).each do |mailserver|
55
+ unless mailserver == '.'
56
+ yield Mailserver.new(mailserver.chomp('.'))
57
+ end
58
+ end
59
+ end
60
+
61
+ end
62
+ end
63
+ end
64
+ end
@@ -0,0 +1,61 @@
1
+ # frozen_string_literal: true
2
+ #
3
+ # ronin-recon - A micro-framework and tool for performing reconnaissance.
4
+ #
5
+ # Copyright (c) 2023-2024 Hal Brodigan (postmodern.mod3@gmail.com)
6
+ #
7
+ # ronin-recon is free software: you can redistribute it and/or modify
8
+ # it under the terms of the GNU Lesser General Public License as published
9
+ # by the Free Software Foundation, either version 3 of the License, or
10
+ # (at your option) any later version.
11
+ #
12
+ # ronin-recon is distributed in the hope that it will be useful,
13
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
14
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
+ # GNU Lesser General Public License for more details.
16
+ #
17
+ # You should have received a copy of the GNU Lesser General Public License
18
+ # along with ronin-recon. If not, see <https://www.gnu.org/licenses/>.
19
+ #
20
+
21
+ require 'ronin/recon/dns_worker'
22
+
23
+ module Ronin
24
+ module Recon
25
+ module DNS
26
+ #
27
+ # Finds the nameservers associated with a domaim.
28
+ #
29
+ class Nameservers < DNSWorker
30
+
31
+ register 'dns/nameservers'
32
+
33
+ summary 'Looks up the nameservers of a domain'
34
+ description <<~DESC
35
+ Queries the nameservers (NS records) for a domain name.
36
+ DESC
37
+
38
+ accepts Domain
39
+ outputs Nameserver
40
+
41
+ #
42
+ # Looks up the nameservers of a given domain.
43
+ #
44
+ # @param [Values::Domain] domain
45
+ # The domain value.
46
+ #
47
+ # @yield [nameserver]
48
+ # The discovered nameservers will be yielded.
49
+ #
50
+ # @yieldparam [Values::Nameserver] nameserver
51
+ #
52
+ def process(domain)
53
+ dns_get_nameservers(domain.name).each do |nameserver|
54
+ yield Nameserver.new(nameserver.chomp('.'))
55
+ end
56
+ end
57
+
58
+ end
59
+ end
60
+ end
61
+ end
@@ -0,0 +1,63 @@
1
+ # frozen_string_literal: true
2
+ #
3
+ # ronin-recon - A micro-framework and tool for performing reconnaissance.
4
+ #
5
+ # Copyright (c) 2023-2024 Hal Brodigan (postmodern.mod3@gmail.com)
6
+ #
7
+ # ronin-recon is free software: you can redistribute it and/or modify
8
+ # it under the terms of the GNU Lesser General Public License as published
9
+ # by the Free Software Foundation, either version 3 of the License, or
10
+ # (at your option) any later version.
11
+ #
12
+ # ronin-recon is distributed in the hope that it will be useful,
13
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
14
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
+ # GNU Lesser General Public License for more details.
16
+ #
17
+ # You should have received a copy of the GNU Lesser General Public License
18
+ # along with ronin-recon. If not, see <https://www.gnu.org/licenses/>.
19
+ #
20
+
21
+ require 'ronin/recon/dns_worker'
22
+
23
+ module Ronin
24
+ module Recon
25
+ module DNS
26
+ #
27
+ # Performs reverse DNS lookup on an IP address and finds it's host name.
28
+ #
29
+ class ReverseLookup < DNSWorker
30
+
31
+ register 'dns/reverse_lookup'
32
+
33
+ summary 'Reverse looks up an IP address'
34
+ description <<~DESC
35
+ Reverse looks up an IP address and return the host names associated
36
+ with the IP address.
37
+ DESC
38
+
39
+ accepts IP
40
+ outputs Host
41
+
42
+ #
43
+ # Reverse DNS looks up an IP address and finds it's host name.
44
+ #
45
+ # @param [Values::IP] ip
46
+ #
47
+ # @yield [host]
48
+ #
49
+ # @yieldparam [Values::Host] host
50
+ #
51
+ def process(ip)
52
+ unless ip.host
53
+ # NOTE: only query IP addresses not associated with a hostname
54
+ dns_get_ptr_names(ip.address).each do |host_name|
55
+ yield Host.new(host_name.chomp('.'))
56
+ end
57
+ end
58
+ end
59
+
60
+ end
61
+ end
62
+ end
63
+ end
@@ -0,0 +1,178 @@
1
+ # frozen_string_literal: true
2
+ #
3
+ # ronin-recon - A micro-framework and tool for performing reconnaissance.
4
+ #
5
+ # Copyright (c) 2023-2024 Hal Brodigan (postmodern.mod3@gmail.com)
6
+ #
7
+ # ronin-recon is free software: you can redistribute it and/or modify
8
+ # it under the terms of the GNU Lesser General Public License as published
9
+ # by the Free Software Foundation, either version 3 of the License, or
10
+ # (at your option) any later version.
11
+ #
12
+ # ronin-recon is distributed in the hope that it will be useful,
13
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
14
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
+ # GNU Lesser General Public License for more details.
16
+ #
17
+ # You should have received a copy of the GNU Lesser General Public License
18
+ # along with ronin-recon. If not, see <https://www.gnu.org/licenses/>.
19
+ #
20
+
21
+ require 'ronin/recon/dns_worker'
22
+ require 'ronin/recon/root'
23
+
24
+ require 'wordlist'
25
+ require 'async/queue'
26
+
27
+ module Ronin
28
+ module Recon
29
+ module DNS
30
+ #
31
+ # Finds other host names by querying common `SRV` record names under a
32
+ # domain.
33
+ #
34
+ class SRVEnum < DNSWorker
35
+
36
+ # Common `SRV` record names.
37
+ RECORD_NAMES = %w[
38
+ _gc._tcp
39
+ _kerberos._tcp
40
+ _kerberos._udp
41
+ _ldap._tcp
42
+ _test._tcp
43
+ _sips._tcp
44
+ _sip._udp
45
+ _sip._tcp
46
+ _aix._tcp
47
+ _aix._tcp
48
+ _finger._tcp
49
+ _ftp._tcp
50
+ _http._tcp
51
+ _nntp._tcp
52
+ _telnet._tcp
53
+ _whois._tcp
54
+ _h323cs._tcp
55
+ _h323cs._udp
56
+ _h323be._tcp
57
+ _h323be._udp
58
+ _h323ls._tcp
59
+ _https._tcp
60
+ _h323ls._udp
61
+ _sipinternal._tcp
62
+ _sipinternaltls._tcp
63
+ _sip._tls
64
+ _sipfederationtls._tcp
65
+ _jabber._tcp
66
+ _xmpp-server._tcp
67
+ _xmpp-client._tcp
68
+ _xmpp-server._udp
69
+ _xmpp-client._udp
70
+ _imap.tcp
71
+ _certificates._tcp
72
+ _crls._tcp
73
+ _pgpkeys._tcp
74
+ _pgprevokations._tcp
75
+ _cmp._tcp
76
+ _svcp._tcp
77
+ _crl._tcp
78
+ _ocsp._tcp
79
+ _PKIXREP._tcp
80
+ _smtp._tcp
81
+ _hkp._tcp
82
+ _hkps._tcp
83
+ _jabber._udp
84
+ _jabber-client._tcp
85
+ _jabber-client._udp
86
+ _kerberos.tcp.dc._msdcs
87
+ _ldap._tcp.ForestDNSZones
88
+ _ldap._tcp.dc._msdcs
89
+ _ldap._tcp.pdc._msdcs
90
+ _ldap._tcp.gc._msdcs
91
+ _kerberos._tcp.dc._msdcs
92
+ _kpasswd._tcp
93
+ _kpasswd._udp
94
+ _imap._tcp
95
+ _imaps._tcp
96
+ _submission._tcp
97
+ _pop3._tcp
98
+ _pop3s._tcp
99
+ _caldav._tcp
100
+ _caldavs._tcp
101
+ _carddav._tcp
102
+ _carddavs._tcp
103
+ _x-puppet._tcp
104
+ _x-puppet-ca._tcp
105
+ _autodiscover._tcp
106
+ ]
107
+
108
+ register 'dns/srv_enum'
109
+
110
+ summary 'Enumerates common SRV record names for a domain'
111
+ description <<~DESC
112
+ Attempts to find additional hosts by querying common SRV record names
113
+ for the domain name.
114
+ DESC
115
+
116
+ accepts Domain
117
+ outputs Host
118
+
119
+ param :concurrency, Integer, default: 10,
120
+ desc: 'Sets the number of async tasks'
121
+
122
+ #
123
+ # Bruteforce resolves common `SRV` records for a domain.
124
+ #
125
+ # @param [Values::Domain] domain
126
+ # The domain to query.
127
+ #
128
+ # @yield [host]
129
+ # A discovered host from `SRV` record under the domain.
130
+ #
131
+ # @yieldparam [Values::Host] host
132
+ # A host name pointed to by a `SRV` record under the domain.
133
+ #
134
+ def process(domain)
135
+ wordlist = RECORD_NAMES
136
+ queue = Async::LimitedQueue.new(params[:concurrency])
137
+
138
+ Async do |task|
139
+ task.async do
140
+ # populate the queue with SRV record names to query
141
+ wordlist.each do |name|
142
+ queue << "#{name}.#{domain.name}"
143
+ end
144
+
145
+ # send stop messages for each sub-task
146
+ params[:concurrency].times do
147
+ queue << nil
148
+ end
149
+ end
150
+
151
+ # spawn the sub-tasks
152
+ params[:concurrency].times do
153
+ task.async do
154
+ while (name = queue.dequeue)
155
+ records = dns_get_srv_records(name)
156
+
157
+ records.each do |record|
158
+ # BUG: async-dns will return `CNAME` records for domains
159
+ # with catch-all subdomain aliases.
160
+ if record.kind_of?(Resolv::DNS::Resource::IN::SRV)
161
+ hostname = record.target.to_s
162
+ hostname.chomp!('.')
163
+
164
+ unless hostname.empty?
165
+ yield Host.new(hostname)
166
+ end
167
+ end
168
+ end
169
+ end
170
+ end
171
+ end
172
+ end
173
+ end
174
+
175
+ end
176
+ end
177
+ end
178
+ end
@@ -0,0 +1,105 @@
1
+ # frozen_string_literal: true
2
+ #
3
+ # ronin-recon - A micro-framework and tool for performing reconnaissance.
4
+ #
5
+ # Copyright (c) 2023-2024 Hal Brodigan (postmodern.mod3@gmail.com)
6
+ #
7
+ # ronin-recon is free software: you can redistribute it and/or modify
8
+ # it under the terms of the GNU Lesser General Public License as published
9
+ # by the Free Software Foundation, either version 3 of the License, or
10
+ # (at your option) any later version.
11
+ #
12
+ # ronin-recon is distributed in the hope that it will be useful,
13
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
14
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
+ # GNU Lesser General Public License for more details.
16
+ #
17
+ # You should have received a copy of the GNU Lesser General Public License
18
+ # along with ronin-recon. If not, see <https://www.gnu.org/licenses/>.
19
+ #
20
+
21
+ require 'ronin/recon/dns_worker'
22
+ require 'ronin/recon/root'
23
+
24
+ require 'wordlist'
25
+ require 'async/queue'
26
+
27
+ module Ronin
28
+ module Recon
29
+ module DNS
30
+ #
31
+ # Finds common subdomains of a domain using a wordlist of commong
32
+ # subdomains.
33
+ #
34
+ class SubdomainEnum < DNSWorker
35
+
36
+ DEFAULT_WORDLIST = File.join(WORDLISTS_DIR, 'subdomains-1000.txt.gz')
37
+
38
+ register 'dns/subdomain_enum'
39
+
40
+ summary 'Enumerates subdomains of a domain'
41
+ description <<~DESC
42
+ Attempts to find the subdomains of a given domain by looking up
43
+ host names of the domain using a wordlist of common subdomains.
44
+ DESC
45
+
46
+ accepts Domain, Wildcard
47
+ outputs Host
48
+
49
+ param :concurrency, Integer, default: 10,
50
+ desc: 'Sets the number of async tasks'
51
+
52
+ param :wordlist, String, desc: 'Optional subdomain wordlist to use'
53
+
54
+ #
55
+ # Bruteforce resolves the subdomains of a given domain.
56
+ #
57
+ # @param [Values::Domain, Values::Wildcard] domain
58
+ # The domain or wildcard host name to bruteforce.
59
+ #
60
+ # @yield [host]
61
+ # Subdomains that have DNS records will be yielded.
62
+ #
63
+ # @yieldparam [Values::Host] host
64
+ # A valid subdomain of the domain.
65
+ #
66
+ def process(domain)
67
+ wordlist = Wordlist.open(params[:wordlist] || DEFAULT_WORDLIST)
68
+ queue = Async::LimitedQueue.new(params[:concurrency])
69
+
70
+ Async do |task|
71
+ task.async do
72
+ case domain
73
+ when Domain
74
+ wordlist.each do |name|
75
+ queue << "#{name}.#{domain.name}"
76
+ end
77
+ when Wildcard
78
+ wordlist.each do |name|
79
+ queue << domain.template.sub('*',name)
80
+ end
81
+ end
82
+
83
+ # send stop messages for each sub-task
84
+ params[:concurrency].times do
85
+ queue << nil
86
+ end
87
+ end
88
+
89
+ # spawn the sub-tasks
90
+ params[:concurrency].times do
91
+ task.async do
92
+ while (subdomain = queue.dequeue)
93
+ if dns_get_address(subdomain)
94
+ yield Host.new(subdomain)
95
+ end
96
+ end
97
+ end
98
+ end
99
+ end
100
+ end
101
+
102
+ end
103
+ end
104
+ end
105
+ end