BugPoc's XSS challenge, Buggy Calculator writeup
This is a write-up for an XSS Challenge by `BugPoC`, Buggy Calculator (calc.buggywebsite.com) that popped out on
Twitter recently (link)
This is a website of calculator app designed by angular js.
Eval js by using gadget inside the script (which is the functionality of the caculator) is the best part in this challenge.
This is a website of calculator app designed by angular js.
Eval js by using gadget inside the script (which is the functionality of the caculator) is the best part in this challenge.
Buggy Calculator
A Website running at http://calc.buggywebsite.com/. It's a complete client side application. Our goal is to popup alert(domain).Functionality is simple like a calculator, on button clicks it is constructing the equation(string), and finally eval that equation on calculate.
Observation - 1
By reading the source codeThe app is using iframe(frame.html) to display the result by using `postMessage` communication.
Whereas in frame.html it is directly injecting that postMessage data into the HTML (document.body.innerHTML=msg) with a origin check. we can achieve HTML injection if we can bypass the origin check. Instead of equality it is checking the origin is started with `http://calc.buggywebsite.com`, So we can continue it as `http://calc.buggywebsite.com.evil.com` and get control over it.
Now we achieved HTML injection on calc.buggywebsite.com
Observation - 2
But here comes the main issue.We can inject a script tag, but we can't execute it as the HTML is injected through `innerHTML`
There is way But inline execution is blocked through the CSP :(
CSP : script-src 'unsafe-eval' 'self'
we can only include self scripts, use eval in script.
Then gone through the srcipt.js to find any gadgets in it and found one. Evaluating the equation directly with out any sanitising.
Then gone through, how the equation in build up. num value might be anything , it might be alert(1) there is no check implemented to make sure it is a digit or not.
Through the HTML injection we can use that to achieve XSS like But it need the user interaction click, so searched for the directive components in ng in the angular js docs and found ng-init through which we can call the angular js functions automatically(on initiation).
Final HTML payload to get alert(domain) We need those scripts for the gadget, and CSP allows self scripts so no problem.
As the script try to access the iframe object (theiframe), it's rises as error, to avoid it <iframe name=theiframe></iframe>.
We have to inject that HTML into calc.buggywebsite.com/frame.html through postMessage.
But the payload contains script tags, script does loads through innerHTML injection, but we can use iframe srcdoc. Injecting that payload doesn't worked. but why :(
Observation - 3
There is check in frame.js before injecting the HTMLAt first it doesn't make any sense,so leaved. But now it blocking the payload. First tried my best to avoid & and ' in the payload, but no use.
After that tried to bypass the check. as it is a string it is checking char by char, what if it a list.
we know that, through postMessage we can send list, object, string.
`["asdf"].toString() => "asdf"` so it doesn't make any difference, through which the check was bypassed
This is amazing!
ReplyDelete