【发布时间】:2020-07-17 10:48:48
【问题描述】:
我正在学习 opensecuritytraining 课程“exploits 1”。目前,我正在尝试使用缓冲区溢出在 32 位 linux 系统上利用带有一些 shellcode 的简单 c 程序。 c程序:
void main(int argc, char **argv)
{
char buf[64];
strcpy(buf,argv[1]);
}
我使用命令“tcc -g -o basic_vuln basic_vuln.c”编译了程序。然后,我编写了以下 shellcode。
section .text
global _start
_start:
xor eax, eax
xor ebx, ebx
xor ecx, ecx
xor edx, edx
mov al, 11
push ebx
push 0x68732f2f
push 0x6e69622f
mov ebx, esp
int 0x80
我通过键入“nasm -f elf shell.asm; ld -o shell shell.o”来编译它。当我尝试自己执行“shell”时,它可以工作并且我得到一个shell。接下来,我用 objdump 反汇编程序,编写了一个打印操作码的 perl 文件,然后将所述 perl 文件的输出以及 shellcode 之前的 39 个 nop 指令重定向到一个名为“shellcode”的文件,因此有效负载现在是 64 字节长,填充缓冲区。然后,我在 gdb 中打开 c 程序,并在 nop sled 中间选择一个地址,这将是新的返回地址(0xbffff540)。我将地址附加到“shellcode”文件中,并附加了 4 个字节来覆盖保存的帧指针。 shellcode 如下所示:
现在,当我尝试在 c 程序的 gdb 中运行这个 shellcode 时,它会导致地址 0xbffff575 处出现分段错误,该地址指向我的 shellcode 中的某个点 0x62,即“/”中的字符“b”垃圾箱/sh”。这是什么原因造成的?
这是我的堆栈帧,确认我选择的返回地址确实返回到 nop sled 的中间。
【问题讨论】:
-
您的 C 程序是否编译为 64 位程序?或者你只是为你的漏洞选择了错误的返回地址,所以你返回到你的 shellcode 的中间,EIP 指向立即数的一个字节?在它崩溃之前使用调试器单步执行,看看会发生什么。在您正在攻击的函数中的
ret上设置断点。也许你的 NOP 幻灯片不够长。或者你在把它变成 shellcode 的时候打错了一些东西。你只有你的文字图片,所以我不能复制/粘贴它和 unhexdump + 反汇编,即使我想。你可以使用ndisasm -b32 -
您可能已经针对这种漏洞利用了系统缓解措施:在当前的 Linux 系统上,无法从包含堆栈的内存区域执行机器指令。跳入该区域会立即导致段错误。您的课程是否提到过这种可能性?
-
@PeterCordes 我在 opensecuritytraining 提供的虚拟机中运行它,所以复制粘贴有点困难。我在 shellcode 上运行了 ndisasm -b32,这是程序返回的内容:imgur.com/a/DULAnzz
-
那是什么鬼?你的指令有问题吗?我认为您只是将屏幕截图做得不好,因为指令地址也不连续。无论如何,使用 GDB 单步进入漏洞利用有效负载并查看内存中实际内容的反汇编。
-
我会尝试从
strcpy返回的点开始单步执行程序(在 gdb 中使用si一次执行一条指令)。如果您还没有熟悉 gdb,现在是时候熟悉一下了。
标签: c linux security assembly exploit