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,112 @@
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/values/wildcard'
22
+ require 'ronin/recon/values/domain'
23
+ require 'ronin/recon/values/host'
24
+ require 'ronin/recon/values/ip_range'
25
+ require 'ronin/recon/values/ip'
26
+
27
+ module Ronin
28
+ module Recon
29
+ #
30
+ # Defines which domains, hosts, IP addresses are considered "in scope".
31
+ #
32
+ # @api private
33
+ #
34
+ class Scope
35
+
36
+ # List of domain or IP range values which are considered "in scope".
37
+ #
38
+ # @return [Array<Values::Domain, Values::Host, Values::IPRange, Values::IP>]
39
+ attr_reader :values
40
+
41
+ # The list of values to ignore and are not considered "in scope".
42
+ #
43
+ # @return [Array<Value>]
44
+ attr_reader :ignore
45
+
46
+ #
47
+ # Initializes the scope.
48
+ #
49
+ # @param [Array<Values::Wildcard, Values::Domain, Values::Host, Values::IPRange, Values::IP>] values
50
+ # The list of "in scope" values.
51
+ #
52
+ # @param [Array<Value>] ignore
53
+ # The recon values to ignore and are not "in scope".
54
+ #
55
+ # @raise [NotImplementedError]
56
+ # An unsupported value object was given.
57
+ #
58
+ def initialize(values, ignore: [])
59
+ @values = values
60
+ @ignore = ignore
61
+
62
+ @host_values = []
63
+ @ip_values = []
64
+
65
+ values.each do |value|
66
+ case value
67
+ when Values::Wildcard, Values::Domain, Values::Host
68
+ @host_values << value
69
+ when Values::IP, Values::IPRange
70
+ @ip_values << value
71
+ else
72
+ raise(NotImplementedError,"scope value type not supported: #{value.inspect}")
73
+ end
74
+ end
75
+ end
76
+
77
+ #
78
+ # Determines if a value is "in scope".
79
+ #
80
+ # @param [Value] value
81
+ # The value to check.
82
+ #
83
+ # @return [Boolean]
84
+ # Indicates whether the value is "in scope" or not.
85
+ # If the given value is not a {Values::Domain Domain},
86
+ # {Values::Host Host}, {Values::IPRange IPRange}, or {Values::IP IP}
87
+ # then `true` is returned by default.
88
+ #
89
+ def include?(value)
90
+ scope_values = case value
91
+ when Values::Wildcard,
92
+ Values::Domain,
93
+ Values::Host,
94
+ Values::URL
95
+ @host_values
96
+ when Values::IP,
97
+ Values::IPRange
98
+ @ip_values
99
+ end
100
+
101
+ return false if @ignore.any? { |ignore| ignore === value }
102
+
103
+ if (scope_values && !scope_values.empty?)
104
+ scope_values.any? { |scope_value| scope_value === value }
105
+ else
106
+ true
107
+ end
108
+ end
109
+
110
+ end
111
+ end
112
+ end
@@ -0,0 +1,113 @@
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/values/host'
22
+ require 'ronin/recon/values/domain'
23
+ require 'ronin/recon/values/wildcard'
24
+ require 'ronin/recon/values/ip'
25
+ require 'ronin/recon/values/ip_range'
26
+ require 'ronin/recon/values/website'
27
+ require 'ronin/recon/exceptions'
28
+
29
+ require 'ronin/support/network/ip'
30
+ require 'ronin/support/network/ip_range'
31
+ require 'ronin/support/text/patterns/network'
32
+ require 'ronin/support/network/public_suffix'
33
+
34
+ require 'ipaddr'
35
+ require 'uri'
36
+
37
+ module Ronin
38
+ module Recon
39
+ #
40
+ # Base class for all {Values} classes.
41
+ #
42
+ class Value
43
+
44
+ #
45
+ # Module that parses strings into {Values::IP}, {Values::IPRange},
46
+ # {Values::Domain}, {Values::Host}, or {Values::Website}.
47
+ #
48
+ module Parser
49
+ # Regular expression to match IPv4 and IPv6 addresses.
50
+ IP_REGEX = Support::Network::IP::REGEX
51
+
52
+ # Regular expression to match IPv4 and IPv6 CIDR ranges.
53
+ IP_RANGE_REGEX = Support::Network::IPRange::REGEX
54
+
55
+ # Regular expression to match sub-domain host-names.
56
+ HOSTNAME_REGEX = /\A(?:[a-zA-Z0-9_-]{1,63}\.)+#{Support::Text::Patterns::DOMAIN}\z/
57
+
58
+ # Regular expression to match domain host-names.
59
+ DOMAIN_REGEX = /\A#{Support::Text::Patterns::DOMAIN}\z/
60
+
61
+ # Regular expression to match wildcard host-names.
62
+ WILDCARD_REGEX = /\A\*(?:\.[a-z0-9_-]+)+\z/
63
+
64
+ # Regular expression to match https:// and http:// website base URLs.
65
+ WEBSITE_REGEX = %r{\Ahttp(?:s)?://[a-zA-Z0-9_-]+(?:\.[a-zA-Z0-9_-]+)*(?::\d+)?/?\z}
66
+
67
+ #
68
+ # Parses a value string.
69
+ #
70
+ # @param [String] string
71
+ # The string to parse.
72
+ #
73
+ # @return [Values::IP, Values::IPRange, Values::Host, Values::Domain, Values::Wildcard, Values::Website]
74
+ # The parsed value.
75
+ #
76
+ # @raise [UnknownValue]
77
+ # Could not identify what value the string represents.
78
+ #
79
+ def self.parse(string)
80
+ case string
81
+ when IP_REGEX then Values::IP.new(string)
82
+ when IP_RANGE_REGEX then Values::IPRange.new(string)
83
+ when WEBSITE_REGEX then Values::Website.parse(string)
84
+ when WILDCARD_REGEX then Values::Wildcard.new(string)
85
+ when HOSTNAME_REGEX then Values::Host.new(string)
86
+ when DOMAIN_REGEX then Values::Domain.new(string)
87
+ else
88
+ raise(UnknownValue,"unrecognized recon value: #{string.inspect}")
89
+ end
90
+ end
91
+ end
92
+
93
+ #
94
+ # Parses a value string.
95
+ #
96
+ # @param [String] string
97
+ # The string to parse.
98
+ #
99
+ # @return [Values::IP, Values::IPRange, Values::Host, Values::Domain, Values::Wildcard, Values::Website]
100
+ # The parsed value.
101
+ #
102
+ # @raise [UnknownValue]
103
+ # Could not identify what value the string represents.
104
+ #
105
+ # @see Parser.parse
106
+ #
107
+ def self.parse(string)
108
+ Parser.parse(string)
109
+ end
110
+
111
+ end
112
+ end
113
+ end
@@ -0,0 +1,110 @@
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 'json'
22
+ require 'csv'
23
+
24
+ module Ronin
25
+ module Recon
26
+ #
27
+ # Base class for all {Values} classes.
28
+ #
29
+ class Value
30
+
31
+ #
32
+ # Returns the type or kind of recon value.
33
+ #
34
+ # @return [Symbol]
35
+ #
36
+ # @note
37
+ # This is used internally to map a recon value class to a printable
38
+ # type.
39
+ #
40
+ # @abstract
41
+ #
42
+ # @api private
43
+ #
44
+ def self.value_type
45
+ raise(NotImplementedError,"#{self}.value_type was not defined")
46
+ end
47
+
48
+ #
49
+ # Compares the value to another value.
50
+ #
51
+ # @param [Object] other
52
+ # The other value.
53
+ #
54
+ # @return [Boolean]
55
+ # Indicates that the value matches the other value.
56
+ #
57
+ def ==(other)
58
+ eql?(other)
59
+ end
60
+
61
+ #
62
+ # Coerces the value into JSON.
63
+ #
64
+ # @return [Hash{Symbol => Object}]
65
+ # The Ruby Hash that will be converted into JSON.
66
+ #
67
+ # @abstract
68
+ #
69
+ def as_json
70
+ raise(NotImplementedError,"#{self.class}#as_json was not implemented")
71
+ end
72
+
73
+ #
74
+ # Converts the value to a String.
75
+ #
76
+ # @return [String]
77
+ # The string value of the value.
78
+ #
79
+ # @abstract
80
+ #
81
+ def to_s
82
+ raise(NotImplementedError,"#{self.class}#to_s was not implemented")
83
+ end
84
+
85
+ #
86
+ # Converts the value into JSON.
87
+ #
88
+ # @param [Array] args
89
+ # Additional arguments for `Hash#to_json`.
90
+ #
91
+ # @return [String]
92
+ # The raw JSON string.
93
+ #
94
+ def to_json(*args)
95
+ as_json.to_json(*args)
96
+ end
97
+
98
+ #
99
+ # Converts the value to a CSV row.
100
+ #
101
+ # @return [String]
102
+ # The CSV row.
103
+ #
104
+ def to_csv
105
+ CSV.generate_line([self.class.value_type,to_s])
106
+ end
107
+
108
+ end
109
+ end
110
+ end
@@ -0,0 +1,87 @@
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
+ module Ronin
22
+ module Recon
23
+ #
24
+ # Represents the status of every value across all queues and workers.
25
+ #
26
+ class ValueStatus
27
+
28
+ attr_reader :values
29
+
30
+ def initialize
31
+ @values = {}
32
+ end
33
+
34
+ #
35
+ # Records that a value was enqueued for the given worker class.
36
+ #
37
+ # @param [Values::Value] value
38
+ #
39
+ # @param [Class<Worker>] worker_class
40
+ #
41
+ def value_enqueued(worker_class,value)
42
+ (@values[value] ||= {})[worker_class] = :enqueued
43
+ end
44
+
45
+ #
46
+ # Records that a worker has dequeued the value and started processing it.
47
+ #
48
+ # @param [Values::Value] value
49
+ #
50
+ # @param [Class<Worker>] worker_class
51
+ #
52
+ def job_started(worker_class,value)
53
+ (@values[value] ||= {})[worker_class] = :working
54
+ end
55
+
56
+ #
57
+ # Records that a worker has completed processing the value.
58
+ #
59
+ # @param [Values::Value] value
60
+ #
61
+ # @param [Class<Worker>] worker_class
62
+ #
63
+ def job_completed(worker_class,value)
64
+ if (worker_statuses = @values[value])
65
+ worker_statuses.delete(worker_class)
66
+
67
+ if worker_statuses.empty?
68
+ @values.delete(value)
69
+ end
70
+ end
71
+ end
72
+
73
+ alias job_failed job_completed
74
+
75
+ #
76
+ # Determines if there are no more values within the queue or being
77
+ # processed by any of the workers.
78
+ #
79
+ # @return [Boolean]
80
+ #
81
+ def empty?
82
+ @values.empty?
83
+ end
84
+
85
+ end
86
+ end
87
+ end
@@ -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/value'
22
+ require 'ronin/support/crypto'
23
+
24
+ module Ronin
25
+ module Recon
26
+ module Values
27
+ #
28
+ # Represents a SSL/TLS certificate.
29
+ #
30
+ class Cert < Value
31
+
32
+ # The certificate object.
33
+ #
34
+ # @return [Ronin::Support::Crypto::Cert]
35
+ #
36
+ # @api private
37
+ attr_reader :cert
38
+
39
+ #
40
+ # Initializes the certificate value.
41
+ #
42
+ # @param [OpenSSL::X509::Certificate] cert
43
+ # The decoded X509 certificate.
44
+ #
45
+ def initialize(cert)
46
+ @cert = Support::Crypto::Cert(cert)
47
+ end
48
+
49
+ #
50
+ # The serial number of the SSL/TLS certificate.
51
+ #
52
+ # @return [OpenSSL::BN]
53
+ #
54
+ def serial
55
+ @cert.serial
56
+ end
57
+
58
+ #
59
+ # When the certificate begins being valid.
60
+ #
61
+ # @return [Time]
62
+ #
63
+ def not_before
64
+ @cert.not_before
65
+ end
66
+
67
+ #
68
+ # When the certificate expires.
69
+ #
70
+ # @return [Time]
71
+ #
72
+ def not_after
73
+ @cert.not_after
74
+ end
75
+
76
+ #
77
+ # The certificate issuer's information.
78
+ #
79
+ # @return [OpenSSL::X509::Name]
80
+ #
81
+ def issuer
82
+ @cert.issuer
83
+ end
84
+
85
+ #
86
+ # The certificate subject's information.
87
+ #
88
+ # @return [OpenSSL::X509::Name]
89
+ #
90
+ def subject
91
+ @cert.subject
92
+ end
93
+
94
+ #
95
+ # Additional certificate extensions.
96
+ #
97
+ # @return [Array<OpenSSL::X509::Extensions>]
98
+ #
99
+ def extensions
100
+ @cert.extensions
101
+ end
102
+
103
+ #
104
+ # Compares the certificate to another value.
105
+ #
106
+ # @param [Object] other
107
+ #
108
+ # @return [Boolean]
109
+ #
110
+ def eql?(other)
111
+ self.class == other.class && serial == other.serial
112
+ end
113
+
114
+ #
115
+ # The "hash" value of the certificate.
116
+ #
117
+ # @return [Integer]
118
+ #
119
+ def hash
120
+ [self.class, @cert.serial].hash
121
+ end
122
+
123
+ #
124
+ # Converts the certificate to a string.
125
+ #
126
+ # @return [String]
127
+ #
128
+ def to_s
129
+ @cert.to_s
130
+ end
131
+
132
+ #
133
+ # Converts the certificate to a hash of attributes
134
+ #
135
+ # @return [Hash{Symbol => Object}]
136
+ #
137
+ def as_json
138
+ {
139
+ serial: @cert.serial,
140
+ not_before: @cert.not_before,
141
+ not_after: @cert.not_after,
142
+ subject: @cert.subject.to_h,
143
+ issuer: @cert.issuer.to_h,
144
+ extensions: @cert.extensions_hash,
145
+ subject_alt_names: @cert.subject_alt_names,
146
+ pem: @cert.to_pem
147
+ }
148
+ end
149
+
150
+ #
151
+ # Returns the type or kind of recon value.
152
+ #
153
+ # @return [:cert]
154
+ #
155
+ # @note
156
+ # This is used internally to map a recon value class to a printable
157
+ # type.
158
+ #
159
+ # @api private
160
+ #
161
+ def self.value_type
162
+ :cert
163
+ end
164
+
165
+ end
166
+ end
167
+ end
168
+ end
@@ -0,0 +1,88 @@
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/values/host'
22
+ require 'ronin/recon/values/ip'
23
+ require 'ronin/recon/values/website'
24
+ require 'ronin/recon/values/url'
25
+
26
+ module Ronin
27
+ module Recon
28
+ module Values
29
+ #
30
+ # Represents a domain name (ex: `example.com`).
31
+ #
32
+ class Domain < Host
33
+
34
+ #
35
+ # Case equality method used for fuzzy matching.
36
+ #
37
+ # @param [Value] other
38
+ # The other value to compare.
39
+ #
40
+ # @return [Boolean]
41
+ # Imdicates whether the other value is either a {Domain} and has the
42
+ # same domain name, or a {Host}, {IP}, {Website}, {URL} with the same
43
+ # domain name.
44
+ #
45
+ def ===(other)
46
+ case other
47
+ when Domain
48
+ @name == other.name
49
+ when Host
50
+ other.name.end_with?(".#{@name}")
51
+ when IP, Website, URL
52
+ if (other_host = other.host)
53
+ other_host == @name || other_host.end_with?(".#{@name}")
54
+ end
55
+ else
56
+ false
57
+ end
58
+ end
59
+
60
+ #
61
+ # Coerces the domain value into JSON.
62
+ #
63
+ # @return [Hash{Symbol => Object}]
64
+ # The Ruby Hash that will be converted into JSON.
65
+ #
66
+ def as_json
67
+ {type: :domain, name: @name}
68
+ end
69
+
70
+ #
71
+ # Returns the type or kind of recon value.
72
+ #
73
+ # @return [:domain]
74
+ #
75
+ # @note
76
+ # This is used internally to map a recon value class to a printable
77
+ # type.
78
+ #
79
+ # @api private
80
+ #
81
+ def self.value_type
82
+ :domain
83
+ end
84
+
85
+ end
86
+ end
87
+ end
88
+ end