跳转至

第 2 周:缓存溢出

虽然这种攻击现在已经基本没法使用了,但是它作为第一步还是适合入门的。

软件是安全链中的最脆弱的部分之一。

C 和 Java

众所周知,Java 有类型安全(运行时检测)和垃圾回收,而这两个都是 C 所没有的。

Java 还有运行时的边界检测:

int a[10];
a[10] = 3;

这个会直接报错的。

1
2
3
4
int sum = 0;
for (int i = 0; i < a.length; i++) {
  sum += a[i];
}

不过这其中的检测就会被优化器优化掉。

危险的函数

1
2
3
4
5
6
7
SYNOPSIS
       #include <stdio.h>

       char *gets(char *s);

DESCRIPTION
       Never use this function.

C 语言里有很多不会检测边界的函数,比如 strcpystrcatsprintf 等。

这些函数一般可以被当作我们攻击的入口。

栈的布局

1
2
3
4
5
6
7
8
高地址
参数
参数
返回地址 ra
上一次的栈寄存器 sp
变量
低地址
↓↓↓

程序返回时

leave = mov ebp, esp; pop ebp

ret = pop eip