Part of issue 87, issue 63, issue 29, issue 30

In preperation for creating requester and proxy unit tests:

  o Tidied up some of the requester and proxy
  o Partially de-coupled requester from proxy
  o Fixed minor bugs:
    o is_valid_uri was not implemented correctly
    o http scheme validation had "http" instead of "https"
This commit is contained in:
bcoles
2011-12-20 02:47:50 +10:30
parent 76414ca54a
commit 3ee52b82c0
8 changed files with 57 additions and 71 deletions

View File

@@ -28,6 +28,46 @@ module Filters
return false if not (str =~ /\-\-/).nil?
true
end
def self.is_valid_verb?(verb)
["HEAD", "GET", "POST", "OPTIONS", "PUT", "DELETE"].each {|v| return true if verb.eql? v }
false
end
def self.is_valid_url?(uri)
return true if !uri.nil?
# OPTIONS * is not yet supported
#return true if uri.eql? "*"
# TODO : CHECK THE normalize_path method and include it somewhere (maybe here)
#return true if uri.eql? self.normalize_path(uri)
false
end
def self.is_valid_http_version?(version)
# from browsers the http version contains a space at the end ("HTTP/1.0\r")
version.gsub!(/[\r]+/,"")
["HTTP/1.0", "HTTP/1.1"].each {|v| return true if version.eql? v }
false
end
def self.is_valid_host_str?(host_str)
# from browsers the host header contains a space at the end
host_str.gsub!(/[\r]+/,"")
return true if "Host:".eql?(host_str)
false
end
def normalize_path(path)
print_error "abnormal path `#{path}'" if path[0] != ?/
ret = path.dup
ret.gsub!(%r{/+}o, '/') # // => /
while ret.sub!(%r'/\.(?:/|\Z)', '/'); end # /. => /
while ret.sub!(%r'/(?!\.\./)[^/]+/\.\.(?:/|\Z)', '/'); end # /foo/.. => /foo
print_error "abnormal path `#{path}'" if %r{/\.\.(/|\Z)} =~ ret
ret
end
end
end

View File

@@ -154,7 +154,7 @@ beef.net = {
//build the url
var url = "";
if(path.indexOf("http://") != -1 || path.indexOf("http://") != -1){
if(path.indexOf("http://") != -1 || path.indexOf("https://") != -1){
url = path;
}else{
url = scheme + "://" + domain;

View File

@@ -30,6 +30,7 @@ beef.net.requester = {
send: function(requests_array) {
for (i in requests_array) {
request = requests_array[i];
beef.net.proxyrequest('http', request.method, request.host, request.port,
request.uri, null, request.headers, request.data, 10, null, request.id,
function(res, requestid) { beef.net.send('/requester', requestid, {
@@ -40,6 +41,8 @@ beef.net.requester = {
response_headers: res.headers});
}
);
}
}
};

View File

@@ -62,20 +62,24 @@ class Requester < BeEF::Extension::AdminUI::HttpController
# validate that the raw request is correct and can be used
req_parts = raw_request.split(/ |\n/) # break up the request
verb = req_parts[0]
self.err_msg 'Only HEAD, GET, POST, OPTIONS, PUT or DELETE requests are supported' if not BeEF::Filters.is_valid_verb?(verb) #check verb
uri = req_parts[1]
#self.err_msg 'Invalid URI' if not BeEF::Filters.is_valid_url?(uri) #check uri
version = req_parts[2]
(self.err_msg 'Invalid HTTP version';return @body = '{success : false}') if not BeEF::Filters.is_valid_http_version?(version) # check http version - HTTP/1.0
uri = req_parts[1]
(self.err_msg 'Invalid URI';return @body = '{success : false}') if not BeEF::Filters.is_valid_url?(uri) #check uri
version = req_parts[2]
(self.err_msg 'Invalid HTTP version';return @body = '{success : false}') if not BeEF::Filters.is_valid_http_version?(version) # check http version - HTTP/1.0 or HTTP/1.1
host_str = req_parts[3]
(self.err_msg 'Invalid HTTP Host Header';return @body = '{success : false}') if not BeEF::Filters.is_valid_host_str?(host_str) # check host string - Host:
host = req_parts[4]
host_parts = host.split(/:/)
hostname = host_parts[0]
(self.err_msg 'Invalid HTTP HostName';return @body = '{success : false}') if not BeEF::Filters.is_valid_hostname?(hostname) #check the target hostname
hostport = host_parts[1] || nil
if !hostport.nil?
(self.err_msg 'Invalid HTTP HostPort';return @body = '{success : false}') if not BeEF::Filters.nums_only?(hostport) #check the target hostport

View File

@@ -21,12 +21,13 @@ module Proxy
@short_name = 'proxy'
@full_name = 'proxy'
@description = 'The tunneling proxy allow to tunnel HTTP requests to the hooked domain through the victim browser'
@description = 'The tunneling proxy allows HTTP requests to the hooked domain to be tunneled through the victim browser'
end
end
end
require 'extensions/requester/models/http'
#require 'extensions/proxy/models/http'
require 'extensions/proxy/proxy'
require 'extensions/proxy/api'
require 'extensions/proxy/api'

View File

@@ -93,7 +93,7 @@ module BeEF
headers = @response['response_headers']
# The following is needed to forward back some of the original HTTP response headers obtained via XHR calls.
# Original XHR response headers are stored in extension_requester_http table (response_headers column),
# Original XHR response headers are stored in extension_proxy_http table (response_headers column),
# but we are forwarding back only some of them (Server, X-.. - like X-Powered-By -, Content-Type, ... ).
# Some of the original response headers need to be removed, like encoding and cache related: for example
# about encoding, the original response headers says that the content-length is 1000 as the response is gzipped,

View File

@@ -25,4 +25,3 @@ require 'extensions/requester/models/http'
require 'extensions/requester/api/hook'
require 'extensions/requester/handler'
require 'extensions/requester/api'
require 'extensions/requester/filters'

View File

@@ -1,61 +0,0 @@
#
# 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.
#
module BeEF
module Filters
def self.is_valid_verb?(verb)
["HEAD", "GET", "POST", "OPTIONS", "PUT", "DELETE"].each {|v| return true if verb.eql? v }
false
end
def self.is_valid_url?(uri)
# OPTIONS * is not yet supported
# return true if uri.eql? "*"
#TODO : CHECK THE normalize_path method and include it somewhere (maybe here)
return true if uri.eql? self.normalize_path(uri)
false
end
def self.is_valid_http_version?(version)
# from browsers the http version contains a space at the end ("HTTP/1.0\r")
version.gsub!(/[\r]+/,"")
return true if "HTTP/1.1".eql?(version) or "HTTP/1.0".eql?(version)
false
end
def self.is_valid_host_str?(host_str)
# from browsers the host header contains a space at the end
host_str.gsub!(/[\r]+/,"")
return true if "Host:".eql?(host_str)
false
end
def normalize_path(path)
print_error "abnormal path `#{path}'" if path[0] != ?/
ret = path.dup
ret.gsub!(%r{/+}o, '/') # // => /
while ret.sub!(%r'/\.(?:/|\Z)', '/'); end # /. => /
while ret.sub!(%r'/(?!\.\./)[^/]+/\.\.(?:/|\Z)', '/'); end # /foo/.. => /foo
print_error "abnormal path `#{path}'" if %r{/\.\.(/|\Z)} =~ ret
ret
end
end
end