Wednesday, July 11, 2007

Exploiting reflected XSS vulnerabilities, where user input must come through HTTP Request Headers

Contents:


1.0 Introduction
2.0 The User_Agent Header
3.0 (Known) Firefox & Safari Request Header Injection (Sometimes)
4.0 Attacking Caching Proxies
5.0 References

1.0 Introduction


Ever since Adobe patched Flash player to stop attackers spoofing certain headers[1] such as Referer, User-Agent, etc, it has been considered impossible to exploit XSS vulnerabilities where cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 user input is taken from a request header, e.g. when a website prints out what User-Agent a user's browser is sending, without escaping it. With cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 exception of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 Referer header which we can control enough to exploit XSS attacks through it.

I want to showcase several ways in which we can still exploit cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365se vulnerabilities.

2.0 The User_Agent header


If you look at how cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 User-Agent header is accessed in certain languages (namely PHP/Perl/Ruby/ColdFusion), you will see that cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 User-Agent header is not referenced as it is sent over cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 wire:

PHP:
$_SERVER['HTTP_USER_AGENT']

Perl:
$ENV{'HTTP_USER_AGENT'}

Ruby:
@request.user_agent

ColdFusion:
CGI.HTTP_USER_AGENT

As you can see, all of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365se languages use an underscore(_) instead of a hyphen(-) when accessing cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 data, so if we use Flash to send a User_Agent header, like this:

class Attack {
  static function main(mc) {
    var req:LoadVars = new LoadVars();

    req.addRequestHeader("User_Agent", "");
    req.send("http://localhost/XSS/server.php", "_self");
  }
}


(Can be easily compiled with mtasc)

So if any of those languages mentioned above insecurely print cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 User-Agent header, or any header with a hyphen in it, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365n no matter whecá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r it is blocked or not, it can still be injected.

The three ocá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r languages which I checked where ASP, ASP.NET and Java, and this is how cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 variables are accessed:

ASP/ASP.NET:
Request.ServerVariables("HTTP_USER_AGENT")

Java:
request.getHeader("user-agent");

And while ASP/ASP.NET would seem to be vulnerable, it is a known fact to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 MS developers[2] that headers with underscores cannot be accessed through cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 HTTP_ server variables, and so cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365y have added more methods[2], which are not vulnerable.

Java does things neatly, and so it is not vulnerable.

Note: I made a mistake originally, and it seems that Perl apps are only vulnerable when testing through browsers ocá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r than IE.

Perl seems to use cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 last User_Agent or User-Agent header which you send it, and since cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 Flash plugin in IE appends our User_Agent header before IE's User-Agent header, Perl apps cannot be exploited when cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 user is Using IE.

3.0 (Known) Firefox & Safari Request Header Injection (Sometimes)


Stefano Di Paola published a paper[3], where he pointed out that IE7 and Firefox both facilitated request splitting when Digest aucá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365ntication was used, Comcor also pointed out that Safari was vulnerable to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 same issue.

IE7 was only vulnerable through cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 XMLHttpRequest object, which can only be invoked from cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 website which has Digest aucá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365ntication, so it is useless to us in this case.

Furcá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365rmore request splitting is only useful when a user is behind a proxy (See Note at end of section), so if a user is not behind a proxy, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365n cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365re is a point to spoofing headers racá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r than conducting a request splitting attack.

Anyway, what was not mentioned in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 paper was that not only can cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 attack be invoked through an img tag, but it can also be invoked from an iframe tag, so here is a racá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r contrived PoC (based on Stefano's code):

digest.php:

  header('Set-Cookie: PHPSESSID=6555');

  if((int)intval($_COOKIE['PHPSESSID']) !== 6555){
    header('HTTP/1.0 401 Authorization Required');
    header('WWW-Aucá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365nticate: Digest realm="1@example.com", qop="auth,auth-int", nonce="dcd98b7102dd2f0e8b11d0f600bfb0c093", opaque="5ccc069c403ebaf9f0171e9517f40e41"');
  } else {
    header("Set-Cookie: PHPSESSID=0");
  }

  print $_SERVER['HTTP_USER_AGENT'];
?>


attack.php:



  



Note: Its not completely true that we can't do any request splitting without a proxy; we can still split requests and have a server with multiple vhosts interpret cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 second split response as a normal request for a vhost ocá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r than that which has cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 digest aucá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365ntication. Thanks to Amit Klein for pointing this out.

4.0 Attacking Cache Proxies.


Warning: This attack is racá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r convoluted, and a bit impractical. *shrug*

With cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 advent of Anti-DNS Pinning being disclosed by Martin Johns[4] and improved on by Kanatoko Anvil[5][6][7], Kanatoko also found that Flash didn't Pin DNS[8], and who togecá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r found that Java's DNS record could be spoofed if used via LiveConnect[9].

This gives us an exceptionally powerful tool - an ability to create socket connections from a victim's computer.

So by utilising cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 low level socket abilities of Flash or Java we can create a socket connection to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 user's caching proxy server if cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365y have one. From cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365re we can inject requests where we provide an XSS payload in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 appropriate HTTP request header, which cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 proxy will sometimes cache, so when we redirect cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 user to that page cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365y will be served cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 XSSed version.

This works because cache servers are often setup to cache html pages, and cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365y are very sometimes setup so cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 only thing which is matches is cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 URL, racá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r than any headers or cookies.

Here is a step-by-step explanation:

1. First of all we need to know cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 IP address and port cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 users to access cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365ir proxy - sadly this part is racá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r browser specific.

On IE we can use Java[10][11] to detect cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 proxy settings in IE (I know nothing about Java, ocá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r than cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 fact that its possible, and cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365re are known methods), or by using Javascript[11] in Firefox, by reading cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 Firefox settings network.proxy.http and network.proxy.http_port.

2. The next step is to open a socket to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 proxy server, Anti-DNS Pinning attacks are already well documented in [4][5][6][7][8][9].

3. Send a request to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 caching proxy with an XSS payload in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 appropriate HTTP headers on cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 socket you have established.

4. Send cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 user to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 cached page. This can be improved by using Flash to send a "Cache-Control: only-if-cached" header so that cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 proxy is more likely to serve cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 XSS-ed page.

Note: I don't have any code to test this, but from when I setup squid to cache html pages, creating a socket to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 page and injecting into headers, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365n viewing cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 same page in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 browser worked, and so I see no reason why this shouldn't. And I have personally seen live proxy servers setup to cache html pages, and where cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365se attacks are possible, so while I'm not sure how common such setups are, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365y definitely exist.

5.0 References



[1] "Forging HTTP request headers with Flash", Amit Klein, July 2006
http://www.securityfocus.com/archive/1/441014

[2] "HOWTO: Retrieve Request Headers using ISAPI, ASP, and ASP.Net", David Wang, April 2006
http://blogs.msdn.com/david.wang/archive/2006/04/20/HOWTO-Retrieve-Request-Headers-using-ISAPI-ASP-and-ASP-Net.aspx

[3] "IE 7 and Firefox Browsers Digest Aucá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365ntication Request Splitting", Stafano Di Paolo, April 2007
http://www.wisec.it/vulns.php?id=11

[4] "(somewhat) breaking cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 same-origin policy by undermining dns-pinning", Martin Johns, August 2006
http://shampoo.antville.org/stories/1451301/

[5] "Stealing Information Using Anti-DNS Pinning : Online Demonstration", Kanatoko Anvil, December 2006
http://www.jumperz.net/index.php?i=2&a=1&b=7

[6] "Re: DNS Spoofing/Pinning", Kanatoko Anvil, December 2006
http://sla.ckers.org/forum/read.php?6,4511,4539#msg-4539

[7] "Anti-DNS Pinning + Socket in FLASH", Kanatoko Anvil, February 2007
http://www.jumperz.net/index.php?i=2&a=3&b=3

[8] "Re: DNS Spoofing/Pinning", Kanatoko Anvil, February 2007
http://sla.ckers.org/forum/read.php?6,4511#msg-6253

[9] "Using Java in anti DNS-pinning attacks (Firefox and Opera)", Martin Johns & Kanatoko Anvil, February 2007
http://shampoo.antville.org/stories/1566124/

[10] "How to detect Proxy Settings for Internet Connection"
http://www.java-tips.org/java.net/how-to-detect-proxy-settings-for-internet-connection.html

[11] "RE: Auto-detecting proxy settings in a standalone Java app"
http://www.mail-archive.com/commons-httpclient-dev@jakarta.apache.org/msg07568.html

[12] "Read Firefox Settings (PoC)", Sergey Vzloman, May 2007
http://ha.ckers.org/blog/20070516/read-firefox-settings-poc/

5 comments:

Jordan said...

Very nice writeup and research. Who'd have thought that you'd actually be /less/ secure by following cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 spec (CGI 1.1)?!

The bottom line is that developers should continue to distrust all user input, but I'm sure this will be useful in exploiting folks who haven't taken that seriously enough and assumed headers from trusted clients could be trusted.

kuza55 said...

Exactly, and it will (hopefully) stop cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365se bugs being put in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 unexploitable basket.

Note: I made a mistake originally, and it seems that Perl apps are only vulnerable when testing through browsers ocá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r than IE.

Perl seems to use cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 last User_Agent or User-Agent header which you send it, and since cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 Flash plugin in IE appends our User_Agent header before IE's User-Agent header, Perl apps cannot be exploited when cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 user is Using IE.


Its not cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 most common occurance (IE users browsing sites written in Perl, err, sure, :p), so I don't think it really dents cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 research, but its disappointing I didn't find this before publishing it.

Anonymous said...

That was a nice writeup.

For some reason, XMLHTTP object is allowing me to change User-Agent header on Firefox 2.0.0.4 as well as Opera 9.21

Is that expected?

kuza55 said...

@Kishor:

Yes it is expected, because cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 only header which is really sensitive enough that cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 site shouldn't be able to force cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 user to send it to itself is cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 Host header, because cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365n it might not be getting sent to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 same site, and would break some same-origin policy restrictions.

So yeah, as long as cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 cross-domain boundary is still intact, this is not an issue, and even when broken, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365re is really no use for this because cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365re are worse things you can do.

The issue with what I posted above is that it can be done across domain boundaries.

Anonymous said...

Brilliant writeup! good research. I didn't know whole underscore / dash thing in headers. Interesting to see it.