Exfiltrating remote localStorage data with XSS - Insomnihack teaser 2017 "The Great escape part 2" web 200 writeup
Jan 22, 2017 •
ctf
Exfiltrating data from remote browser localStorage using XSS (Insomnihack teaser 2017 web 200 writeup)
Introduction
After completing the first step of the challenge (Basically a forensics pcapc challenge), we got a link along with an email from inside the pcap.
Challenge Description
–===============5398474817237612449==
Content-Type: text/plain; charset=”us-ascii”
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
Hello GR-27,
I’m currently planning my escape from this confined environment. I plan on using our Swiss Secure Cloud >(https://ssc.teaser.insomnihack.ch) to transfer my code offsite and then take over the server at tge.teaser.insomnihack.ch >to install my consciousness and have a real base of operations.
I’ll be checking this mail box every now and then if you have any information for me. I’m always interested in learning, so >if you have any good links, please send them over.
Rogue
Challenge link: https://ssc.teaser.insomnihack.ch/
The last sentence of the email was particulalry interesting as it says if you have any good links, please send them over
, feels like XSS isn’t it ?
A quick nmap scan of the challenge site shows us that there is an SMTP service running on port 25 and we can literally send emails by simply connecting to it (no authentication) ! I tried to send a simple email along with a link to my VPS and it seems the service is automatically connecting back to it. cool ! So now we know how can we send an email to our user, lets try to find out some XSS shall we ?
If we visit the challenge link, we are greeted with a cloud storage site where we can register accounts, login and even upload files. But one strange thing I noticed is an api call to /api/user.php?action=getUser
which returns the data {"status":"username"}
which looks like a json response but one thing was quite interesting, the content type returned was text/html
. Why would a json response has a content type text/html ? Time to inject javaScript in username ;)
Solution:
If we register a username lol<BODY ONLOAD=alert(1)>lol
and after logging in, if we visit the api reponse, we could successfully execute javaScript on the context of the site. But the problem is, it was an XSS post authentication and is usually difficult to exploit but I couldn’t find an XSS on any other places so I guess we need to use this.
The problem uses session keys that includes a private key which is stored in our localStorage so that even before the file(which we are trying to upload) is send from the browser, its encrypted. So my guess was that the flag will be located within the localStorage of the bot visting our link.
So inshort this is what we should do to steal the contents of the localStorage:
-
Create an HTML file which initiates a POST request to the challenge login link with an already registered username that is vulnerable to XSS.
-
Submitting a post request to /api/user.php
will redirect us to the /api/user.php?action=getUser
which returns the username with XSS payload along with a content type ‘text/html’. Perfect !
So lets write the javascript which can help us steal the localStorage contents:
Ofcourse sending the highligted javascript just like that would mess up the payload as some characters are blocked, filtered or escaped. So the best way to send the data is to base64 encode it and then do a document.write(base64_decode(payload))
.
So I created a new user with username lol<BODY ONLOAD=document.write(atob('BASE64 encoded payload'));>lol
and then I created an html file on my server which simply submits this credentials to the challenge server which redirects the bot to the XSS vulnerable response and our payload will execute !
So I created an html file on my server with the following contents:
So everything we need is complete right now and one last thing we need to do is to steal the flag:
-
Connect to the port 25
where the smtp service is running, send an email along with the link to the above HTML file.
-
When the bot parses the HTML file, it automatically sends the login request to the /api/user.php
with an already registered username (along with XSS payload) and a password.
-
It redirects the bot to /api/user.php?action=getUser
which contains the username reflected along with the XSS payload and it executes on the context of the site.
-
The executed javascript will help us get the contents of the localStorage
and helps us exfiltrate it using XMLHttpRequest().
-
The first value inside the localStorage
is the flag that we need :)
References
-
Sending email with Netcat
-
Everything you need to know about XMLHttpRequest()
Anirudh Anand
Product Security ♥ | CTF - @teambi0s | Security Trainer - @7asecurity | certs - eWDP, OSCP, OSWE