Class: Rex::Proto::Http::Request
- Defined in:
- lib/rex/proto/http/request.rb
Overview
HTTP request class.
Defined Under Namespace
Classes: Get, Post, Put, UnitTest
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, #bufq, #chunk_max_size, #chunk_min_size, #compress, #error, #headers, #incomplete, #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
-
#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
#[], #[]=, #chunk, #completed?, #from_s, #parse, #reset, #reset_except_queue
Constructor Details
#initialize(method = 'GET', uri = '/', proto = DefaultProtocol) ⇒ Request
Initializes an instance of an HTTP request with the supplied method, URI, and protocol.
54 55 56 57 58 59 60 61 62 63 64 65 66 |
# File 'lib/rex/proto/http/request.rb', line 54 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' update_uri_parts end |
Instance Attribute Details
#junk_directories ⇒ Object
add junk directories
293 294 295 |
# File 'lib/rex/proto/http/request.rb', line 293 def junk_directories @junk_directories end |
#junk_end_of_uri ⇒ Object
add junk end of URI
311 312 313 |
# File 'lib/rex/proto/http/request.rb', line 311 def junk_end_of_uri @junk_end_of_uri end |
#junk_param_start ⇒ Object
add junk start of params
308 309 310 |
# File 'lib/rex/proto/http/request.rb', line 308 def junk_param_start @junk_param_start end |
#junk_params ⇒ Object
add junk params
302 303 304 |
# File 'lib/rex/proto/http/request.rb', line 302 def junk_params @junk_params end |
#junk_pipeline ⇒ Object
add junk pipeline requests
305 306 307 |
# File 'lib/rex/proto/http/request.rb', line 305 def junk_pipeline @junk_pipeline end |
#junk_self_referring_directories ⇒ Object
add junk self referring directories (aka /././././)
299 300 301 |
# File 'lib/rex/proto/http/request.rb', line 299 def junk_self_referring_directories @junk_self_referring_directories end |
#junk_slashes ⇒ Object
add junk slashes
296 297 298 |
# File 'lib/rex/proto/http/request.rb', line 296 def junk_slashes @junk_slashes end |
#method ⇒ Object
The method being used for the request (e.g. GET).
272 273 274 |
# File 'lib/rex/proto/http/request.rb', line 272 def method @method end |
#proto ⇒ Object
The protocol to be sent with the request.
285 286 287 |
# File 'lib/rex/proto/http/request.rb', line 285 def proto @proto end |
#raw_uri ⇒ Object
The raw URI being requested, before any mucking gets to it
276 277 278 |
# File 'lib/rex/proto/http/request.rb', line 276 def raw_uri @raw_uri end |
#relative_resource ⇒ Object
The resource path relative to the root of a server mount point.
290 291 292 |
# File 'lib/rex/proto/http/request.rb', line 290 def relative_resource @relative_resource end |
#uri_encode_mode ⇒ Object
encoding uri
314 315 316 |
# File 'lib/rex/proto/http/request.rb', line 314 def uri_encode_mode @uri_encode_mode end |
#uri_parts ⇒ Object
The split up parts of the URI.
281 282 283 |
# File 'lib/rex/proto/http/request.rb', line 281 def uri_parts @uri_parts end |
Instance Method Details
#body ⇒ Object
215 216 217 218 219 220 221 222 223 224 225 |
# File 'lib/rex/proto/http/request.rb', line 215 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.
230 231 232 233 234 |
# File 'lib/rex/proto/http/request.rb', line 230 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
266 267 |
# File 'lib/rex/proto/http/request.rb', line 266 def end |
#normalize!(str) ⇒ Object
normalize out multiple slashes, directory traversal, and self referrential directories
104 105 106 107 108 |
# File 'lib/rex/proto/http/request.rb', line 104 def normalize!(str) i = 0 while (str.gsub!(/(\/\.\/|\/\w+\/\.\.\/|\/\/)/,'/')); i += 1; end i end |
#param_string ⇒ Object
164 165 166 167 168 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 |
# File 'lib/rex/proto/http/request.rb', line 164 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 |
#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.
256 257 258 |
# File 'lib/rex/proto/http/request.rb', line 256 def qstring self.uri_parts['QueryString'] end |
#resource ⇒ Object
Returns the resource that is being requested.
239 240 241 |
# File 'lib/rex/proto/http/request.rb', line 239 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.
247 248 249 |
# File 'lib/rex/proto/http/request.rb', line 247 def resource=(rsrc) self.uri_parts['Resource'] = rsrc end |
#to_s ⇒ Object
Returns a request packet
202 203 204 205 206 207 208 209 210 211 212 213 |
# File 'lib/rex/proto/http/request.rb', line 202 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.
71 72 73 74 75 76 77 78 79 80 81 |
# File 'lib/rex/proto/http/request.rb', line 71 def update_cmd_parts(str) if (md = str.match(/^(.+?)\s+(.+?)\s+HTTP\/(.+?)\r?\n?$/)) self.method = md[1] self.raw_uri = URI.decode(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.
86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 |
# File 'lib/rex/proto/http/request.rb', line 86 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
111 112 113 114 115 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 |
# File 'lib/rex/proto/http/request.rb', line 111 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
196 197 198 199 |
# File 'lib/rex/proto/http/request.rb', line 196 def uri=(str) self.raw_uri = str update_uri_parts end |