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,448 @@
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/core/cli/command_shell'
22
+ require 'ronin/web/cli/js_shell'
23
+ require 'ronin/web/browser'
24
+
25
+ module Ronin
26
+ module Web
27
+ class CLI
28
+ #
29
+ # The interactive browser shell used by the `ronin-web browser --shell`
30
+ # command.
31
+ #
32
+ class BrowserShell < Core::CLI::CommandShell
33
+
34
+ shell_name 'browser'
35
+
36
+ # The browser instance.
37
+ #
38
+ # @return [Ronin::Web::Browser::Agent]
39
+ attr_reader :browser
40
+
41
+ #
42
+ # Initializes the browser shell.
43
+ #
44
+ # @param [Ronin::Web::Browser::Agent] browser
45
+ # The browser instance.
46
+ #
47
+ # @param [Hash{Symbol => Object}] kwargs
48
+ # Additional keyword arguments for the shell.
49
+ #
50
+ def initialize(browser,**kwargs)
51
+ super(**kwargs)
52
+
53
+ @browser = browser
54
+ end
55
+
56
+ command :goto, usage: 'URL',
57
+ summary: 'Visits a URL'
58
+
59
+ #
60
+ # The `goto` command.
61
+ #
62
+ # @param [String] url
63
+ # The URL to visit.
64
+ #
65
+ def goto(url)
66
+ @browser.goto(url)
67
+ end
68
+
69
+ command :back, summary: 'Goes to the previous URL'
70
+
71
+ #
72
+ # The `back` command.
73
+ #
74
+ def back
75
+ @browser.back
76
+ end
77
+
78
+ command :foreward, summary: 'Goes to the next URL'
79
+
80
+ #
81
+ # The `foreward` command.
82
+ #
83
+ def foreward
84
+ @browser.foreward
85
+ end
86
+
87
+ command :foreward, summary: 'Refreshes the browser window'
88
+
89
+ #
90
+ # The `refresh` command.
91
+ #
92
+ def refresh
93
+ @browser.refresh
94
+ end
95
+
96
+ command :pos, usage: 'X Y',
97
+ summary: "Set the browser window's position"
98
+
99
+ #
100
+ # The `pos` command.
101
+ #
102
+ # @param [String] x
103
+ # The X coordinate.
104
+ #
105
+ # @param [String] y
106
+ # The Y coordinate.
107
+ #
108
+ def pos(x,y)
109
+ @browser.position = {left: x.to_i, top: y.to_i}
110
+ end
111
+
112
+ command :xpath, usage: 'XPATH',
113
+ summary: "Queries the browser's DOM using the XPath"
114
+
115
+ #
116
+ # The `xpath` command.
117
+ #
118
+ # @param [String] xpath
119
+ # The XPath expression.
120
+ #
121
+ def xpath(xpath)
122
+ puts @browser.xpath(xpath)
123
+ end
124
+
125
+ command :at_xpath, usage: 'XPATH',
126
+ summary: "Queries the browser's DOM using the XPath"
127
+
128
+ #
129
+ # The `at_xpath` command.
130
+ #
131
+ # @param [String] xpath
132
+ # The XPath expression.
133
+ #
134
+ def at_xpath(xpath)
135
+ puts @browser.at_xpath(xpath)
136
+ end
137
+
138
+ command :css, usage: 'CSSPath',
139
+ summary: "Queries the browser's DOM using the CSSPath"
140
+
141
+ #
142
+ # The `css` path command.
143
+ #
144
+ # @param [String] css_path
145
+ # The CSS path expression.
146
+ #
147
+ def css(css_path)
148
+ puts @browser.css(css_path)
149
+ end
150
+
151
+ command :at_css, usage: 'CSSPath',
152
+ summary: "Queries the browser's DOM using the CSSPath"
153
+
154
+ #
155
+ # The `at_css` command.
156
+ #
157
+ # @param [String] css_path
158
+ # The CSS path expression.
159
+ #
160
+ def at_css(css_path)
161
+ puts @browser.at_css(css_path)
162
+ end
163
+
164
+ command :eval_js, usage: 'JAVASCRIPT',
165
+ summary: "Evaluates some JavaScript in the browser's window"
166
+
167
+ #
168
+ # The `eval_js` command.
169
+ #
170
+ # @param [String] javascript
171
+ # The JavaScript source code to inject.
172
+ #
173
+ def eval_js(javascript)
174
+ p @browser.eval_js(javascript)
175
+ end
176
+
177
+ command :inject_js, usage: 'JAVASCRIPT',
178
+ summary: 'Injects JavaScript into each new page'
179
+
180
+ #
181
+ # The `inject_js` command.
182
+ #
183
+ # @param [String] javascript
184
+ # The JavaScript source code to inject.
185
+ #
186
+ def inject_js(javascript)
187
+ @browser.evaluate_on_new_document(javascript)
188
+ end
189
+
190
+ command :load_js, usage: 'URL|JS',
191
+ summary: 'Adds a <script> tag to the page'
192
+
193
+ #
194
+ # The `load_js` command.
195
+ #
196
+ # @param [String] url_or_js
197
+ # The URL or JavaScript code to load.
198
+ #
199
+ def load_js(url_or_js)
200
+ if url_or_js.start_with('http://') ||
201
+ url_or_js.start_with('https://')
202
+ @browser.load_js(url: url_or_js)
203
+ else
204
+ @browser.load_js(content: url_or_js)
205
+ end
206
+ end
207
+
208
+ command :js, summary: 'Starts an interactive JavaScript sub-shell'
209
+
210
+ #
211
+ # The `js` command.
212
+ #
213
+ def js
214
+ JSShell.start(@browser)
215
+ end
216
+
217
+ command :load_css, usage: 'URL|CSS',
218
+ summary: 'Adds a <style> tag to the page'
219
+
220
+ #
221
+ # The `load_css` command.
222
+ #
223
+ # @param [String] url_or_css
224
+ # The URL or CSS code to load.
225
+ #
226
+ def load_css(url_or_css)
227
+ if url_or_css.start_with('http://') ||
228
+ url_or_css.start_with('https://')
229
+ @browser.load_css(url: url_or_css)
230
+ else
231
+ @browser.load_css(content: url_or_css)
232
+ end
233
+ end
234
+
235
+ command :bypass_csp, summary: 'Enables bypassing Content-Security-Policy (CSP)'
236
+
237
+ #
238
+ # The `bypass_csp` command.
239
+ #
240
+ def bypass_csp
241
+ @browser.bypass_csp = true
242
+ end
243
+
244
+ command :url, summary: "Prints the browser's current URL"
245
+
246
+ #
247
+ # The `url` command.
248
+ #
249
+ def url
250
+ puts @browser.current_url
251
+ end
252
+
253
+ command :body, summary: "Print's the page body"
254
+
255
+ #
256
+ # The `body` command.
257
+ #
258
+ def body
259
+ puts @browser.body
260
+ end
261
+
262
+ command :screenshot, usage: 'PATH',
263
+ summary: 'Takes a screenshot of the page'
264
+
265
+ #
266
+ # The `screenshot` command.
267
+ #
268
+ # @param [String] path
269
+ # The output path.
270
+ #
271
+ def screenshot(path)
272
+ @browser.screenshot(path: path)
273
+ end
274
+
275
+ command :pdf, usage: 'PATH',
276
+ summary: 'Convert the page into a PDF'
277
+
278
+ #
279
+ # The `pdf` command.
280
+ #
281
+ # @param [String] path
282
+ # The output path.
283
+ #
284
+ def pdf(path)
285
+ @browser.pdf(path: path)
286
+ end
287
+
288
+ command :mhtml, usage: 'PATH',
289
+ summary: 'Save the current page as MHTML'
290
+
291
+ #
292
+ # The `mhtml` command.
293
+ #
294
+ def mhtml(path)
295
+ @browser.mhtml(path: path)
296
+ end
297
+
298
+ command :reset, summary: 'Resets the browser'
299
+
300
+ #
301
+ # The `reset` command.
302
+ #
303
+ def reset
304
+ @browser.reset
305
+ end
306
+
307
+ command :requests, summary: 'Display all requests'
308
+
309
+ #
310
+ # The `requests` command.
311
+ #
312
+ def requests
313
+ puts @browser.network.traffic
314
+ end
315
+
316
+ command :wait, summary: 'Waits until all network requests have been completed'
317
+
318
+ #
319
+ # The `wait` command.
320
+ #
321
+ def wait
322
+ @browser.wait_for_idle
323
+ end
324
+
325
+ command :clear_cache, summary: "Clears the browser's cache"
326
+
327
+ #
328
+ # The `clear_cache` command.
329
+ #
330
+ def clear_cache
331
+ @browser.clear(:cache)
332
+ end
333
+
334
+ command :basic_auth, usage: 'USER PASSWORD',
335
+ summary: 'Configures Basic-Auth credentials'
336
+
337
+ #
338
+ # The `basic_auth` command.
339
+ #
340
+ # @param [String] user
341
+ # The user name.
342
+ #
343
+ # @param [String] password
344
+ # The password.
345
+ #
346
+ def basic_auth(user,password)
347
+ @browser.network.authorize(user: user, password: password, &:continue)
348
+ end
349
+
350
+ command :cookies, summary: 'Prints all cookies'
351
+
352
+ #
353
+ # The `cookies` command.
354
+ #
355
+ def cookies
356
+ print_cookies(@browser.cookies)
357
+ end
358
+
359
+ command :session_cookies, summary: 'Print all session cookies'
360
+
361
+ #
362
+ # The `session_cookies` command.
363
+ #
364
+ def session_cookies
365
+ print_cookies(@browser.each_session_cookie)
366
+ end
367
+
368
+ command :set_cookie, usage: 'NAME=VALUE; [flags...]',
369
+ summary: 'Sets a cookie in the browser'
370
+
371
+ #
372
+ # The `set_cookie` command.
373
+ #
374
+ # @param [Array<String>] args
375
+ #
376
+ def set_cookie(*args)
377
+ if args.empty?
378
+ print_error "must specify at least a NAME=VALUE"
379
+ return false
380
+ end
381
+
382
+ cookie = Web::Browser::Cookie.parse(args.join(' '))
383
+
384
+ @browser.cookies.set(cookie)
385
+ end
386
+
387
+ command :load_cookies, usage: 'FILE',
388
+ summary: 'Loads cookies from the file into the browser'
389
+
390
+ #
391
+ # The `load_cookies` command.
392
+ #
393
+ # @param [String] path
394
+ # The path to the cookies file.
395
+ #
396
+ def load_cookies(path)
397
+ unless File.file?(path)
398
+ print_error "no such file or directory: #{path}"
399
+ return false
400
+ end
401
+
402
+ @browser.load_cookies(path)
403
+ end
404
+
405
+ command :save_cookies, usage: 'FILE',
406
+ summary: "Saves the browser's cookies to the file"
407
+
408
+ #
409
+ # The `save_cookies` command.
410
+ #
411
+ # @param [String] path
412
+ # The path to the cookies file.
413
+ #
414
+ def save_cookies(path)
415
+ @browser.save_cookies(path)
416
+ end
417
+
418
+ private
419
+
420
+ #
421
+ # Prints cookies grouped by `Domain` and `Path`.
422
+ #
423
+ # @param [Enumerator<Ferrum::Cookies::Cookie>] cookies
424
+ # The cookies to print.
425
+ #
426
+ def print_cookies(cookies)
427
+ cookies_by_domain = cookies.group_by(&:domain)
428
+
429
+ cookies_by_domain.each do |domain,domain_cookies|
430
+ puts domain
431
+
432
+ cookies_by_path = domain_cookies.group_by(&:path)
433
+
434
+ cookies_by_path.each do |path,path_cookies|
435
+ puts " #{path}"
436
+
437
+ path_cookies.each do |cookie|
438
+ puts " #{cookie.name}=#{cookie.value}"
439
+ end
440
+ end
441
+ puts
442
+ end
443
+ end
444
+
445
+ end
446
+ end
447
+ end
448
+ 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