首页 > 解决方案 > 简单的 shellcode 不起作用

问题描述

我有以下代码应该删除一个外壳,但是,在我运行代码之后似乎什么都没有发生。这是我拥有的代码。这取自 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

当我运行它时,会发生以下情况。 shellcode的实际结果

预期结果如下。 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 中获得汇编指令。

从上面的 shellcode 组装

有没有人看到任何会导致外壳不被丢弃的问题?

标签: cgccshellcode

解决方案


在一位同事的帮助下,我们能够弄清楚为什么 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();
}

这是一个与此答案相关的问题。 了解新的 gcc 序言


推荐阅读