Skip to content

Commit

Permalink
Add the ronin-web vulns command (issue #81).
Browse files Browse the repository at this point in the history
  • Loading branch information
postmodern committed Apr 29, 2024
1 parent 8bc0e4b commit 63758ef
Show file tree
Hide file tree
Showing 6 changed files with 503 additions and 0 deletions.
7 changes: 7 additions & 0 deletions Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,13 @@ gem 'ronin-web-browser', '~> 0.1', github: 'ronin-rb/ronin-web-browser'
gem 'ronin-web-session_cookie', '~> 0.1', github: 'ronin-rb/ronin-web-session_cookie',
branch: 'main'

gem 'ronin-db', '~> 0.2', github: 'ronin-rb/ronin-db',
branch: '0.2.0'
gem 'ronin-db-activerecord', '~> 0.2', github: 'ronin-rb/ronin-db-activerecord',
branch: '0.2.0'
gem 'ronin-vulns', '~> 0.2', github: 'ronin-rb/ronin-vulns',
branch: '0.2.0'

group :development do
gem 'rake'
gem 'rubygems-tasks', '~> 0.1'
Expand Down
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ Commands:
session-cookie
spider
user-agent
vulns
wordlist
xml
```
Expand Down Expand Up @@ -600,6 +601,7 @@ For more examples, see [ronin-web-browser][ronin-web-browser-examples].
* [ronin-web-user_agents] ~> 0.1
* [ronin-web-session_cookie] ~> 0.1
* [ronin-core] ~> 0.2
* [ronin-vulns] ~> 0.2

## Install

Expand Down
2 changes: 2 additions & 0 deletions gemspec.yml
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ generated_files:
- man/ronin-web-reverse-proxy.1
- man/ronin-web-session-cookie.1
- man/ronin-web-user-agent.1
- man/ronin-web-vulns.1
- man/ronin-web-wordlist.1
- man/ronin-web-xml.1

Expand All @@ -56,6 +57,7 @@ dependencies:
ronin-web-user_agents: ~> 0.1
ronin-web-session_cookie: ~> 0.1
ronin-core: ~> 0.2
ronin-vulns: ~> 0.2

development_dependencies:
bundler: ~> 2.0
308 changes: 308 additions & 0 deletions lib/ronin/web/cli/commands/vulns.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,308 @@
# frozen_string_literal: true
#
# ronin-web - A collection of useful web helper methods and commands.
#
# Copyright (c) 2006-2024 Hal Brodigan (postmodern.mod3 at gmail.com)
#
# ronin-web is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# ronin-web is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with ronin-web. If not, see <https://www.gnu.org/licenses/>.
#

require 'ronin/web/cli/command'
require 'ronin/web/cli/spider_options'
require 'ronin/core/cli/logging'
require 'ronin/vulns/url_scanner'
require 'ronin/vulns/cli/printing'
require 'ronin/vulns/cli/importable'

module Ronin
module Web
class CLI
module Commands
#
# ## Usage
#
# ronin-web vulns [options] {--host HOST | --domain DOMAIN | --site URL}
#
# ## Options
#
# --host HOST Spiders the specific HOST
# --domain DOMAIN Spiders the whole domain
# --site URL Spiders the website, starting at the URL
# --open-timeout SECS Sets the connection open timeout
# --read-timeout SECS Sets the read timeout
# --ssl-timeout SECS Sets the SSL connection timeout
# --continue-timeout SECS Sets the continue timeout
# --keep-alive-timeout SECS Sets the connection keep alive timeout
# -P, --proxy PROXY Sets the proxy to use.
# -H, --header NAME: VALUE Sets a default header
# --host-header NAME=VALUE Sets a default header
# -u chrome-linux|chrome-macos|chrome-windows|chrome-iphone|chrome-ipad|chrome-android|firefox-linux|firefox-macos|firefox-windows|firefox-iphone|firefox-ipad|firefox-android|safari-macos|safari-iphone|safari-ipad|edge,
# --user-agent The User-Agent to use
# -U, --user-agent-string STRING The User-Agent string to use
# -R, --referer URL Sets the Referer URL
# --delay SECS Sets the delay in seconds between each request
# -l, --limit COUNT Only spiders up to COUNT pages
# -d, --max-depth DEPTH Only spiders up to max depth
# --enqueue URL Adds the URL to the queue
# --visited URL Marks the URL as previously visited
# --strip-fragments Enables/disables stripping the fragment component of every URL
# --strip-query Enables/disables stripping the query component of every URL
# --visit-host HOST Visit URLs with the matching host name
# --visit-hosts-like /REGEX/ Visit URLs with hostnames that match the REGEX
# --ignore-host HOST Ignore the host name
# --ignore-hosts-like /REGEX/ Ignore the host names matching the REGEX
# --visit-port PORT Visit URLs with the matching port number
# --visit-ports-like /REGEX/ Visit URLs with port numbers that match the REGEX
# --ignore-port PORT Ignore the port number
# --ignore-ports-like /REGEX/ Ignore the port numbers matching the REGEXP
# --visit-link URL Visit the URL
# --visit-links-like /REGEX/ Visit URLs that match the REGEX
# --ignore-link URL Ignore the URL
# --ignore-links-like /REGEX/ Ignore URLs matching the REGEX
# --visit-ext FILE_EXT Visit URLs with the matching file ext
# --visit-exts-like /REGEX/ Visit URLs with file exts that match the REGEX
# --ignore-ext FILE_EXT Ignore the URLs with the file ext
# --ignore-exts-like /REGEX/ Ignore URLs with file exts matching the REGEX
# -r, --robots Specifies whether to honor robots.txt
# -v, --verbose Enables verbose output
# --lfi-os unix|windows Sets the OS to test for
# --lfi-depth COUNT Sets the directory depth to escape up
# --lfi-filter-bypass null_byte|double_escape|base64|rot13|zlib
# Sets the filter bypass strategy to use
# --rfi-filter-bypass double-encode|suffix-escape|null-byte
# Optional filter-bypass strategy to use
# --rfi-script-lang asp|asp.net|coldfusion|jsp|php|perl
# Explicitly specify the scripting language to test for
# --rfi-test-script-url URL Use an alternative test script URL
# --sqli-escape-quote Escapes quotation marks
# --sqli-escape-parens Escapes parenthesis
# --sqli-terminate Terminates the SQL expression with a --
# --ssti-test-expr {X*Y | X/Z | X+Y | X-Y}
# Optional numeric test to use
# --open-redirect-url URL Optional test URL to try to redirect to
#
# @since 2.0.0
#
class Vulns < Command

include Core::CLI::Logging
include SpiderOptions
include Ronin::Vulns::CLI::Printing
include Ronin::Vulns::CLI::Importable

option :first, desc: 'Stops spidering once the first vulnerability is found' do
@scan_mode = :first
end

option :all, short: '-A',
desc: 'Spiders every URL and tests every param' do
@scan_mode = :all
end

option :print_curl, desc: 'Also prints an example curl command for each vulnerability'

option :print_http, desc: 'Also prints an example HTTP request for each vulnerability'

option :import, desc: 'Imports discovered vulnerabilities into the database'

option :lfi_os, value: {
type: [:unix, :windows]
},
desc: 'Sets the OS to test for'

option :lfi_depth, value: {
type: Integer,
usage: 'COUNT'
},
desc: 'Sets the directory depth to escape up'

option :lfi_filter_bypass, value: {
type: [
:null_byte,
:double_escape,
:base64,
:rot13,
:zlib
]
},
desc: 'Sets the filter bypass strategy to use'

option :rfi_filter_bypass, value: {
type: {
'double-encode' => :double_encode,
'suffix-escape' => :suffix_escape,
'null-byte' => :null_byte
}
},
desc: 'Optional filter-bypass strategy to use'

option :rfi_script_lang, value: {
type: {
'asp' => :asp,
'asp.net' => :asp_net,
'coldfusion' => :cold_fusion,
'jsp' => :jsp,
'php' => :php,
'perl' => :perl
}
},
desc: 'Explicitly specify the scripting language to test for'

option :rfi_test_script_url, value: {
type: String,
usage: 'URL'
},
desc: 'Use an alternative test script URL'

option :sqli_escape_quote, desc: 'Escapes quotation marks'

option :sqli_escape_parens, desc: 'Escapes parenthesis'

option :sqli_terminate, desc: 'Terminates the SQL expression with a --'

option :ssti_test_expr, value: {
type: %r{\A\d+\s*[\*/\+\-]\s*\d+\z},
usage: '{X*Y | X/Z | X+Y | X-Y}'
},
desc: 'Optional numeric test to use' do |expr|
@ssti_test_expr = Ronin::Vulns::SSTI::TestExpression.parse(expr)
end

option :open_redirect_url, value: {
type: String,
usage: 'URL'
},
desc: 'Optional test URL to try to redirect to'

description "Spiders a website and scans every URL for web vulnerabilities"

man_page 'ronin-web-vulns.1'

# The scan mode
#
# @return [:first, :all]
attr_reader :scan_mode

#
# Initializes the `ronin-web vulns` command.
#
# @param [Hash{Symbol => Object}] kwargs
# Additional keyword arguments.
#
def initialize(**kwargs)
super(**kwargs)

@scan_mode = :all
end

#
# Runs the `ronin-web vulns` command.
#
def run
db_connect if options[:import]

vulns = []

begin
new_agent do |agent|
case @scan_mode
when :first
agent.every_url do |url|
log_info "Testing #{url}"

if (vuln = test_url(url))
process_vuln(vuln)
vulns << vuln

agent.stop
end
end
when :all
agent.every_url do |url|
log_info "Testing #{url}"

scan_url(url) do |vuln|
process_vuln(vuln)
vulns << vuln
end
end
end
end
rescue Interrupt
puts
end

puts unless vulns.empty?
print_vulns(vulns)
end

#
# Logs and optioanlly imports a new discovered web vulnerability.
#
# @param [Ronin::Vulns::WebVuln] vuln
# The discovered web vulnerability.
#
# @since 2.0.0
#
def process_vuln(vuln)
log_vuln(vuln)
import_vuln(vuln) if options[:import]
end

#
# Scans the URL for web vulnerabilities.
#
# @param [URI::HTTP, String] url
# The URL to scan.
#
# @yield [vuln]
# The given block will be yielded each discovered web vulnerability.
#
# @yieldparam [Ronin::Vulns::LFI,
# Ronin::Vulns::RFI,
# Ronin::Vulns::SQLI,
# Ronin::Vulns::SSTI,
# Ronin::Vulns::ReflectedXSS,
# Ronin::Vulns::OpenRedirect] vuln
# A discovered web vulnerability in the URL.
#
def scan_url(url,&block)
Ronin::Vulns::URLScanner.scan(url,&block)
end

#
# Tests the URL for web vulnerabilities and prints the first
# vulnerability.
#
# @param [URI::HTTP, String] url
# The URL to scan.
#
# @return [Ronin::Vulns::LFI,
# Ronin::Vulns::RFI,
# Ronin::Vulns::SQLI,
# Ronin::Vulns::SSTI,
# Ronin::Vulns::ReflectedXSS,
# Ronin::Vulns::OpenRedirect, nil]
# The first discovered web vulnerability or `nil` if no
# vulnerabilities were discovered.
#
def test_url(url)
Ronin::Vulns::URLScanner.test(url)
end

end
end
end
end
end
Loading

0 comments on commit 63758ef

Please sign in to comment.