class Rex::Proto::Http::ClientRequest
Constants
- DefaultConfig
- DefaultUserAgent
Attributes
opts[R]
Public Class Methods
new(opts={})
click to toggle source
# File lib/rex/proto/http/client_request.rb, line 87 def initialize(opts={}) @opts = DefaultConfig.merge(opts) @opts['headers'] ||= {} end
Public Instance Methods
to_s()
click to toggle source
# File lib/rex/proto/http/client_request.rb, line 92 def to_s # Start GET query string qstr = opts['query'] ? opts['query'].dup : "" # Start POST data string pstr = opts['data'] ? opts['data'].dup : "" if opts['cgi'] uri_str = set_uri if (opts['pad_get_params']) 1.upto(opts['pad_get_params_count'].to_i) do |i| qstr << '&' if qstr.length > 0 qstr << set_encode_uri(Rex::Text.rand_text_alphanumeric(rand(32)+1)) qstr << '=' qstr << set_encode_uri(Rex::Text.rand_text_alphanumeric(rand(32)+1)) end end opts['vars_get'].each_pair do |var,val| var = var.to_s qstr << '&' if qstr.length > 0 qstr << (opts['encode_params'] ? set_encode_uri(var) : var) # support get parameter without value # Example: uri?parameter if val val = val.to_s qstr << '=' qstr << (opts['encode_params'] ? set_encode_uri(val) : val) end end if (opts['pad_post_params']) 1.upto(opts['pad_post_params_count'].to_i) do |i| rand_var = Rex::Text.rand_text_alphanumeric(rand(32)+1) rand_val = Rex::Text.rand_text_alphanumeric(rand(32)+1) pstr << '&' if pstr.length > 0 pstr << (opts['encode_params'] ? set_encode_uri(rand_var) : rand_var) pstr << '=' pstr << (opts['encode_params'] ? set_encode_uri(rand_val) : rand_val) end end opts['vars_post'].each_pair do |var,val| var = var.to_s val = val.to_s pstr << '&' if pstr.length > 0 pstr << (opts['encode_params'] ? set_encode_uri(var) : var) pstr << '=' pstr << (opts['encode_params'] ? set_encode_uri(val) : val) end else if opts['encode'] qstr = set_encode_uri(qstr) end uri_str = set_uri end req = '' req << set_method req << set_method_uri_spacer() req << set_uri_prepend() if opts['encode'] req << set_encode_uri(uri_str) else req << uri_str end if (qstr.length > 0) req << '?' req << qstr end req << set_path_info req << set_uri_append() req << set_uri_version_spacer() req << set_version req << set_host_header # If an explicit User-Agent header is set, then use that instead of # the default unless opts['headers'] and opts['headers'].keys.map{|x| x.downcase }.include?('user-agent') req << set_agent_header end # Similar to user-agent, only add an automatic auth header if a # manual one hasn't been provided unless opts['headers'] and opts['headers'].keys.map{|x| x.downcase }.include?('authorization') req << set_auth_header end req << set_cookie_header req << set_connection_header req << set_extra_headers req << set_content_type_header req << set_content_len_header(pstr.length) req << set_chunked_header() req << opts['raw_headers'] req << set_body(pstr) end
Protected Instance Methods
set_agent_header()
click to toggle source
Return the HTTP agent header
# File lib/rex/proto/http/client_request.rb, line 367 def set_agent_header opts['agent'] ? set_formatted_header("User-Agent", opts['agent']) : "" end
set_auth_header()
click to toggle source
# File lib/rex/proto/http/client_request.rb, line 371 def set_auth_header opts['authorization'] ? set_formatted_header("Authorization", opts['authorization']) : "" end
set_body(bdata)
click to toggle source
Return the HTTP seperator and body string
# File lib/rex/proto/http/client_request.rb, line 453 def set_body(bdata) return "\r\n" + bdata if opts['chunked_size'] == 0 str = bdata.dup chunked = '' while str.size > 0 chunk = str.slice!(0,rand(opts['chunked_size']) + 1) chunked << sprintf("%x", chunk.size) + "\r\n" + chunk + "\r\n" end "\r\n" + chunked + "0\r\n\r\n" end
set_chunked_header()
click to toggle source
# File lib/rex/proto/http/client_request.rb, line 445 def set_chunked_header return "" if opts['chunked_size'] == 0 set_formatted_header('Transfer-Encoding', 'chunked') end
set_connection_header()
click to toggle source
Return the HTTP connection header
# File lib/rex/proto/http/client_request.rb, line 385 def set_connection_header opts['connection'] ? set_formatted_header("Connection", opts['connection']) : "" end
set_content_len_header(clen)
click to toggle source
Return the content length header
# File lib/rex/proto/http/client_request.rb, line 398 def set_content_len_header(clen) return "" if opts['chunked_size'] > 0 set_formatted_header("Content-Length", clen) end
set_content_type_header()
click to toggle source
Return the content type header
# File lib/rex/proto/http/client_request.rb, line 392 def set_content_type_header opts['ctype'] ? set_formatted_header("Content-Type", opts['ctype']) : "" end
set_encode_uri(str)
click to toggle source
# File lib/rex/proto/http/client_request.rb, line 231 def set_encode_uri(str) a = str.to_s.dup opts['uri_encode_count'].times { a = Rex::Text.uri_encode(a, opts['uri_encode_mode']) } return a end
set_extra_headers()
click to toggle source
Return a string of formatted extra headers
# File lib/rex/proto/http/client_request.rb, line 426 def set_extra_headers buf = '' if (opts['pad_fake_headers']) 1.upto(opts['pad_fake_headers_count'].to_i) do |i| buf << set_formatted_header( Rex::Text.rand_text_alphanumeric(rand(32)+1), Rex::Text.rand_text_alphanumeric(rand(32)+1) ) end end opts['headers'].each_pair do |var,val| buf << set_formatted_header(var, val) end buf end
set_formatted_header(var, val)
click to toggle source
Return a formatted header string
# File lib/rex/proto/http/client_request.rb, line 356 def set_formatted_header(var, val) if (self.opts['header_folding']) "#{var}:\r\n\t#{val}\r\n" else "#{var}: #{val}\r\n" end end
set_host_header()
click to toggle source
Return the HTTP Host header
# File lib/rex/proto/http/client_request.rb, line 406 def set_host_header return "" if opts['uri_full_url'] host = opts['vhost'] # IPv6 addresses must be placed in brackets if Rex::Socket.is_ipv6?(host) host = "[#{host}]" end # The port should be appended if non-standard if not [80,443].include?(opts['port']) host = host + ":#{opts['port']}" end set_formatted_header("Host", host) end
set_method()
click to toggle source
# File lib/rex/proto/http/client_request.rb, line 239 def set_method ret = opts['method'].dup if (opts['method_random_valid']) ret = ['GET', 'POST', 'HEAD'][rand(3)] end if (opts['method_random_invalid']) ret = Rex::Text.rand_text_alpha(rand(20)+1) end if (opts['method_random_case']) ret = Rex::Text.to_rand_case(ret) end ret end
set_method_uri_spacer()
click to toggle source
# File lib/rex/proto/http/client_request.rb, line 257 def set_method_uri_spacer len = opts['pad_method_uri_count'].to_i set = " " buf = "" case opts['pad_method_uri_type'] when 'tab' set = "\t" when 'apache' set = "\t \x0b\x0c\x0d" end while(buf.length < len) buf << set[ rand(set.length) ] end return buf end
set_path_info()
click to toggle source
Return the HTTP path info TODO:
* Encode path information
# File lib/rex/proto/http/client_request.rb, line 297 def set_path_info opts['path_info'] ? opts['path_info'] : '' end
set_uri()
click to toggle source
# File lib/rex/proto/http/client_request.rb, line 201 def set_uri uri_str = opts['uri'].dup if (opts['uri_dir_self_reference']) uri_str.gsub!('/', '/./') end if (opts['uri_dir_fake_relative']) buf = "" uri_str.split('/',-1).each do |part| cnt = rand(8)+2 1.upto(cnt) { |idx| buf << "/" + Rex::Text.rand_text_alphanumeric(rand(32)+1) } buf << ("/.." * cnt) buf << "/" + part end uri_str = buf end if (opts['uri_full_url']) url = opts['ssl'] ? "https://" : "http://" url << opts['vhost'] url << ((opts['port'] == 80) ? "" : ":#{opts['port']}") url << uri_str url else uri_str end end
set_uri_append()
click to toggle source
Return the padding to place before the uri
# File lib/rex/proto/http/client_request.rb, line 304 def set_uri_append # TODO: # * Support different padding types "" end
set_uri_prepend()
click to toggle source
Return the padding to place before the uri
# File lib/rex/proto/http/client_request.rb, line 279 def set_uri_prepend prefix = "" if (opts['uri_fake_params_start']) prefix << '/%3fa=b/../' end if (opts['uri_fake_end']) prefix << '/%20HTTP/1.0/../../' end prefix end
set_uri_version_spacer()
click to toggle source
Return the spacing between the uri and the version
# File lib/rex/proto/http/client_request.rb, line 313 def set_uri_version_spacer len = opts['pad_uri_version_count'].to_i set = " " buf = "" case opts['pad_uri_version_type'] when 'tab' set = "\t" when 'apache' set = "\t \x0b\x0c\x0d" end while(buf.length < len) buf << set[ rand(set.length) ] end return buf end
set_version()
click to toggle source
Return the HTTP version string
# File lib/rex/proto/http/client_request.rb, line 335 def set_version ret = opts['proto'] + "/" + opts['version'] if (opts['version_random_valid']) ret = opts['proto'] + "/" + ['1.0', '1.1'][rand(2)] end if (opts['version_random_invalid']) ret = Rex::Text.rand_text_alphanumeric(rand(20)+1) end if (opts['version_random_case']) ret = Rex::Text.to_rand_case(ret) end ret << "\r\n" end