维基百科
栈缓冲区溢出
栈缓冲区溢出(stack buffer overflow或stack buffer overrun)是计算机程序把数据写入调用栈上的内存时超出了数据结构的边界。[1][2]栈缓冲区溢出是缓冲区溢出的一种。[1] 这会损坏相邻数据的值,引发程序崩溃或者修改了函数返回地址从而导致执行恶意的程序。这种攻击方式称为stack smashing。可被用于注入可执行代码、接管进程的执行。是最为古老的黑客攻击行为之一。[3][4][5]
例子
下例可用于覆盖函数返回地址。[3][6] 通过函数 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]); return 0; }
当命令行参数少于12个字符时(例子B时)该程序是安全的。
foo()
函数的不同输入下的调用栈:
例子C中, 命令行参数多于11个字符,导致foo()
覆盖了本地调用栈的数据、存储的栈指针(EBP)以及最重要的返回地址。
攻击也可以修改内部变量值:
#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; }
平台相关
保护方式
常用三种方式来对抗栈缓冲区溢出攻击。
检查栈缓冲区溢出的发生
栈的警惕标志(stack canary),得名于煤矿里的金丝雀,用于探测该灾难的发生。具体办法是在栈的返回地址的存储位置之前放置一个整形值,该值在装入程序时随机确定。栈缓冲区攻击时从低地址向高地址覆盖栈空间,因此会在覆盖返回地址之前就覆盖了警惕标志。返回返回前会检查该警惕标志是否被篡改。[2]
栈数据不可执行
采取了“写异或执行”策略(W^X, "Write XOR Execute"),即内存要么可写,要么可执行,但二者不能兼得。这是最常用的方法,大部分桌面处理器都硬件支持不可执行标志(no-execute flag)。
随机化内存空间布局
著名例子
参见
参考文献
- ^ 1.0 1.1 Fithen, William L.; Seacord, Robert. VT-MB. Violation of Memory Bounds. US CERT. 2007-03-27 [2017-02-19]. (原始内容于2012-02-05).
- ^ 2.0 2.1 Dowd, Mark; McDonald, John; Schuh, Justin. The Art Of Software Security Assessment. Addison Wesley. November 2006: 169–196. ISBN 0-321-44442-6.
- ^ 3.0 3.1 Levy, Elias. Smashing The Stack for Fun and Profit. Phrack. 1996-11-08, 7 (49): 14 [2017-02-19]. (原始内容于2021-03-04).
- ^ Pincus, J.; Baker, B. Beyond Stack Smashing: Recent Advances in Exploiting Buffer Overruns (PDF). IEEE Security and Privacy Magazine. July–August 2004, 2 (4): 20–27 [2017-02-19]. doi:10.1109/MSP.2004.36. (原始内容 (PDF)于2016-03-04).
- ^ Burebista. (PDF). [2017-02-19]. (原始内容 (PDF)存档于2007-09-28). (dead link)
- ^ Bertrand, Louis. . MUSESS '02: McMaster University Software Engineering Symposium. 2002 [2017-02-19]. (原始内容存档于2007-09-30).