ronin-web 1.0.2 → 2.0.0.rc1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (91) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ruby.yml +3 -2
  3. data/.gitignore +1 -0
  4. data/.rubocop.yml +5 -0
  5. data/ChangeLog.md +46 -1
  6. data/Gemfile +25 -12
  7. data/README.md +257 -51
  8. data/Rakefile +9 -0
  9. data/data/completions/ronin-web +203 -0
  10. data/gemspec.yml +18 -5
  11. data/lib/ronin/web/cli/browser_options.rb +92 -0
  12. data/lib/ronin/web/cli/browser_shell.rb +448 -0
  13. data/lib/ronin/web/cli/command.rb +1 -1
  14. data/lib/ronin/web/cli/commands/browser.rb +373 -0
  15. data/lib/ronin/web/cli/commands/completion.rb +63 -0
  16. data/lib/ronin/web/cli/commands/diff.rb +60 -8
  17. data/lib/ronin/web/cli/commands/html.rb +21 -33
  18. data/lib/ronin/web/cli/commands/irb.rb +1 -1
  19. data/lib/ronin/web/cli/commands/new/{webapp.rb → app.rb} +8 -8
  20. data/lib/ronin/web/cli/commands/new/nokogiri.rb +4 -4
  21. data/lib/ronin/web/cli/commands/new/server.rb +1 -1
  22. data/lib/ronin/web/cli/commands/new/spider.rb +1 -1
  23. data/lib/ronin/web/cli/commands/new.rb +5 -3
  24. data/lib/ronin/web/cli/commands/reverse_proxy.rb +1 -1
  25. data/lib/ronin/web/cli/commands/screenshot.rb +186 -0
  26. data/lib/ronin/web/cli/commands/server.rb +1 -1
  27. data/lib/ronin/web/cli/commands/session_cookie.rb +265 -0
  28. data/lib/ronin/web/cli/commands/spider.rb +61 -467
  29. data/lib/ronin/web/cli/commands/user_agent.rb +177 -0
  30. data/lib/ronin/web/cli/commands/vulns.rb +463 -0
  31. data/lib/ronin/web/cli/commands/wordlist.rb +484 -0
  32. data/lib/ronin/web/cli/commands/xml.rb +149 -0
  33. data/lib/ronin/web/cli/js_shell.rb +69 -0
  34. data/lib/ronin/web/cli/ruby_shell.rb +1 -1
  35. data/lib/ronin/web/cli/spider_options.rb +919 -0
  36. data/lib/ronin/web/cli.rb +3 -1
  37. data/lib/ronin/web/html.rb +1 -1
  38. data/lib/ronin/web/root.rb +1 -1
  39. data/lib/ronin/web/version.rb +2 -2
  40. data/lib/ronin/web/xml.rb +1 -1
  41. data/lib/ronin/web.rb +4 -364
  42. data/man/ronin-web-browser.1 +92 -0
  43. data/man/ronin-web-browser.1.md +96 -0
  44. data/man/ronin-web-completion.1 +76 -0
  45. data/man/ronin-web-completion.1.md +78 -0
  46. data/man/ronin-web-diff.1 +14 -21
  47. data/man/ronin-web-diff.1.md +13 -6
  48. data/man/ronin-web-html.1 +30 -46
  49. data/man/ronin-web-html.1.md +27 -17
  50. data/man/ronin-web-irb.1 +9 -16
  51. data/man/ronin-web-irb.1.md +6 -2
  52. data/man/ronin-web-new-app.1.md +39 -0
  53. data/man/ronin-web-new-nokogiri.1 +9 -20
  54. data/man/ronin-web-new-nokogiri.1.md +5 -5
  55. data/man/ronin-web-new-server.1 +11 -23
  56. data/man/ronin-web-new-server.1.md +5 -5
  57. data/man/ronin-web-new-spider.1 +44 -88
  58. data/man/ronin-web-new-spider.1.md +37 -37
  59. data/man/ronin-web-new.1 +18 -30
  60. data/man/ronin-web-new.1.md +15 -11
  61. data/man/ronin-web-reverse-proxy.1 +33 -38
  62. data/man/ronin-web-reverse-proxy.1.md +20 -14
  63. data/man/ronin-web-screenshot.1 +56 -0
  64. data/man/ronin-web-screenshot.1.md +56 -0
  65. data/man/ronin-web-server.1 +15 -29
  66. data/man/ronin-web-server.1.md +13 -9
  67. data/man/ronin-web-session-cookie.1 +38 -0
  68. data/man/ronin-web-session-cookie.1.md +41 -0
  69. data/man/ronin-web-spider.1 +121 -130
  70. data/man/ronin-web-spider.1.md +115 -66
  71. data/man/ronin-web-user-agent.1 +44 -0
  72. data/man/ronin-web-user-agent.1.md +46 -0
  73. data/man/ronin-web-vulns.1 +175 -0
  74. data/man/ronin-web-vulns.1.md +177 -0
  75. data/man/ronin-web-wordlist.1 +258 -0
  76. data/man/ronin-web-wordlist.1.md +263 -0
  77. data/man/ronin-web-xml.1 +43 -0
  78. data/man/ronin-web-xml.1.md +46 -0
  79. data/man/ronin-web.1 +67 -18
  80. data/man/ronin-web.1.md +55 -4
  81. data/scripts/setup +58 -0
  82. metadata +122 -31
  83. data/lib/ronin/web/mechanize.rb +0 -84
  84. data/man/ronin-web-new-webapp.1.md +0 -39
  85. /data/data/new/{webapp → app}/.gitignore +0 -0
  86. /data/data/new/{webapp → app}/.ruby-version.erb +0 -0
  87. /data/data/new/{webapp → app}/Dockerfile.erb +0 -0
  88. /data/data/new/{webapp → app}/Gemfile +0 -0
  89. /data/data/new/{webapp → app}/app.rb.erb +0 -0
  90. /data/data/new/{webapp → app}/config.ru +0 -0
  91. /data/data/new/{webapp → app}/docker-compose.yml.erb +0 -0
@@ -0,0 +1,373 @@
1
+ # frozen_string_literal: true
2
+ #
3
+ # ronin-web - A collection of useful web helper methods and commands.
4
+ #
5
+ # Copyright (c) 2006-2024 Hal Brodigan (postmodern.mod3 at gmail.com)
6
+ #
7
+ # ronin-web is free software: you can redistribute it and/or modify
8
+ # it under the terms of the GNU General Public License as published by
9
+ # the Free Software Foundation, either version 3 of the License, or
10
+ # (at your option) any later version.
11
+ #
12
+ # ronin-web 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 General Public License for more details.
16
+ #
17
+ # You should have received a copy of the GNU General Public License
18
+ # along with ronin-web. If not, see <https://www.gnu.org/licenses/>.
19
+ #
20
+
21
+ require 'ronin/web/cli/command'
22
+ require 'ronin/web/cli/browser_options'
23
+ require 'ronin/web/cli/browser_shell'
24
+ require 'ronin/web/cli/js_shell'
25
+
26
+ require 'command_kit/colors'
27
+
28
+ module Ronin
29
+ module Web
30
+ class CLI
31
+ module Commands
32
+ #
33
+ # Screenshots one or more URLs.
34
+ #
35
+ # ## Usage
36
+ #
37
+ # ronin-web browser [options] [URL]
38
+ #
39
+ # ## Options
40
+ #
41
+ # -B, --browser NAME|PATH The browser name or path to execute
42
+ # -W, --width WIDTH Sets the width of the browser viewport (Default: 1024)
43
+ # -H, --height HEIGHT Sets the height of the browser viewport (Default: 768)
44
+ # --headless Run the browser in headless mode
45
+ # --visible Open a visible browser
46
+ # -x, --x INT Sets the position of the browser X coordinate
47
+ # -y, --y INT Sets the position of the browser Y coordinate
48
+ # --inject-js JS Injects JavaScript into every page
49
+ # --inject-js-file FILE Injects a JavaScript file into every page
50
+ # --bypass-csp Enables bypassing CSP
51
+ # --print-urls Print all requested URLs
52
+ # --print-status Print the status of all requested URLs
53
+ # --print-requests Print all requests sent by the browser
54
+ # --print-responses Print responses to all requests
55
+ # --print-traffic Print requests and responses
56
+ # --print-headers Print headers of requests/responses
57
+ # --print-body Print request/response bodies
58
+ # --shell Starts an interactive shell
59
+ # --js-shell Starts an interactive JavaScript shell
60
+ # -h, --help Print help information
61
+ #
62
+ # ## Arguments
63
+ #
64
+ # [URL] The initial URL to visit
65
+ #
66
+ # @since 2.0.0
67
+ #
68
+ class Browser < Command
69
+
70
+ include BrowserOptions
71
+ include CommandKit::Colors
72
+
73
+ usage '[options] [URL]'
74
+
75
+ option :headless, desc: 'Run the browser in headless mode' do
76
+ @mode = :headless
77
+ end
78
+
79
+ option :visible, desc: 'Open a visible browser' do
80
+ @mode = :visible
81
+ end
82
+
83
+ option :x, short: '-x',
84
+ value: {
85
+ type: Integer
86
+ },
87
+ desc: "Sets the position of the browser X coordinate"
88
+
89
+ option :y, short: '-y',
90
+ value: {
91
+ type: Integer
92
+ },
93
+ desc: "Sets the position of the browser Y coordinate"
94
+
95
+ option :inject_js, value: {
96
+ type: String,
97
+ usage: 'JS'
98
+ },
99
+ desc: 'Injects JavaScript into every page'
100
+
101
+ option :inject_js_file, value: {
102
+ type: String,
103
+ usage: 'FILE'
104
+ },
105
+ desc: 'Injects a JavaScript file into every page'
106
+
107
+ option :bypass_csp, desc: 'Enables bypassing CSP'
108
+
109
+ option :print_urls, desc: 'Print all requested URLs'
110
+
111
+ option :print_status, desc: 'Print the status of all requested URLs'
112
+
113
+ option :print_requests, desc: 'Print all requests sent by the browser'
114
+
115
+ option :print_responses, desc: 'Print responses to all requests'
116
+
117
+ option :print_traffic, desc: 'Print requests and responses'
118
+
119
+ option :print_headers, desc: 'Print headers of requests/responses'
120
+
121
+ option :print_cookies, desc: 'Print Set-Cookie headers from all responses'
122
+
123
+ option :print_body, desc: 'Print request/response bodies'
124
+
125
+ option :shell, desc: 'Starts an interactive shell'
126
+
127
+ option :js_shell, desc: 'Starts an interactive JavaScript shell'
128
+
129
+ argument :url, required: false,
130
+ desc: 'The initial URL to visit'
131
+
132
+ description "Automates a web browser"
133
+
134
+ man_page 'ronin-web-browser.1'
135
+
136
+ #
137
+ # Initializes the `ronin-web browser` command.
138
+ #
139
+ # @param [Hash{Symbol => Object}] kwargs
140
+ # Additional keywords for the command.
141
+ #
142
+ def initialize(**kwargs)
143
+ super(**kwargs)
144
+
145
+ @mode = if stdout.tty? then :visible
146
+ else :headless
147
+ end
148
+ end
149
+
150
+ #
151
+ # Runs the `ronin-web browser` command.
152
+ #
153
+ # @param [String, nil] url
154
+ # The optional URL to visit.
155
+ #
156
+ def run(url=nil)
157
+ unless (url || options[:shell] || options[:js_shell])
158
+ print_error "must specify a URL or --shell / --js-shell"
159
+ exit(-1)
160
+ end
161
+
162
+ configure_browser
163
+ open_browser(url)
164
+
165
+ if options[:shell] || options[:js_shell]
166
+ start_shell
167
+ else
168
+ wait_until_closed
169
+ end
170
+
171
+ close_browser
172
+ end
173
+
174
+ #
175
+ # Configures the browser and registers callbacks.
176
+ #
177
+ def configure_browser
178
+ if options[:x] || options[:y]
179
+ browser.position = {
180
+ left: options.fetch(:x,0),
181
+ top: options.fetch(:y,0)
182
+ }
183
+ end
184
+
185
+ browser.bypass_csp = true if options[:bypass_csp]
186
+
187
+ if options[:inject_js_file]
188
+ browser.inject_js(File.read(options[:inject_js_file]))
189
+ elsif options[:inject_js]
190
+ browser.inject_js(options[:inject_js])
191
+ end
192
+
193
+ if options[:print_status]
194
+ browser.every_response(&method(:print_url_status))
195
+ elsif options[:print_cookies]
196
+ browser.every_response(&method(:print_cookies))
197
+ elsif options[:print_urls]
198
+ browser.every_url(&method(:puts))
199
+ elsif options[:print_traffic]
200
+ browser.every_request(&method(:print_request))
201
+ browser.every_response(&method(:print_response))
202
+ else
203
+ browser.every_request(&method(:print_request)) if options[:print_requests]
204
+ browser.every_response(&method(:print_response)) if options[:print_responses]
205
+ end
206
+ end
207
+
208
+ #
209
+ # Open the browser window.
210
+ #
211
+ # @param [String, nil] url
212
+ # The optional URL to visit.
213
+ #
214
+ def open_browser(url=nil)
215
+ browser.goto(url) if url
216
+ end
217
+
218
+ #
219
+ # Starts an interactive browser shell.
220
+ #
221
+ def start_shell
222
+ # start the shell then immediately quit the browser once exited
223
+ if options[:js_shell]
224
+ JSShell.start(browser)
225
+ elsif options[:shell]
226
+ BrowserShell.start(browser)
227
+ end
228
+ end
229
+
230
+ #
231
+ # Waits until the browser is done or if the user exits the command.
232
+ #
233
+ def wait_until_closed
234
+ if @mode == :visible
235
+ # wait for the browser window to be closed
236
+ browser.wait_until_closed
237
+ else
238
+ # wait until there's no network traffic
239
+ browser.network.wait_for_idle { browser.quit }
240
+ end
241
+ end
242
+
243
+ #
244
+ # Close the browser.
245
+ #
246
+ def close_browser
247
+ browser.quit
248
+ end
249
+
250
+ #
251
+ # Additional keyword arguments for `Ronin::Web::Browser.new`.
252
+ #
253
+ # @return [Hash{Symbol => Object}]
254
+ #
255
+ def browser_kwargs
256
+ kwargs = super()
257
+
258
+ case @mode
259
+ when :headless then kwargs[:headless] = true
260
+ when :visible then kwargs[:visible] = true
261
+ end
262
+
263
+ return kwargs
264
+ end
265
+
266
+ #
267
+ # Prints the status and URL of a response.
268
+ #
269
+ # @param [Ferrum::Network::Response] response
270
+ # The respones object.
271
+ #
272
+ def print_url_status(response)
273
+ if response.status < 300
274
+ puts "#{colors.bright_green(response.status)} #{colors.green(response.url)}"
275
+ elsif response.status < 400
276
+ puts "#{colors.bright_yellow(response.status)} #{colors.yellow(response.url)}"
277
+ elsif response.status < 500
278
+ puts "#{colors.bright_red(response.status)} #{colors.red(response.url)}"
279
+ else
280
+ puts "#{colors.bold(colors.bright_red(response.status))} #{colors.bold(colors.red(response.url))}"
281
+ end
282
+ end
283
+
284
+ #
285
+ # Prints a request from the browser.
286
+ #
287
+ # @param [Ferrum::Network::InterceptedRequest] request
288
+ #
289
+ def print_request(request)
290
+ sigil = colors.bold(colors.bright_white('>'))
291
+
292
+ puts "#{sigil} #{colors.bold(colors.bright_cyan(request.method))} #{colors.cyan(request.url)}"
293
+
294
+ if options[:print_headers]
295
+ print_headers(sigil,request.headers)
296
+ end
297
+
298
+ if options[:print_body] && (body = request.body)
299
+ print_body(sigil,body)
300
+ end
301
+ end
302
+
303
+ #
304
+ # Prints a response.
305
+ #
306
+ # @param [Ferrum::Network::Response] response
307
+ # The respones object.
308
+ #
309
+ def print_response(response)
310
+ sigil = colors.bold(colors.bright_white('<'))
311
+
312
+ print "#{sigil} "
313
+ print_url_status(response)
314
+
315
+ if options[:print_headers]
316
+ print_headers(sigil,response.headers)
317
+ end
318
+
319
+ if options[:print_body]
320
+ print_body(sigil,response.body)
321
+ end
322
+ end
323
+
324
+ #
325
+ # Prints headers.
326
+ #
327
+ # @param [String] sigil
328
+ # The "sigil" representing either a request (`>`) or
329
+ # a response (`<`).
330
+ #
331
+ # @param [Hash{String => String}] headers
332
+ # The header names and values.
333
+ #
334
+ def print_headers(sigil,headers)
335
+ headers.each do |name,value|
336
+ puts "#{sigil} #{colors.bright_white(name)}: #{value}"
337
+ end
338
+ end
339
+
340
+ #
341
+ # Prints the request or response body.
342
+ #
343
+ # @param [String] sigil
344
+ # The "sigil" representing either a request (`>`) or
345
+ # a response (`<`).
346
+ #
347
+ # @param [String] body
348
+ # the request or response body.
349
+ #
350
+ def print_body(sigil,body)
351
+ puts sigil
352
+ response.body.each_line do |line|
353
+ puts "#{sigil} #{line}"
354
+ end
355
+ end
356
+
357
+ #
358
+ # Prints the `Set-Cookie` header for each HTTP response.
359
+ #
360
+ # @param [Ferrum::Network::Response] response
361
+ # A response from the browser.
362
+ #
363
+ def print_cookies(response)
364
+ if (set_cookie = respones.headers['set-cookie'])
365
+ puts set_cookie
366
+ end
367
+ end
368
+
369
+ end
370
+ end
371
+ end
372
+ end
373
+ end
@@ -0,0 +1,63 @@
1
+ # frozen_string_literal: true
2
+ #
3
+ # ronin-web - A collection of useful web helper methods and commands.
4
+ #
5
+ # Copyright (c) 2006-2024 Hal Brodigan (postmodern.mod3 at gmail.com)
6
+ #
7
+ # ronin-web is free software: you can redistribute it and/or modify
8
+ # it under the terms of the GNU General Public License as published by
9
+ # the Free Software Foundation, either version 3 of the License, or
10
+ # (at your option) any later version.
11
+ #
12
+ # ronin-web 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 General Public License for more details.
16
+ #
17
+ # You should have received a copy of the GNU General Public License
18
+ # along with ronin-web. If not, see <https://www.gnu.org/licenses/>.
19
+ #
20
+
21
+ require 'ronin/web/root'
22
+ require 'ronin/core/cli/completion_command'
23
+
24
+ module Ronin
25
+ module Web
26
+ class CLI
27
+ module Commands
28
+ #
29
+ # Manages the shell completion rules for `ronin-web`.
30
+ #
31
+ # ## Usage
32
+ #
33
+ # ronin-web completion [options]
34
+ #
35
+ # ## Options
36
+ #
37
+ # --print Prints the shell completion file
38
+ # --install Installs the shell completion file
39
+ # --uninstall Uninstalls the shell completion file
40
+ # -h, --help Print help information
41
+ #
42
+ # ## Examples
43
+ #
44
+ # ronin-web completion --print
45
+ # ronin-web completion --install
46
+ # ronin-web completion --uninstall
47
+ #
48
+ # @since 2.0.0
49
+ #
50
+ class Completion < Core::CLI::CompletionCommand
51
+
52
+ completion_file File.join(ROOT,'data','completions','ronin-web')
53
+
54
+ man_dir File.join(ROOT,'man')
55
+ man_page 'ronin-web-completion.1'
56
+
57
+ description 'Manages the shell completion rules for ronin-web'
58
+
59
+ end
60
+ end
61
+ end
62
+ end
63
+ end
@@ -2,7 +2,7 @@
2
2
  #
3
3
  # ronin-web - A collection of useful web helper methods and commands.
4
4
  #
5
- # Copyright (c) 2006-2023 Hal Brodigan (postmodern.mod3 at gmail.com)
5
+ # Copyright (c) 2006-2024 Hal Brodigan (postmodern.mod3 at gmail.com)
6
6
  #
7
7
  # ronin-web is free software: you can redistribute it and/or modify
8
8
  # it under the terms of the GNU General Public License as published by
@@ -21,7 +21,7 @@
21
21
  require 'ronin/web/cli/command'
22
22
  require 'ronin/support/network/http'
23
23
 
24
- require 'command_kit/terminal'
24
+ require 'command_kit/colors'
25
25
  require 'nokogiri/diff'
26
26
 
27
27
  module Ronin
@@ -43,10 +43,11 @@ module Ronin
43
43
  # ## Options
44
44
  #
45
45
  # -h, --help Print help information
46
+ # -f, --format Pass the format of the URL or files. Supported formats are html and xml. (Default: html)
46
47
  #
47
48
  class Diff < Command
48
49
 
49
- include CommandKit::Terminal
50
+ include CommandKit::Colors
50
51
 
51
52
  usage '[options] {URL | FILE} {URL | FILE}'
52
53
 
@@ -58,7 +59,14 @@ module Ronin
58
59
  usage: 'URL | FILE',
59
60
  desc: 'The modified URL or file'
60
61
 
61
- description 'Diffs two web pges'
62
+ option :format, short: '-f',
63
+ value: {
64
+ type: [:html, :xml],
65
+ default: :html
66
+ },
67
+ desc: 'The format of the web pages'
68
+
69
+ description 'Diffs two web pages'
62
70
 
63
71
  man_page 'ronin-web-diff.1'
64
72
 
@@ -72,16 +80,41 @@ module Ronin
72
80
  # The URL or file path of the modified page.
73
81
  #
74
82
  def run(page1,page2)
75
- doc1 = Nokogiri::HTML(read(page1))
76
- doc2 = Nokogiri::HTML(read(page2))
83
+ doc1 = parse_doc(page1)
84
+ doc2 = parse_doc(page2)
77
85
 
78
86
  doc1.diff(doc2) do |change,node|
79
- unless change == ' '
80
- puts "#{change} #{node}"
87
+ unless change == ' ' # ignroe unchanged nodes
88
+ print_change(change,node)
81
89
  end
82
90
  end
83
91
  end
84
92
 
93
+ #
94
+ # Prints a change to the document.
95
+ #
96
+ # @param ["+", "-"] change
97
+ # The type of change.
98
+ #
99
+ # * `+` - indicates an added node.
100
+ # * `-` - indicates a removed node.
101
+ #
102
+ # @param [Nokogiri::HTML::Node, Nokogiri::HTML::Node] node
103
+ # The node that was changed.
104
+ #
105
+ def print_change(change,node)
106
+ color = case change
107
+ when '+' then colors.method(:green)
108
+ when '-' then colors.method(:red)
109
+ end
110
+
111
+ content = node.to_s
112
+
113
+ content.each_line(chomp: true) do |line|
114
+ puts color.call("#{change} #{line}")
115
+ end
116
+ end
117
+
85
118
  #
86
119
  # Reads a web page.
87
120
  #
@@ -100,6 +133,25 @@ module Ronin
100
133
  end
101
134
  end
102
135
 
136
+ #
137
+ # Loads the given html or xml sources
138
+ #
139
+ # @param [String] page
140
+ # The URL or file path of the original page.
141
+ #
142
+ # @return [Nokogiri::HTML::Document, Nokogiri::XML::Document]
143
+ # html or xml document depends upon --format option
144
+ #
145
+ def parse_doc(page)
146
+ case options[:format]
147
+ when :html
148
+ Nokogiri::HTML(read(page))
149
+ when :xml
150
+ Nokogiri::XML(read(page))
151
+ else
152
+ raise(NotImplementedError,"unsupported format: #{options[:format].inspect}")
153
+ end
154
+ end
103
155
  end
104
156
  end
105
157
  end
@@ -2,7 +2,7 @@
2
2
  #
3
3
  # ronin-web - A collection of useful web helper methods and commands.
4
4
  #
5
- # Copyright (c) 2006-2023 Hal Brodigan (postmodern.mod3 at gmail.com)
5
+ # Copyright (c) 2006-2024 Hal Brodigan (postmodern.mod3 at gmail.com)
6
6
  #
7
7
  # ronin-web is free software: you can redistribute it and/or modify
8
8
  # it under the terms of the GNU General Public License as published by
@@ -18,7 +18,7 @@
18
18
  # along with ronin-web. If not, see <https://www.gnu.org/licenses/>.
19
19
  #
20
20
 
21
- require 'ronin/web/cli/command'
21
+ require 'ronin/web/cli/commands/xml'
22
22
  require 'ronin/support/network/http'
23
23
 
24
24
  require 'nokogiri'
@@ -38,6 +38,7 @@ module Ronin
38
38
  #
39
39
  # -X, --xpath XPATH XPath query
40
40
  # -C, --css-path CSSPath CSS-path query
41
+ # -t, --text Prints the inner-text
41
42
  # -M, --meta-tags Searches for all <meta ...> tags
42
43
  # -l, --links Searches for all <a href="..."> URLs
43
44
  # -S, --style Dumps all <style> tags
@@ -54,18 +55,15 @@ module Ronin
54
55
  # URL | FILE The URL or FILE to search
55
56
  # [XPATH | CSS-path] The XPath or CSS-path query
56
57
  #
57
- class Html < Command
58
+ class Html < Xml
58
59
 
59
60
  usage '[options] {URL | FILE} [XPATH | CSS-path]'
60
61
 
61
- option :xpath, short: '-X',
62
- value: {type: String, usage: 'XPATH'},
63
- desc: 'XPath query' do |xpath|
64
- @query = xpath
65
- end
66
-
67
62
  option :css_path, short: '-C',
68
- value: {type: String, usage: 'CSSPath'},
63
+ value: {
64
+ type: String,
65
+ usage: 'CSSPath'
66
+ },
69
67
  desc: 'CSS-path query' do |css_path|
70
68
  @query = css_path
71
69
  end
@@ -110,9 +108,6 @@ module Ronin
110
108
  @query = '//a/@href | //link/@href | //script/@src | //form/@action'
111
109
  end
112
110
 
113
- option :first, short: '-F',
114
- desc: 'Only print the first match'
115
-
116
111
  argument :source, required: true,
117
112
  usage: 'URL | FILE',
118
113
  desc: 'The URL or FILE to search'
@@ -125,6 +120,11 @@ module Ronin
125
120
 
126
121
  man_page 'ronin-web-html.1'
127
122
 
123
+ # The XPath or CSS-path query.
124
+ #
125
+ # @return [String, nil]
126
+ attr_reader :query
127
+
128
128
  #
129
129
  # Runs the `ronin-web xpath` command.
130
130
  #
@@ -140,32 +140,20 @@ module Ronin
140
140
  exit(-1)
141
141
  end
142
142
 
143
- doc = Nokogiri::HTML(read(source))
144
- nodes = if options[:first] then [doc.at(query)]
145
- else doc.search(query)
146
- end
147
-
148
- nodes.each do |node|
149
- puts node
150
- end
143
+ super(source,query)
151
144
  end
152
145
 
153
146
  #
154
- # Reads a URI or file.
147
+ # Parses the HTML source code.
155
148
  #
156
- # @param [String] source
157
- # The URI or file path.
149
+ # @param [String] html
150
+ # The raw unparsed HTML.
158
151
  #
159
- # @return [File, String]
160
- # The contents of the URI or file.
152
+ # @return [Nokogiri::HTML::Document]
153
+ # The parsed HTML document.
161
154
  #
162
- def read(source)
163
- if source.start_with?('https://') ||
164
- source.start_with?('http://')
165
- Support::Network::HTTP.get_body(source)
166
- else
167
- File.new(source)
168
- end
155
+ def parse(html)
156
+ Nokogiri::HTML(html)
169
157
  end
170
158
 
171
159
  end
@@ -2,7 +2,7 @@
2
2
  #
3
3
  # ronin-web - A collection of useful web helper methods and commands.
4
4
  #
5
- # Copyright (c) 2006-2023 Hal Brodigan (postmodern.mod3 at gmail.com)
5
+ # Copyright (c) 2006-2024 Hal Brodigan (postmodern.mod3 at gmail.com)
6
6
  #
7
7
  # ronin-web is free software: you can redistribute it and/or modify
8
8
  # it under the terms of the GNU General Public License as published by