YauzaCTF 2021 HackBack WriteUp
So today I’ll show you how we solved a task called HackBack from YauzaCTF 2021. We was the only team who solved the task and our solution was not identical to developers’ one in some parts. So let’s get started
After a quick look at the task’s site I realized we are dealing with some kind of bulletin board like app, and there is only six items on main page. No other links are working.
Item page also is not so informative, no buttons are working on any item’s page.
I tried to bruteforce files and directories with no success and it was clear — I should try to bruteforce item’s ID as I can see from the url there is only two bytes (4 hex chars) to bruteforce so it’s definitely possible.
Here is six items’ links from the main page to understand what I am talking about:
https://shop.tasks.yauzactf.com/item/00001af3
https://shop.tasks.yauzactf.com/item/00001251
https://shop.tasks.yauzactf.com/item/0000147e
https://shop.tasks.yauzactf.com/item/00001f35
https://shop.tasks.yauzactf.com/item/0000a802
https://shop.tasks.yauzactf.com/item/0000e1a5
Now I used Burp Suite’s Intruder for bruteforcing the id with following options:
But after like 10 requests I’ve got rate-limited with interesting message
It was saying something about “name” so I started to think what can I do with “name”. Maybe only existing items would not throw error, but that was wrong.
After some time I remembered — some items contained names (you can see one on the screenshot with Flipper)! The names was: John Althouse, Jeff Atkinson, Josh Atkins. Googling that three will point us on the article about TLS fingerprint technique called JA3 (https://engineering.salesforce.com/finding-evil-on-the-network-using-ja3-s-and-hassh-11431a8606e4?gi=adc3ddf45791).
Now it was clear — we need to bypass ratelimit algorithm based on JA3 fingerprint. So I read the article below and started to google more about it.
I found an app that fingerprints a client and also contains lots of JA3 fingerprints as text: https://ja3er.com/ (fingerprint can be found here:https://ja3er.com/getAllHashesJson). It would be useful later.
So now we should find the way to use this fingerprints as an options for TLS transfer. After some github digging and trying different tools I’ve found a working one with was https://github.com/h0nde/ja3-proxy.
It required a patch to work with self-signed TLS certificate, so line 173 of main.go changed to
config := &tls.Config{ServerName: hostname, InsecureSkipVerify: true}
Also README of tool says the following:
Chrome and firefox fingerprints are not functional so far.
Now we should find working fingerprints. I wrote a quick script based on example from repo to extract working JA3 sequences (https://gist.github.com/juwilie/b01595218b557d976e160176fd4eda5e) and ran it with proxy itself.
Side note: developers’ solution did not required whole JA3 fingerprint impersonation — changing TLS version and ciphersuite set would be enough, but we’re not looking for easy ways, right?
Now we have a list of working JA3 fingerprints and we can bruteforce items’ id’s. I think it is not so interesting to see almost same script as above, so I am only providing a result of bruteforce which is the following links:
https://shop.tasks.yauzactf.com/item/0000006c
https://shop.tasks.yauzactf.com/item/00000105
https://shop.tasks.yauzactf.com/item/0000faed
https://shop.tasks.yauzactf.com/item/00001251
https://shop.tasks.yauzactf.com/item/0000147e
https://shop.tasks.yauzactf.com/item/00001af3
https://shop.tasks.yauzactf.com/item/00001da6
https://shop.tasks.yauzactf.com/item/00001f35
https://shop.tasks.yauzactf.com/item/0000e1a5
https://shop.tasks.yauzactf.com/item/000035ff
https://shop.tasks.yauzactf.com/item/00005a29
https://shop.tasks.yauzactf.com/item/0000a802
https://shop.tasks.yauzactf.com/item/00009e7b
Third one got my attention because it’s description says it is an item for API testing. And yes, “Show phone” button was working now!
Now we got an API method and that’s something we can work with! I tried to find another methods by guessing and succeed with following:
Now we have user_id, and following same logic I tried to access GetUser method and it worked
And we got an interesting description. Flag clearly is near, but we need to look deeper.
There is two hints that can help us with the task (we used only the first one)
Obviously we should fuzz our requests for any type of server side vulns. After many tries (sqli, traversals, etc) I’ve found a strange behavior for a couple of cases:
Seeing this cases I was like “wow, that’s some sqli” but it’s not. Because first request (even if stacked queries was enabled) won’t send us a second row.
Second row is obviously an admin account and it’s description says
Welcome to Fun with Flags! If you are not blind, check new one in my flag field!
Field in some query and this behavior got me thinking it is MongoDB. And I started to construct a query for injection. Finally I got this:
Now we just need to get a flag, but simply replacing username to flag is not working and query does not return anything.
But we know that admin account has a flag field, so constructing query a little bit differently:
We got a response! Now we can just write an exploit using same ratelimit bypass as we do initially: https://gist.github.com/juwilie/ef692554ec5ed88b732e2024f48fec3f.
And finally we got a flag: {4v1t0_4nt1b0t_t3st} (flag format is different tho)
After all, thanks to organizers and developers for a cool CTF!
Writeup was prepared by Maxim Prokopovich (juwilie), Team Popugi.