Process memory exploitation and protection in runtime

To begin understanding why process memory patching is a serious issue we need to understand what it is and how it works. So, without further ado let's answer these questions. Memory patching is modification of process memory in runtime (in this post I am not going to talk about patching binary files). To help you better understand, let's imagine the following scenario: you created a game that has a high score system, user's score is stored in a variable in memory and at game over it is sent to the server. Now, imagine if someone changes the variable in memory right before it is sent. Sounds unfair to other honest players, doesn't it?

To better demonstrate how it works I wrote a simple demo in c++ (which you can compile and test on your system). It this post I will be only talking about how it's done in user mode.

Target program:

Attacker program:
First we compile and run a target program, it will display it's process identifier (PID) and a memory location of the buffer. Then, compile an attacker program, but before that make sure that the variable memAddr is equal to the memory location of the buffer. Now we can run an attacker program and pass it a PID of the target. First thing it will do is read memory content at specified location, next it will ask if we want to modify it (enter 'y') and enter a new sting, for example "Did it work". Finally, go back to the target program and press Enter to continue, it should display our altered string. Here is a simplified diagram:

Now the scary part: we are not limited to modifying just variables, we can alter code itself. That makes it hard to defend against memory patching, because integrity check functions can be overwritten (in case we decide to check our variable/memory against the hash). Another smart solution would be to check parts of code from the binary file with the code loaded in memory, but again, function that does the check can be overwritten to always return 'true'.
Similar approach would be to start a second instance of our program and make it compare it's memory with original process memory (assuming that binary file has not been altered). Here is my implementation of this technique:

Obfuscating your code to make it harder to locate variables in memory and manually allocating memory for variables and adding random amount of junk data in there, so that address to the actual variable is different every time, would make it difficult for attackers to exploit your program. Or if you do not want to protect your executable yourself, there are plenty of packers and protectors that will help you ensure that your program is secure.

If you are interested about what can be done to protect against memory patching on kernel level, then here is a great post by @evilsocket on how to defend against unwanted process manipulations by creating a driver.

If you know any other techniques to protect process memory, please share them in the comments or write me a message, I would really appreciate it.

References:
https://blog.malwarebytes.com/cybercrime/malware/2017/03/explained-packer-crypter-and-protector/
https://www.cybrary.it/0p3n/advanced-exe-multi-protection-reverse-engineering-free-tools/
https://www.ncsc.gov.uk/content/files/protected_files/guidance_files/Code-obfuscation.pdf
https://polystream.com/polystream-tech/2017/10/9/runtime-memory-patching
https://www.sciencedirect.com/science/article/pii/S1877050915032780
http://electronicmusic.wikia.com/wiki/Patch_memory

Comments

Popular Posts

DLL injection - detection and prevention

Function Hooking