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
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d74a1711d3d63c034cb9a4e37f765c27cc1dd4b7e5cbf21154fc936a1db02e02
4
- data.tar.gz: 06b58a6806d23dd2a201942978349cedfd57341f9acd9c9c687dcf1c41ec95bc
3
+ metadata.gz: f60603cab05fa8db75002d8f90142f5ff2e76ea562cf9a85e86e7ee770c5c289
4
+ data.tar.gz: 279e4106b0cbd800136f624a51893b264ab3643a3abbfc6869c85593f012d65c
5
5
  SHA512:
6
- metadata.gz: be61036695c8a3ec44f095008352ab9d7fbc741218ca202f3dfbea9fd235bbb7a38ddc3d79896d62d349512f17085473ac2ac73aff7ae2bad4e2d7fda013c49a
7
- data.tar.gz: 2ea04d21c0cd5dbdee6ffe714ffd94f89a4b2c8f2dceefeafd9daba0908f890da0b78a78b9df302ae14b39b44ca51e674c262b5fd470671382d9786f3904b6af
6
+ metadata.gz: 128dece960fcb880232c477a16d9a6146b3897a2f7a40f4acdddbdd076599c6c12a0001c5ff37192f99ac226fa18cf2b0d5bad10ee13cbe916e0dbaa715d2bb4
7
+ data.tar.gz: 8b0db291154cf808e36585fb0d9d722e020fd918f92d57b9ccd3efad128a5bca29c43a3a61ca4a4ae3b99db131b0a081fc7cbf41877227a4f2c878ac1e12f1d0
@@ -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/.ruby-version CHANGED
@@ -1 +1 @@
1
- ruby-3.1
1
+ ruby-3.3
data/ChangeLog.md CHANGED
@@ -1,7 +1,47 @@
1
+ ### 2.0.0 / 2024-07-22
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]