In reports on security exploits/vulnerabilities on desktop applications, I often read that memory problems lead to the execution of malicious code.

For example, the description of Internet Explorer vulnerability CVE-2018-8653 says (https://portal.msrc.microsoft.com/en-US/security-guidance/advisory/CVE-2018-8653)

The vulnerability could corrupt memory in such a way that an attacker could execute arbitrary code

How does this work in general?

As far as I understand it, issues of this kind have in common that in a desktop application/process memory allocation was not done properly, i.e. there is something in the memory where it shouldn't or the other way around: There should be something there, but it isn't. So far so bad. Problems of this kind almost always lead to malfunction of programs or crashes. But how can an attacker use such an issue to inject/execute code?

closed as too broad by forest, Xander, Teun Vink, Tobi Nary, A. Hersean Jan 11 at 12:25

Please edit the question to limit it to a specific problem with enough detail to identify an adequate answer. Avoid asking multiple distinct questions at once. See the How to Ask page for help clarifying this question. If this question can be reworded to fit the rules in the help center, please edit the question.

  • 5
    Please look up the concept of "buffer overflow" and similar. The idea is that you plant code and then manipulate the execution flow in memory to point to the new code. – schroeder Dec 20 '18 at 19:28

The memory a program uses includes both what you would think of as "data" (text you wrote, an image you're viewing, the script source code your web browser downloaded, a string of text which is being built by that script...), what you might think of as "metadata" (a mapping of free and used memory blocks, pointers to the start of those memory blocks, pointers linking that text string to the functions that can be executed on it, pointers to loaded libraries such as IE's jscript.dll that parses and compiles JavaScript), and executable code (the actual binary code the CPU runs, including the DLL contents, the result of compiling the JS, and the functions on "objects" in data).

When memory corruption occurs, an attacker can usually exert some control over where and how it occurs. For example, if the attacker finds a way to cause some data to be deleted but the program to treat it as still present (called a "use after free" vulnerability, and relatively common in JavaScript engines), the attacker's script could then create a new data object (such as an array of carefully-chosen bytes) that is a similar size and will be created in the same place as the deleted-but-still-usable object. The attacker then might set some value on the deleted object, but because the memory that defines the object holds some totally new data now (the attacker-crafted array) it actually changes some value that the attacker isn't supposed to be able to control such as the extent of the array. The attacker then uses the array - which the program now thinks is super-long, extending well beyond the allocated chunk of memory that it is actually stored in and into memory used for other things - and does something like change the "return pointer" metadata that says "when this block of code finishes, continue executing code over here". The attacker changes this return pointer so that the code that will run after the current function ends does something like launch a program the attacker wrote, executing arbitrary code on the victim's computer.

This type of attack (use-after-free to gain an arbitrary-offset memory read/write, using that to overwrite the return address into some attacker-desired function) is but one of many, many ways to exploit memory corruption. Some other memory corruption vulns are double-free (trying to delete the same block of memory twice, which is dangerous because you may end up treating attacker-controlled data as though it is actually metadata about the memory allocations and thus change data the user shouldn't have access to), buffer overflows on the stack or heap (two different places program data goes; the stack is where you'll also find things like return pointers and the heap where you'll find things like function tables and arbitrary-length arrays) where you can write past the end of a memory allocation and change other data, integer overflow where the program does some math on two numbers that ends up with a result too big for the program to hold in the space it reserved for that number, so it loses part of that number and treats the totally-different number as a pointer into safe memory when in fact it could be anything at all, and so on.


One scenario: The attacker chooses a piece of shell code or sequence of system calls it wants to execute, then uses Metasploit, or similar frameworks, to generate a binary payload for the targeted CPU. Then the attacker feeds the payload to the network service or to local API. Assuming the input size validation is broken and did not reject the input data, the buffer holding the input data will overflow from the buffer onto the stack and overwrite the return address to the calling function. Metasploit has crafted the payload such that the new return address now points to a selected system call and the shellcode will be fed to the system call. It is possible as the systems calls are always on predefined and well-known addresses.

Not the answer you're looking for? Browse other questions tagged or ask your own question.