This challenge was solved by and the write up was written by one of my teammates, tukan
We were given an x64 ELF binary and the corresponding libc. It had most protections enabled but still had writeable .got entries.
Reversing the challenge revealed that:
the binary sniffs trafic via libpcap.
processes only icmp and tcp/80 traffic.
the icmp handler contains an information leak via a format string bug.
the tcp handler contains a buffer overflow inside the structure allocated for tcp connections, allowing us to modify pointers later used as destination addresses for memcpy calls with attacker-controlled source data.
The relevant parts of the struct:
The exploitation plan is as follows:
leak pointers to libc and the binary from the stack using the format string bug.
overwrite the username pointer in the connection struct with the address of the strstr .got entry.
overwrite the strstr got entry (called on attacker-controlled data in the tcp handler) via the address of system from libc.
read the flag using the the shell command: “. ./flag” (made possible by stderr coming back from the binary)
The flag was:
(not stable, you probably have to run multiple times)
The second part of the challenge was exploiting a UAF (use-after-free) vulnerability.
This could be triggered if the admin deleted a “Bragisdumu” (btw what is a Bragisdumu!? :D).
But there were some restrictions, for example: the admin could only delete items if there were no stock of it, so we had to buy them first. But you could not buy any amount of them, only 16, so you had to buy the Knight Rider one.
Although the program tried to nullify the object, but it did not nullify the pointer, but the active field of the pointed object. And then deleted the object. So it did not trigged the vulnerability by itself, you also had to use a long enough username + password.
To make the exploit stable I had to leak some addresses. To do this I overwrite the whole item structure until the ptr value:
This way the address of the KnightRider preview function is leaked out, then I logged out and logged in with username which overwrite the preview function call (0x1275) to printf in the PLT (0xda0). As the parameter for this call is the Item structure’s address which is fully controlled by me I could sent in a format string which contained a lot of “%p”’s, thus leaking out the libc base address from the stack (among other things).
Then in the next round I simple overwrite the pointer with the calculated system address and got a shell :)
The main vulnerability for getting the admin password is that if you send in a maximum length username (32 bytes) and password (64 bytes) then no string terminating null character was written. Also, usernames and passwords were checked with memcpy and exact length instead of strcpy.
As the program prints out the logged in username this leads to leaking out the next value in the stack: the memcmp result of the admin password.
So the attack was basically:
try to login with admin and the password you leaked so far (empty at first) plus “~” (0x7e)
although this will lead to failed login, the memcpy result won’t be cleared
I am using 0x7e because it is the last readable ASCII character and comparison with password will give smaller results
try to login with username “guest” + “A”(32-5) and password “guest” + “A”(64-5)
read the leaked value, this will be the positive difference between “~” and the next character from the password
logout and try again, until you found the password and can login as admin :)
This can be done by a simple backtrack algorithm, we try to guess the digits of both primes starting from the outermost.
KT’s note: we found out that they were emirps by factorizing some small public moduluses with Yafu. And we had to factorize only one public key as the cipher text was 129 bytes, but only 1028 bits (started with 08 which is ~4 bits) and the smallest public key which was larger than 1028 bits was the n in the python code (it is ~1029 bits btw).