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
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d74a1711d3d63c034cb9a4e37f765c27cc1dd4b7e5cbf21154fc936a1db02e02
4
- data.tar.gz: 06b58a6806d23dd2a201942978349cedfd57341f9acd9c9c687dcf1c41ec95bc
3
+ metadata.gz: 8bd87f5c3602ae1ece1f09ff4d689221c41e63b1302f9edf58576a3aec06108e
4
+ data.tar.gz: 5fa836bd013ea5b74a4b79fbda0fc4dd84ac09d9abafea689aba504c3decb32e
5
5
  SHA512:
6
- metadata.gz: be61036695c8a3ec44f095008352ab9d7fbc741218ca202f3dfbea9fd235bbb7a38ddc3d79896d62d349512f17085473ac2ac73aff7ae2bad4e2d7fda013c49a
7
- data.tar.gz: 2ea04d21c0cd5dbdee6ffe714ffd94f89a4b2c8f2dceefeafd9daba0908f890da0b78a78b9df302ae14b39b44ca51e674c262b5fd470671382d9786f3904b6af
6
+ metadata.gz: b56e783acb097f2c43f7c144f5bb5225a060b48000b458ba098280a8bd690d0831141ead1c00d3cafba1922428022d36643bba780c483400c27ac3d05af3ce65
7
+ data.tar.gz: c78a468778822cbe8dfc0d3efa845d08471e1440fecfa849784b54bd8719bb4c8abca4568213df8de961acfafa85beb33f13dc853a1480dfafc3f37127a308b2
@@ -12,11 +12,12 @@ jobs:
12
12
  - '3.0'
13
13
  - '3.1'
14
14
  - '3.2'
15
+ - '3.3'
15
16
  # - jruby
16
17
  - truffleruby
17
18
  name: Ruby ${{ matrix.ruby }}
18
19
  steps:
19
- - uses: actions/checkout@v2
20
+ - uses: actions/checkout@v4
20
21
  - name: Set up Ruby
21
22
  uses: ruby/setup-ruby@v1
22
23
  with:
@@ -31,7 +32,7 @@ jobs:
31
32
  rubocop:
32
33
  runs-on: ubuntu-latest
33
34
  steps:
34
- - uses: actions/checkout@v2
35
+ - uses: actions/checkout@v4
35
36
  - name: Set up Ruby
36
37
  uses: ruby/setup-ruby@v1
37
38
  with:
data/.gitignore CHANGED
@@ -1,4 +1,5 @@
1
1
  /coverage
2
+ /data/completions/ronin-web
2
3
  /doc
3
4
  /pkg
4
5
  /man/*.[1-9]
data/.rubocop.yml CHANGED
@@ -18,3 +18,8 @@ Lint/ShadowingOuterLocalVariable:
18
18
  Exclude:
19
19
  - 'lib/ronin/web/cli/commands/reverse_proxy.rb'
20
20
  - 'lib/ronin/web/cli/commands/spider.rb'
21
+
22
+ Naming/MethodParameterName:
23
+ Exclude:
24
+ - 'lib/ronin/web/cli/browser_shell.rb'
25
+ - 'lib/ronin/web/cli/js_shell.rb'
data/ChangeLog.md CHANGED
@@ -1,7 +1,47 @@
1
+ ### 2.0.0 / 2024-XX-XX
2
+
3
+ * Require [wordlist] ~> 1.0, >= 1.0.1.
4
+ * Require [ronin-support-web] ~> 0.1.
5
+ * Require [ronin-web-browser] ~> 0.1.
6
+ * Require [ronin-web-session_cookie] ~> 0.1.
7
+ * Require [ronin-web-spider] ~> 0.2.
8
+
9
+ #### CLI
10
+
11
+ * Added the `ronin-web xml` command.
12
+ * Added the `ronin-web session-cookie` command.
13
+ * Added the `ronin-web user-agent` command.
14
+ * Added the `ronin-web wordlist` command.
15
+ * Added the `ronin-web browser` command.
16
+ * Added the `ronin-web screenshot` command.
17
+ * Added the `ronin-web vulns` command.
18
+ * Added the `ronin-web completion` command to install shell completion files
19
+ for all `ronin-web` commands for Bash and Zsh shells.
20
+ * Added the `--format=html|xml` option to the `ronin-web diff` command.
21
+ * Added the `-t,--text` option to `ronin-web html`.
22
+ * Added the `--print-js-url-strings` option to the `ronin-web spider` command.
23
+ * Added the `--print-js-path-strings` option to the `ronin-web spider` command.
24
+ * Added the `--print-js-relative-path-strings` option to the `ronin-web spider`
25
+ command.
26
+ * Added the `--print-js-absolute-path-strings` option to the `ronin-web spider`
27
+ command.
28
+ * Added ANSI colored output to the `ronin-web diff` command.
29
+ * Renamed `ronin-web new webapp` to `ronin-web new app`.
30
+
31
+ ### 1.0.2 / 2023-04-04
32
+
33
+ * Improved documentation.
34
+
35
+ #### CLI
36
+
37
+ * Fixed a bug in `ronin-web server` where `App.host` was being called instead of
38
+ `App.bind`.
39
+ * Fixed a typo in the `ronin-web spider --print-status` option.
40
+
1
41
  ### 1.0.1 / 2023-03-01
2
42
 
3
43
  * Require `ronin-web-server` ~> 0.1, >= 0.1.1.
4
- * Disable SSL/TLS verification by default in {Ronin::Web::Mechanize}.
44
+ * Disable SSL/TLS verification by default in `Ronin::Web::Mechanize`.
5
45
 
6
46
  ### 1.0.0 / 2023-02-01
7
47
 
@@ -169,6 +209,11 @@
169
209
  [rack]: https://github.com/rack/rack
170
210
  [sinatra]: https://github.com/sinatra/sinatra
171
211
  [data_paths]: https://github.com/postmodern/data_paths
212
+ [wordlist]: https://github.com/postmodern/wordlist.rb#readme
172
213
  [ronin-support]: https://github.com/ronin-rb/ronin-support
214
+ [ronin-support-web]: https://github.com/ronin-rb/ronin-support-web#readme
215
+ [ronin-web-browser]: https://github.com/ronin-rb/ronin-web-browser#readme
216
+ [ronin-web-session_cookie]: https://github.com/ronin-rb/ronin-web-session_cookie#readme
217
+ [ronin-web-spider]: https://github.com/ronin-rb/ronin-web-spider#readme
173
218
  [ronin]: https://github.com/ronin-rb/ronin
174
219
  [ronin-scanners]: https://github.com/ronin-rb/ronin-scanners
data/Gemfile CHANGED
@@ -4,11 +4,6 @@ source 'https://rubygems.org'
4
4
 
5
5
  gemspec
6
6
 
7
- if RUBY_VERSION >= '3.0'
8
- # XXX: dep in webrick for mechanize for Ruby 3.0
9
- gem 'webrick', platform: :ruby
10
- end
11
-
12
7
  platforms :jruby do
13
8
  gem 'jruby-openssl', '~> 0.7'
14
9
  end
@@ -21,18 +16,33 @@ end
21
16
  # gem 'command_kit', '~> 0.4', github: 'postmodern/command_kit.rb',
22
17
  # branch: '0.4.0'
23
18
 
24
- # gem 'spidr', '~> 0.7', github: 'postmodern/spidr'
19
+ # gem 'spidr', '~> 0.7', github: 'postmodern/spidr'
20
+ # gem 'wordlist', '~> 1.0', github: 'postmodern/wordlist.rb'
25
21
 
26
22
  # Ronin dependencies
27
- # gem 'ronin-support', '~> 1.0', github: "ronin-rb/ronin-support",
28
- # branch: 'main'
23
+ # gem 'ronin-support', '~> 1.1', github: "ronin-rb/ronin-support",
24
+ # branch: 'main'
25
+ # gem 'ronin-support-web', '~> 0.1', github: "ronin-rb/ronin-support-web",
26
+ # branch: 'main'
27
+ # gem 'ronin-core', '~> 0.2', github: "ronin-rb/ronin-core",
28
+ # branch: 'main'
29
+
30
+ # gem 'ferrum', github: 'rubycdp/ferrum'
31
+ # gem 'ronin-web-browser', '~> 0.1', github: 'ronin-rb/ronin-web-browser'
29
32
  # gem 'ronin-web-server', '~> 0.1', github: "ronin-rb/ronin-web-server",
30
33
  # branch: 'main'
31
- # gem 'ronin-web-spider', '~> 0.1', github: "ronin-rb/ronin-web-spider",
34
+ # gem 'ronin-web-spider', '~> 0.2', github: 'ronin-rb/ronin-web-spider',
32
35
  # branch: 'main'
33
- # gem 'ronin-web-user_agents', '~> 0.1', github: "ronin-rb/ronin-web-user_agents",
36
+ # gem 'ronin-web-user_agents', '~> 0.1', github: 'ronin-rb/ronin-web-user_agents',
34
37
  # branch: 'main'
35
- # gem 'ronin-core', '~> 0.1', github: "ronin-rb/ronin-core",
38
+ # gem 'ronin-web-session_cookie', '~> 0.1', github: 'ronin-rb/ronin-web-session_cookie',
39
+ # branch: 'main'
40
+
41
+ # gem 'ronin-db', '~> 0.2', github: 'ronin-rb/ronin-db',
42
+ # branch: 'main'
43
+ # gem 'ronin-db-activerecord', '~> 0.2', github: 'ronin-rb/ronin-db-activerecord',
44
+ # branch: 'main'
45
+ # gem 'ronin-vulns', '~> 0.2', github: 'ronin-rb/ronin-vulns',
36
46
  # branch: 'main'
37
47
 
38
48
  group :development do
@@ -42,17 +52,20 @@ group :development do
42
52
  gem 'rspec', '~> 3.0'
43
53
  gem 'simplecov', '~> 0.20'
44
54
  gem 'rack-test', '~> 0.6'
55
+ gem 'webmock', '~> 3.0'
45
56
 
46
57
  gem 'kramdown', '~> 2.0'
47
58
  gem 'redcarpet', platform: :mri
48
59
  gem 'yard', '~> 0.9'
49
60
  gem 'yard-spellcheck', require: false
50
61
 
51
- gem 'kramdown-man', '~> 0.1'
62
+ gem 'kramdown-man', '~> 1.0'
52
63
 
53
64
  gem 'dead_end', require: false
54
65
  gem 'sord', require: false, platform: :mri
55
66
  gem 'stackprof', require: false, platform: :mri
56
67
  gem 'rubocop', require: false, platform: :mri
57
68
  gem 'rubocop-ronin', require: false, platform: :mri
69
+
70
+ gem 'command_kit-completion', '~> 0.2', require: false
58
71
  end
data/README.md CHANGED
@@ -8,7 +8,6 @@
8
8
  * [Issues](https://github.com/ronin-rb/ronin-web/issues)
9
9
  * [Documentation](https://ronin-rb.dev/docs/ronin-web/frames)
10
10
  * [Discord](https://discord.gg/6WAb3PsVX9) |
11
- [Twitter](https://twitter.com/ronin_rb) |
12
11
  [Mastodon](https://infosec.exchange/@ronin_rb)
13
12
 
14
13
  ## Description
@@ -25,7 +24,6 @@ research and development.
25
24
  * Also provides additional extensions to [Nokogiri][nokogiri] using
26
25
  [nokogiri-ext].
27
26
  * Supports diffing HTML/XML documents using [nokogiri-diff].
28
- * Automated Web Browsing using [Mechanize][mechanize].
29
27
  * Supports random `User-Agent` generation using [ronin-web-user_agents].
30
28
  * Provides an easy to use [Sinatra][sinatra] based web server using
31
29
  [ronin-web-server].
@@ -47,14 +45,21 @@ Arguments:
47
45
  [ARGS ...] Additional arguments for the command
48
46
 
49
47
  Commands:
48
+ completion
50
49
  diff
51
50
  help
52
51
  html
53
52
  irb
54
53
  new
55
54
  reverse-proxy
55
+ screenshot
56
56
  server
57
+ session-cookie
57
58
  spider
59
+ user-agent
60
+ vulns
61
+ wordlist
62
+ xml
58
63
  ```
59
64
 
60
65
  Open the `ronin-web` Ruby REPL:
@@ -287,56 +292,98 @@ $ ronin-web new server server.rb
287
292
  Generate a new web app:
288
293
 
289
294
  ```shell
290
- $ ronin-web new webapp app
291
- mkdir app
292
- mkdir app/lib
293
- mkdir app/views
294
- mkdir app/public
295
- erb .ruby-version.erb app/.ruby-version
296
- cp Gemfile app
297
- erb app.rb.erb app/app.rb
298
- cp config.ru app
295
+ $ ronin-web new app myapp
296
+ mkdir myapp
297
+ mkdir myapp/lib
298
+ mkdir myapp/views
299
+ mkdir myapp/public
300
+ erb .ruby-version.erb myapp/.ruby-version
301
+ cp Gemfile myapp
302
+ erb app.rb.erb myapp/app.rb
303
+ cp config.ru myapp
299
304
  ```
300
305
 
301
- ## Examples
302
-
303
- Get a web-page:
306
+ Open the Ronin Web Ruby REPL:
304
307
 
305
- ```ruby
306
- Web.get('http://www.rubyinside.com/')
308
+ ```
309
+ $ ronin-web irb
310
+ , Jµ ▓▓█▓
311
+ J▌ ▐▓██▌ ████ ██ ▐███D
312
+ ╓▄▓▓█████▌ ██µ ████ ▄███ÖJ██▌ ███▌
313
+ ,╓µ▄▄▄▄▄▄▄▄µ;, ,▄▓██████████ ▐███ ▐███▀ ███▌ ████µ ▄███
314
+ ¬∞MÆ▓███████████████████████▓M ▄██████▀▀╙████▌ ████▌ ████ ▄███ J█████ ███▌
315
+ `█████▀▀▀▀▀███████ -████▀└ ████ ▐█████n ▄███O ███▌ ██████████
316
+ ▓████L ████▀ ▓████ ▓███Ö ███████ ███▌ ▓███ ▐█████████▀
317
+ ▄████▀ ,╓▄▄▄█████ J████Ü ,███▌ ▄███████████ J███▀ ████ █████
318
+ J█████████████████─ ████▌ ████ ████`██████▌ ████ ▐███Ü ▐███Ü
319
+ ███████████▀▀▀╙└ ▐████ J███▌ ▓███▌ ²█████ J███Ü ███▌ ▀█▌
320
+ ▓██████████▌ ████▌ ████ ;████ ▀███▀ ███▌ J▀▀▀- █
321
+ ▄█████▀ ▀█████µ ▐████ ,▄▓████▀ ████▀ ███ J███ `
322
+ J█████- ╙▀███▄ ████████████▀╙ J█▀▀▀ █U ▀█▌
323
+ ████▀ ▀███ ▄████████▀▀ ╨ █
324
+ ▓██▀ ²▀█▄ █▀▀▀╙└
325
+ ▄██╜ ╙W
326
+ J█▀
327
+ ▌└
328
+
329
+
330
+ irb(ronin-web)>
307
331
  ```
308
332
 
309
- Get only the body of the web-page:
333
+ ## Examples
310
334
 
311
- ```ruby
312
- Web.get_body('http://www.rubyinside.com/')
313
- ```
335
+ ### HTML
314
336
 
315
- Get a [Mechanize agent][mechanize]:
337
+ Parse an HTML string:
316
338
 
317
339
  ```ruby
318
- agent = Web.agent
340
+ doc = html_parse("<html>\n <body>\n <p>Hello world</p>\n </body>\n</html>\n")
341
+ # =>
342
+ # #(Document:0x6ab8 {
343
+ # name = "document",
344
+ # children = [
345
+ # #(DTD:0x6be4 { name = "html" }),
346
+ # #(Element:0x6cd4 {
347
+ # name = "html",
348
+ # children = [
349
+ # #(Text "\n "),
350
+ # #(Element:0x6e64 {
351
+ # name = "body",
352
+ # children = [
353
+ # #(Text "\n "),
354
+ # #(Element:0x6ff4 { name = "p", children = [ #(Text "Hello world")] }),
355
+ # #(Text "\n ")]
356
+ # }),
357
+ # #(Text "\n")]
358
+ # })]
359
+ # })
360
+ ```
361
+
362
+ Parse a HTML file:
363
+
364
+ ```ruby
365
+ doc = html_open("index.html")
366
+ # => #<Nokogiri::HTML::Document:...>
319
367
  ```
320
368
 
321
- Parse HTML:
369
+ Searching an HTML document using [XPath] or CSS-path:
322
370
 
323
371
  ```ruby
324
- HTML.parse(open('some_file.html'))
325
- # => <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
326
- # <html>
327
- # <head>
328
- # <script type="text/javascript" src="redirect.js"></script>
329
- # </head>
330
- # </html>
372
+ nodes = doc.search('//div/p')
373
+ nodes = doc.search('div p.class')
374
+ # => [#<Nokogiri::HTML::Element:...>, ...]
375
+
376
+ node = doc.at('#id')
377
+ # => #<Nokogiri::HTML::Element:...>
331
378
  ```
332
379
 
333
380
  Build a HTML document:
334
381
 
335
382
  ```ruby
336
- doc = HTML.build do
383
+ doc = html_build do
337
384
  html {
338
385
  head {
339
- script(:type => 'text/javascript', :src => 'redirect.js')
386
+ script(type: 'text/javascript', src: 'redirect.js')
340
387
  }
341
388
  }
342
389
  end
@@ -346,23 +393,56 @@ puts doc.to_html
346
393
  # <html><head><script src="redirect.js" type="text/javascript"></script></head></html>
347
394
  ```
348
395
 
349
- Parse XML:
396
+ ### XML
397
+
398
+ Parse an XML response body:
399
+
400
+ ```ruby
401
+ xml_parse("<?xml version=\"1.0\"?>\n<users>\n <user>\n <name>admin</name>\n <password>0mni</password>\n <user>\n</users>\n")
402
+ # =>
403
+ # #(Document:0xdebc {
404
+ # name = "document",
405
+ # children = [
406
+ # #(Element:0xdfe8 {
407
+ # name = "users",
408
+ # children = [
409
+ # #(Text "\n "),
410
+ # #(Element:0xe178 {
411
+ # name = "user",
412
+ # children = [
413
+ # #(Text "\n "),
414
+ # #(Element:0xe308 { name = "name", children = [ #(Text "admin")] }),
415
+ # #(Text "\n "),
416
+ # #(Element:0xe538 { name = "password", children = [ #(Text "0mni")] }),
417
+ # #(Text "\n "),
418
+ # #(Element:0xe768 { name = "user", children = [ #(Text "\n")] }),
419
+ # #(Text "\n")]
420
+ # })]
421
+ # })]
422
+ # })
423
+ ```
424
+
425
+ Parse a XML file:
426
+
427
+ ```ruby
428
+ doc = html_open("data.xml")
429
+ # => #<Nokogiri:XML:::Document:...>
430
+ ```
431
+
432
+ Searching an XML document using [XPath]:
350
433
 
351
434
  ```ruby
352
- XML.parse(some_text)
353
- # => <?xml version="1.0"?>
354
- # <users>
355
- # <user>
356
- # <name>admin</name>
357
- # <password>0mni</password>
358
- # </user>
359
- # </users>
435
+ users = doc.search('//user')
436
+ # => [#<Nokogiri::XML::Element:...>, ...]
437
+
438
+ admin = doc.at('//user[@name="admin"]')
439
+ # => #<Nokogiri::XML::Element:...>
360
440
  ```
361
441
 
362
442
  Build a XML document:
363
443
 
364
444
  ```ruby
365
- doc = XML.build do
445
+ doc = xml_build do
366
446
  playlist {
367
447
  mp3 {
368
448
  file { text('02 THE WAIT.mp3') }
@@ -385,19 +465,143 @@ puts doc.to_xml
385
465
  # </playlist>
386
466
  ```
387
467
 
468
+ ### Web Requests
469
+
470
+ Gets a URL and follows any redirects:
471
+
472
+ ```ruby
473
+ get 'https://example.com/'
474
+ # => #<Net::HTTPResponse:...>
475
+ ```
476
+
477
+ Gets a URL and parses the HTML response:
478
+
479
+ ```ruby
480
+ get_html 'https://example.com/'
481
+ # => #<Nokogiri::HTML::Document:...>
482
+ ```
483
+
484
+ Gets a URL and parses the XML response:
485
+
486
+ ```ruby
487
+ get_xml 'https://example.com/sitemap.xml'
488
+ # => #<Nokogiri::XML::Document:...>
489
+ ```
490
+
491
+ Gets a URL and parses the JSON response:
492
+
493
+ ```ruby
494
+ get_json 'https://example.com/api/endpoint.json'
495
+ # => {...}
496
+ ```
497
+
498
+ POSTs to a URL and follows any redirects:
499
+
500
+ ```ruby
501
+ post 'https://example.com/form', form_data: {'foo' => 'bar'}
502
+ # => #<Net::HTTPResponse:...>
503
+ ```
504
+
505
+ POSTs to a URL and parses the HTML response:
506
+
507
+ ```ruby
508
+ post_html 'https://example.com/form', form_data: {'foo' => 'bar'}
509
+ # => #<Nokogiri::HTML::Document:...>
510
+ ```
511
+
512
+ POSTs to a URL and parses the XML response:
513
+
514
+ ```ruby
515
+ post_xml 'https://example.com/form', form_data: {'foo' => 'bar'}
516
+ # => #<Nokogiri::XML::Document:...>
517
+ ```
518
+
519
+ POSTs to a URL and parses the JSON response:
520
+
521
+ ```ruby
522
+ post_json 'https://example.com/api/endpoint.json', json: {foo: 'bar'}
523
+ # => {...}
524
+ ```
525
+
526
+ ### User Agents
527
+
528
+ Get a random `User-Agent` string:
529
+
530
+ ```ruby
531
+ user_agent = UserAgents.random
532
+ # => "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.230 Safari/537.36"
533
+ ```
534
+
535
+ For more examples, see [ronin-web-user_agents][ronin-web-user_agents-examples].
536
+
537
+ [ronin-web-user_agents-examples]: https://github.com/ronin-rb/ronin-web-user_agents#examples
538
+
539
+ ### Session Cookie
540
+
541
+ Parse a Django JSON session cookie:
542
+
543
+ ```ruby
544
+ SessionCookie.parse('sessionid=eyJmb28iOiJiYXIifQ:1pQcTx:UufiSnuPIjNs7zOAJS0UpqnyvRt7KET7BVes0I8LYbA')
545
+ # =>
546
+ # #<Ronin::Web::SessionCookie::Django:0x00007f29bb9c6b70
547
+ # @hmac=
548
+ # "R\xE7\xE2J{\x8F\"3l\xEF3\x80%-\x14\xA6\xA9\xF2\xBD\e{(D\xFB\x05W\xAC\xD0\x8F\va\xB0",
549
+ # @params={"foo"=>"bar"},
550
+ # @salt=1676070425>
551
+ ```
552
+
553
+ For more examples, see [ronin-web-session_cookie][ronin-web-session_cookie-examples].
554
+
555
+ [ronin-web-session_cookie-examples]: https://github.com/ronin-rb/ronin-web-session_cookie#examples
556
+
557
+ ### Spider
558
+
559
+ Spider a website and print out visited URLs:
560
+
561
+ ```ruby
562
+ Spider.site('http://www.rubyinside.com/') do |spider|
563
+ spider.every_url { |url| puts url }
564
+ end
565
+ ```
566
+
567
+ For more examples, see [ronin-web-spider][ronin-web-spider-examples].
568
+
569
+ [ronin-web-spider-examples]: https://github.com/ronin-rb/ronin-web-spider#examples
570
+
571
+ ### Browser
572
+
573
+ Open a visible web browser and intercept all requests:
574
+
575
+ ```ruby
576
+ browser = Ronin::Web::Browser.new(visible: true)
577
+ browser.every_request do |request|
578
+ puts "> #{request.method} #{request.url}"
579
+ end
580
+
581
+ browser.go_to("https://twitter.com/login")
582
+ ```
583
+
584
+ For more examples, see [ronin-web-browser][ronin-web-browser-examples].
585
+
586
+ [ronin-web-browser-examples]: https://github.com/ronin-rb/ronin-web-browser#examples
587
+
388
588
  ## Requirements
389
589
 
390
590
  * [Ruby] >= 3.0.0
391
591
  * [nokogiri] ~> 1.4
392
- * [nokogiri-ext] ~> 0.1
393
592
  * [nokogiri-diff] ~> 0.2
394
- * [mechanize] ~> 2.0
593
+ * [robots] ~> 0.10
395
594
  * [open_namespace] ~> 0.4
396
- * [ronin-support] ~> 1.0
595
+ * [wordlist] ~> 1.0, >= 1.0.1
596
+ * [ronin-support] ~> 1.1
597
+ * [ronin-support-web] ~> 0.1
598
+ * [ronin-web-browser] ~> 0.1
397
599
  * [ronin-web-server] ~> 0.1
398
- * [ronin-web-spider] ~> 0.1
600
+ * [ronin-web-spider] ~> 0.2
399
601
  * [ronin-web-user_agents] ~> 0.1
400
- * [ronin-core] ~> 0.1
602
+ * [ronin-web-session_cookie] ~> 0.1
603
+ * [ronin-core] ~> 0.2
604
+ * [ronin-vulns] ~> 0.2
401
605
 
402
606
  ## Install
403
607
 
@@ -410,7 +614,7 @@ $ gem install ronin-web
410
614
  1. [Fork It!](https://github.com/ronin-rb/ronin-web/fork)
411
615
  2. Clone It!
412
616
  3. `cd ronin-web`
413
- 4. `bundle install`
617
+ 4. `./scripts/setup`
414
618
  5. `git checkout -b my_feature`
415
619
  6. Code It!
416
620
  7. `bundle exec rake spec`
@@ -420,7 +624,7 @@ $ gem install ronin-web
420
624
 
421
625
  ronin-web - A collection of useful web helper methods and commands.
422
626
 
423
- Copyright (c) 2006-2023 Hal Brodigan (postmodern.mod3 at gmail.com)
627
+ Copyright (c) 2006-2024 Hal Brodigan (postmodern.mod3 at gmail.com)
424
628
 
425
629
  ronin-web is free software: you can redistribute it and/or modify
426
630
  it under the terms of the GNU General Public License as published by
@@ -439,14 +643,16 @@ along with ronin-web. If not, see <https://www.gnu.org/licenses/>.
439
643
  [Ruby]: https://www.ruby-lang.org
440
644
 
441
645
  [nokogiri]: https://nokogiri.org/
442
- [nokogiri-ext]: https://github.com/postmodern/nokogiri-ext#readme
443
646
  [nokogiri-diff]: https://github.com/postmodern/nokogiri-diff#readme
444
- [mechanize]: https://github.com/sparklemotion/mechanize#readme
445
647
  [open_namespace]: https://github.com/postmodern/open_namespace#readme
446
648
  [ronin-support]: https://github.com/ronin-rb/ronin-support#readme
649
+ [ronin-support-web]: https://github.com/ronin-rb/ronin-support-web#readme
447
650
  [ronin-core]: https://github.com/ronin-rb/ronin-core#readme
651
+ [ronin-web-browser]: https://github.com/ronin-rb/ronin-web-browser#readme
448
652
  [ronin-web-server]: https://github.com/ronin-rb/ronin-web-server#readme
449
653
  [ronin-web-spider]: https://github.com/ronin-rb/ronin-web-spider#readme
450
654
  [ronin-web-user_agents]: https://github.com/ronin-rb/ronin-web-user_agents#readme
451
655
  [ronin]: https://github.com/ronin-rb/ronin#readme
452
656
  [sinatra]: https://sinatrarb.com/
657
+
658
+ [XPath]: https://developer.mozilla.org/en-US/docs/Web/XPath
data/Rakefile CHANGED
@@ -37,3 +37,12 @@ YARD::Rake::YardocTask.new
37
37
 
38
38
  require 'kramdown/man/task'
39
39
  Kramdown::Man::Task.new
40
+
41
+ require 'command_kit/completion/task'
42
+ CommandKit::Completion::Task.new(
43
+ class_file: 'ronin/web/cli',
44
+ class_name: 'Ronin::Web::CLI',
45
+ output_file: 'data/completions/ronin-web'
46
+ )
47
+
48
+ task :setup => %w[man command_kit:completion]