Class: Rex::Proto::Http::Request
- Defined in:
- lib/rex/proto/http/request.rb
Overview
HTTP request class.
Direct Known Subclasses
Defined Under Namespace
Constant Summary collapse
- PostRequests =
['POST', 'SEARCH']
Instance Attribute Summary collapse
-
#junk_directories ⇒ Object
add junk directories.
-
#junk_end_of_uri ⇒ Object
add junk end of URI.
-
#junk_param_start ⇒ Object
add junk start of params.
-
#junk_params ⇒ Object
add junk params.
-
#junk_pipeline ⇒ Object
add junk pipeline requests.
-
#junk_self_referring_directories ⇒ Object
add junk self referring directories (aka /././././).
-
#junk_slashes ⇒ Object
add junk slashes.
-
#method ⇒ Object
The method being used for the request (e.g. GET).
-
#proto ⇒ Object
The protocol to be sent with the request.
-
#raw_uri ⇒ Object
The raw URI being requested, before any mucking gets to it.
-
#relative_resource ⇒ Object
The resource path relative to the root of a server mount point.
-
#uri_encode_mode ⇒ Object
encoding uri.
-
#uri_parts ⇒ Object
The split up parts of the URI.
Attributes inherited from Packet
#auto_cl, #body_bytes_left, #bufq, #chunk_max_size, #chunk_min_size, #compress, #error, #headers, #incomplete, #inside_chunk, #keepalive, #max_data, #state, #transfer_chunked
Instance Method Summary collapse
- #body ⇒ Object
-
#cmd_string ⇒ Object
Returns the command string derived from the three values.
-
#initialize(method = 'GET', uri = '/', proto = DefaultProtocol) ⇒ Request
constructor
Initializes an instance of an HTTP request with the supplied method, URI, and protocol.
-
#meta_vars ⇒ Object
Returns a hash of variables that contain information about the request, such as the remote host information.
-
#normalize!(str) ⇒ Object
normalize out multiple slashes, directory traversal, and self referrential directories.
- #param_string ⇒ Object
-
#parse_cgi_qstring(str) ⇒ Object
Parses a CGI query string into the var/val combinations.
-
#qstring ⇒ Object
If there were CGI parameters in the URI, this will hold a hash of each variable to value.
-
#resource ⇒ Object
Returns the resource that is being requested.
-
#resource=(rsrc) ⇒ Object
Changes the resource URI.
-
#to_s ⇒ Object
Returns a request packet.
-
#update_cmd_parts(str) ⇒ Object
Updates the command parts for this specific packet type.
-
#update_uri_parts ⇒ Object
Split the URI into the resource being requested and its query string.
-
#uri ⇒ Object
Puts a URI back together based on the URI parts.
-
#uri=(str) ⇒ Object
Updates the underlying URI structure.
Methods inherited from Packet
#[], #[]=, #check_100, #chunk, #completed?, #from_s, #output_packet, #parse, #parse_body, #parse_header, #reset, #reset_except_queue, #to_terminal_output
Constructor Details
#initialize(method = 'GET', uri = '/', proto = DefaultProtocol) ⇒ Request
Initializes an instance of an HTTP request with the supplied method, URI, and protocol.
55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 |
# File 'lib/rex/proto/http/request.rb', line 55 def initialize(method = 'GET', uri = '/', proto = DefaultProtocol) super() self.method = method self.raw_uri = uri self.uri_parts = {} self.proto = proto || DefaultProtocol self.chunk_min_size = 1 self.chunk_max_size = 10 self.uri_encode_mode = 'hex-normal' if self.method == 'GET' || self.method == 'CONNECT' self.auto_cl = false end update_uri_parts end |
Instance Attribute Details
#junk_directories ⇒ Object
add junk directories
298 299 300 |
# File 'lib/rex/proto/http/request.rb', line 298 def junk_directories @junk_directories end |
#junk_end_of_uri ⇒ Object
add junk end of URI
316 317 318 |
# File 'lib/rex/proto/http/request.rb', line 316 def junk_end_of_uri @junk_end_of_uri end |
#junk_param_start ⇒ Object
add junk start of params
313 314 315 |
# File 'lib/rex/proto/http/request.rb', line 313 def junk_param_start @junk_param_start end |
#junk_params ⇒ Object
add junk params
307 308 309 |
# File 'lib/rex/proto/http/request.rb', line 307 def junk_params @junk_params end |
#junk_pipeline ⇒ Object
add junk pipeline requests
310 311 312 |
# File 'lib/rex/proto/http/request.rb', line 310 def junk_pipeline @junk_pipeline end |
#junk_self_referring_directories ⇒ Object
add junk self referring directories (aka /././././)
304 305 306 |
# File 'lib/rex/proto/http/request.rb', line 304 def junk_self_referring_directories @junk_self_referring_directories end |
#junk_slashes ⇒ Object
add junk slashes
301 302 303 |
# File 'lib/rex/proto/http/request.rb', line 301 def junk_slashes @junk_slashes end |
#method ⇒ Object
The method being used for the request (e.g. GET).
277 278 279 |
# File 'lib/rex/proto/http/request.rb', line 277 def method @method end |
#proto ⇒ Object
The protocol to be sent with the request.
290 291 292 |
# File 'lib/rex/proto/http/request.rb', line 290 def proto @proto end |
#raw_uri ⇒ Object
The raw URI being requested, before any mucking gets to it
281 282 283 |
# File 'lib/rex/proto/http/request.rb', line 281 def raw_uri @raw_uri end |
#relative_resource ⇒ Object
The resource path relative to the root of a server mount point.
295 296 297 |
# File 'lib/rex/proto/http/request.rb', line 295 def relative_resource @relative_resource end |
#uri_encode_mode ⇒ Object
encoding uri
319 320 321 |
# File 'lib/rex/proto/http/request.rb', line 319 def uri_encode_mode @uri_encode_mode end |
#uri_parts ⇒ Object
The split up parts of the URI.
286 287 288 |
# File 'lib/rex/proto/http/request.rb', line 286 def uri_parts @uri_parts end |
Instance Method Details
#body ⇒ Object
220 221 222 223 224 225 226 227 228 229 230 |
# File 'lib/rex/proto/http/request.rb', line 220 def body str = super || '' if str.length > 0 return str end if PostRequests.include?(self.method) return param_string end '' end |
#cmd_string ⇒ Object
Returns the command string derived from the three values.
235 236 237 238 239 |
# File 'lib/rex/proto/http/request.rb', line 235 def cmd_string proto_str = (self.proto =~ /^\d/) ? "HTTP/#{self.proto}" : self.proto "#{self.method} #{self.uri} #{proto_str}\r\n" end |
#meta_vars ⇒ Object
Returns a hash of variables that contain information about the request, such as the remote host information.
TODO
271 272 |
# File 'lib/rex/proto/http/request.rb', line 271 def end |
#normalize!(str) ⇒ Object
normalize out multiple slashes, directory traversal, and self referrential directories
109 110 111 112 113 |
# File 'lib/rex/proto/http/request.rb', line 109 def normalize!(str) i = 0 while (str.gsub!(/(\/\.\/|\/\w+\/\.\.\/|\/\/)/,'/')); i += 1; end i end |
#param_string ⇒ Object
169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 |
# File 'lib/rex/proto/http/request.rb', line 169 def param_string params=[] self.uri_parts['QueryString'].each_pair { |param, value| # inject a random number of params in between each param if self.junk_params rand(10)+5.times { params.push(Rex::Text.rand_text_alpha(rand(16) + 5) + '=' + Rex::Text.rand_text_alpha(rand(10) + 1)) } end if value.kind_of?(Array) value.each { |subvalue| params.push(Rex::Text.uri_encode(param, self.uri_encode_mode) + '=' + Rex::Text.uri_encode(subvalue, self.uri_encode_mode)) } else if !value.nil? params.push(Rex::Text.uri_encode(param, self.uri_encode_mode) + '=' + Rex::Text.uri_encode(value, self.uri_encode_mode)) else params.push(Rex::Text.uri_encode(param, self.uri_encode_mode)) end end } # inject some junk params at the end of the param list, just to be sure :P if self.junk_params rand(10)+5.times { params.push(Rex::Text.rand_text_alpha(rand(32) + 5) + '=' + Rex::Text.rand_text_alpha(rand(64) + 5)) } end params.join('&') end |
#parse_cgi_qstring(str) ⇒ Object
Parses a CGI query string into the var/val combinations.
324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 |
# File 'lib/rex/proto/http/request.rb', line 324 def parse_cgi_qstring(str) qstring = {} # Delimit on each variable str.split(/[;&]/).each { |vv| var = vv val = '' if (md = vv.match(/(.+?)=(.*)/)) var = md[1] val = md[2] end # Add the item to the hash with logic to convert values to an array # if so desired. if (qstring.include?(var)) if (qstring[var].kind_of?(Array)) qstring[var] << val else curr = self.qstring[var] qstring[var] = [ curr, val ] end else qstring[var] = val end } return qstring end |
#qstring ⇒ Object
If there were CGI parameters in the URI, this will hold a hash of each variable to value. If there is more than one value for a given variable, an array of each value is returned.
261 262 263 |
# File 'lib/rex/proto/http/request.rb', line 261 def qstring self.uri_parts['QueryString'] end |
#resource ⇒ Object
Returns the resource that is being requested.
244 245 246 |
# File 'lib/rex/proto/http/request.rb', line 244 def resource self.uri_parts['Resource'] end |
#resource=(rsrc) ⇒ Object
Changes the resource URI. This is used when making a request relative to a given mount point.
252 253 254 |
# File 'lib/rex/proto/http/request.rb', line 252 def resource=(rsrc) self.uri_parts['Resource'] = rsrc end |
#to_s ⇒ Object
Returns a request packet
207 208 209 210 211 212 213 214 215 216 217 218 |
# File 'lib/rex/proto/http/request.rb', line 207 def to_s str = '' if self.junk_pipeline host = '' if self.headers['Host'] host = "Host: #{self.headers['Host']}\r\n" end str << "GET / HTTP/1.1\r\n#{host}Connection: Keep-Alive\r\n\r\n" * self.junk_pipeline self.headers['Connection'] = 'Closed' end str + super end |
#update_cmd_parts(str) ⇒ Object
Updates the command parts for this specific packet type.
76 77 78 79 80 81 82 83 84 85 86 |
# File 'lib/rex/proto/http/request.rb', line 76 def update_cmd_parts(str) if (md = str.match(/^(.+?)\s+(.+?)\s+HTTP\/(.+?)\r?\n?$/i)) self.method = md[1] self.raw_uri = CGI.unescape(md[2]) self.proto = md[3] update_uri_parts else raise RuntimeError, "Invalid request command string", caller end end |
#update_uri_parts ⇒ Object
Split the URI into the resource being requested and its query string.
91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 |
# File 'lib/rex/proto/http/request.rb', line 91 def update_uri_parts # If it has a query string, get the parts. if ((self.raw_uri) and (md = self.raw_uri.match(/(.+?)\?(.*)$/))) self.uri_parts['QueryString'] = parse_cgi_qstring(md[2]) self.uri_parts['Resource'] = md[1] # Otherwise, just assume that the URI is equal to the resource being # requested. else self.uri_parts['QueryString'] = {} self.uri_parts['Resource'] = self.raw_uri end self.normalize!(resource) # Set the relative resource to the actual resource. self.relative_resource = resource end |
#uri ⇒ Object
Puts a URI back together based on the URI parts
116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 |
# File 'lib/rex/proto/http/request.rb', line 116 def uri str = self.uri_parts['Resource'].dup || '/' # /././././ if self.junk_self_referring_directories str.gsub!(/\//) { '/.' * (rand(3) + 1) + '/' } end # /%3faaa=bbbbb # which could possibly decode to "/?aaa=bbbbb", which if the IDS normalizes first, then splits the URI on ?, then it can be bypassed if self.junk_param_start str.sub!(/\//, '/%3f' + Rex::Text.rand_text_alpha(rand(5) + 1) + '=' + Rex::Text.rand_text_alpha(rand(10) + 1) + '/../') end # /RAND/../RAND../ if self.junk_directories str.gsub!(/\//) { dirs = '' (rand(5)+5).times { dirs << '/' + Rex::Text.rand_text_alpha(rand(5) + 1) + '/..' } dirs + '/' } end # //// # # NOTE: this must be done after all other odd directory junk, since they would cancel this out, except junk_end_of_uri, since that a specific slash in a specific place if self.junk_slashes str.gsub!(/\//) { '/' * (rand(3) + 2) } str.sub!(/^[\/]+/, '/') # only one beginning slash! end # /%20HTTP/1.0%0d%0a/../../ # which decodes to "/ HTTP/1.0\r\n" if self.junk_end_of_uri str.sub!(/^\//, '/%20HTTP/1.0%0d%0a/../../') end Rex::Text.uri_encode(str, self.uri_encode_mode) if !PostRequests.include?(self.method) if param_string.size > 0 str << '?' + param_string end end str end |
#uri=(str) ⇒ Object
Updates the underlying URI structure
201 202 203 204 |
# File 'lib/rex/proto/http/request.rb', line 201 def uri=(str) self.raw_uri = str update_uri_parts end |