page_title: Stack buffer overflow
section_title: Exploiting stack buffer overflows
hierarchical_section_title: Stack buffer overflow / Exploiting stack buffer overflows
caption_attribution_description: English: Image showing program stack after buffer overflow
context_page_description: In software, a stack buffer overflow or stack buffer overrun occurs when a program writes to a memory address on the program's call stack outside of the intended data structure, which is usually a fixed-length buffer.
  Stack buffer overflow bugs are caused when a program writes more data to a buffer located on the stack than what is actually allocated for that buffer. This almost always results in corruption of adjacent data on the stack, and in cases where the overflow was triggered by mistake, will often cause the program to crash or operate incorrectly. Stack buffer overflow is a type of the more general programming malfunction known as buffer overflow. Overfilling a buffer on the stack is more likely to derail program execution than overfilling a buffer on the heap because the stack contains the return addresses for all active function calls.
  A stack buffer overflow can be caused deliberately as part of an attack known as stack smashing. If the affected program is running with special privileges, or accepts data from untrusted network hosts then the bug is a potential security vulnerability.
context_section_description: The canonical method for exploiting a stack-based buffer overflow is to overwrite the function return address with a pointer to attacker-controlled data (usually on the stack itself). This is illustrated with strcpy() in the following example:
  #include <string.h>void foo(char *bar){
     char c[12];
  
     strcpy(c, bar);  // no bounds checking}int main(int argc, char **argv){
     foo(argv[1]);
     return 0;}
  This code takes an argument from the command line and copies it to a local stack variable c. This works fine for command-line arguments smaller than 12 characters (as you can see in figure B below). Any arguments larger than 11 characters long will result in corruption of the stack. (The maximum number of characters that is safe is one less than the size of the buffer here because in the C programming language, strings are terminated by a null byte character. A twelve-character input thus requires thirteen bytes to store, the input followed by the sentinel zero byte. The zero byte then ends up overwriting a memory location that's one byte beyond the end of the buffer.)
  The program stack in foo() with various inputs:
  Notice in figure C above, when an argument larger than 11 bytes is supplied on the command line foo() overwrites local stack data, the saved frame pointer, and most importantly, the return address. When foo() returns it pops the return address off the stack and jumps to that address (i.e. starts executing instructions from that address). Thus, the attacker has overwritten the return address with a pointer to the stack buffer char c[12], which now contains attacker-supplied data. In an actual stack buffer overflow exploit the string of "A"'s would instead be shellcode suitable to the platform and desired function. If this program had special privileges (e.g. the SUID bit set to run as the superuser), then the attacker could use this vulnerability to gain superuser privileges on the affected machine.
  The attacker can also modify internal variable values to exploit some bugs.
  With this example:
  #include <string.h>#include <stdio.h>void foo(char *bar){
     float My_Float = 10.5; // Addr = 0x0023FF4C
     char  c[28];           // Addr = 0x0023FF30
  
     // Will print 10.500000
     printf("My Float value = %f\n", My_Float);
  
      /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~       Memory map:       @ : c allocated memory       # : My_Float allocated memory           *c                      *My_Float       0x0023FF30                  0x0023FF4C           |                           |           @@@@@@@@@@@@@@@@@@@@@@@@@@@@#####      foo("my string is too long !!!!! XXXXX");   memcpy will put 0x1010C042 (little endian) in My_Float value.   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  
     memcpy(c, bar, strlen(bar));  // no bounds checking...
  
     // Will print 96.031372
     printf("My Float value = %f\n", My_Float);}int main(int argc, char **argv){
     foo("my string is too long !!!!! \x10\x10\xc0\x42");
     return 0;}
caption: C. - "A​A​A​A​A​A​A​A​A​A​A​A​A​A​A​A​A​A​A​A​\x08​\x35​\xC0​\x80" is the first command line argument.
exif: {}