WHOAMI
Hey Everyone! ๐ I am Isira Adithya and I am a 16 years old ethical hacker from Sri Lanka. Recently (21/03/2021), I found out that the Intigriti, Europe's #1 ethical hacking and bug bounty platform was releasing XSS Challenge. I've never participated to these before, but I found some cool write-ups about previous challenges on the internet. Those XSS challenges were very interesting and I thought this may be my chance to win. (But, It was hard. ๐ ) Sorry, for my bad english. ๐Website Overview
Website is very simple. I will highlight the interesting parts. There is a little text box below to save notes. ๐ค It's kinda weird that there is a box to save notes. So, I immediately thought that will be the target. ๐ We can type anything in the textbox and we can save it.When we click the save button, it reloads the website. So, That means web browser is sending a request to the server. Hopefully, It is not using AJAX. That's great because javascript code will be very simple. ๐
Enumeration
Now, let's analyze deeply how the website works. ๐ I used Chrome Dev Tools to analyze the website. (Ctrl + Shift + I)As you can see, our data is injected into a <p>
tag with id called notes-display
. But, if you try to inject something like <script>
it will be encoded with HTML entities. So, there's no hope using tags.
Also, the javascript was very simple and there's no vulnerability in the code. So, the only way to get XSS is to use http requests.
Then, let's navigate to the networks tab and analyze what kinda request this website uses.
As always, GET Request was not interesting at all.
But, when we save a note, it sends a POST request to the server with csrf
& notes
as parameters.
As you can see I highlighted 3 major parameters,
- Request Headers
Method: POST
(A common method used to send data to server)Cookies: PHPSESSID:3d34ex7...
(Used to track your browser's session)
- Form Data
csrf: [MD5 Hash]
(Used to protect against Cross-Site Request Forgery ๐ค)notes: [Your_Data]
(Our data... This is the parameter we are going to use to get XSS ๐)
csrf token
with a very interesting comment. ๐คจ
So, whenever we refresh the page, it returns a new CSRF token
with a new Date\Time
in that comment. ๐ค
That gives us a hint ๐คฉ. So, I was thinking how the CSRF could be generated.
Now, I will show you how to decode this using Cyber Chef.
Analyzing CSRF Token
If you look closer in the Response headers you will find that the website uses PHP/7.2. (This is useful to know.)Paste the CSRF token, and analyze hash. It shows some interesting hashing functions there. But, we already know that server-side language is PHP. So, It's super clear that developers are using MD5 to generate the hash. (There is a function called md5
in PHP)
So, Intigriti is giving us the date and the time when the page was generated. If you know about Unix Timestamp it's good way to generate current time in a number.
Ex: 1616914585 -> Sun 28 March 2021 06:56:45 UTC
So, I thought that the CSRF is generated based on the time that web page generated.
Then, I navigated to Cyberchef
The Cyber Swiss Army Knife - Cyberchef
In the above picture, You can see the recipe I used.
I know about PHP and I knew it's very easy to generate MD5 hash of something in PHP. You just have to call md5(data)
also I knew that time()
function returns the current time in Unix Timestamp. So, dev only have to call <?php echo md5(time()) ?>
output the CSRF to the page.
(I am developing a Android Application. Server-side is written in PHP that's why I already knew about these. ๐)
So, let's discover how to exploit it in my way.
Finding the XSS
OK, First of all, I have to tell this. I know everyone uses BurpSuite by Portswigger when it comes to Web Application Testing.However, I am not used to burp at all. I know the basics but I don't know how to use it with this kinda CSRF token ๐. I will learn how to use it in the future. But, for this challenge I used Python Programming Language
I wrote a little script to test my custom payloads. I will add the Github link below.
Here's a little preview how the tool works. (It helped me a lot)
So, I tried basic functions and All of the payloads returns encoded data. (Html Entities)
But, as you can see in the above (Terminal Animate - Ascii Cinema) urls returns a <a>
tag. That's kinda good right?
When we send something like, [email protected] it detects it as a Email and returns a <a>
tag with following code in it.
<a href="mailto:[email protected]"> [email protected] </a>
There was some hints about the challenge in Intigriti's Twitter Announcement and in one of them they mentioned a RFC.
I think it is RFC822. It describes STANDARD FOR THE FORMAT OF ARPA INTERNET TEXT MESSAGES.
Then, I started to search about this and eventually I came across this payload by PayloadsAllTheThings - Github.
Payload is "><svg/onload=confirm(1)>"@x.y
and I tried it.
As you can see it returned,
<a ><svg="" href="mailto:" onload='confirm(1)>"@x.y"'> "><svg/onload=confirm(1)>"@x.y </a>
.
Then, I tried it in the browser and it didn't triggered the XSS. I was so confused and I found out that the problem is onload
attribute. As you can see that < and >
was encoded in that <svg>
payload. But, onload
attribute is in the <a>
tag and that's enough to perform a XSS attack.
I modified the onload
attribute to onmouseover
then I tried once again and Boom! ๐ฅ. It triggered the xss when I got my mouse pointer over it.
That's it. Then, I modified the payload little bit according to the Intigriti.
So, after modifying it. The final payload looks like this.
"><svg/onmouseover=alert('flag{THIS_IS_THE_FLAG}')>"@x.y
.
Finally, I got the CSRF Bypass and XSS. Then, I started to create a POC.
Writing a POC
So, This was my solution to the problem.To reset the CSRF token, I used a <iframe>
tag with sandbox
attribute in it. So, the browser will send the cookies to the https://challenge-0321.intigriti.io/ website. Remember, we need to send the PHPSESSID cookie to the server. That's important if not the XSS attack is useless because we can't interact with victim's account. So, we have to send the cookies with the iframe request.
You can get more details from below website. Check it out. HTML5Rocks.com - Sandboxed Iframe
But, chrome was more protective about this. Chrome checks if the cookie has the attribute SameSite= None
, if not it won't send those cookies to server. But, in the other hand firefox was vulnerable to this.
So, You have to use Firefox to trigger the XSS with CSRF Bypass.
Now, It's time to write the code. However you can use below link to read the whole code. Replit - Intigriti 0321 POC You can read the code to understand the attack, but I am trying my best to explain it further. ๐
First, I created the iframe in the html.
<iframe sandbox="allow-scripts" src="https://challenge-0321.intigriti.io/"></iframe> <script src="script.js"></script>
Then, I found a MD5 function for javascript from CSS-Tricks thanks to Chris Coyier ๐๐ฝ.
I copied it directly in to my javascript file and wrote the rest of the javascript like below.
Replit - Intigriti 0321 POC - script.js
That's it. Whenever, someone open this code, the iframe
is going to reset the CSRF token of
the intigriti's challenge website and the javascript will redirect the page to the intigriti's challenge's website via POST request
containing the XSS payload.
That's the solution for the Intigriti 0321 - XSS challenge. I hope you learned something from this writeup.