【问题标题】:Simple shellcode not working简单的 shellcode 不起作用
【发布时间】:2018-05-19 20:26:41
【问题描述】:

我有以下代码,它应该删除一个 shell,但是,在我运行代码之后,似乎什么都没有发生。这是我拥有的代码。这摘自 shellcoder 的手册。

`

char shellcode[] = 
    "\xeb\x1a\x5e\x31\xc0\x88\x46\x07\x8d\x1e\x89\x5e\x08\x89\x46"
    "\x0c\xb0\x0b\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xcd\x80\xe8\xe1"
    "\xff\xff\xff\x2f\x62\x69\x6e\x2f\x73\x68";
int main()
{
    int *ret;
    ret = (int *)&ret + 2;
    (*ret) = (int)shellcode;
}`

我使用gcc -fno-stack-protector -z execstack shellcode.c -o shellcode编译它

当我运行它时,会发生以下情况。

预期结果如下。

这是产生上述结果的代码:

int main()
{
  char *name[2];

  name[0] = "/bin/sh";
  name[1] = 0x0;
  execve(name[0], name, 0x0);
  exit(0);

}

我不确定为什么会这样。我在 Windows 10 上使用 Ubuntu。这可能不会影响我的结果,但我禁用了 ASLR。这可能是个问题。我还没有在虚拟机上试过这个。在我这样做之前,我想尝试弄清楚为什么这不起作用。如果不清楚,请告诉我,我很乐意澄清任何细节。

提前感谢您的所有帮助。

--更新--

我能够从我提供的 shellcode 中获得汇编指令。

有没有人发现任何会导致 shell 不被丢弃的问题?

【问题讨论】:

  • uname -a 的输出是什么?
  • 如何在没有虚拟机的情况下在 Windows 10 上运行 Ubuntu?
  • @jwdonahue:Windows 10 上有一个 Linux (Ubuntu) 子系统。
  • @jwdonahue 他说了什么, uname -a 的输出是Linux DESKTOP-P4KG81D 4.4.0-17134-Microsoft #48-Microsoft Fri Apr 27 18:06:00 PST 2018 x86_64 x86_64 x86_64 GNU/Linux
  • 如果有帮助的话,我相信参考文献使用的是 Debian 3.1r4

标签: c gcc shellcode


【解决方案1】:

在一位同事的帮助下,我们能够弄清楚为什么 shellcode 没有执行。 shellcode 很好,问题实际上是对 gcc 编译器的更新,它改变了代码执行时 prolog/epilog 的处理方式。当程序启动时,编译器生成的代码将返回地址放入堆栈,但它使用了一种新模式。执行程序不再通过将返回地址弹出到指令指针 (IP) 中来直接使用返回地址。相反,它将堆栈值弹出到%ecx,然后使用地址%ecx-4(对于32 位机器)处的内容作为返回地址。因此,即使关闭了保护措施,我试图这样做的方式也永远不会奏效。此行为仅影响 main() 而不会影响 main 调用的函数。因此,一个简单的解决方案是将 main 的内容放入另一个函数 foo() 并从 main() 调用 foo(),如下所示。

char shellcode[] = 
    "\xeb\x1a\x5e\x31\xc0\x88\x46\x07\x8d\x1e\x89\x5e\x08\x89\x46"
    "\x0c\xb0\x0b\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xcd\x80\xe8\xe1"
    "\xff\xff\xff\x2f\x62\x69\x6e\x2f\x73\x68";
void foo()
{
    int *ret;
    ret = (int *)&ret + 4; 
    (*ret) = (int)shellcode;
}

int main()
{
  foo();
}

这是一个与此答案相关的问题。 Understanding new gcc prologue

【讨论】:

    【解决方案2】:

    这里有几件事可能会出错:

    • shell 代码地址的存储已被优化掉,因为它是从堆栈变量派生的,之后不会从堆栈中读取任何内容。
    • 商店已被优化掉,因为它超出了边界。
    • 从局部变量的偏移量计算错误,所以shellcode地址不会覆盖返回地址。 (这就是我编译您的示例时发生的情况。)
    • 执行是重定向,但是shellcode没有运行,因为它位于不可执行的.data段中。 (不过,这会导致进程以信号终止)。

    【讨论】:

    • 你是如何确定 shellcode 没有覆盖返回地址的?
    • 我在 gdb 中运行时确实遇到了段错误。
    • @user3431573 我看了机器码,看看栈指针是怎么更新的。
    • 我可能听起来像个十足的菜鸟,但你可以通过查看十六进制推断出这一点!?
    • 我通过反汇编程序运行了编译后的main 函数。 (这部分不是关于shellcode,而是关于重定向到shellcode的代码。)
    猜你喜欢
    • 1970-01-01
    • 2013-11-01
    • 2021-03-11
    • 2021-05-18
    • 2018-11-14
    • 2017-05-19
    • 2013-03-21
    • 1970-01-01
    相关资源
    最近更新 更多