AssaultCube is a video game that is open source. The main goal of the research was to get a client to server RCE.
To find the bug, the author of the vulnerability went through all points of input and looked for general bad parsing. Finding the bug is hard; exploiting it almost feels impossible, in the real world. This article goes into chaining one bug to cause all sorts of corruption, to eventually get code execution.
The main vulnerability is an issue with an index validation (which can be seen below). What's the issue? The validation checks with an
& instead of an
|. Because of this, the break on the index check will NEVER work!
if (nextprimary < 0 && nextprimary >= NUMGUNS)
break;
With the ability to control this index, it is possible to write a seemingly random integer to anywhere in memory. This creates a write-WHERE primitive, which is similar to the unsorted bin attack with heap exploitation.
Using the ability to overwrite ANYWHERE in memory (with the bad index), the author looked for ways to edit the inherit flow of the client. Using the C++ client, the author decided to edit a vector variable; in particular, overwrite the amount of variables that can be held within the vector (max size of the array).
The messages buffer was chosen, as a user could easily control this vector. In order to get code execution, the data next to the vectors V-Tables would allow for the ability to edit function pointers, if overwritten! The V-Table was adjacent to the data on the heap.
Another issue was getting this payload to be consistent. A path had to be found that would not cause the program to crash upon corruption. Real world exploits are VERY messy.
Sound like a gameover, right? Well, the messages can only contain printable characters, which makes writing function pointers SO hard. To get a foothold, eventually syslog was called as an easy way to create ANOTHER vuln (format string issue).
From the format string vuln, they used it in order to overwrite the GOT entry of strcmp with the PLT of system! Now, just send a message with an easy /bin/sh and a shell was popped :)
Overall, real world exploitation is MUCH harder than some CTF, as there are less ways to get a foothold on the system. Additionally, small, seemingly insignificant issues, can lead to further memory corruptions to eventually allow for complete compromise. Awesome article!