所以我试图在此代码中执行shellcode,这就是我到目前为止,已经做过了:
我设法覆盖了缓冲区并将foo函数的返回地址设置为关键函数,但是我的问题是如何在此处运行特定的shellcode? execv将运行bin / sh,但我无法用shellcode替换第一个参数,它将无法正常工作,我不确定是否甚至可以使用execv运行shellcode,以及何时将shellcode传递给sh它不起作用。
我也知道返回libc漏洞,但仍然不知道如何使用system()执行shellcode?甚至可以将shellcode传递给它吗?或者也许我可以使用另一个函数只是将shellcode传递给它?
如果我创建了自己的shellcode文件并替换了sh路径,我想我们可以运行自己的shellcode,但是我们无权创建文件,我们只需要使用此代码即可。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
int bar(char *arg, char *out)
{
strcpy(out, arg);
return 0;
}
int foo(char *arg)
{
char buffer1[100]="Test program.\n";
char buffer2[100];
bar(arg, buffer2);
printf("%s",buffer1);
return 0;
}
void critical()
{
char *msg[]={"/bin/sh",NULL};
execv(msg[0],msg);
}
int main(int argc, char *argv[])
{
if (argc != 2)
{
fprintf(stderr, "prog_vuln2: argc != 2\n");
exit(EXIT_FAILURE);
}
foo(argv[1]);
return 0;
}
#1 楼
当您拥有不可执行的堆栈时,首先想到的是面向返回的程序,顾名思义,该程序使用return来执行所需的代码。使用ROP时,您将希望使用程序的可执行文件和dll(或Linux中的.so文件),并尽可能减少对系统dll的依赖,因为它们会随操作系统版本的变化而变化。
想法是,您会找到一系列指令。每个人都叫
gadget
。小工具可以通过以下操作来设置寄存器值:q4312079从堆栈中查询一个值,pop
一个值或添加/减去一个寄存器,然后mov
(这意味着您通常可以在函数末尾找到它们),从而使它们返回堆栈上的下一个值(预期返回地址将在其中)创建一个ret
。一个简单的示例是,当您想使用
ROP Chain
执行命令时。您可以(在64位上) OS)跳转到弹出返回,其中堆栈上的第一个值是您的缓冲区地址,第二个值是
system
的地址,从而导致系统使用缓冲区作为正确寄存器中的参数来调用系统(对于Linux,rdi,ecx对于Windows)。在32位操作系统上,溢出稍微简单一些。您需要做的是将返回地址覆盖到
system
,并将其后的4个字节覆盖为缓冲区的地址。这将以缓冲区作为第一个参数执行system
。