Kinda disappointed I wasn’t able to do any Web ones (that weren’t solved already), but it’s alright. We got 7th place across all teams despite only having 4 members participating in this :)
Details | Links |
---|---|
CTFtime.org Event Page | https://ctftime.org/event/1434 |
rev
headless_horseman
Our sponsor, Battelle, donated this challenge. The challenge will be posted on their Cyber Challenge site at the beginning of BuckeyeCTF, and was created for this competition.
Be sure to select the Headless Horseman challenge, although there are others on their site not associated with BuckeyeCTF. Flag format: flag{…}
The actual challenge is https://www.battelle.org/cyber-challenge/unicorns-undercover, where headless_horseman.zip
is provided for download. Below are the contents of the zip file.
|
|
|
|
Our goal is to identify the bodies (in body_bag
folder) of Ichabod, Katrina, and Brom Bones.
Number check
The binary headless_horseman
prompts you to enter the number of pumpkins you have, after which this number is checked in count_offering
by first_count
and second_count
. All the code that will be seen below is pseudocode generated by IDA Pro.
|
|
The upper WORD of the number input has to be 0xDEAD
,
|
|
while the lower WORD has to be 0xFACE
.
|
|
so the number that should be given is 0xDEADFACE
which is 3735943886
. After the 2 number checks, dump_heads
is called where 0xDEADFACE
is used to XOR-decode contents that are written to 6 _head
files.
|
|
Matching head to body
According to the puts
statements above, we need to match the 3 _body
files in the given body_bag
folder to their correct corresponding heads among the 6 XOR-decoded _head
files. QEMU is suggested to help us, but we’ll see that this is not needed.
I first wrote a Python script to generate all the different combinations of head and body. All _head
and _body
files were placed in the same directory.
|
|
Next, I ran file
on all the files to see which of them are valid.
|
|
The majority of them have section header issues except for dessicateddecomposing_complete
, moldybloated_complete
and shrunkenrotting_complete
which have proper BuildID
s detected too.
Katrina (XOR-decoding)
In dessicateddecomposing_complete
, we see that the body belongs to Katrina.
|
|
A 13 character string user input is taken and used to XOR-decode 13 bytes stored at encrpyted_words
(the 14th byte is null). The encoded bytes are 21 09 04 09 1C 00 7F 24 00 1A 09 1C 28
.
The puts
statements suggest that the decryption key could be Katrina’s Home Town, so I tried Sleepy Hollow
as mentioned in the Disney Fandom Wiki and it worked. Here’s the result in CyberChef.
Flag fragment: really_loves_
Ichabod (Environment Variable)
moldybloated_complete
belongs to Ichabod.
|
|
check_surroundings()
checks that the environment variable ICHABODS_HORSE
is set to GUNPOWDER
.
|
|
Then, in print_incantation()
, the flag is base64-decoded and printed. So actually we don’t even need to care about the environment variable.
|
|
Flag fragment: flag{the_horseman_just_
Brom (Buffer Overflow)
The last body, shrunkenrotting_complete
, belongs to Brom Bones (or Brom for short).
|
|
v2
is initialized to 0xDEADBEEF
at the start, but the desired value for the flag to be printed is 'DAED'
. Since both s
and v2
are stack variables, s
is a buffer of 20 char
s, and the insecure gets
is called on s
where no bounds checking is performed, the buffer of s
can be overflowed and overwritten into v2
.
We provide of payload of 20 characters + DEAD
which will overwrite v2
with DAED
due to little-endianness.
|
|
Flag fragment: pumpkin_pie}
Final Flag
Flag fragments: really_loves_
, flag{the_horseman_just_
, pumpkin_pie}
Final flag: flag{the_horseman_just_really_loves_pumpkin_pie}
misc
USB Exfiltration
Someone stole data from our servers and you need to figure out exactly what they took or you’re fired! We know they zipped the files then transferred them via USB somehow so here’s a capture of the USB traffic. You should be able to recover the files from that, right?
Attached: exfiltration.pcapng
There were lots of USB URB packets with small lengths (~60-~90) so I just ignored them and continued scrolling down until I found some interesting consistently large packets.
The first large packet’s Leftover Capture Data
starts with 50 4b 03 04
a.k.a “PK..
” which are the header bytes for a ZIP file. This means that this is probably the ZIP file that is being exfiltrated.
The last packet with a larger-than-usual length is also spotted to have the ZIP file trailer bytes 50 4B [17 characters] 00 00 00
as referenced from https://www.garykessler.net/library/file_sigs.html, thus confirming the transfer of an entire ZIP file.
We can filter for these large packets exfiltrated from host
to 1.76.3
using the display filter usb.urb_type == 'S' and (usb.data_len > 200)
and then form our ZIP file using the data bytes.
|
|
|
|
flag.b64
contains the flag base64-encoded: YnVja2V5ZXt3aHlfMXNudF83aDNyM180X2RpNTVlY3Qwcl80X3RoMXN9Cg==
. Decoded in CyberChef.
Flag: buckeye{why_1snt_7h3r3_4_di55ect0r_4_th1s}
replay
Somebody pwned my app! Luckily I managed to capture the network traffic of their exploit. Oh by the way, the same app is also running on misc.chall.pwnoh.io on port 13371. Can you pwn it for me?
Attached: replay.pcap
The file captures traffic of what seems like a remote buffer overflow exploit as evident by the long string of alphabet letters. We just have to replay the traffic sent but modify the id
command to cat flag.txt
.
|
|
|
|
layers
Check out my brand new docker repo https://hub.docker.com/r/qxxxb/layers
If you visit the latest image tag/digest in Docker Hub, you can see that the image has 5 layers.
The flag was probably added in layer 1 then removed in layer 4. We can extract out flag.png
which should be present in layer 2 using the following steps:
- Pull the image with
sudo docker pull qxxxb/layers:latest
- Save the image to a tar file with
sudo docker save qxxxb/layers -o layers.tar
- Build docker-layer-extract from source with
go build main.go
- List layers with
sudo ./main --imagefile layers.tar list
|
|
Now, we can extract Layer 1
where the flag image should be present with sudo ./main --imagefile layers.tar extract --layerid a6951987fab1e53365680416db4c728a89783aa2b8c39bd2879aabfcffab95d9 --layerfile layer.tar
.
We can confirm that the flag is now inside layer.tar
:
|
|
So just extract it with tar -xf layer.tar flag.png
and we’re done!
Flag: buckeye{D0CK3R_H4S_L4Y3RS}
Don’t Talk to Blue Birds
Gillian Owens is the head of Witch Security. She’s been oversharing on her personal accounts. Challenge type: OSINT. Note: flag format is flag{} for this challenge!
Search for “Witch Security” in Twitter, sort by latest, and you’ll see a tweet from @hackerbot2275 mentioning @witch_security which has the account name Gillian Owens.
One of her tweet replies to @0xfractals is https://pastebin.com/4KHrJcUX, which contains https://pastebin.com/qXDb43m1, which contains the flag.
Flag: flag{aggre55ive_Hall0we3n_prepArati0ns_Und3rw4y}
Open Source In(sta)telligence
Gillian Owens is the head of Witch Security. She’s been oversharing on her personal accounts. Challenge type: OSINT. Note: flag format is flag{} for this challenge!
Search on Instagram for Witch Security and you’ll come across witch_security1 with the name Gillian Owens in the account’s bio.
One of her posts has a link in the image: bit.ly/3jgDwui
which leads to https://pastebin.com/UgWRFWuB and contains the flag.
Flag: flag{spo00ky_szn_15_very_AestH3tic}
Thanks for reading!