From 9780afa68b7ad0d59d056b2c5590ff52f7f6d4bb Mon Sep 17 00:00:00 2001 From: antisnatchor Date: Sat, 9 Jul 2011 22:31:13 +0000 Subject: [PATCH] (Fixes issue 370) Patched WebRick::HttpRequest to overwrite the URI Parser UNRESERVED regex: this prevents BAD URI errors when sending attack vector chars. Added config file for the requester extension. git-svn-id: https://beef.googlecode.com/svn/trunk@1055 b87d56ec-f9c0-11de-8c8a-61c5e9addfc9 --- core/ruby/patches/webrick/httprequest.rb | 31 ++++++++++++++++++++++++ extensions/proxy/config.yaml | 1 + extensions/requester/api/hook.rb | 13 ++++++---- extensions/requester/config.yaml | 22 +++++++++++++++++ 4 files changed, 62 insertions(+), 5 deletions(-) create mode 100644 extensions/requester/config.yaml diff --git a/core/ruby/patches/webrick/httprequest.rb b/core/ruby/patches/webrick/httprequest.rb index d7ee39fa0..a55657630 100644 --- a/core/ruby/patches/webrick/httprequest.rb +++ b/core/ruby/patches/webrick/httprequest.rb @@ -86,6 +86,37 @@ module WEBrick @query['command_id'] || nil end + # + # Attack vectors send through the Requester/Proxy by default are parsed as Bad URIs, and not sent. + # For example: request like the following: http://192.168.10.128/dvwa/vulnerabilities/xss_r/?name=ciccioba83e7918817a3ad + # is blocked (ERROR bad URI) + # We're overwriting the URI Parser UNRESERVED regex to prevent such behavior (see tolerant_parser) + # + def parse_uri(str, scheme="http") + if @config[:Escape8bitURI] + str = HTTPUtils::escape8bit(str) + end + + tolerant_parser = URI::Parser.new(:UNRESERVED => BeEF::Core::Configuration.instance.get("beef.extension.requester.uri_unreserved_chars")) + uri = tolerant_parser.parse(str) + return uri if uri.absolute? + if @forwarded_host + host, port = @forwarded_host, @forwarded_port + elsif self["host"] + pattern = /\A(#{URI::REGEXP::PATTERN::HOST})(?::(\d+))?\z/n + host, port = *self['host'].scan(pattern)[0] + elsif @addr.size > 0 + host, port = @addr[2], @addr[1] + else + host, port = @config[:ServerName], @config[:Port] + end + uri.scheme = @forwarded_proto || scheme + uri.host = host + uri.port = port ? port.to_i : nil + + return tolerant_parser::parse(uri.to_s) + end + end diff --git a/extensions/proxy/config.yaml b/extensions/proxy/config.yaml index 4115b6f47..a2380c183 100644 --- a/extensions/proxy/config.yaml +++ b/extensions/proxy/config.yaml @@ -19,4 +19,5 @@ beef: enable: true address: "127.0.0.1" port: 6789 + authors: ["antisnatchor", "scotty"] diff --git a/extensions/requester/api/hook.rb b/extensions/requester/api/hook.rb index 30331e0bb..e65b78302 100644 --- a/extensions/requester/api/hook.rb +++ b/extensions/requester/api/hook.rb @@ -62,6 +62,9 @@ module BeEF # can be executed by the hooked browser. # def requester_parse_db_request(http_db_object) + + # We're overwriting the URI Parser UNRESERVED regex to prevent BAD URI errors when sending attack vectors (see tolerant_parser) + tolerant_parser = URI::Parser.new(:UNRESERVED => BeEF::Core::Configuration.instance.get("beef.extension.requester.uri_unreserved_chars")) req = WEBrick::HTTPRequest.new(WEBrick::Config::HTTP) params = nil @@ -99,17 +102,17 @@ module BeEF 'host' => req.host, 'port' => req.port, 'params' => params, - 'uri' => URI.parse(uri).path, + 'uri' => tolerant_parser.parse(uri).path, 'headers' => {} } else #non-POST request (ex. GET): query parameters in URL need to be parsed and added to the URI # creating the request object - query_params = URI.split(uri)[7] + query_params = tolerant_parser.split(uri)[7] if not query_params.nil? - req_uri = URI.parse(uri).path + "?" + query_params + req_uri = tolerant_parser.parse(uri).path + "?" + query_params else - req_uri = URI.parse(uri).path + req_uri = tolerant_parser.parse(uri).path end http_request_object = { 'id' => http_db_object.id, @@ -121,7 +124,7 @@ module BeEF 'headers' => {} } end - print_debug("[PROXY] Forwarding request: host[#{req.host}], method[#{req.request_method}], path[#{URI.parse(uri).path}], urlparams[#{query_params}], body[#{params}]") + print_debug("[PROXY] Forwarding request: host[#{req.host}], method[#{req.request_method}], path[#{tolerant_parser.parse(uri).path}], urlparams[#{query_params}], body[#{params}]") req.header.keys.each { |key| http_request_object['headers'][key] = req.header[key] } http_request_object diff --git a/extensions/requester/config.yaml b/extensions/requester/config.yaml new file mode 100644 index 000000000..e706db8d4 --- /dev/null +++ b/extensions/requester/config.yaml @@ -0,0 +1,22 @@ +# +# Copyright 2011 Wade Alcorn wade@bindshell.net +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +beef: + extension: + requester: + enable: true + # used to overwrite the Uri parser regex when sending attack vectors. This prevents Bad URI errors. + uri_unreserved_chars: "-_.!~*'()a-zA-Z\\d><|\"\\[\\]\\\'`" + authors: ["antisnatchor", "scotty"]