From 52fa0da439aed59e65098fca1dc0f88e8d44b4cd Mon Sep 17 00:00:00 2001 From: bmc <> Date: Mon, 23 Jan 2006 21:58:53 +0000 Subject: [PATCH] * add support for inserting junk directories, slashes, and params git-svn-id: file:///home/svn/incoming/trunk@3436 4d416f70-5f16-0410-b530-b9f4589650da --- lib/rex/proto/http/request.rb | 94 +++++++++++++++++++++++++++-- lib/rex/proto/http/request.rb.ut.rb | 29 +++++++++ 2 files changed, 117 insertions(+), 6 deletions(-) diff --git a/lib/rex/proto/http/request.rb b/lib/rex/proto/http/request.rb index e15ffd37d3..cf164ef556 100644 --- a/lib/rex/proto/http/request.rb +++ b/lib/rex/proto/http/request.rb @@ -53,7 +53,7 @@ class Request < Packet super() self.method = method - self.uri = uri + self.raw_uri = uri self.uri_parts = {} self.proto = proto || DefaultProtocol @@ -66,7 +66,7 @@ class Request < Packet def update_cmd_parts(str) if (md = str.match(/^(.+?)\s+(.+?)\s+HTTP\/(.+?)\r?\n?$/)) self.method = md[1] - self.uri = URI.decode(md[2]) + self.raw_uri = URI.decode(md[2]) self.proto = md[3] update_uri_parts @@ -80,20 +80,91 @@ class Request < Packet # def update_uri_parts # If it has a query string, get the parts. - if ((self.uri) and (md = self.uri.match(/(.+?)\?(.*)$/))) + 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.uri + self.uri_parts['Resource'] = self.raw_uri end # Set the relative resource to the actual resource. self.relative_resource = resource end + # Puts a URI back together based on the URI parts + def uri + uri = self.uri_parts['Resource'] || '/' + + if self.junk_directories + uri.gsub!(/\//) { + dirs = '' + rand(10)+5.times { + dirs += '/' + Rex::Text.rand_text_alpha(rand(64) + 5) + '/..' + } + dirs + '/' + } + end + + # NOTE: this must be done after junk directories, since junk_directories would cancel this out + if self.junk_slashes + uri.gsub!(/\//) { + '/' * (rand(5) + 2) + } + end + + if self.method != 'POST' + 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.nil? + params.push(self.escape(param) + '=' + self.escape(value)) + else + params.push(self.escape(param)) + 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 + + if params.size > 0 + uri += '?' + params.join('&') + end + end + uri + end + + # Updates the underlying URI structure + def uri=(uri) + self.raw_uri = uri + update_uri_parts + end + + def inject_directories(uri) + + end + + # Returns a URI escaped version of the provided string, by providing an additional argument, all characters are escaped + def escape(str, all = nil) + if all + return str.gsub(/./) { |s| Rex::Text.to_hex(s, '%') } + else + return str.gsub(/[^a-zA-Z1-9]/) { |s| Rex::Text.to_hex(s, '%') } + end + end + + # # Returns the command string derived from the three values. # @@ -139,9 +210,10 @@ class Request < Packet # attr_accessor :method # - # The URI being requested. + # The raw URI being requested, before any mucking gets to it # - attr_accessor :uri + attr_accessor :raw_uri + # # The split up parts of the URI. # @@ -155,6 +227,16 @@ class Request < Packet # attr_accessor :relative_resource + # add junk directories + attr_accessor :junk_directories + + # add junk slashes + attr_accessor :junk_slashes + + + # add junk params + attr_accessor :junk_params + protected # diff --git a/lib/rex/proto/http/request.rb.ut.rb b/lib/rex/proto/http/request.rb.ut.rb index 97903ca7e4..1c478a3940 100644 --- a/lib/rex/proto/http/request.rb.ut.rb +++ b/lib/rex/proto/http/request.rb.ut.rb @@ -50,4 +50,33 @@ class Rex::Proto::Http::Request::UnitTest < Test::Unit::TestCase assert_equal("GET /bar HTTP/1.2\r\n", h.cmd_string, 'set proto') end + def test_params + h = Klass.new + h.from_s("GET /foo?a=1&b=2 HTTP/1.0\r\n" + + "Foo: Bar\r\n\r\n") + assert_equal('GET', h.method, 'method') + assert_equal('1.0', h.proto, 'proto') + assert_equal('Bar', h['Foo'], 'header') + assert_equal('/foo?a=1&b=2', h.uri, 'uri') + + h.uri_parts['QueryString']['c'] = '3' + assert_equal('/foo?a=1&b=2&c=3', h.uri, 'uri with additional params') + + h.uri_parts['QueryString']['d'] = '=' + assert_equal('/foo?a=1&b=2&c=3&d=%3d', h.uri, 'uri with additional params that require escaping') + + srand(0) + h.junk_directories = 1 + assert_equal('/DDnJT/../ykXGYYMBmnXuYRlZNIJUzQzFPv/../SjYxz/../TTOngBJgfKXjLyciAAkFmoRPEpqfBBnpjm/../LuSbAOjMqULEGEvDMkoOPUjXPNVwxFpjAfFeAxykiwdDiqNwnVJAKyrXCije/../foo?a=1&b=2&c=3&d=%3d', h.uri, 'uri with junk directories') + + srand(0) + h.junk_slashes = 1 + assert_equal('//////DDnJT////..////ykXGYYMBmnXuYRlZNIJUzQzFPv////..//////SjYxz////..//////TTOngBJgfKXjLyciAAkFmoRPEpqfBBnpjm/////..//////LuSbAOjMqULEGEvDMkoOPUjXPNVwxFpjAfFeAxykiwdDiqNwnVJAKyrXCije///..//DDnJT//ujURybOpBkKWroLCzQgAmTu///..//////zoNeYCDeirNwoITfIaCDsOgEDtLWNtLQYdVuZQThogkGVfN//..///YPpSoPLmvdBf////..///sYYDSvDqMmjWFXrgLoUKrlcvoCbTZXzuUdDjnJJpXDuaysDfJKbtHnVhsii//..//////hFokALiFQIBRwjbokwZDnjyedxhSR//////..//////..//CFlMsCvbVnnLWeRGHScrTxpduVJZygbJcrRpAWQqkeYDzIbduXgTIHXNRALckZgqOW////..//////USEWjTHINFAIPPLEnctaKuxbzjpSizerS/////..////XBGqweQajxqJsNGmnINHQWPZIjGRHUZCQytXYEksxXeZUhlXbd///../////zzWHpxJATkRUwDqBUkEQwvKtoebrfUGJbvjTMS////..//KihrDMkBxAnYkjFGDiohcEagtzJFhHeIUHDVbsDmUHTfAFbreJTHVl/////..////ykXGYYMBmnXuYRlZNIJUzQzFPv////uAozmZKziXgTaOgzGhsytpEdbRjCUtPkpExyNetXijJaaWMP////..////azmuQvoAKLNHeGtePpmrSHcBpCycOlbkfdyudyh//////../////gpQCIzKwabBAFYiPD////..///ulrTYGUGczGCccmlFtJkNVfRjtzIZVtlWQZulBFGMaKOIHtFvqDKybZDOSFERFeYD////..//////okxYhShOxH/////../////..////uwhRdMugizXZuyrpuAMJSEHDwMltwtSzxHaxudDKUqBUQqyc////..///XwCmJCspZkaEpKMohlnghajZyYSUecI/////../////ZYnqcYSDsTtAKDGbjGTiyym/////..//rAktpChMPhXMFmBKGGmmLyVyy/////../////CMdJzIFrBrPMvMVSZNecspVGkwoaeFPllxfgwQgKMdAdanWTFkTkFcMa///..///SjYxz//////MmHQdAXPKDDQwJUlwRJsPmOh///../////QkHXbuHWi/////../////QbvvyLXOneaiRjHtwlENlTrIgRFkBdFQmoW///..////TEUqKDWldpoRzoqedheulYQjndBXIAXlvaZ//..//////GYPlpRQwruFTvWtLLhHawHvgkSXVCI////..//..///mkBkFFmjYxPUyJExYeCTDNLNkRaGviVUqRlZVkEviLi//////..//////uTwLhZhftGZYtmzQXaDaudCFHPOjnHzmzdxLDN///..////YEzWdmLOSZsDlHdOLJLQnBScAVYJISLczRPDqYVcVOvBMLZnLatiBQBQhhsmoIN//../////TygXEfWAlfPTPzMtKpQGVeDQABygrSSWPPcHbYYMNSOOUHs/////..//bsPXLNdfuSEcBxxXQpawCvRUmAGsWPKiomVigqsjpnbwKERD/////..////TTOngBJgfKXjLyciAAkFmoRPEpqfBBnpjm///XdmeLCdHzJXAwRozVeaPwRKRDnJdDHQiEak/////..///gRlbzOWfIdc/////../////iRcvQIsHMgUrLdoAUtcNlvnyEuMlwEpkQSle//////../////ujwAxJyhwxMGzkjmkeyTmsjOdzRDdbDhzbkVnqKdxdYyQAkiNBCCTMenVN//////..//azMxABkKqgcCcBNTvRkHGJPSdqSCdRjTQXMjtCUDRsmqKlqovbEzWl/////../////../////HYYvPKTNnlnSHYgsnovkqQaoQugeUXPsTib//////../////iRXbNwXeFnhxicBEVIyhjwjZFBjHBBHZkNsybgrTitkQwqrDIT////..//AUgirFVYCHsLzcfBQySOVvvFhqCboTPHsdjhwxQYFzqTRtgWhmJ///..///MqQREZOtRd//////..//cKFkkUyyWKr//..///LuSbAOjMqULEGEvDMkoOPUjXPNVwxFpjAfFeAxykiwdDiqNwnVJAKyrXCije//////BoHFPpgXOidzZEAaUFYREgxRIJkfeJswjgOXgcrhyusIlCRPDVwyd////..//WSHxaEtZazvTOSgbkmUsDSNzxfhSMvbniHetQBYQtb///..////yYwMEwzuoOxKbOmNEWPdOqZLfbWurUCZAfuGSWuZNM////..////lTfcTooZvdcqKURAnmiBwWtxWncBVCgyGmjkXzSmZuPxbVBJzRLADkUTvFUEpQQFgWD/////..////cpKmcfsLibxHn////..///..//////FJYMohOtPEWCHtIFnPPpZWZZTdJLjanSIBjyxuKKYfrbNOFXqnxlmLrYRVeS/////..///ZdlxoxqfnLOgBBkZMIyMYTDKHcOIujjRXMtHvuneTqtyBrSOZlIyiaLsLokxMRfKwKLd///..////KMxnwKCvLuzpbDQANmEDTRQHYLWbCIIZmhYVEfz/////..//////lHWqfJzzSXTZFZtv//////..///zsargeOHgBvtraPEKVnqreWARMbrv/////..///foo?a=1&b=2&c=3&d=%3d', h.uri, 'uri with junk directories') + + h = Klass.new + h.from_s("GET /foo?a=1&b=2 HTTP/1.0\r\n" + "Foo: Bar\r\n\r\n") + h.junk_params = 1 + assert_equal("/foo?sZHlUi=t&nhhBJXEYGhyYK=cYDSVGUVb&ZAuDlHQLLsCFROF=pu&eiDAdssszARdbiyzk=elRmPB&pWtRsWNyvCLJyozvEKxG=sIIIslS&a=1&dlkqdbRLxI=DwLyPDknV&DLPtaPhLFeEglrtdbn=LhOmLKZgy&GeWLjUEExdbvT=aaJyfeRHz&JcvwHDHI=Fhcumx&BCQCLfKUkOHdF=uPz&b=2&bGJBLXGokMjFMSABUNawrVONoDpR=abrtpNtwRW&ZcNHaRErvecIbGHaLldxUdcXJAmTHymDelpF=QafGZLRffUanyKmEnPNjmLnLwkSLziQcJlIRwscZeleSMBbKDQbGAHZDksVxIvmq&kEbNNp=GeMiDoQFodWlX&kriGGYMRfwlAKxsEfKdhpwNTpMszrQyl=kyEyvAxlLsFouQQKFXv&mwSeQfqv=hKsfTCTfyTnnhssenMQQGEtUeM",h.uri, 'junk params') + + end end