Debian provides virtual machine images of their distribution for MIPS-I
CPUs, which we were able to use with qemu in order to run the binary. It
serves a simple shell with the following commands available:

1
2
3
4
5
6

qotd
ls
png2ascii
help
exit
quit

When we used the ls command we could see the key file. The goal of this
challenge was obviously to get it back. But the vulnerability was in another
command: png2ascii (sub_00401BC4). This functions reserves a buffer of size
0x100 on the stack but reads 0x200 from it, stopping at the first '\n'
byte encountered. We can use this to overwrite the return address stored on the
stack and control the execution flow.

The problem we encountered next was bypassing ASLR, which made the address of
our stack buffer random. We tried to find gadgets in the binary in order to
return to our buffer address but no register pointed to our buffer and no
pointer to the buffer was present at a useful location in the stack. Luckily,
the server uses fork() to serve each connection, which means each connection
will use the same base stack address. We don't know where our buffer is but if
we can find it once we know it will always be there until a server reboot.

We decided to leak informations about our memory map by using a write syscall
present in the binary and returning to it. It loads arguments from the stack so
we can control these as well, and the file descriptor we need to write the data
on is already loaded with the right value.

Using this trick we were able to find our buffer filled with "A" characters, so
we knew exactly where to jump to. We just needed a valid MIPS shellcode to
execute a shell on the remote server. Using this website we were able to
do this very quickly. After testing it on the remote server we noticed that
simply running dup2 and execve was not enough because the server had a hard
file descriptor limit. We bypassed it by using setrlimit before execve,
giving us this final exploit script: