BOOK THIS SPACE FOR AD
ARTICLE ADThis is a challenge made by BugPOC and it has a program in hackerone , and this is the link of challenge :
http://calc.buggywebsite.com/
I tried to explain the challenge step by step even there are some basics .
Must alert(domain)Must bypass CSP,Must work in Chrome,Must provide a BugPoC demoFirst we need to see the view the html source so we can understand it:
index.html
frame.html
frame.js
script.js
I also did a dynamic analysis with chrome debugger , it isn’t necessary for this challenge as it has few sources , but this concept is very important specially for huge files .
Break point in the postmessage
When we write any number , this number will be sent to iframe using postmessage and is written on the calculator
The reciever for postmessage will check the origin and extract message and check for its content before writing it.
So now we have PostMessage that can be converted into XSS .
We need first to know a bit about PostMessage
So , postMessage allow communications between a page “source” and another page “destination” , so index.html can communicate with frame.html through postMessage .
The Syntax for the source is :
targetWindow.postMessage(message, targetOrigin, [transfer]);so we have three important attributes :
1. targetwindow : which is the destination , in out example we have frame.html
2. message : which the message to be sent and will be received in the destination .
3. targetorigin : which could be * to allow communication with any target .
The syntax for Destination :
we have to do a listener which will receive the message in certain condition like verifying the origin for security reasons .
Let’s try to do small tutorial regarding postmessage using the challenge code.
I hosted the challenge on my server so that I can bypass restrictions one by one .
First restriction is the origin :
This is simple html to postmessage in the frame.html:
so we can test it from another origin rather than my domain ctf.io and see if the message will be printed in the body of frame.html or not .
we can see that the body of frame.html is still 0 not ‘test’ which we have sent :
We can remove the origin check and verify that again :
we can see that ‘test’ message has been written in the body :
So we need to bypass this check , we can notice that the regex is check for the beginning of the domain not the end , so if we can make a subdomain with name of “ctf.io” .
So , we can run our html from ctf.io.attacker.io .
Using the original script :
we can bypass the origin :
Now we can try to put simple html tags like <img src=x onerror=alert(1)>
The image tag worked but with no javascript execution :
There is Content Security Policy , so we can check for it using
https://csp-evaluator.withgoogle.com/
This means that we can load scripts from the challenge origin and also execute eval function .
Now we can try to send a message as script tag :
<script src="script.js"></script>
but script.js hasn’t been fetched :
After search I found that innerHTML doesn’t execute script tags :
This was for security reasons :
This is the second restriction we need to bypass .
So we need to do something like encapsulation , means to encapsulate our script tag in another tag which doesn’t annoy innerHTML :D
The best tag which carry any thing is iframe :D
But if we try to make the src of iframe to be another domain, this means the XSS will be executed in the other domain to the challenge domain .
Iframe also has great attribute that can be used is srcdoc instead of src attribute :
This attribute can carry the HTML including script tags and be written in the body using innerHTML , so we can do something like that :
<iframe srcdoc="<html><script src=script.js></script></html>"></iframe>
so , we can load the script.js from the ctf.io as shown:
Now , we need to execute javascript using self-src bypassing CSP.
After search , I found that can be done using anguler sandbox escape to get XSS via this article:
I decided at last to use this payload , which I didn’t have no idea about its syntax :D
I need to simplify the html so that I can understand how it works , as there will be another restriction.
By using this HTML :
and when I click on “foo” , the alert is poped up:
This payload contains quotes and double quotes which will make restriction as we will put this payload in srcdoc of iframe , and the iframe is put in the message variable , it will be like that :
var message='<iframe srcdoc="payload"></iframe>'
so payload doesn’t have to contain and double quotes as it will break the srcdoc , and also the message variable also , because of the restriction in frame.js which prevents using 'or & :
So our payload must be free of ' , " , and & .
At this time I should understand the payload to see how to bypass this restriction , so I need to know a bit angular which I don’t anything except {{2*2}} :D
When I tried to remove ng-app , the payload is broken , I didn’t that it was important so I realized that, I have to read documentation :D
There is something called directive components , we used four of them :
ng-app :2. ng-focus
3. ng-repeat
4. ng-if
This is simple illustration of the payload as I understood
First problem from me is the ng-repeat as it uses " and ng-if as it uses ",'
I was also need to know why this makes alert , so I began to discover what is the values of key,value of the event focus , so I modify the payload to print the key:value
so when the key=window , its value will be $window :
so the most important thing that search for key which value is window .
I tried to access the window without this looping and if condition :
Then I got what I need :
so we can craft our payload without any quotes :
var message='<iframe srcdoc="<html><script src=angular.min.js></script><div ng-app><div ng-focus=x=$event; id=f tabindex=0>foo</div>{{[1].reduce(x.view.self.alert, 1); }}</div></div></div></html>"></iframe><iframe>';and it worked but alert(1)
we need to make it alert document.domain , I spent a time to explore how to do that , but I can’t access document.domain as it always undefined ,so I used eval to generate alert(document.domain) from String.fromCharCode function .
To do this using angular , we can use [].constructor.name.constructor to represent string as I can’t access String :
so I have to define a variable xss :
xss=[].constructor.name.constructor.fromCharCode(97,108,101,114,116,40,100,111,99,117,109,101,110,116,46,100,111,109,97,105,110,41);and use eval to execute it :
The payload worked successfully
Let’s try to use exploit the challenge itself , we will need to change the url to :
http://calc.buggywebsite.com/frame.html , and make subdomain calc.buggywebsite.com
This will be final exploit :
<html><iframe id="VulnerableSiteIframe" height="400" width="1024" src="http://calc.buggywebsite.com/frame.html" onload="SendMessage()"></iframe>
<script>
function SendMessage() {
var IframeElement = document.getElementById('VulnerableSiteIframe');
var message='<iframe srcdoc="<html><script src=angular.min.js>\<\/script><div ng-app><div ng-focus=x=$event; id=f tabindex=0>foo{{xss=[].constructor.name.constructor.fromCharCode(97,108,101,114,116,40,100,111,99,117,109,101,110,116,46,100,111,109,97,105,110,41);[1].reduce(x.view.self.eval, xss); }}</div></div></div></html>"></iframe>';
IframeElement.contentWindow.postMessage(message, '*');
};
</script>
<body>
</body>
</html>
There is also another payload that can be worked , and easier than what I did
</body ng-app ><div ng-app ng-csp>{{l=[].constructor.name.constructor.fromCharCode(120,61,49,125,32,125,32,125,59,97,108,101,114,116,40,100,111,99,117,109,101,110,116,46,100,111,109,97,105,110,41,47,47);a=toString().constructor.prototype;a.charAt=a.trim;$eval(l)}}</div>It is a famous one , I tried it but didn’t work at first time , but it worked at the end , so I put it in the poc , as it has no user interaction
Thanks for reading .
https://sites.google.com/site/bughunteruniversity/nonvuln/angularjs-expression-sandbox-bypasshttps://code.angularjs.org/1.5.6/docs/api/nghttps://developer.mozilla.org/en-US/docs/Web/API/Window/postMessagehttps://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/reducehttps://book.hacktricks.xyz/pentesting-web/content-security-policy-csp-bypasshttps://www.blackhat.com/docs/us-17/thursday/us-17-Lekies-Dont-Trust-The-DOM-Bypassing-XSS-Mitigations-Via-Script-Gadgets.pdf