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,420 @@
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/cli/command'
22
+ require 'ronin/recon/cli/debug_option'
23
+ require 'ronin/recon/cli/printing'
24
+ require 'ronin/recon/value/parser'
25
+ require 'ronin/recon/registry'
26
+ require 'ronin/recon/engine'
27
+ require 'ronin/recon/output_formats'
28
+
29
+ require 'ronin/db/cli/database_options'
30
+ require 'ronin/core/cli/logging'
31
+
32
+ module Ronin
33
+ module Recon
34
+ class CLI
35
+ module Commands
36
+ #
37
+ # Runs the recon engine with one or more initial values.
38
+ #
39
+ # ## Usage
40
+ #
41
+ # ronin-recon run [options] {IP | IP-range | DOMAIN | HOST | WILDCARD | WEBSITE} ...
42
+ #
43
+ # ## Options
44
+ #
45
+ # -D, --debug Enable debugging output
46
+ # -C, --config-file FILE Loads the configuration file
47
+ # -w, --worker WORKER Explicitly uses a worker
48
+ # -e, --enable WORKER Enables a worker
49
+ # -d, --disable WORKER Disables a worker
50
+ # --worker-file FILE Loads a worker from a file
51
+ # -p, --param WORKER.NAME=VALUE Sets a param for a worker
52
+ # -c, --concurrency WORKER=NUM Sets the concurrency of a worker
53
+ # --max-depth NUM The maximum recon depth (Default: 3)
54
+ # -o, --output FILE The output file to write results to
55
+ # -I, --ignore VALUE The values to ignore in result
56
+ # -F txt|list|csv|json|ndjson|dot|svg|png|pdf,
57
+ # --output-format The output format
58
+ # --import Imports each newly discovered value into the Ronin database
59
+ # -h, --help Print help information
60
+ #
61
+ # ## Arguments
62
+ #
63
+ # IP|IP-range|DOMAIN|HOST|WILDCARD|WEBSITE An initial recon value.
64
+ #
65
+ class Run < Command
66
+
67
+ include DebugOption
68
+ include Printing
69
+ include Core::CLI::Logging
70
+ include DB::CLI::DatabaseOptions
71
+
72
+ usage '[options] {IP | IP-range | DOMAIN | HOST | WILDCARD | WEBSITE} ...'
73
+
74
+ option :config_file, short: '-C',
75
+ value: {
76
+ type: String,
77
+ usage: 'FILE'
78
+ },
79
+ desc: 'Loads the configuration file'
80
+
81
+ option :worker, short: '-w',
82
+ value: {
83
+ type: String,
84
+ usage: 'WORKER'
85
+ },
86
+ desc: 'Explicitly uses a worker' do |worker|
87
+ @only_workers << worker
88
+ end
89
+
90
+ option :enable, short: '-e',
91
+ value: {
92
+ type: String,
93
+ usage: 'WORKER'
94
+ },
95
+ desc: 'Enables a worker' do |worker|
96
+ @enable_workers << worker
97
+ end
98
+
99
+ option :disable, short: '-d',
100
+ value: {
101
+ type: String,
102
+ usage: 'WORKER'
103
+ },
104
+ desc: 'Disables a worker' do |worker|
105
+ @disable_workers << worker
106
+ end
107
+
108
+ option :worker_file, value: {
109
+ type: String,
110
+ usage: 'FILE'
111
+ },
112
+ desc: 'Loads a worker from a file' do |path|
113
+ @worker_files << path
114
+ end
115
+
116
+ option :param, short: '-p',
117
+ value: {
118
+ type: /\A[^\.\=\s]+\.[^=\s]+=.+\z/,
119
+ usage: 'WORKER.NAME=VALUE'
120
+ },
121
+ desc: 'Sets a param for a worker' do |str|
122
+ prefix, value = str.split('=',2)
123
+ worker, name = prefix.split('.',2)
124
+
125
+ @worker_params[worker][name.to_sym] = value
126
+ end
127
+
128
+ option :concurrency, short: '-c',
129
+ value: {
130
+ type: /\A[^\.\=\s]+=\d+\z/,
131
+ usage: 'WORKER=NUM'
132
+ },
133
+ desc: 'Sets the concurrency of a worker' do |str|
134
+ worker, concurrency = str.split('=',2)
135
+
136
+ @worker_concurrency[worker] = concurrency.to_i
137
+ end
138
+
139
+ option :intensity, value: {
140
+ type: [:passive, :active, :aggressive]
141
+ },
142
+ desc: 'Filter workers by intensity'
143
+
144
+ option :max_depth, value: {
145
+ type: Integer,
146
+ usage: 'NUM',
147
+ default: 3
148
+ },
149
+ desc: 'The maximum recon depth'
150
+
151
+ option :output, short: '-o',
152
+ value: {
153
+ type: String,
154
+ usage: 'FILE'
155
+ },
156
+ desc: 'The output file to write results to' do |path|
157
+ options[:output] = path
158
+ options[:output_format] ||= OutputFormats.infer_from(path)
159
+ end
160
+
161
+ option :output_format, short: '-F',
162
+ value: {
163
+ type: OutputFormats.formats
164
+ },
165
+ desc: 'The output format'
166
+
167
+ option :import, desc: 'Imports each newly discovered value into the Ronin database'
168
+
169
+ option :ignore, short: '-I',
170
+ value: {
171
+ type: String,
172
+ usage: 'IP|IP-range|DOMAIN|HOST|WILDCARD|WEBSITE'
173
+ },
174
+ desc: 'The value to ignore in the result' do |value|
175
+ @ignore << Value.parse(value)
176
+ end
177
+
178
+ argument :value, required: true,
179
+ repeats: true,
180
+ usage: 'IP|IP-range|DOMAIN|HOST|WILDCARD|WEBSITE',
181
+ desc: 'An initial recon value'
182
+
183
+ description 'Runs the recon engine with one or more initial values'
184
+
185
+ man_page 'ronin-recon-run.1'
186
+
187
+ # Explicit set of workers to only use.
188
+ #
189
+ # @return [Set<String>]
190
+ attr_reader :only_workers
191
+
192
+ # Additional set of workers to enable.
193
+ #
194
+ # @return [Set<String>]
195
+ attr_reader :enable_workers
196
+
197
+ # Additional set of workers to disable.
198
+ #
199
+ # @return [Set<String>]
200
+ attr_reader :disable_workers
201
+
202
+ # Additional set of worker files to load.
203
+ #
204
+ # @return [Set<String>]
205
+ attr_reader :worker_files
206
+
207
+ # The loaded configuration for the {Engine}.
208
+ #
209
+ # @return [Config]
210
+ attr_reader :config
211
+
212
+ # The loaded workers for the {Engine}.
213
+ #
214
+ # @return [Workers]
215
+ attr_reader :workers
216
+
217
+ # The params for the workers.
218
+ #
219
+ # @return [Hash{String => Hash{String => String}}]
220
+ attr_reader :worker_params
221
+
222
+ # The concurrency for the workers.
223
+ #
224
+ # @return [Hash{String => Integer}]
225
+ attr_reader :worker_concurrency
226
+
227
+ # The values that are out of scope.
228
+ #
229
+ # @return [Array<Values::Value>]
230
+ attr_reader :ignore
231
+
232
+ #
233
+ # Initializes the `ronin-recon run` command.
234
+ #
235
+ # @param [Hash{Symbol => Object}] kwargs
236
+ # Additional keyword arguments.
237
+ #
238
+ def initialize(**kwargs)
239
+ super(**kwargs)
240
+
241
+ @only_workers = Set.new
242
+ @enable_workers = Set.new
243
+ @disable_workers = Set.new
244
+ @worker_files = Set.new
245
+
246
+ @worker_params = Hash.new { |hash,key| hash[key] = {} }
247
+ @worker_concurrency = {}
248
+
249
+ @ignore = []
250
+ end
251
+
252
+ #
253
+ # Runs the `ronin-recon run` command.
254
+ #
255
+ # @param [Array<String>] values
256
+ # The initial recon values.
257
+ #
258
+ def run(*values)
259
+ load_config
260
+ load_workers
261
+
262
+ values = values.map { |value| parse_value(value) }
263
+
264
+ output_file = if options[:output] && options[:output_format]
265
+ options[:output_format].open(options[:output])
266
+ end
267
+
268
+ if options[:import]
269
+ require 'ronin/db'
270
+ require 'ronin/recon/importer'
271
+ db_connect
272
+ end
273
+
274
+ begin
275
+ Engine.run(values, config: @config,
276
+ workers: @workers,
277
+ max_depth: options[:max_depth],
278
+ ignore: @ignore) do |engine|
279
+ engine.on(:value) do |value,parent|
280
+ print_value(value,parent)
281
+ end
282
+
283
+ if output_file
284
+ engine.on(:value) do |value|
285
+ output_file << value
286
+ end
287
+
288
+ if output_file.kind_of?(OutputFormats::GraphFormat)
289
+ engine.on(:connection) do |value,parent|
290
+ output_file[value] = parent
291
+ end
292
+ end
293
+ end
294
+
295
+ if options[:import]
296
+ engine.on(:connection) do |value,parent|
297
+ import_connection(value,parent)
298
+ end
299
+ end
300
+
301
+ engine.on(:job_failed) do |worker,value,exception|
302
+ log_error "[#{worker.id}] job failed for value #{value}:"
303
+ log_error " #{exception.class}: #{exception.message}"
304
+
305
+ exception.backtrace.each do |line|
306
+ log_error " #{line}"
307
+ end
308
+ end
309
+ end
310
+ ensure
311
+ output_file.close if options[:output]
312
+ end
313
+ end
314
+
315
+ #
316
+ # Parses the value string.
317
+ #
318
+ # @param [String] value
319
+ # The value to parse.
320
+ #
321
+ # @return [Values::Value]
322
+ # The parsed value.
323
+ #
324
+ def parse_value(value)
325
+ Value.parse(value)
326
+ rescue UnknownValue => error
327
+ print_error(error.message)
328
+ print_error("value must be an IP address, CIDR IP-range, domain, sub-domain, wildcard hostname, or website base URL")
329
+ exit(-1)
330
+ end
331
+
332
+ #
333
+ # Loads the recon configuration file from either
334
+ # the `--config-file` option or `~/.config/ronin-recon/config.yml`.
335
+ #
336
+ def load_config
337
+ @config = if (path = options[:config_file])
338
+ Config.load(path)
339
+ else
340
+ Config.default
341
+ end
342
+
343
+ unless @only_workers.empty?
344
+ @config.workers = @only_workers
345
+ end
346
+
347
+ @enable_workers.each do |worker_id|
348
+ @config.workers.add(worker_id)
349
+ end
350
+
351
+ @disable_workers.each do |worker_id|
352
+ @config.workers.delete(worker_id)
353
+ end
354
+
355
+ @worker_params.each do |worker,params|
356
+ if @config.params.has_key?(params)
357
+ @config.params[worker].merge!(params)
358
+ else
359
+ @config.params[worker] = params
360
+ end
361
+ end
362
+
363
+ @worker_concurrency.each do |worker,concurrency|
364
+ @config.concurrency[worker] = concurrency
365
+ end
366
+ end
367
+
368
+ #
369
+ # Loads the worker classes from the {Config#workers}, as well as
370
+ # additional workers loaded by `--load-worker`.
371
+ #
372
+ # @note
373
+ # If the `--intensity` option is given, then the workers will be
374
+ # filtered by intensity.
375
+ #
376
+ def load_workers
377
+ @workers = Ronin::Recon::Workers.load(@config.workers)
378
+
379
+ unless @worker_files.empty?
380
+ @worker_files.each do |path|
381
+ @workers.load_file(path)
382
+ end
383
+ end
384
+
385
+ if (level = options[:intensity])
386
+ @workers = @workers.intensity(level)
387
+ end
388
+ rescue Ronin::Recon::ClassNotFound => error
389
+ print_error(error.message)
390
+ exit(1)
391
+ end
392
+
393
+ #
394
+ # Imports a discovered value into ronin-db.
395
+ #
396
+ # @param [Values::Value] value
397
+ # A discovered recon value to import.
398
+ #
399
+ def import_value(value)
400
+ Importer.import_value(value)
401
+ end
402
+
403
+ #
404
+ # Imports a connection between two values into ronin-db.
405
+ #
406
+ # @param [Values::Value] value
407
+ # A discovered recon value to import.
408
+ #
409
+ # @param [Values::Value] parent
410
+ # The parent value of the discovered recon value.
411
+ #
412
+ def import_connection(value,parent)
413
+ Importer.import_connection(value,parent)
414
+ end
415
+
416
+ end
417
+ end
418
+ end
419
+ end
420
+ end
@@ -0,0 +1,99 @@
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/cli/worker_command'
22
+ require 'ronin/recon/cli/debug_option'
23
+ require 'ronin/recon/cli/printing'
24
+ require 'ronin/recon/value/parser'
25
+
26
+ require 'ronin/core/cli/options/param'
27
+ require 'ronin/core/cli/logging'
28
+
29
+ module Ronin
30
+ module Recon
31
+ class CLI
32
+ module Commands
33
+ #
34
+ # Loads an individual worker and tests it.
35
+ #
36
+ # ## Usage
37
+ #
38
+ # ronin-recon test [options] {--file FILE | NAME} {IP | IP-range | DOMAIN | HOST | WILDCARD | WEBSITE}
39
+ #
40
+ # ## Options
41
+ #
42
+ # -f, --file FILE The recon worker file to load
43
+ # -D, --debug Enable debugging output
44
+ # -h, --help Print help information
45
+ #
46
+ # ## Arguments
47
+ #
48
+ # IP|IP-range|DOMAIN|HOST|WILDCARD|WEBSITE An initial recon value.
49
+ #
50
+ class Test < WorkerCommand
51
+
52
+ include DebugOption
53
+ include Printing
54
+ include Core::CLI::Logging
55
+ include Core::CLI::Options::Param
56
+
57
+ usage '[options] {IP | IP-range | DOMAIN | HOST | WILDCARD | WEBSITE}'
58
+
59
+ argument :value, required: true,
60
+ usage: 'IP|IP-range|DOMAIN|HOST|WILDCARD|WEBSITE',
61
+ desc: 'The initial recon value'
62
+
63
+ description 'Loads an individual worker and tests it'
64
+
65
+ man_page 'ronin-recon-test.1'
66
+
67
+ #
68
+ # Runs the `ronin-recon test` command.
69
+ #
70
+ # @param [String, nil] name
71
+ # The optional worker name to load and print metadata for.
72
+ #
73
+ def run(name=nil,value)
74
+ super(name)
75
+
76
+ value = begin
77
+ Value.parse(value)
78
+ rescue UnknownValue => error
79
+ print_error(error.message)
80
+ print_error("must be a #{worker_class.accepts.map(&method(:value_class_name)).join(', ')} value")
81
+ exit(-1)
82
+ end
83
+
84
+ unless worker_class.accepts.include?(value.class)
85
+ print_error "worker #{worker_class.id.inspect} does not accept #{value_class_name(value.class)} values"
86
+ print_error "must be a #{worker_class.accepts.map(&method(:value_class_name)).join(', ')} value"
87
+ exit(1)
88
+ end
89
+
90
+ worker_class.run(value, params: params) do |new_value|
91
+ print_value(new_value)
92
+ end
93
+ end
94
+
95
+ end
96
+ end
97
+ end
98
+ end
99
+ end
@@ -0,0 +1,114 @@
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/cli/worker_command'
22
+ require 'ronin/recon/cli/printing'
23
+ require 'ronin/core/cli/printing/metadata'
24
+ require 'ronin/core/cli/printing/params'
25
+
26
+ require 'command_kit/printing/lists'
27
+
28
+ module Ronin
29
+ module Recon
30
+ class CLI
31
+ module Commands
32
+ #
33
+ # Prints information about a recon worker.
34
+ #
35
+ # ## Usage
36
+ #
37
+ # ronin-recon worker [options] {--file FILE | NAME}
38
+ #
39
+ # ## Options
40
+ #
41
+ # -f, --file FILE The recon worker file to load
42
+ # -v, --verbose Enables verbose output
43
+ # -h, --help Print help information
44
+ #
45
+ # ## Arguments
46
+ #
47
+ # [NAME] The recon worker to load
48
+ #
49
+ class Worker < WorkerCommand
50
+
51
+ include Printing
52
+ include Core::CLI::Printing::Metadata
53
+ include Core::CLI::Printing::Params
54
+ include CommandKit::Printing::Lists
55
+
56
+ usage '[options] {--file FILE | NAME}'
57
+
58
+ description 'Prints information about a recon worker'
59
+
60
+ man_page 'ronin-recon-worker.1'
61
+
62
+ #
63
+ # Runs the `ronin-recon worker` command.
64
+ #
65
+ # @param [String, nil] name
66
+ # The optional worker name to load and print metadata for.
67
+ #
68
+ def run(name=nil)
69
+ super(name)
70
+
71
+ print_worker(worker_class)
72
+ end
73
+
74
+ #
75
+ # Prints the metadata for a recon worker class.
76
+ #
77
+ # @param [Class<Ronin::Recon::Worker>] worker
78
+ # The worker class to print metadata for.
79
+ #
80
+ def print_worker(worker)
81
+ puts "[ #{worker.id} ]"
82
+ puts
83
+
84
+ indent do
85
+ puts "Summary: #{worker.summary}" if worker.summary
86
+
87
+ print_authors(worker)
88
+ print_description(worker)
89
+
90
+ puts 'Accepts:'
91
+ puts
92
+ indent do
93
+ print_list(worker.accepts.map(&method(:value_class_name)))
94
+ end
95
+ puts
96
+
97
+ puts 'Outputs:'
98
+ puts
99
+ indent do
100
+ print_list(worker.outputs.map(&method(:value_class_name)))
101
+ end
102
+ puts
103
+
104
+ puts "Intensity: #{worker.intensity}"
105
+
106
+ print_params(worker)
107
+ end
108
+ end
109
+
110
+ end
111
+ end
112
+ end
113
+ end
114
+ end