tl;dr
- You need to pass 999 levels to get the flag.
- Each of the levels involves multiple checks on input characters.
- Each check happens in seperate functions which are decrypted during runtime.
- Extract function order and arguments.
- Automate finding input for each check.
Challenge Points: 951
Challenge Solves: 4
Solved by: R3x, k4iz3n, silverf3lix
Initial Analysis
Our initial approach was to manually reverse the first round and then find patterns
between each rounds since we thought they would be somehow similar. But we saw that
the order in which functions were called in each round was completely random.
Next step was to figure out the logic behind which all functions get executed and how
the arguments and return values are defined by the program. Some searching got us to
this really huge array(~2 Mb) which was being used to get function addresses and all.
Now we just need to figure out what each of the functions do.
Analysis of the array dump
We did some diggging around the array to figure out what were the different parts of
the array and we noticed a pattern.
$ cat dump
480d 4000 7200 0000 fd00 0000 0c00 0000 0300 0000 d120 0400 2ce7 0300 6714 0600 2b0e 4000
| fn addr | Don’t care | index | size | results of each size inputs | next |
|:—:|:—:|:—:|:—:|:—:|:—:|:—:|
|480d 4000|7200 0000 fd00 0000|0c00 0000|0300 0000|d120 0400 2ce7 0300 6714 0600|2b0e 4000|
We noticed the call to the function address in the array and the index of the input
in the array and size number of values were computed and compared with the
corresponding results given in the program.
Next step is to reverse the functions.
Figuring out the different functions
There were a total of 7 functions in the code. We used the addresses to differentiate
each of them.
Most of them were very trivial to reverse. You can see the reverse implementation in
the python script below.
Solving 999 rounds
We decided to perform the reverse opertations based on the dumped array. So I wrote
a script which would parse the function addresses and then return the corresponding
input.
1 | import struct |
The flag generation of the challenge was messed up due to some mistake by the admins - so they had asked us to send the output (Basically each of the 999 round passwords). We got the flag once we gave them the information.