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.
- checksums.yaml +4 -4
- data/.github/workflows/ruby.yml +3 -2
- data/.gitignore +1 -0
- data/.rubocop.yml +5 -0
- data/ChangeLog.md +46 -1
- data/Gemfile +25 -12
- data/README.md +257 -51
- data/Rakefile +9 -0
- data/data/completions/ronin-web +203 -0
- data/gemspec.yml +18 -5
- data/lib/ronin/web/cli/browser_options.rb +92 -0
- data/lib/ronin/web/cli/browser_shell.rb +448 -0
- data/lib/ronin/web/cli/command.rb +1 -1
- data/lib/ronin/web/cli/commands/browser.rb +373 -0
- data/lib/ronin/web/cli/commands/completion.rb +63 -0
- data/lib/ronin/web/cli/commands/diff.rb +60 -8
- data/lib/ronin/web/cli/commands/html.rb +21 -33
- data/lib/ronin/web/cli/commands/irb.rb +1 -1
- data/lib/ronin/web/cli/commands/new/{webapp.rb → app.rb} +8 -8
- data/lib/ronin/web/cli/commands/new/nokogiri.rb +4 -4
- data/lib/ronin/web/cli/commands/new/server.rb +1 -1
- data/lib/ronin/web/cli/commands/new/spider.rb +1 -1
- data/lib/ronin/web/cli/commands/new.rb +5 -3
- data/lib/ronin/web/cli/commands/reverse_proxy.rb +1 -1
- data/lib/ronin/web/cli/commands/screenshot.rb +186 -0
- data/lib/ronin/web/cli/commands/server.rb +1 -1
- data/lib/ronin/web/cli/commands/session_cookie.rb +265 -0
- data/lib/ronin/web/cli/commands/spider.rb +61 -467
- data/lib/ronin/web/cli/commands/user_agent.rb +177 -0
- data/lib/ronin/web/cli/commands/vulns.rb +463 -0
- data/lib/ronin/web/cli/commands/wordlist.rb +484 -0
- data/lib/ronin/web/cli/commands/xml.rb +149 -0
- data/lib/ronin/web/cli/js_shell.rb +69 -0
- data/lib/ronin/web/cli/ruby_shell.rb +1 -1
- data/lib/ronin/web/cli/spider_options.rb +919 -0
- data/lib/ronin/web/cli.rb +3 -1
- data/lib/ronin/web/html.rb +1 -1
- data/lib/ronin/web/root.rb +1 -1
- data/lib/ronin/web/version.rb +2 -2
- data/lib/ronin/web/xml.rb +1 -1
- data/lib/ronin/web.rb +4 -364
- data/man/ronin-web-browser.1 +92 -0
- data/man/ronin-web-browser.1.md +96 -0
- data/man/ronin-web-completion.1 +76 -0
- data/man/ronin-web-completion.1.md +78 -0
- data/man/ronin-web-diff.1 +14 -21
- data/man/ronin-web-diff.1.md +13 -6
- data/man/ronin-web-html.1 +30 -46
- data/man/ronin-web-html.1.md +27 -17
- data/man/ronin-web-irb.1 +9 -16
- data/man/ronin-web-irb.1.md +6 -2
- data/man/ronin-web-new-app.1.md +39 -0
- data/man/ronin-web-new-nokogiri.1 +9 -20
- data/man/ronin-web-new-nokogiri.1.md +5 -5
- data/man/ronin-web-new-server.1 +11 -23
- data/man/ronin-web-new-server.1.md +5 -5
- data/man/ronin-web-new-spider.1 +44 -88
- data/man/ronin-web-new-spider.1.md +37 -37
- data/man/ronin-web-new.1 +18 -30
- data/man/ronin-web-new.1.md +15 -11
- data/man/ronin-web-reverse-proxy.1 +33 -38
- data/man/ronin-web-reverse-proxy.1.md +20 -14
- data/man/ronin-web-screenshot.1 +56 -0
- data/man/ronin-web-screenshot.1.md +56 -0
- data/man/ronin-web-server.1 +15 -29
- data/man/ronin-web-server.1.md +13 -9
- data/man/ronin-web-session-cookie.1 +38 -0
- data/man/ronin-web-session-cookie.1.md +41 -0
- data/man/ronin-web-spider.1 +121 -130
- data/man/ronin-web-spider.1.md +115 -66
- data/man/ronin-web-user-agent.1 +44 -0
- data/man/ronin-web-user-agent.1.md +46 -0
- data/man/ronin-web-vulns.1 +175 -0
- data/man/ronin-web-vulns.1.md +177 -0
- data/man/ronin-web-wordlist.1 +258 -0
- data/man/ronin-web-wordlist.1.md +263 -0
- data/man/ronin-web-xml.1 +43 -0
- data/man/ronin-web-xml.1.md +46 -0
- data/man/ronin-web.1 +67 -18
- data/man/ronin-web.1.md +55 -4
- data/scripts/setup +58 -0
- metadata +122 -31
- data/lib/ronin/web/mechanize.rb +0 -84
- data/man/ronin-web-new-webapp.1.md +0 -39
- /data/data/new/{webapp → app}/.gitignore +0 -0
- /data/data/new/{webapp → app}/.ruby-version.erb +0 -0
- /data/data/new/{webapp → app}/Dockerfile.erb +0 -0
- /data/data/new/{webapp → app}/Gemfile +0 -0
- /data/data/new/{webapp → app}/app.rb.erb +0 -0
- /data/data/new/{webapp → app}/config.ru +0 -0
- /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-
|
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
|