Well this is a typical XSS challenge, you find an injection point and pop and alert. Pretty straightforward, just have to find that injection point.
This month's challenge is a community feed website with register, login page, Testimonials page where you can post and a profile page where you can edit your profile, that's a bunch of potential injection points to test, surely its one of them. and the footer mentions something called SCA Shield v1.0, is it Side Channel Attack?
Upon inspecting the source, all the page content is generated dynamically using a single app.js script. and innerHTML is heavily used throughout the script to inject content, but surprisingly DOMPurify is only used to sanitize the user comment and not their name?
nameDiv.innerHTML = t.user_name;
I thought its the moment, we found an injection point, went and changed name to a typical XSS script and... it didn't work, its the same SCA Shield which was mentioned in the footer, which is preventing us, its a server side check.
we get a message
SCA Shield: Malicious characters detected! Quotes, parenthesis, dots, commas, and semicolons are strictly forbidden.
and this when using script tags
SCA Shield: Malicious payload signature detected!
Well, at least now we have a list of things to remove from our payload and it should just work. it seems it only detects few tags like script and other related words. tags like style, svg just work fine.
I had read about this XSS payload using CSS keyframes, so I thought to give it a try. and it worked.
After a bit of back and forth, I came across this
<style>@keyframes x{}</style><b style=animation-name:x onanimationstart=window[atob`YWxlcnQ=`]`pwned`>
window is blocked, so we use top which points to topmost frame, and in a normal page, its the page itself
alert is blocked, we just base64 it lol, atob isn't blocked
and tagged literals instead of quotes
and it works! 🎉
now for the origin version for domain check, we need to due few modifications.
I released we can just use character hex code equivalents to mask the words since it does exact match, we can use parenthesis now!
replacing a with its equivalent \x61, ( to \x28 and ) to \x29 we have the following:
<style>@keyframes x{}</style><b style=animation-name:x onanimationstart=Function\\x61lert\x28origin\x29\```>
and there you go, we're done!
I submitted it to Intigriti, and they told it was an unintended solution. while i haven't yet gone to an intended solution, i feel its something related to the PixelAnalyticsConfig residing in the app.js and seeing their first hint makes it more probable, but haven't yet explored it.



















