How’s it been? Recently, I played UIUCTF with Project Sekai instead of ARESx, but I was also at DiceCTF Finals on vacation, so I didn’t get much done. Still, I managed to solve a few of the misc and rev challenges, so here are their writeups.
Misc
I helped in solving astea and push and pickle as well, but since I didn’t fully solve them, I won’t be covering them here.
Slot Machine
453 Passengers / 76 Solves
Author: Jake
We have onboard entertainment! Try your luck on our newly installed slot machine.
ncat --ssl slot-machine.chal.uiuc.tf 1337
We have one attachment, a simple chal.py:
There’s a lot of messy logic in here we can ignore, but the main thing is that we control some input that is sha256 hashed, then the trailing hex digits are used to determine if we “win” the slot machine.
So, the goal is to find some input that creates a hash with a lot of the same trailing hex digits. We can deal with the encoding issues later, but for now, we need to find some hash that satisfies this.
The first thing that came to mind for me was Bitcoin hashes. Bitcoin hashes are SHA256 hashes that have a lot of leading zeros, which in this case, means a lot of trailing zeros.
Fortunately, a quick google search shows us quite a few hashes with lots of 0s here.
We can take this known block with 24 zeroes, extract the block like so, and then send it over to the server for 24 characters of the flag. As it turns out, this is enough!
(Unfortunately I don’t remember what the flag was and remote is down, but this does get the flag)
Rev
Summarize
381 Passengers / 161 Solves
Author: Nikhil
All you have to do is find six numbers. How hard can that be?
Chucking into a decomplier, we see a pretty simple main function that reads in 6 numbers and passes them into a checker.
The checker seems simple as well, we have a range check and then a final check at the end.
The goal here is to figure out what each inner function does, then we can write a Z3 script to solve for the 6 numbers and get the flag.
Inner functions
Let’s start from the top.
This function accepts 2 numbers, then does some bitwise operations. var_1c seems to be some counter for the number of bits, leaving var_20 as the carry, and var_10 as the result.
Clearly, this must be addition. Every bit, we add the XOR of the bits and the carry, then shift it over by the counter. The carry is updated by the OR of the ANDs of the bits and the carry. Finally, we add any remaining carry.
If sub_40163d is addition, then this is subtraction. We can see that the second argument is negated, then passed into sub_40163d.
For every bit in arg1, we multiply arg2 by the bit and shift it over by the counter. This is multiplication.
This is similar to addition, but this time there is no carry, only the XOR of the bits. This is XOR.
This is just like XOR, but this time we only add the AND of the bits. This is AND.
Finally, renaming all the functions, we can see what the checker really looks like:
Z3 Script
Now that we know what each function does, we can write a Z3 script to solve for the 6 numbers.
Running this script, we get the 6 numbers and the flag.
Pwnymaps
483 Passengers / 30 Solves
Author: spicypete
My friend gave me his address, but the coords he gave are n dimensional… Can you help me setup my GPS to find him?
Once you pass all checks, you need to plot all the x, y points in order as a line plot in order to reveal the flag. The flag consists of three valid words seperated by underscores, wrapped in the flag format, and all lowercase.
The main gimmick with this challenge is that the coordinates are stored in Morton encoding. Other than that, the rest is mostly just simple operations and checks.
Here’s Binja’s decompilation of the main function:
The program reads in 512 x, y coordinates, then does some fairly simple operations, and finally checks each number in two ways.
First, it checks the number of set bits by calculating a checksum given the number of set bits and ensuring it matches the stored checksum.
Then, there is another seperate check for a calculated correct value.
I won’t go into detail about the Morton encoding, you can read the previously linked article, but essentially it interweaves the bits of the stored numbers to create a single number.
To deal with this encoding, I recreated the encoding and decoding functions in the binary in Python like so:
I used entirely bitwise functions to ensure that these functions would also work with Z3 BitVecs.
All we have to do now is to write a Z3 script to solve for all the x, y coordinates.
Finally, we need to graph the X, Y coordinates as described in the challenge prompt.