我有以下应该放入外壳的代码,但是,运行代码后,似乎什么也没有发生。这是我的代码。这摘自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。那可能是个问题。我尚未在VM上尝试过此操作。我想尝试找出为什么这样做不起作用。如果不清楚,请告知我,我们将很乐意澄清所有细节。
感谢您提前提供的所有帮助。
-更新-
我能够从提供的shellcode中获得汇编指令。
是否有人看到任何会导致外壳无法掉落的问题?
最佳答案
在同事的帮助下,我们能够弄清楚为什么shellcode无法执行。 shellcode很好,问题实际上是对gcc编译器的更新,它更改了代码执行时处理序言/后记的方式。程序启动时,编译器生成的代码将返回地址放在堆栈上,但是它使用新的模式来执行此操作。执行程序不再通过将返回地址弹出到指令指针(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
关于c - 简单的shellcode不起作用,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/50429199/