Init
How do I say it? I wasn’t expecting anything like this at all… it’s kinda hardware-jeopardy-ish.
Actually, a day after this event I have to present my fyp, so I’m literally traveling back and forth between Johor and Selangor like crazy.
People usually do this kind of thing for their gf, but I’m doing it for ctf 😭.
Format Overview
The format of the competition is really unique I would say, and it consists of an immense amount of hardware hacking knowledge, to be more specific the usage of proxmark.
Luckily my group mate, @TanSc was there and he literally cloned a couple of cards before using his own phone, so proxmark should not be a problem for him.
There are multiple stages btw, and if you didn’t manage to solve the previous stage you couldn’t proceed to solve the other one and it’s something like this:
- Stage 0 - Card Cracking
- Stage 1 - Open Sesame
- Stage 2 - Scada Hacking
Stage 0 - Card Cracking (Token)
So for us to access stage 1, we need to get the token available inside the card (solving stage 0 first).
Stage 0 is quite easy, all you need to do is crack the MIFARE keys of the card, and then dump the data contained inside it.
hf mf darkside
command to recover the first key of the card
hf mf nested
use first key to find other keys
hf mf dump
extract all data once keys are owned
Here is the data that was dumped, it is in hex 746F6B656E3A65383734386534306336 0000000000000000000000000
1 | // Convert the hex string to text |
Change it to text from hex, and we got the token to access the web panel, and vpn file (will come in handy for stage 2 instances) for our team!
Stage 1 - Open Sesame (Watson)
Okay for this part right here it’s a little bit tricky.
They actually gave us the Raspberry Pi image a day before, and we need to find out where the challenges are located inside the image, so it is actually testing out our forensic knowledge here.
Challenges were found at /opt/janus
and this is the one to solve watson
1 | def watson(uid, blocks): |
So we need to use the card given, and fill it with the raspberry pi infos:
- the UID of our team’s card
- the node hostname
- the kernel release string
- the OS codename
- the C library version
Computes an MD5 of each piece and compares to one block each (data block)
- 3d955d7444c80970660bc3233ba398b6
- df256845c7212af8a6ef1a25d13ba7be
- b879b8d65ca0895296e64e3e87928d10
- e0bfa30ac77faf071cda9e9af49d9bcc
- 46ef89558baf4b56a4c29fe69c21ab10
All infos can be collected like so:
Mount the raspberry pi image and do the following to get:
- node hostname
1 | cat /etc/hostname |
- kernel release string
1 | ┌──(aan㉿aan)-[/mnt/pi] |
Tried both versions, turns out this one works 6.12.25+rpt-rpi-v8
- OS codename
1 | ┌──(aan㉿aan)-[/mnt/pi] |
It’s bookworm
- C Library Version
1 | ┌──(aan㉿aan)-[/mnt/pi/lib] |
It’s 2.36
Now we need to overwrite the data into the card’s data block, can use proxmark given
Scan it to the scada platform and cross your fingers, it will blink green if it works!
Stage 2 - Scada Hacking (Billboard)
This challenge I think had the most fun cuz it’s finally related to what I love which is web exploitation!
On the website, we can actually see a couple of billboards that we can control. Our main goal is actually to obtain the key to use it to forge a signature before transmitting emergency messages to electronic billboards.
We found a file upload functionality here, and retrieve its path by pressing a button or something I forgot what it was.
So we figured out how to upload a webshell by sending a file with the byte signature of a webp file, but the content after the signature is actually a php code xd
Request
Response
From here we enumerated the source code of the web application and found the value of the secret key obtained from EMERGENCY_SECRET_KEY
which can be retrieved from phpinfo()
function.
Here from this part Sc signed the message using the signature and we pwned the billboard.