intigriti Challenge 0921 by Bug Emir & Pepijn van der Stap
Yet another awesome XSS challenge from Intigriti. By solving the challenge learned cool stuff about DOM-based XSS, hope you will enjoy reading this article about how I solved this challenge & won Intigriti Swag for one the best writeup 😋
Let’s get to it.
Let’s enter some characters into the text field and see what happens!
As you can see model error message popup requesting a parameter. This is a good indication there might be a parameter that takes in a value to save a password, also as you can see the second part of the message “may be look at the source code?”. Ok, let’s look at the source code then.
We can see main page uses an iframe with source (src=”challenge/manager.html”) and uses two javascript files. Let’s visit this page then.
https://challenge-0921.intigriti.io/challenge/manager.html
Let’s check the code inside those javascript files as an error message hinting.
In that page’s source, we can find javascript library “sweetalert.min.js & “manager.js” being loaded.
First checked the sweetalert.min.js file, because of the error alert message popup asking for a parameter. Found that is file is for the SweetAlert library for those cool popups.
When I saw the above-highlighted part of the code thought, “ok this is an indication this library might be using the old version”. As you can see /guide/#upgrading-from-1x, then googled SweetAlert vulnerabilities. Got some article showing this library is (older versions) vulnerable to XSS attacks.
Crafted some payloads entered into the input box and no luck, still getting the same message “I need a parameter”. Time to check the other Javascript file “manager.js”….. Here are all the fun begins… 😅
This looks interesting… 🧐 “This ASCII was stolen from phrack.” Okay.. & “go read: — http://phrack.org/”. There might be some hints for payloads here, visited http://phrack.org
After spending some time on http://phrack.org/ realized it’s a rabbit hole, couldn’t find anything related to this challenge. I am not sure maybe someone else found some useful stuff here related to this XSS challenge. (Will wait for the official report).
But there are some cool articles about some exploits, I believe it is worth a read, Okay maybe later…📖
Before moving to check the code for that mystery parameter below part caught my eye (Highlighted on above image).
“- hmm, is it ⠕⠃⠋⠥⠎⠉⠁⠞⠑⠙?” whooo Braille 🛎 but I cannot read it, let’s ask google what this means? (http://xahlee.info/comp/unicode_braille.html)
⠕⠃⠋⠥⠎⠉⠁⠞⠑⠙ means obfuscated, this explains why code in this js file looks funny. Anyway, let's see what more surprises are in here 🤨
Tip # 1 from Intigriti, but this time I’ve already known that this code is obfuscated and needs deobfuscating (reverse engineering).
But before asking google for deobfuscating help I’ve decided to scan the code and found _0x5195 being used all over the manager.js file.
Array “_0x5195”, the game-changer… 😙 So to see the array values I used this javascript code in the developer console
_0x5195.forEach(e => {console.log(e)}) → This will list out all the values inside the array, and found the parameter its requiring → “password=” 🙃 (Or.. simply copy _0x5195 and paste inside the developer console and press enter… you will see all the values and index numbers)
Tried below payload straight away..
Ohh 😳 something being added “amsterdam_coffeeshop”.
Provided <script>alert(1)</script>… and where is my payload??😬 Inspected the HTML no payload, 🤣 what is this “amsterdam_coffeeshop”
At this point I thought some filter here replacing the payload with “amsterdam_coffeeshop”, then decided to put some plain text like “test1234” to see this get reflected anywhere in the HTML, but something wired happened “amsterdam_coffeeshop” got replaced with “µë-×mø”. I get this wired characters when enter value length is multiple of 4 (4,8,12,16).. actually there is code to check this.
Another fun fact is, by accident remove one character from “test1234” → “test123” then again “amsterdam_coffeeshop” appeared. Then realised ok the values enter has some affects how content which get added to the page and wanted to find where all this happening in the code?
Also noticed whenever “amsterdam_coffeeshop” get added to the page in developer console there was a message “Try Harder” (this index 701: “try hard” in array _0x5195).
Time for deobfuscating the whole code, again google to rescue. http://jsnice.org
https://www.dcode.fr/javascript-unobfuscator
Started to see some javascript specific function but still, the code doesn’t make sense. Here comes the developer skill, DEBUGGING. Placed some breakpoints, on the main array _0x5195 and start to look at values being added to variables. Also copied all the values from Array _0x5195 a text file incase needs to use later, indeed it helped, you will see below how!
After spending some time debugging with breakpoints found a javascript function that responsible to convert values provide to “password” parameter to this wired “µë-×mø” characters. It was on line 1424
When searching for Javascript use https://developer.mozilla.org and in google search bar javascript atob MDN
Google time again for “atob()”. This function is to decode base64 encoded values. YES YES YES, time for CyberCehf
Crafted payloads with base64 encoded (<img/src=x onerror=alert(1)>) aaaannndd.. No POPUP.. what is going on 😂
Let’s check the HTML,
After trying many base64 payloads & checking the HTML noticed that all the events gets cuts off. So there is a Filters/Sanitizer being used in the code as we cannot see any other Javascript library file. Same time second Tip being published on twitter by Intigriti, let’s have a look. (This tip helped me to crack the Filters/Sanitizer)
They are hinting about MEMORY and “AntIH4Ck3RC0D3zzzzzzzzz”, Ohh I have seen this in that magic array _0x5195 index 681 (681: “AntIH4Ck3RC0D3zzzzzzzzz”)
And “Memory” make sense, since code uses lots of Closures & IIFE
So something must be leaking in the Global Scope… Yap it is…. (see the below image)
It is always good the keep an eye on Scope tab when analysing/debugging unclear code, you can see variables and their values being assigned to them. I believe most of the hackers miss this part. So next time do not miss this area.
As you can see AntIH4Ck3RC0D3zzzzzzzzz starts with capital “A”. This indicated its a class.. again seen index 668: “constructor” in array _0x5195.
In many programming languages constructor method is a special method of a class for creating and initializing an object of that class.
So what is this AntIH4Ck3RC0D3zzzzzzzzz class do… It’s obvious this is the Filter/sanitizer library, why? look at the image above it has version number 2.0.8, try running below code in the developer console.
AntIH4Ck3RC0D3zzzzzzzzz.MCAST_MSFILTER
AntIH4Ck3RC0D3zzzzzzzzz.version
So what we do with it.. come on we are hackers.. Google dork it “2.0.8” sanitizer
https://www.google.com/search?client=safari&rls=en&q=%222.0.8%22+sanitizer&ie=UTF-8&oe=UTF-8
https://www.npmjs.com/package/dompurify/v/2.0.8 → Same version as AntIH4Ck3RC0D3zzzzzzzzz.version, GOOD GOOD… Lets check for vulnerabilities in this library.
So now we know this version is vulnerable for XSS. Let’s ask our good buddy Google…
This awesome article from portswigger.net saved my day ,
Payload time baby….. 😎
Raw Payload:
<math><mtext><table><mglyph><style><! — </style><img title=” — ></mglyph><img	src=1	onerror=alert(document.domain)>”>
Why do we need URL Encode after base64 🤔
Since base64 strings can contain the “+”, “=” and “/” characters. which could alter the meaning of your data.
Payload with Base64 Encoded+URL encoded:
💥 Booom !!! Finally !!!
Thanks for reading, hope you learned something from this post. Stay Safe !!!
Make sure you give this post some 👏 and my blog a follow if you enjoy this post and want to see more. 🤝 ❤️ 🇱🇰
BOUNS READ:
How I did reverse engineering manually some part of the code to get a feel of what these codes are doing. Lets do this simple console.log() part…
console[_0x5195[-0x3 * 0xb3 + 0x96e + -0x74c]](_0x5195[-0x393 + -0x11ab + 0x17fb]);
Step 1: We know _0x5195 is the array.. so lets copy [-0x3 * 0xb3 + 0x96e + -0x74c] and paste in google…
Step 2: Take 0x9 and paste in google and hit search (Hexadecimal 0x9 = 9)
So what is “9” for us in this challenge.. it is the index 9 of the array _0x5195, so let’s have a look index 9 then (that’s why copied all the values to a text file from array _0x5195 as mentioned earlier)
index 9 is “log”, let’s replace it (Note I am replacing these in my code editor)
console.log(_0x5195[-0x393 + -0x11ab + 0x17fb]);
Lets move to second part.. [-0x393 + -0x11ab + 0x17fb], same steps again, copy to google and the see the result,
It’s 0x2BD..Copy this value, paste again & search..
You can click on “0x2BD” to decimal link to see the value or you can see “701” bit below. 1
Let’s see what is index 701 in array _0x5195… It’s “try harder”… Let’s put this in…
console.log(“try harder”) 😎
This is how i did it..
Simpler way of doing this…
Just copy and paste into developer console and press enter
console[_0x5195[-0x3 * 0xb3 + 0x96e + -0x74c]](_0x5195[-0x393 + -0x11ab + 0x17fb])