Concept: Exploitation Techniques
This page lists a number of common exploitation tricks.
Brute-forcing static memory
Sometimes, there is static memory that you need to leak, and you don’t have a direct leak. This technique requires the following preconditions:
- The memory you need to leak is too big to just brute-force outright (otherwise, you should just do that).
- You can perform a partial overwrite of the data.
- The program tells you when you corrupt the data (i.e., quits due to a canary, fails a decryption, etc).
- You can repeat the overwrite procedure without the underlying data changing.
A specific application of this is leaking the canary of a forking program. Some classes of network applications fork (i.e., copy the process) on every connection. Interestingly, canaries are randomized only when the process starts, but not when it forks. Because forked processes are independent of each other, you can experiment with vulnerabilities in the child process (and overwrite the canary with incorrect values, leading to process termination) without adversely affecting the parent.
Aside from network services, this also happens with Android applications. On Android, every process is forked off of a common process called the Zygote. This weird setup causes all the canaries to be the same, so if you can leak one, you will know them all.
So how do you do it? If you overwite the whole canary, you have a 1 out of 72057594037927936 chance of randomly guessing the right value (1/2^56, rather than 1/2^64, because the LSB is always NULL). But, you can do it byte by byte! Consider the least significant (and, in little endian, left-most) byte (which we know is NULL, or 0x00): if you overwrite it with an incorrect value, the canary check will fail. If you overwrite it with 0, it will succeed. Since you know the leftmost/LSB byte, you can begin to attack the next byte. You can guess a value, see if the process aborts with a canary fail, and if it does, try another value. Since you are brute-forcing one byte, this should take at most 256 tries. Then you move on to the next one. The entire canary can be brute-forced byte-by-byte in 256*7 (1792) tries.
Of course, this only works with static canaries (or other static data that you need to leak without actual output).