Stack buffer overflow (wiki)

转载 2011年01月22日 12:27:00

Stack buffer overflow

From Wikipedia, the free encyclopedia
Jump to: navigation, search

In software, a stack buffer overflow occurs when a program writes to a memory address on the program's call stack outside of the intended data structure; usually a fixed length buffer.[1][2] Stack buffer overflow bugs are caused when a program writes more data to a buffer located on the stack than there was 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. This type of overflow is part of the more general class of programming bugs known as buffer overflows.[1]

If the affected program is running with special privileges, or accepts data from untrusted network hosts (e.g. a webserver) then the bug is a potential security vulnerability. If the stack buffer is filled with data supplied from an untrusted user then that user can corrupt the stack in such a way as to inject executable code into the running program and take control of the process. This is one of the oldest and more reliable methods for hackers to gain unauthorized access to a computer.[3][4][5]

Contents

[hide]

[edit] Exploiting stack buffer overflows

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).[3][6] This is illustrated in the example below:

An example with strcpy
#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]); 
}

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 delimited by a zero 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
A. - Before data is copied.
B. - "hello" is the first command line argument.
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.

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). As you can see in figure C above, 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 be replaced with 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.[3]

The attacker also can modify internal variables values to exploit some bugs. With same example :

#include <string.h>
#include <stdio.h>
 
void foo (char *bar)
{
   float My_Float = 10.5; // Addr = 0x0023FF4C
   char  c[12];           // Addr = 0x0023FF30
 
 
   // Will print 10.500000
   printf("My Float value = %f/n", My_Float);
 
    /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
       Memory map:
       @ : c allocated memory
       # : My_Float allocated memory
       - : other memory
 
 
           *c                      *My_Float
       0x0023FF30                  0x0023FF4C
           |                           |
           @@@@@@@@@@@@----------------#####
      foo("my string is too long !!!!! XXXXX");
 
   memcpy will put 0x1010C042 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;
}

[edit] Platform related differences

A number of platforms have subtle differences in their implementation of the call stack that can affect the way a stack buffer overflow exploit will work. Some machine architectures store the top level return address of the call stack in a register. This means that any overwritten return address will not be used until a later unwinding of the call stack. Another example of a machine specific detail that can affect the choice of exploitation techniques is the fact that most RISC style machine architectures will not allow unaligned access to memory.[7] Combined with a fixed length for machine opcodes this machine limitation can make the jump to ESP technique almost impossible to implement (with the one exception being when the program actually contains the unlikely code to explicitly jump to the stack register).[8][9]

[edit] Stacks that grow up

Within the topic of stack buffer overflows, an often discussed but rarely seen architecture is one in which the stack grows in the opposite direction. This change in architecture is frequently suggested as a solution to the stack buffer overflow problem because any overflow of a stack buffer that occurs within the same stack frame can not overwrite the return pointer. Further investigation of this claimed protection finds it to be a naive solution at best. Any overflow that occurs in a buffer from a previous stack frame will still overwrite a return pointer and allow for malicious exploitation of the bug.[10] For instance, in the example above, the return pointer for foo will not be overwritten because the overflow actually occurs within the stack frame for strcpy. However, because the buffer that overflows during the call to strcpy resides in a previous stack frame, the return pointer for strcpy will have a numerically higher memory address than the buffer. This means that instead of the return pointer for foo being overwritten, the return pointer for strcpy will be overwritten. At most this means that growing the stack in the opposite direction will change some details of how stack buffer overflows are exploitable, but it will not reduce significantly in the number of exploitable bugs.

[edit] Protection schemes

Over the years a number of schemes have been developed to inhibit malicious stack buffer overflow exploitation. These usually have taken one of two forms. The first method is to detect that a stack buffer overflow has occurred and thus prevent redirection of the instruction pointer to malicious code. The second attempts to prevent the execution of malicious code from the stack without directly detecting the stack buffer overflow.[11]

[edit] Stack canaries

Stack canaries, so named because they operate as a canary in a coal mine so to speak, are used to detect a stack buffer overflow before execution of malicious code can occur. This method works by placing a small integer, the value of which is randomly chosen at program start, in memory just before the stack return pointer. Most buffer overflows overwrite memory from lower to higher memory addresses, so in order to overwrite the return pointer (and thus take control of the process) the canary value must also be overwritten. This value is checked to make sure it has not changed before a routine uses the return pointer on the stack.[2] This technique can greatly increase the difficulty of exploiting a stack buffer overflow because it forces the attacker to gain control of the instruction pointer by some nontraditional means such as corrupting other important variables on the stack.[2]

[edit] Nonexecutable stack

Another approach to preventing stack buffer overflow exploitation is to enforce memory policy on stack memory region to disallow execution from the stack. This means that in order to execute shellcode from the stack an attacker must either find a way to disable the execution protection from memory, or find a way to put his shellcode payload in a non-protected region of memory. This method is becoming more popular now that hardware support for the no-execute flag is available in most desktop processors. While this method definitely makes the canonical approach to stack buffer overflow exploitation fail it is not without its problems. First it is common to find ways to store shellcode in unprotected memory regions like the heap, and so very little need change in the way of exploitation.[12] Even if this were not so, there are other ways. The most damning is the so called return to libc method for shellcode creation. In this attack the malicious payload will load the stack not with shellcode, but with a proper call stack so that execution is vectored to a chain of standard library calls, usually with the effect of disabling memory execute protections and allowing shellcode to run as normal.[13] This works because the execution never actually vectors to the stack itself. Still if used in conjunction with techniques like ASLR a nonexecutable stack can be somewhat resistant to return to libc attacks and thus can greatly improve the security of an application.

Notable examples

Exploitation of Buffer Overflow Vulnerabilities Under Windows XP

Hitchhikers World (Issue #8) http://www.infosecwri...
  • iiprogram
  • iiprogram
  • 2006年04月28日 15:33
  • 1735

关于buffer overflow detected 程序崩溃的思考

我是在使用别人源码(DBT2 benchmark)的时候,编译成功一运行就出现了这个问题。本以为像这种开源的软件应该没什么bug,但是仔细想想,buffer overflow暗示着指针操作内存不当导致...
  • hustsselbj
  • hustsselbj
  • 2015年07月09日 08:45
  • 4976

网站漏洞整理

1,xss Cross Site Script 恶意攻击者在某web页面植入恶意的html代码,当用户浏览该页面时,恶意的html代码会被执行,从而达到恶意用户的特殊目的, 比如窃取用户的用户名...
  • u013393981
  • u013393981
  • 2014年09月08日 18:22
  • 1429

vim+gdb=vimgdb完美安装教程

本人系统Ubuntu12.04 http://blog.csdn.net/citongke1/article/details/8438904
  • lh499315384
  • lh499315384
  • 2014年07月29日 18:34
  • 1107

关于缓冲区溢出(Buffer Overflow)

接触黑客的同志们经常遇到,使用一些扫描工具扫描的时候,会得到一些缓冲区溢出的漏洞,但是怎么利用自己是一团雾水 网上很少有相关的工具,也很少有相关的文章,下面我们就说说这个“窿西”吧  [蛋痛]文章...
  • aqzwss
  • aqzwss
  • 2015年06月05日 18:10
  • 464

缓存溢出(Buffer overflow)

缓存溢出(Buffer overflow),是针对程序设计缺陷,向程序输入缓冲区写入使之溢出的内容(通常是超过缓冲区能保存的最大数据量的数据)从而破坏程序运行并取得程序乃至系统的控制权。 缓存溢...
  • V_Grubby
  • V_Grubby
  • 2013年09月10日 19:36
  • 1167

CSAPP 六个重要实验 lab3

CSAPP 六个重要实验 lab3
  • u011368821
  • u011368821
  • 2014年09月15日 17:00
  • 3788

OWASP WebGoat---安全测试学习笔记(五)---缓冲区溢出

OWASP WebGoat---安全测试学习笔记(五)---缓冲区溢出
  • ggf123456789
  • ggf123456789
  • 2014年05月23日 21:31
  • 1784

R软件学习笔记—Legend

当图表中承载了多组数据用于比较时,通常会使用不同的颜色来区分,并且使用图例说明不同颜色代表的数据,如图3-17所示。   图例中既包括文字,也包括点和线元素。R语言中的图例可以使用legend...
  • myl1992
  • myl1992
  • 2015年05月18日 20:40
  • 8142

R的legend参数设置

在作图的时候,legend很重要,在R中设置很繁琐,不像MATLAB有图形界面的,可以手动的设置。下面以?legend中例子学习一下legend参数。   #首先导入数据 >x > x  [...
  • flyfrommath
  • flyfrommath
  • 2016年05月31日 15:16
  • 3811
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Stack buffer overflow (wiki)
举报原因:
原因补充:

(最多只允许输入30个字)