问题实际上是关于C中的堆栈溢出,我有一个无法完成的任务,我已经查看了gdb中的所有内容,我只是无法理解它。
问题如下:
int i,n;
void confused()
{
printf("who called me");
exit(0);
}
void shell_call(char *c)
{
printf(" ***Now calling \"%s\" shell command *** \n",c);
system(c);
exit(0);
}
void victim_func()
{
int a[4];
printf("[8]:%x\n", &a[8]);
printf("Enter n: "); scanf("%d",&n);
printf("Enter %d HEX Values \n",n);
for(i=0;i<n;i++) scanf("%x",&a[i]);
printf("Done reading junk numbers\n");
}
int main()
{
printf("ls=736c --- ps = 7370 --- cal = 6c6163\n");
printf("location of confused %x \n", confused);
printf("location of shell_call %x \n", shell_call);
victim_func();
printf("Done, thank you\n");
}好的,所以我正确地得到了第一个问题,就是任意调用主路径中没有显式调用的两个函数之一。顺便说一句,这必须在运行程序时不作任何修改。我这样做是通过运行程序,将N设置为7,这使我可以找到victim_func框架的函数指针,我用困惑或shell_call的内存地址编写了a[7],它可以工作。(我有一台64位的机器,这就是为什么我必须将它设置为7,因为EBI指针是2 int宽,而不是1)
我的问题是,我如何控制哪个参数被传递给shell_code函数?即。如何将string写到char* c。重点是执行unix命令,如、ps、等,只运行程序。
我认为用ps的十六进制表示编写EBI指针,并将shell_call的arg列表设置为该指针,但这不起作用。我还尝试输入argsv参数并将shell_call的arg列表设置为main的arg_list,但也没有工作。
我认为第二个版本应该可以工作,但我认为我没有正确地设置新堆栈框架的arg列表(我是通过将a[8]写入0来实现的,因为它是函数指针的第一部分,并且编写了a[9]=736c和a[10]=0000,但可能不正确,因为这些都是victim_func的参数。那么如何访问shell_call的参数呢?
发布于 2008-11-13 03:56:37
我可能不该帮你做作业。但基本上:
您需要在内存中的某个地方获得一个字符缓冲区来存储要执行的字符串。显然,您可以以调用其他函数(也就是将文本放在堆栈上)的方式来完成这一任务。写完之后,需要将指向堆栈的指针写入到shell_code函数希望查找其参数的位置。
如果不让我为您做所有的工作,最好的方法就是在一张纸/白板上写下您的堆栈/内存内容。写下如果你通常从程序内部调用shell_code,它会是什么样子的。然后在victum_func中写下堆栈的样子,并找出要更改哪些东西,使其看起来像“自然”的(当然,要记住,有些事情是“不关心”的,比如返回地址)。
这就是你今天要从我这里得到的全部慈善!
发布于 2008-11-15 13:22:42
SoapBox已经把你引向了正确的方向,做得很好。
有关更多信息,请参见http://www.skullsecurity.org/wiki/index.php/Example_4
发布于 2008-11-15 13:06:06
您需要操作调用方的堆栈帧(main()),并将其安排为从溢出victim_func()的epilog返回到victim_func(),后者可以在主调用时找到一个固定的堆栈。
在这样做时,您可能必须损坏受害者的堆栈帧中的帧指针,通过leave在%ebp中还原该帧指针。
https://stackoverflow.com/questions/286090
复制相似问题