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
@@ -0,0 +1,168 @@
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/support/network/public_suffix'
23
+
24
+ require 'async/queue'
25
+
26
+ module Ronin
27
+ module Recon
28
+ module DNS
29
+ #
30
+ # Finds other domains with different suffixes for a given domain
31
+ # using the [public suffix list].
32
+ #
33
+ # [public suffix list]: https://publicsuffix.org/
34
+ #
35
+ class SuffixEnum < DNSWorker
36
+
37
+ register 'dns/suffix_enum'
38
+
39
+ summary 'Enumerates suffixes of a domain'
40
+ description <<~DESC
41
+ Attempts to find other domains with different suffixes for the given
42
+ domain using the public suffix list.
43
+ DESC
44
+
45
+ references [
46
+ 'https://publicsuffix.org/'
47
+ ]
48
+
49
+ accepts Domain
50
+ outputs Domain
51
+
52
+ param :concurrency, Integer, default: 10,
53
+ desc: 'Sets the number of async tasks'
54
+
55
+ # Known bad suffixes that act like wildcard domains.
56
+ BAD_SUFFIXES = Set[
57
+ 'aquila.it',
58
+ 'arab',
59
+ 'belau.pw',
60
+ 'biz.ni',
61
+ 'com.ph',
62
+ 'com.ws',
63
+ 'co.pw',
64
+ 'df.gov.br',
65
+ 'ed.pw',
66
+ 'edu.ee',
67
+ 'edu.ps',
68
+ 'edu.ws',
69
+ 'gob.ni',
70
+ 'go.pw',
71
+ 'int.la',
72
+ 'int.ni',
73
+ 'lib.ee',
74
+ 'mil.ph',
75
+ 'mobi.tt',
76
+ 'music',
77
+ 'net.ph',
78
+ 'net.ws',
79
+ 'ngo.ph',
80
+ 'nom.za',
81
+ 'org.ee',
82
+ 'org.ph',
83
+ 'org.ws',
84
+ 'or.pw',
85
+ 'plo.ps',
86
+ 'ph',
87
+ 'vg',
88
+ 'ws',
89
+ 'გე',
90
+ 'عرب',
91
+ '中国',
92
+ '中國',
93
+ '公司.cn',
94
+ '政府',
95
+ '網絡.cn',
96
+ '网络.cn'
97
+ ]
98
+
99
+ # The public suffix list.
100
+ #
101
+ # @return [Ronin::Support::Network::PublicSuffixList]
102
+ attr_reader :public_suffix_list
103
+
104
+ #
105
+ # Initializes the DNS suffix enum worker.
106
+ #
107
+ # @param [Hash{Symbol => Object}] kwargs
108
+ # Additional keyword arguments.
109
+ #
110
+ def initialize(**kwargs)
111
+ super(**kwargs)
112
+
113
+ @public_suffix_list = Support::Network::PublicSuffix.list
114
+ end
115
+
116
+ #
117
+ # Bruteforce resolves the other domains with different suffixes for the
118
+ # given domain.
119
+ #
120
+ # @param [Values::Domain] domain
121
+ # The domain name to bruteforce.
122
+ #
123
+ # @yield [new_domain]
124
+ # Each new domain with a different public suffix.
125
+ #
126
+ # @yieldparam [Values::Domain] new_domain
127
+ # A valid domain with a different suffix.
128
+ #
129
+ def process(domain)
130
+ queue = Async::LimitedQueue.new(params[:concurrency])
131
+
132
+ domain_name, orig_suffix = @public_suffix_list.split(domain.name)
133
+
134
+ Async do |task|
135
+ task.async do
136
+ public_suffixes = @public_suffix_list.non_wildcards.icann.reject do |suffix|
137
+ BAD_SUFFIXES.include?(suffix.name)
138
+ end
139
+
140
+ public_suffixes.each do |suffix|
141
+ unless suffix.name == orig_suffix
142
+ queue << "#{domain_name}.#{suffix.name}"
143
+ end
144
+ end
145
+
146
+ # send stop messages for each sub-task
147
+ params[:concurrency].times do
148
+ queue << nil
149
+ end
150
+ end
151
+
152
+ # spawn the sub-tasks
153
+ params[:concurrency].times do
154
+ task.async do
155
+ while (new_domain = queue.dequeue)
156
+ if dns_get_address(new_domain)
157
+ yield Domain.new(new_domain)
158
+ end
159
+ end
160
+ end
161
+ end
162
+ end
163
+ end
164
+
165
+ end
166
+ end
167
+ end
168
+ end
@@ -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/worker'
22
+ require 'ronin/support/network/ip_range'
23
+
24
+ module Ronin
25
+ module Recon
26
+ module Net
27
+ #
28
+ # A recon worker that enumerates every IP address within an IP range.
29
+ #
30
+ class IPRangeEnum < Worker
31
+
32
+ register 'net/ip_range_enum'
33
+
34
+ summary 'Enumerates the IP addresses in an IP range'
35
+
36
+ description <<~DESC
37
+ Enumerates over every IP address in a CIDR IP range.
38
+ DESC
39
+
40
+ accepts IPRange
41
+ outputs IP
42
+ intensity :passive
43
+
44
+ #
45
+ # Enumerates an IP range.
46
+ #
47
+ # @param [Values::IPRange] ip_range
48
+ # The IP range value.
49
+ #
50
+ # @yield [ip]
51
+ # Each IP value within the IP range will be yielded.
52
+ #
53
+ # @yieldparam [Values::IP] ip
54
+ # An IP value.
55
+ #
56
+ def process(ip_range)
57
+ ip_range.range.each do |address|
58
+ yield IP.new(address)
59
+ end
60
+ end
61
+
62
+ end
63
+ end
64
+ end
65
+ end
@@ -0,0 +1,84 @@
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/worker'
22
+
23
+ require 'ronin/nmap'
24
+
25
+ module Ronin
26
+ module Recon
27
+ module Net
28
+ #
29
+ # A recon worker that performs a nmap port scan.
30
+ #
31
+ class PortScan < Worker
32
+
33
+ register 'net/port_scan'
34
+
35
+ summary 'Scans an IP for open ports'
36
+
37
+ description <<~DESC
38
+ Performs a nmap port scan of the given IP and retruns the open
39
+ ports and their services.
40
+ DESC
41
+
42
+ accepts IP
43
+ outputs OpenPort
44
+
45
+ param :ports, String, desc: 'Optional port list to scan'
46
+
47
+ #
48
+ # Performs an nmap port scan on the given IP value.
49
+ #
50
+ # @param [Values::IP] ip
51
+ # The given IP to scan.
52
+ #
53
+ # @yield [new_value]
54
+ # The discovered open ports will be yielded.
55
+ #
56
+ # @yieldparam [Values::OpenPort] new_value
57
+ # A discovered open port.
58
+ #
59
+ def process(ip)
60
+ xml = Nmap.scan(ip.address, verbose: true,
61
+ service_scan: true,
62
+ ports: params[:ports])
63
+
64
+ address = ip.address
65
+ host = ip.host || xml.host.to_s
66
+
67
+ xml.host.open_ports.each do |open_port|
68
+ number = open_port.number
69
+ protocol = open_port.protocol
70
+ service = open_port.service
71
+
72
+ yield OpenPort.new(
73
+ address,number, host: host,
74
+ protocol: protocol,
75
+ service: service && service.name,
76
+ ssl: service && service.ssl?
77
+ )
78
+ end
79
+ end
80
+
81
+ end
82
+ end
83
+ end
84
+ end
@@ -0,0 +1,75 @@
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/worker'
22
+
23
+ module Ronin
24
+ module Recon
25
+ module Net
26
+ #
27
+ # A recon worker that identifies services on open ports.
28
+ #
29
+ class ServiceID < Worker
30
+
31
+ register 'net/service_id'
32
+
33
+ summary 'Identifies services running on open ports'
34
+
35
+ description <<~DESC
36
+ Identifies various services that are running on open ports.
37
+ DESC
38
+
39
+ accepts OpenPort
40
+ outputs Nameserver, Mailserver, Website
41
+ intensity :passive
42
+
43
+ #
44
+ # Identifies the service running on an open port.
45
+ #
46
+ # @param [Values::OpenPort] open_port
47
+ # The given open port.
48
+ #
49
+ # @yield [new_value]
50
+ # The identified service will be yielded.
51
+ #
52
+ # @yieldparam [Values::Nameserver, Values::Mailserver, Values::Website] new_value
53
+ # A discovered nameserver, mailserver, or website.
54
+ #
55
+ def process(open_port)
56
+ case open_port.service
57
+ when 'domain'
58
+ yield Nameserver.new(open_port.host)
59
+ when 'smtp'
60
+ yield Mailserver.new(open_port.host)
61
+ when 'http'
62
+ if open_port.ssl?
63
+ yield Website.https(open_port.host,open_port.number)
64
+ else
65
+ yield Website.http(open_port.host,open_port.number)
66
+ end
67
+ when 'https'
68
+ yield Website.https(open_port.host,open_port.number)
69
+ end
70
+ end
71
+
72
+ end
73
+ end
74
+ end
75
+ end
@@ -0,0 +1,109 @@
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/worker'
22
+ require 'ronin/recon/value/parser'
23
+
24
+ require 'async/io'
25
+
26
+ module Ronin
27
+ module Recon
28
+ module SSL
29
+ #
30
+ # A recon worker that enumerates over the host names within the SSL/TLS
31
+ # certificate.
32
+ #
33
+ class CertEnum < Worker
34
+
35
+ register 'ssl/cert_enum'
36
+
37
+ summary 'Enumerates over the host names within a SSL/TLS certificate'
38
+
39
+ description <<~DESC
40
+ Enumerates over the subject CommonName and subjectAltNames of a
41
+ SSL/TLS certificate.
42
+ DESC
43
+
44
+ accepts Cert
45
+ outputs Domain, Host, Wildcard, EmailAddress
46
+
47
+ #
48
+ # Grabs the TLS certificate from the open port, if it supports SSL/TLS.
49
+ #
50
+ # @param [Values::Cert] cert
51
+ # The SSL/TLS certificate.
52
+ #
53
+ # @yield [name]
54
+ # All host names, wildcard host names, IP addresses, or email
55
+ # addresses, from the SSL/TLS certificate will be yielded.
56
+ #
57
+ # @yieldparam [Values::Host, Values::Wildcard, Values::IP, Values::EmailAddress] name
58
+ # A host name, wildcard host name, IP address, or email address from
59
+ # the certificate.
60
+ #
61
+ def process(cert)
62
+ subject_entries = cert.subject.to_a
63
+ subject_entries.each do |entry|
64
+ case entry[0]
65
+ when 'CN' # Common Name
66
+ case entry[1]
67
+ when Value::Parser::DOMAIN_REGEX
68
+ yield Domain.new(entry[1])
69
+ when Value::Parser::HOSTNAME_REGEX
70
+ yield Host.new(entry[1])
71
+ end
72
+ when 'emailAddress'
73
+ yield EmailAddress.new(entry[1])
74
+ end
75
+ end
76
+
77
+ subject_alt_names = cert.extensions.find do |ext|
78
+ ext.oid == 'subjectAltName'
79
+ end
80
+
81
+ if subject_alt_names
82
+ values = subject_alt_names.value.split(', ')
83
+
84
+ values.each do |string|
85
+ name, value = string.split(':',2)
86
+
87
+ case name
88
+ when 'DNS'
89
+ case value
90
+ when Value::Parser::DOMAIN_REGEX
91
+ yield Domain.new(value)
92
+ when Value::Parser::HOSTNAME_REGEX
93
+ yield Host.new(value)
94
+ when Value::Parser::WILDCARD_REGEX
95
+ yield Wildcard.new(value)
96
+ end
97
+ when 'IP'
98
+ yield IP.new(value)
99
+ when 'email'
100
+ yield EmailAddress.new(value)
101
+ end
102
+ end
103
+ end
104
+ end
105
+
106
+ end
107
+ end
108
+ end
109
+ end
@@ -0,0 +1,76 @@
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/worker'
22
+
23
+ require 'async/io'
24
+
25
+ module Ronin
26
+ module Recon
27
+ module SSL
28
+ #
29
+ # A recon worker that grabs the SSL/TLS certificate from open ports that
30
+ # use SSL/TLS.
31
+ #
32
+ class CertGrab < Worker
33
+
34
+ register 'ssl/cert_grab'
35
+
36
+ summary 'Fetches the SSL/TLS certificate from an open port'
37
+
38
+ description <<~DESC
39
+ Grabs and decodes the X509 SSL/TLS peer certificate from an open port
40
+ which supports SSL/TLS.
41
+ DESC
42
+
43
+ accepts OpenPort
44
+ outputs Cert
45
+
46
+ #
47
+ # Grabs the TLS certificate from the open port, if it supports SSL/TLS.
48
+ #
49
+ # @param [Values::OpenPort] open_port
50
+ # The open port value to check.
51
+ #
52
+ # @yield [cert]
53
+ # If the open port supports SSL/TLS, then a certificate value will be
54
+ # yielded.
55
+ #
56
+ # @yieldparam [Values::Cert] cert
57
+ # The grabbed certificate value.
58
+ #
59
+ def process(open_port)
60
+ if open_port.ssl?
61
+ address = open_port.address
62
+ port = open_port.number
63
+ endpoint = Async::IO::Endpoint.ssl(address,port)
64
+
65
+ endpoint.connect do |socket|
66
+ peer_cert = socket.peer_cert
67
+
68
+ yield Cert.new(peer_cert)
69
+ end
70
+ end
71
+ end
72
+
73
+ end
74
+ end
75
+ end
76
+ end
@@ -0,0 +1,77 @@
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/worker'
22
+
23
+ require 'async/http/internet/instance'
24
+
25
+ module Ronin
26
+ module Recon
27
+ module SSL
28
+ #
29
+ # A recon worker that returns host from each domains certificate
30
+ #
31
+ class CertSh < Worker
32
+
33
+ register 'ssl/cert_sh'
34
+
35
+ summary 'Queries cert.sh and returns host from each domains certificate.'
36
+
37
+ description <<~DESC
38
+ Queries cert.sh and returns host from each domains certificate.
39
+ DESC
40
+
41
+ accepts Domain
42
+ outputs Host
43
+ intensity :passive
44
+
45
+ #
46
+ # Returns host from each domains certificate.
47
+ #
48
+ # @param [Values::Domain] domain
49
+ # The domain value to check.
50
+ #
51
+ # @yield [host]
52
+ # If the domain has certificates, then a host value will be
53
+ # yielded.
54
+ #
55
+ # @yieldparam [Values::Host] host
56
+ # The host from certificate.
57
+ #
58
+ def process(domain)
59
+ Async do
60
+ internet = Async::HTTP::Internet.instance
61
+ path = "https://crt.sh/?dNSName=#{domain}&exclude=expired&output=json"
62
+
63
+ response = internet.get(path)
64
+ certs = JSON.parse(response.read, symbolize_names: true)
65
+
66
+ certs.each do |cert|
67
+ if (common_name = cert[:common_name])
68
+ yield Host.new(common_name)
69
+ end
70
+ end
71
+ end
72
+ end
73
+
74
+ end
75
+ end
76
+ end
77
+ end