ronin-web 1.0.2 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (92) 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/.ruby-version +1 -1
  6. data/ChangeLog.md +46 -1
  7. data/Gemfile +25 -12
  8. data/README.md +257 -51
  9. data/Rakefile +9 -0
  10. data/data/completions/ronin-web +203 -0
  11. data/gemspec.yml +18 -5
  12. data/lib/ronin/web/cli/browser_options.rb +92 -0
  13. data/lib/ronin/web/cli/browser_shell.rb +448 -0
  14. data/lib/ronin/web/cli/command.rb +1 -1
  15. data/lib/ronin/web/cli/commands/browser.rb +373 -0
  16. data/lib/ronin/web/cli/commands/completion.rb +63 -0
  17. data/lib/ronin/web/cli/commands/diff.rb +60 -8
  18. data/lib/ronin/web/cli/commands/html.rb +21 -33
  19. data/lib/ronin/web/cli/commands/irb.rb +1 -1
  20. data/lib/ronin/web/cli/commands/new/{webapp.rb → app.rb} +8 -8
  21. data/lib/ronin/web/cli/commands/new/nokogiri.rb +4 -4
  22. data/lib/ronin/web/cli/commands/new/server.rb +1 -1
  23. data/lib/ronin/web/cli/commands/new/spider.rb +1 -1
  24. data/lib/ronin/web/cli/commands/new.rb +5 -3
  25. data/lib/ronin/web/cli/commands/reverse_proxy.rb +1 -1
  26. data/lib/ronin/web/cli/commands/screenshot.rb +186 -0
  27. data/lib/ronin/web/cli/commands/server.rb +1 -1
  28. data/lib/ronin/web/cli/commands/session_cookie.rb +265 -0
  29. data/lib/ronin/web/cli/commands/spider.rb +61 -467
  30. data/lib/ronin/web/cli/commands/user_agent.rb +177 -0
  31. data/lib/ronin/web/cli/commands/vulns.rb +463 -0
  32. data/lib/ronin/web/cli/commands/wordlist.rb +484 -0
  33. data/lib/ronin/web/cli/commands/xml.rb +149 -0
  34. data/lib/ronin/web/cli/js_shell.rb +69 -0
  35. data/lib/ronin/web/cli/ruby_shell.rb +1 -1
  36. data/lib/ronin/web/cli/spider_options.rb +919 -0
  37. data/lib/ronin/web/cli.rb +3 -1
  38. data/lib/ronin/web/html.rb +1 -1
  39. data/lib/ronin/web/root.rb +1 -1
  40. data/lib/ronin/web/version.rb +2 -2
  41. data/lib/ronin/web/xml.rb +1 -1
  42. data/lib/ronin/web.rb +4 -364
  43. data/man/ronin-web-browser.1 +92 -0
  44. data/man/ronin-web-browser.1.md +96 -0
  45. data/man/ronin-web-completion.1 +76 -0
  46. data/man/ronin-web-completion.1.md +78 -0
  47. data/man/ronin-web-diff.1 +14 -21
  48. data/man/ronin-web-diff.1.md +13 -6
  49. data/man/ronin-web-html.1 +30 -46
  50. data/man/ronin-web-html.1.md +27 -17
  51. data/man/ronin-web-irb.1 +9 -16
  52. data/man/ronin-web-irb.1.md +6 -2
  53. data/man/ronin-web-new-app.1.md +39 -0
  54. data/man/ronin-web-new-nokogiri.1 +9 -20
  55. data/man/ronin-web-new-nokogiri.1.md +5 -5
  56. data/man/ronin-web-new-server.1 +11 -23
  57. data/man/ronin-web-new-server.1.md +5 -5
  58. data/man/ronin-web-new-spider.1 +44 -88
  59. data/man/ronin-web-new-spider.1.md +37 -37
  60. data/man/ronin-web-new.1 +18 -30
  61. data/man/ronin-web-new.1.md +15 -11
  62. data/man/ronin-web-reverse-proxy.1 +33 -38
  63. data/man/ronin-web-reverse-proxy.1.md +20 -14
  64. data/man/ronin-web-screenshot.1 +56 -0
  65. data/man/ronin-web-screenshot.1.md +56 -0
  66. data/man/ronin-web-server.1 +15 -29
  67. data/man/ronin-web-server.1.md +13 -9
  68. data/man/ronin-web-session-cookie.1 +38 -0
  69. data/man/ronin-web-session-cookie.1.md +41 -0
  70. data/man/ronin-web-spider.1 +121 -130
  71. data/man/ronin-web-spider.1.md +115 -66
  72. data/man/ronin-web-user-agent.1 +44 -0
  73. data/man/ronin-web-user-agent.1.md +46 -0
  74. data/man/ronin-web-vulns.1 +175 -0
  75. data/man/ronin-web-vulns.1.md +177 -0
  76. data/man/ronin-web-wordlist.1 +258 -0
  77. data/man/ronin-web-wordlist.1.md +263 -0
  78. data/man/ronin-web-xml.1 +43 -0
  79. data/man/ronin-web-xml.1.md +46 -0
  80. data/man/ronin-web.1 +67 -18
  81. data/man/ronin-web.1.md +55 -4
  82. data/scripts/setup +58 -0
  83. metadata +121 -30
  84. data/lib/ronin/web/mechanize.rb +0 -84
  85. data/man/ronin-web-new-webapp.1.md +0 -39
  86. /data/data/new/{webapp → app}/.gitignore +0 -0
  87. /data/data/new/{webapp → app}/.ruby-version.erb +0 -0
  88. /data/data/new/{webapp → app}/Dockerfile.erb +0 -0
  89. /data/data/new/{webapp → app}/Gemfile +0 -0
  90. /data/data/new/{webapp → app}/app.rb.erb +0 -0
  91. /data/data/new/{webapp → app}/config.ru +0 -0
  92. /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