Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/70.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 简单外壳代码不工作_C_Gcc_Shellcode - Fatal编程技术网

C 简单外壳代码不工作

C 简单外壳代码不工作,c,gcc,shellcode,C,Gcc,Shellcode,我有下面的代码,它应该放下一个shell,但是,在我运行代码之后,似乎什么都没有发生。这是我的代码。这是从炮弹编码器手册中摘取的 ` 我使用gcc-fno-stack-protector-z execstack外壳代码.c-o外壳代码编译它 当我运行它时,会发生以下情况。 预期结果如下。 以下是生成上述结果的代码: int main() { char *name[2]; name[0] = "/bin/sh"; name[1] = 0x0; execve(name[0],

我有下面的代码,它应该放下一个shell,但是,在我运行代码之后,似乎什么都没有发生。这是我的代码。这是从炮弹编码器手册中摘取的

`

我使用
gcc-fno-stack-protector-z execstack外壳代码.c-o外壳代码编译它

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

预期结果如下。

以下是生成上述结果的代码:

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

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

}
我不知道为什么会这样。我在Windows10上使用Ubuntu。这可能不会影响我的结果,但我已禁用ASLR。这可能是个问题。我还没有在虚拟机上尝试过这个。在我这么做之前,我想试着弄明白为什么这不起作用。如果这是不清楚的,请让我知道,我会很高兴地澄清任何细节

我提前感谢你的帮助

--更新--

我能够从我提供的外壳代码中获得组装说明


是否有人发现任何可能导致外壳无法掉落的问题?

这里有两件事情可能会出错:

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

在一位同事的帮助下,我们找到了外壳代码无法执行的原因。外壳代码很好,问题实际上是对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();
}
这是一个与这个答案相关的问题。

uname-a的输出是什么??在没有虚拟机的情况下,如何在Windows 10上运行Ubuntu?@jwdonahue:有一个Linux(Ubuntu)Windows 10上的子系统。@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,如果这有帮助的话,您如何确定外壳代码没有覆盖返回地址?我在gdb中运行时确实遇到seg错误。@user3431573我读取了机器代码,查看堆栈指针是如何更新的。我可能听起来像一个完整的noob,但您可以从十六进制中推断出来!?我通过反汇编程序运行编译的
main
函数。(这部分不是关于外壳代码,而是关于代码重定向到外壳代码。)
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();
}