8

问题实际上是关于 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");

}

好的,所以我设法正确地得到了第一个问题,即任意调用主路径中未显式调用的两个函数之一。顺便说一句,这必须在运行程序时完成,无需任何修改。我通过运行程序来做到这一点,设置N7,这让我到了victim_func帧的函数指针,我a[7]用混淆或的内存地址写入shell_call,它可以工作。(我有一台 64 位机器,这就是为什么我必须将其设置为 7,因为 EBI 指针是 2 个整数宽,而不是 1)

我的问题如下,我如何控制将哪个参数传递给函数shell_code?IE。我怎么写string重点是通过仅运行程序来执行pschar* cunix 命令。

我想用ps的十六进制表示来编写 EBI 指针并将 arg 列表设置shell_call为此,但这不起作用。我也尝试输入argsv参数并将 arg 列表设置shell_callarg_listmain,但也没有工作。

我认为第二个版本应该可以工作,但我相信我没有正确设置新堆栈帧的 arg 列表(我是通过写入a[8]来完成的0,因为它是函数指针的第一部分,并且写入a[9]=736cand a[10]=0000,但它可能不对,因为这些是 的参数victim_func。那么如何访问 的参数shell_call

4

3 回答 3

8

我可能不应该为你做作业。但基本上:

您需要在内存中的某处获取一个字符缓冲区来存储您要执行的字符串。显然,您可以像调用其他函数一样执行此操作(即,您也可以将文本放入堆栈)。写完之后,您需要将指向它的指针写入堆栈中 shell_code 函数期望找到其参数的位置。

在没有我为您完成所有工作的情况下解决这个问题的最佳方法是在一张纸/白板上写下您的堆栈/内存内容。写下如果你从程序内部正常调用 shell_code 的样子。然后写下 victum_func 中的堆栈是什么样子,并弄清楚要更改哪些内容以使其看起来“自然”(当然请记住,有些事情是“无关紧要的”,例如返回地址)。

这就是你今天要从我这里得到的所有慈善!:-P

于 2008-11-13T03:56:37.030 回答
2

SoapBox 已经很好地引导您朝着正确的方向前进。

了解更多信息; http://www.skullsecurity.org/wiki/index.php/Example_4

于 2008-11-15T13:22:42.230 回答
1

您需要操作调用者 ( main()) 的堆栈框架,并以这样的方式安排它,以便shell_call()从溢出的 Epilog返回victim_func()后者可以找到一个已解决的堆栈,因为它被 main 调用。

这样做时,您可能必须破坏受害者堆栈帧中的帧指针,该指针将通过leave.

于 2008-11-15T13:06:06.913 回答