Re: [W3af-develop] HTTP Parameter Parameter Pollution Plugin
For some strange reason, I kept this email in my inbox for a long time, unread but without actually doing anything. Created a github issue so I can remove this from my Inbox and it's also there for every other potential contributor to see. https://github.com/andresriancho/w3af/issues/167 On Mon, May 21, 2012 at 1:44 PM, Stephen Breen breen.mach...@gmail.com wrote: That's great! Thanks. I was meaning to do this soon and just hadn't gotten around to it. I'll definitely try these out soon. As of right now the plugin is pretty simple. All it does is inject into each parameter in the request (one at a time) and then check the links in the response to see if the injection succeeded. If it doesn't find any injectable parameters, it will go through the original response to find all the parameters in the response that weren't present in the URL. Then it tries the injection on each of these parameters (this is useful to find parameters that weren't specified in our original request). What I would like to do next is detect the parameter precedence for the page. So whether the server is using the first occurrence of a parameter, the second, some combination of both, or blowing up. I would also like to figure out if it is possible to exploit parameter injection into form values rather than just links in the page, from what I've seen so far the browser will URL encode anything you inject into a form variable, making it useless. I also haven't tested it for POST requests yet, although it should work and I believe it is still relevant because it could be exploited through javascript making the client perform a POST request with an injected parameter. Do you have any other suggestions for things this plugin should be able to do? On Mon, May 21, 2012 at 1:18 PM, Andres Riancho andres.rian...@gmail.com wrote: Stephen, I've implemented a couple of test scripts for HTTP Parameter Pollution that you can see here: http://sourceforge.net/apps/trac/w3af/browser/extras/testEnv/webroot/w3af/audit/hpp You might find them useful for testing your stuff, Regards, On Tue, May 15, 2012 at 7:27 PM, Stephen Breen breen.mach...@gmail.com wrote: I did, the most efficient way I could think to do it required the following changes to dataContainer.py and queryString.py. Basically all I did was add a _safeEncodeChars field to the dataContainer and make sure it was used when doing URL encoding: Index: core/data/dc/dataContainer.py === --- core/data/dc/dataContainer.py(revision 5002) +++ core/data/dc/dataContainer.py(working copy) @@ -38,7 +38,7 @@ super(DataContainer, self).__init__() self.encoding = encoding - +self._safeEncodeChars = '' if isinstance(init_val, DataContainer): self.update(init_val) elif isinstance(init_val, dict): @@ -80,7 +80,7 @@ @return: string representation of the DataContainer Object. ''' -return enc_dec.urlencode(self, encoding=self.encoding) +return enc_dec.urlencode(self, encoding=self.encoding,safe=self._safeEncodeChars) def __unicode__(self): ''' Index: core/data/dc/queryString.py === --- core/data/dc/queryString.py(revision 5002) +++ core/data/dc/queryString.py(working copy) @@ -43,4 +43,4 @@ @return: string representation of the QueryString object. ''' -return enc_dec.urlencode(self, encoding=self.encoding, safe='') \ No newline at end of file +return enc_dec.urlencode(self, encoding=self.encoding, safe=self._safeEncodeChars) \ No newline at end of file In my audit plugin, to avoid encoding the % character I do this before I create the mutants: def audit(self, freq): dc = freq.getDc() dc._safeEncodeChars +='%' for param in dc: mutants = createMutants(freq,['%26ZJkL%3DNrZp'],True,[param]) After these changes it works MOST of the time. When I give w3af a URL with a bunch of parameters, it generates 2 fuzzable requests if no discovery plugins are used; one request is the URL I provided, one has parameters that w3af seemed to pick randomly. For some reason the safeEncodeChars are ignored for the request w3af created. To fix this I had to add the % character to the default safe characters of the urlencode function. I don't like this fix very much and would like to figure out why it is necessary but here is the diff that makes it work for now: Index: core/data/parsers/encode_decode.py === --- core/data/parsers/encode_decode.py(revision 5002) +++ core/data/parsers/encode_decode.py(working copy) @@ -71,7 +71,7 @@ return
Re: [W3af-develop] HTTP Parameter Parameter Pollution Plugin
Stephen, I've implemented a couple of test scripts for HTTP Parameter Pollution that you can see here: http://sourceforge.net/apps/trac/w3af/browser/extras/testEnv/webroot/w3af/audit/hpp You might find them useful for testing your stuff, Regards, On Tue, May 15, 2012 at 7:27 PM, Stephen Breen breen.mach...@gmail.com wrote: I did, the most efficient way I could think to do it required the following changes to dataContainer.py and queryString.py. Basically all I did was add a _safeEncodeChars field to the dataContainer and make sure it was used when doing URL encoding: Index: core/data/dc/dataContainer.py === --- core/data/dc/dataContainer.py (revision 5002) +++ core/data/dc/dataContainer.py (working copy) @@ -38,7 +38,7 @@ super(DataContainer, self).__init__() self.encoding = encoding - + self._safeEncodeChars = '' if isinstance(init_val, DataContainer): self.update(init_val) elif isinstance(init_val, dict): @@ -80,7 +80,7 @@ @return: string representation of the DataContainer Object. ''' - return enc_dec.urlencode(self, encoding=self.encoding) + return enc_dec.urlencode(self, encoding=self.encoding,safe=self._safeEncodeChars) def __unicode__(self): ''' Index: core/data/dc/queryString.py === --- core/data/dc/queryString.py (revision 5002) +++ core/data/dc/queryString.py (working copy) @@ -43,4 +43,4 @@ @return: string representation of the QueryString object. ''' - return enc_dec.urlencode(self, encoding=self.encoding, safe='') \ No newline at end of file + return enc_dec.urlencode(self, encoding=self.encoding, safe=self._safeEncodeChars) \ No newline at end of file In my audit plugin, to avoid encoding the % character I do this before I create the mutants: def audit(self, freq): dc = freq.getDc() dc._safeEncodeChars +='%' for param in dc: mutants = createMutants(freq,['%26ZJkL%3DNrZp'],True,[param]) After these changes it works MOST of the time. When I give w3af a URL with a bunch of parameters, it generates 2 fuzzable requests if no discovery plugins are used; one request is the URL I provided, one has parameters that w3af seemed to pick randomly. For some reason the safeEncodeChars are ignored for the request w3af created. To fix this I had to add the % character to the default safe characters of the urlencode function. I don't like this fix very much and would like to figure out why it is necessary but here is the diff that makes it work for now: Index: core/data/parsers/encode_decode.py === --- core/data/parsers/encode_decode.py (revision 5002) +++ core/data/parsers/encode_decode.py (working copy) @@ -71,7 +71,7 @@ return CHAR_REF_PATT.sub(entitydecode, text) -def urlencode(query, encoding, safe='/\'=:()'): +def urlencode(query, encoding, safe='/\'=:()%'): ''' This is my version of urllib.urlencode. It adds / as a safe character and also adds support for repeated parameter names. On Tue, May 15, 2012 at 11:45 AM, Andres Riancho andres.rian...@gmail.com wrote: Stephen, On Sat, May 12, 2012 at 3:31 PM, Stephen Breen breen.mach...@gmail.com wrote: After comparing the browser and w3af requests/responses in wireshark I was able to figure it out. When I send the request: http://www.example.com/?x=abc%26ZJkL%3DNrZp In w3af it is being converted to: http://www.example.com/?x=abc%2526ZJkL%253DNrZp i.e. my '%' characters are being url encoded into a '%25'. Did you find the way to avoid that double encoding issue? On Wed, May 9, 2012 at 6:08 PM, Stephen Breen breen.mach...@gmail.com wrote: Forgive me, I don't have the time to be brief -- unfortunately this is going to be a longish one. I'm confused about an issue I've been having trying to detect client side parameter pollution vulnerabilities. Been stuck on this for a while. What I'm doing is for each parameter in a request, you inject an innocuous parameter, for example if the request were: http://www.example.com/?x=abcy=xyz We could inject the parameter ZJkl=NrZp like so: http://www.example.com/?x=abc%26ZJkL%3DNrZpy=xyz http://www.example.com/?x=abcy=xyz%26ZJkL%3DNrZp Then we examine the response from each of those requests and check if there are any links in the response that contain our injected parameter, so for example, in the response body if we found the following, it would mean the x parameter is vulnerable to parameter pollution: http://www.example.com/submit.php?x=abcZJkL=NrZpy=xyz If this is the case, then we can use the fact that a server will discard a duplicate
Re: [W3af-develop] HTTP Parameter Parameter Pollution Plugin
That's great! Thanks. I was meaning to do this soon and just hadn't gotten around to it. I'll definitely try these out soon. As of right now the plugin is pretty simple. All it does is inject into each parameter in the request (one at a time) and then check the links in the response to see if the injection succeeded. If it doesn't find any injectable parameters, it will go through the original response to find all the parameters in the response that weren't present in the URL. Then it tries the injection on each of these parameters (this is useful to find parameters that weren't specified in our original request). What I would like to do next is detect the parameter precedence for the page. So whether the server is using the first occurrence of a parameter, the second, some combination of both, or blowing up. I would also like to figure out if it is possible to exploit parameter injection into form values rather than just links in the page, from what I've seen so far the browser will URL encode anything you inject into a form variable, making it useless. I also haven't tested it for POST requests yet, although it should work and I believe it is still relevant because it could be exploited through javascript making the client perform a POST request with an injected parameter. Do you have any other suggestions for things this plugin should be able to do? On Mon, May 21, 2012 at 1:18 PM, Andres Riancho andres.rian...@gmail.comwrote: Stephen, I've implemented a couple of test scripts for HTTP Parameter Pollution that you can see here: http://sourceforge.net/apps/trac/w3af/browser/extras/testEnv/webroot/w3af/audit/hpp You might find them useful for testing your stuff, Regards, On Tue, May 15, 2012 at 7:27 PM, Stephen Breen breen.mach...@gmail.com wrote: I did, the most efficient way I could think to do it required the following changes to dataContainer.py and queryString.py. Basically all I did was add a _safeEncodeChars field to the dataContainer and make sure it was used when doing URL encoding: Index: core/data/dc/dataContainer.py === --- core/data/dc/dataContainer.py(revision 5002) +++ core/data/dc/dataContainer.py(working copy) @@ -38,7 +38,7 @@ super(DataContainer, self).__init__() self.encoding = encoding - +self._safeEncodeChars = '' if isinstance(init_val, DataContainer): self.update(init_val) elif isinstance(init_val, dict): @@ -80,7 +80,7 @@ @return: string representation of the DataContainer Object. ''' -return enc_dec.urlencode(self, encoding=self.encoding) +return enc_dec.urlencode(self, encoding=self.encoding,safe=self._safeEncodeChars) def __unicode__(self): ''' Index: core/data/dc/queryString.py === --- core/data/dc/queryString.py(revision 5002) +++ core/data/dc/queryString.py(working copy) @@ -43,4 +43,4 @@ @return: string representation of the QueryString object. ''' -return enc_dec.urlencode(self, encoding=self.encoding, safe='') \ No newline at end of file +return enc_dec.urlencode(self, encoding=self.encoding, safe=self._safeEncodeChars) \ No newline at end of file In my audit plugin, to avoid encoding the % character I do this before I create the mutants: def audit(self, freq): dc = freq.getDc() dc._safeEncodeChars +='%' for param in dc: mutants = createMutants(freq,['%26ZJkL%3DNrZp'],True,[param]) After these changes it works MOST of the time. When I give w3af a URL with a bunch of parameters, it generates 2 fuzzable requests if no discovery plugins are used; one request is the URL I provided, one has parameters that w3af seemed to pick randomly. For some reason the safeEncodeChars are ignored for the request w3af created. To fix this I had to add the % character to the default safe characters of the urlencode function. I don't like this fix very much and would like to figure out why it is necessary but here is the diff that makes it work for now: Index: core/data/parsers/encode_decode.py === --- core/data/parsers/encode_decode.py(revision 5002) +++ core/data/parsers/encode_decode.py(working copy) @@ -71,7 +71,7 @@ return CHAR_REF_PATT.sub(entitydecode, text) -def urlencode(query, encoding, safe='/\'=:()'): +def urlencode(query, encoding, safe='/\'=:()%'): ''' This is my version of urllib.urlencode. It adds / as a safe character and also adds support for repeated parameter names. On Tue, May 15, 2012 at 11:45 AM, Andres Riancho andres.rian...@gmail.com wrote: Stephen, On Sat, May
Re: [W3af-develop] HTTP Parameter Parameter Pollution Plugin
Stephen, On Sat, May 12, 2012 at 3:31 PM, Stephen Breen breen.mach...@gmail.com wrote: After comparing the browser and w3af requests/responses in wireshark I was able to figure it out. When I send the request: http://www.example.com/?x=abc%26ZJkL%3DNrZp In w3af it is being converted to: http://www.example.com/?x=abc%2526ZJkL%253DNrZp i.e. my '%' characters are being url encoded into a '%25'. Did you find the way to avoid that double encoding issue? On Wed, May 9, 2012 at 6:08 PM, Stephen Breen breen.mach...@gmail.com wrote: Forgive me, I don't have the time to be brief -- unfortunately this is going to be a longish one. I'm confused about an issue I've been having trying to detect client side parameter pollution vulnerabilities. Been stuck on this for a while. What I'm doing is for each parameter in a request, you inject an innocuous parameter, for example if the request were: http://www.example.com/?x=abcy=xyz We could inject the parameter ZJkl=NrZp like so: http://www.example.com/?x=abc%26ZJkL%3DNrZpy=xyz http://www.example.com/?x=abcy=xyz%26ZJkL%3DNrZp Then we examine the response from each of those requests and check if there are any links in the response that contain our injected parameter, so for example, in the response body if we found the following, it would mean the x parameter is vulnerable to parameter pollution: http://www.example.com/submit.php?x=abcZJkL=NrZpy=xyz If this is the case, then we can use the fact that a server will discard a duplicate parameter and use either the first or second occurrence to overwrite other parameters in the requests for the forms and links on the page. The problem I am having is that while my browser (firefox) will return responses containing things like: http://www.example.om/submit.php?x=abcZJkL=NrZpy=xyz When I use sendMutant or urlOpener.GET, the same request will result in the URL in the response looking like this: http://www.example.om/submit.php?x=abc%26ZJkL%3DNrZpy=xyz The characters are not being decoded and I have no idea why! I thought that the decoding would be done on the server side, is this done in the browser? Does that mean these vulnerabilities will be browser specific? I'm really not sure how this works behind the scenes. For a real example of this vulnerability I've been using the following URL for testing: http://www.pof.com/basicsearch.aspx?iama=m%26ZJkL%3DNrZpseekinga=fminage=18maxage=40imagesetting=0searchtype=intent=ethnicity=0country=1City=Chicagoz_code=miles=25sorting=0cmdSearch=SearchProfession=Interests=save=1#in If you look at the links to More Search Results 1,2,3 etc... on the bottom of the page, you will see that the parameter ZJkL=NrZp has been injected into the links. Thanks! On Wed, May 2, 2012 at 11:02 PM, Andres Riancho andres.rian...@gmail.com wrote: Stephen, On Wed, May 2, 2012 at 4:10 PM, Stephen Breen breen.mach...@gmail.com wrote: In case anyone else is interested in this, someone else has already created a system to scan and detect HTTP parameter pollution vulnerabilities. They don't provide the source for their tool but it can be found here: http://papas.iseclab.org/cgi-bin/index.py Their paper describing how it works can be found here: http://www.iseclab.org/people/embyte/papers/hpp.pdf I plan on reading it and taking a shot at implementation as a w3af plugin. Great! For comparing HTTP response bodies (which I assume you'll have to do) take a look at levenshtein.py (relative_distance_boolean function). Regards, -- Live Security Virtual Conference Exclusive live event will cover all the ways today's security and threat landscape has changed and how IT managers can respond. Discussions will include endpoint security, mobile security and the latest in malware threats. http://www.accelacomm.com/jaw/sfrnl04242012/114/50122263/ ___ W3af-develop mailing list W3af-develop@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/w3af-develop -- Andrés Riancho Project Leader at w3af - http://w3af.org/ Web Application Attack and Audit Framework Twitter: @w3af GPG: 0x93C344F3 -- Andrés Riancho Project Leader at w3af - http://w3af.org/ Web Application Attack and Audit Framework Twitter: @w3af GPG: 0x93C344F3 -- Live Security Virtual Conference Exclusive live event will cover all the ways today's security and threat landscape has changed and how IT managers can respond. Discussions will include endpoint security, mobile security and the latest in malware threats. http://www.accelacomm.com/jaw/sfrnl04242012/114/50122263/ ___ W3af-develop mailing list W3af-develop@lists.sourceforge.net
Re: [W3af-develop] HTTP Parameter Parameter Pollution Plugin
I did, the most efficient way I could think to do it required the following changes to dataContainer.py and queryString.py. Basically all I did was add a _safeEncodeChars field to the dataContainer and make sure it was used when doing URL encoding: Index: core/data/dc/dataContainer.py === --- core/data/dc/dataContainer.py(revision 5002) +++ core/data/dc/dataContainer.py(working copy) @@ -38,7 +38,7 @@ super(DataContainer, self).__init__() self.encoding = encoding - +self._safeEncodeChars = '' if isinstance(init_val, DataContainer): self.update(init_val) elif isinstance(init_val, dict): @@ -80,7 +80,7 @@ @return: string representation of the DataContainer Object. ''' -return enc_dec.urlencode(self, encoding=self.encoding) +return enc_dec.urlencode(self, encoding=self.encoding,safe=self._safeEncodeChars) def __unicode__(self): ''' Index: core/data/dc/queryString.py === --- core/data/dc/queryString.py(revision 5002) +++ core/data/dc/queryString.py(working copy) @@ -43,4 +43,4 @@ @return: string representation of the QueryString object. ''' -return enc_dec.urlencode(self, encoding=self.encoding, safe='') \ No newline at end of file +return enc_dec.urlencode(self, encoding=self.encoding, safe=self._safeEncodeChars) \ No newline at end of file In my audit plugin, to avoid encoding the % character I do this before I create the mutants: def audit(self, freq): dc = freq.getDc() dc._safeEncodeChars +='%' for param in dc: mutants = createMutants(freq,['%26ZJkL%3DNrZp'],True,[param]) After these changes it works MOST of the time. When I give w3af a URL with a bunch of parameters, it generates 2 fuzzable requests if no discovery plugins are used; one request is the URL I provided, one has parameters that w3af seemed to pick randomly. For some reason the safeEncodeChars are ignored for the request w3af created. To fix this I had to add the % character to the default safe characters of the urlencode function. I don't like this fix very much and would like to figure out why it is necessary but here is the diff that makes it work for now: Index: core/data/parsers/encode_decode.py === --- core/data/parsers/encode_decode.py(revision 5002) +++ core/data/parsers/encode_decode.py(working copy) @@ -71,7 +71,7 @@ return CHAR_REF_PATT.sub(entitydecode, text) -def urlencode(query, encoding, safe='/\'=:()'): +def urlencode(query, encoding, safe='/\'=:()%'): ''' This is my version of urllib.urlencode. It adds / as a safe character and also adds support for repeated parameter names. On Tue, May 15, 2012 at 11:45 AM, Andres Riancho andres.rian...@gmail.comwrote: Stephen, On Sat, May 12, 2012 at 3:31 PM, Stephen Breen breen.mach...@gmail.com wrote: After comparing the browser and w3af requests/responses in wireshark I was able to figure it out. When I send the request: http://www.example.com/?x=abc%26ZJkL%3DNrZp In w3af it is being converted to: http://www.example.com/?x=abc%2526ZJkL%253DNrZp i.e. my '%' characters are being url encoded into a '%25'. Did you find the way to avoid that double encoding issue? On Wed, May 9, 2012 at 6:08 PM, Stephen Breen breen.mach...@gmail.com wrote: Forgive me, I don't have the time to be brief -- unfortunately this is going to be a longish one. I'm confused about an issue I've been having trying to detect client side parameter pollution vulnerabilities. Been stuck on this for a while. What I'm doing is for each parameter in a request, you inject an innocuous parameter, for example if the request were: http://www.example.com/?x=abcy=xyz We could inject the parameter ZJkl=NrZp like so: http://www.example.com/?x=abc%26ZJkL%3DNrZpy=xyz http://www.example.com/?x=abcy=xyz%26ZJkL%3DNrZp Then we examine the response from each of those requests and check if there are any links in the response that contain our injected parameter, so for example, in the response body if we found the following, it would mean the x parameter is vulnerable to parameter pollution: http://www.example.com/submit.php?x=abcZJkL=NrZpy=xyz If this is the case, then we can use the fact that a server will discard a duplicate parameter and use either the first or second occurrence to overwrite other parameters in the requests for the forms and links on the page. The problem I am having is that while my browser (firefox) will return responses containing things like: http://www.example.om/submit.php?x=abcZJkL=NrZpy=xyz When I use sendMutant or urlOpener.GET, the same request will result in the URL in the response looking
Re: [W3af-develop] HTTP Parameter Parameter Pollution Plugin
Stephen, On Wed, May 2, 2012 at 4:10 PM, Stephen Breen breen.mach...@gmail.com wrote: In case anyone else is interested in this, someone else has already created a system to scan and detect HTTP parameter pollution vulnerabilities. They don't provide the source for their tool but it can be found here: http://papas.iseclab.org/cgi-bin/index.py Their paper describing how it works can be found here: http://www.iseclab.org/people/embyte/papers/hpp.pdf I plan on reading it and taking a shot at implementation as a w3af plugin. Great! For comparing HTTP response bodies (which I assume you'll have to do) take a look at levenshtein.py (relative_distance_boolean function). Regards, -- Live Security Virtual Conference Exclusive live event will cover all the ways today's security and threat landscape has changed and how IT managers can respond. Discussions will include endpoint security, mobile security and the latest in malware threats. http://www.accelacomm.com/jaw/sfrnl04242012/114/50122263/ ___ W3af-develop mailing list W3af-develop@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/w3af-develop -- Andrés Riancho Project Leader at w3af - http://w3af.org/ Web Application Attack and Audit Framework Twitter: @w3af GPG: 0x93C344F3 -- Live Security Virtual Conference Exclusive live event will cover all the ways today's security and threat landscape has changed and how IT managers can respond. Discussions will include endpoint security, mobile security and the latest in malware threats. http://www.accelacomm.com/jaw/sfrnl04242012/114/50122263/ ___ W3af-develop mailing list W3af-develop@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/w3af-develop