diff --git a/README.md b/README.md index bb353e8..2c39c66 100644 --- a/README.md +++ b/README.md @@ -271,6 +271,25 @@ end # => [#, ...] ``` +### URI + +Finds all vulnerabilities for a given URI: + +```ruby +require 'ronin/vulns/core_ext' + +URI('https://example.com/page.php?lang=en').vulns +# => [#, ...] + +``` + +Check if a URI contains any vulnerabilities: + +```ruby +URI('https://example.com/page.php?lang=en').has_vulns? +# => true +``` + ## Requirements * [Ruby] >= 3.0.0 diff --git a/lib/ronin/vulns.rb b/lib/ronin/vulns.rb index 6cc15f8..9bde574 100644 --- a/lib/ronin/vulns.rb +++ b/lib/ronin/vulns.rb @@ -30,3 +30,4 @@ require_relative 'vulns/url_scanner' require_relative 'vulns/importer' require_relative 'vulns/version' +require_relative 'vulns/core_ext' diff --git a/lib/ronin/vulns/core_ext.rb b/lib/ronin/vulns/core_ext.rb new file mode 100644 index 0000000..0195e52 --- /dev/null +++ b/lib/ronin/vulns/core_ext.rb @@ -0,0 +1,19 @@ +# frozen_string_literal: true +# +# Copyright (c) 2006-2024 Hal Brodigan (postmodern.mod3 at gmail.com) +# +# ronin-support is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published +# by the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# ronin-support 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 Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with ronin-support. If not, see . +# + +require_relative "core_ext/uri" diff --git a/lib/ronin/vulns/core_ext/uri.rb b/lib/ronin/vulns/core_ext/uri.rb new file mode 100644 index 0000000..f17e3a8 --- /dev/null +++ b/lib/ronin/vulns/core_ext/uri.rb @@ -0,0 +1,19 @@ +# frozen_string_literal: true +# +# Copyright (c) 2006-2024 Hal Brodigan (postmodern.mod3 at gmail.com) +# +# ronin-support is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published +# by the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# ronin-support 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 Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with ronin-support. If not, see . +# + +require_relative "uri/http" diff --git a/lib/ronin/vulns/core_ext/uri/http.rb b/lib/ronin/vulns/core_ext/uri/http.rb new file mode 100644 index 0000000..7aa0e39 --- /dev/null +++ b/lib/ronin/vulns/core_ext/uri/http.rb @@ -0,0 +1,73 @@ +# frozen_string_literal: true +# +# Copyright (c) 2006-2024 Hal Brodigan (postmodern.mod3 at gmail.com) +# +# ronin-support is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published +# by the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# ronin-support 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 Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with ronin-support. If not, see . +# + +require_relative "../../../vulns/url_scanner" + +module URI + # + # Provides helper methods for HTTP + # + # ## Core-Ext Methods + # + # * { URI::HTTP#vulns } + # * { URI::HTTP#has_vulns? } + # + # @api public + # + class HTTP + + # + # Return all vulnerabilities found for URI + # + # @param [Hash{Symbol => Object}] kwargs + # Additional keyword arguments for + # {Ronin::Vulns::URLScanner.scan}. + # + # @return [Array] + # All discovered Web vulnerabilities + # + # @example + # URI('https://testphp.vulnweb.com/').vulns + # # => [#, ...] + # + # @see Ronin::Vulns::URLScanner.scan + # + def vulns(**kwargs) + Ronin::Vulns::URLScanner.scan(self, **kwargs) + end + + # + # Checks if the URI contains any vulnerabilities + # + # @param [Hash{Symbol => Object}] kwargs + # Additional keyword arguments for + # {Ronin::Vulns::URLScanner.test}. + # + # @return [Boolean] + # + # @example + # URI('https://testphp.vulnweb.com/').has_vulns? + # # => true + # + # @see Ronin::Vulns::URLScanner.test + # + def has_vulns?(**kwargs) + Ronin::Vulns::URLScanner.test(self, **kwargs) != nil + end + end +end diff --git a/spec/core_ext/uri/http_spec.rb b/spec/core_ext/uri/http_spec.rb new file mode 100644 index 0000000..52fab84 --- /dev/null +++ b/spec/core_ext/uri/http_spec.rb @@ -0,0 +1,47 @@ +require 'spec_helper' +require 'ronin/vulns/core_ext/uri/http' + +describe URI::HTTP do + let(:url) { 'https://example.com/' } + + subject { URI(url) } + + let(:web_vuln1) { Ronin::Vulns::LFI.new(url) } + let(:web_vuln2) { Ronin::Vulns::SQLI.new(url) } + + describe "#vulns" do + context "when URI contains vulnerabilities" do + it "must return array with vulnerabilities" do + expect(Ronin::Vulns::URLScanner).to receive(:scan).and_return([web_vuln1, web_vuln2]) + + expect(subject.vulns).to match_array([web_vuln1, web_vuln2]) + end + end + + context "when URI does not contain any vulnerabilities" do + it "must return an empty array" do + expect(Ronin::Vulns::URLScanner).to receive(:scan).and_return([]) + + expect(subject.vulns).to be_empty + end + end + end + + describe "#has_vulns?" do + context "when URI contains vulnerabilities" do + it "must return true" do + expect(Ronin::Vulns::URLScanner).to receive(:test).and_return(web_vuln1) + + expect(subject.has_vulns?).to be(true) + end + end + + context "when URI does not contain any vulnerabilities" do + it "must return false" do + expect(Ronin::Vulns::URLScanner).to receive(:test).and_return(nil) + + expect(subject.has_vulns?).to be(false) + end + end + end +end