[英]Trouble replicating a stack buffer overflow exploit
I am having trouble replicating the stack buffer overflow example given by OWASP here . 我在这里复制OWASP给出的堆栈缓冲区溢出示例时遇到问题。
Here is my attempt: 这是我的尝试:
$ cat test.c
#include <stdio.h>
#include <string.h>
void doit(void)
{
char buf[8];
gets(buf);
printf("%s\n", buf);
}
int main(void)
{
printf("So... The End...\n");
doit();
printf("or... maybe not?\n");
return 0;
}
$ gcc test.c -o test -fno-stack-protection -ggdb
$ objdump -d test # omitted irrelevant parts i think
000000000040054c <doit>:
40054c: 55 push %rbp
40054d: 48 89 e5 mov %rsp,%rbp
400550: 48 83 ec 10 sub $0x10,%rsp
400554: 48 8d 45 f0 lea -0x10(%rbp),%rax
400558: 48 89 c7 mov %rax,%rdi
40055b: e8 d0 fe ff ff callq 400430 <gets@plt>
400560: 48 8d 45 f0 lea -0x10(%rbp),%rax
400564: 48 89 c7 mov %rax,%rdi
400567: e8 a4 fe ff ff callq 400410 <puts@plt>
40056c: c9 leaveq
40056d: c3 retq
000000000040056e <main>:
40056e: 55 push %rbp
40056f: 48 89 e5 mov %rsp,%rbp
400572: bf 4c 06 40 00 mov $0x40064c,%edi
400577: e8 94 fe ff ff callq 400410 <puts@plt>
40057c: e8 cb ff ff ff callq 40054c <doit>
400581: bf 5d 06 40 00 mov $0x40065d,%edi
400586: e8 85 fe ff ff callq 400410 <puts@plt>
40058b: b8 00 00 00 00 mov $0x0,%eax
400590: 5d pop %rbp
400591: c3 retq # this is where i took my overflow value from
400592: 90 nop
400593: 90 nop
400594: 90 nop
400595: 90 nop
400596: 90 nop
400597: 90 nop
400598: 90 nop
400599: 90 nop
40059a: 90 nop
40059b: 90 nop
40059c: 90 nop
40059d: 90 nop
40059e: 90 nop
40059f: 90 nop
$ perl -e 'print "A"x12 ."\x91\x05\x40"' | ./test
So... The End...
AAAAAAAAAAAA▒@
or... maybe not? # this shouldn't be outputted
Why isn't this working? 为什么这不起作用? I'm assuming that the memory address that I am supposed to insert is the
retq
from <main>
. 我假设应该插入的内存地址是
<main>
的retq
。
My goal is to figure out how to do a stack buffer overflow that calls a function elsewhere in the program. 我的目标是弄清楚如何执行程序在其他地方调用函数的堆栈缓冲区溢出。 Any help is much appreciated.
任何帮助深表感谢。 :)
:)
I'm using Windows & MSVC but you should get the idea. 我正在使用Windows和MSVC,但您应该明白这一点。
Consider the following code: 考虑以下代码:
#include <stdio.h>
void someFunc()
{
puts("wow, we should never get here :|");
}
// MSVC inlines this otherwise
void __declspec(noinline) doit(void)
{
char buf[8];
gets(buf);
printf("%s\n", buf);
}
int main(void)
{
printf("So... The End...\n");
doit();
printf("or... maybe not?\n");
return 0;
}
(Note: I had to compile it with /OPT:NOREF
to force MSVC not to remove "unused" code and /GS-
to turn off stack checks) (注意:我必须使用
/OPT:NOREF
进行编译,以强制MSVC不要删除“未使用的”代码,并强制使用/GS-
关闭堆栈检查)
Now, let's open it in my favorite disassembler: 现在,让我们在我最喜欢的反汇编程序中打开它:
We'd like to exploit the gets
vulnerability so the execution jumps to someFunc
. 我们想利用
gets
漏洞,使执行跳至someFunc
。 We can see that its address is 001D1000
, so if we can write enough bytes past the buffer to overwrite the return address, we'll be good. 我们可以看到它的地址是
001D1000
,因此,如果我们可以在缓冲区后写入足够的字节以覆盖返回地址,那将会很好。 Let's take a look at the stack when gets
is called: 让我们看一下调用
gets
时的堆栈:
As we can see, there's 8 bytes of our stack allocated buffer ( buf
), 4 bytes of some stuff (actually the PUSH
ed EBP), and the return address. 如我们所见,堆栈分配缓冲区(
buf
)有8个字节,一些东西(实际上是PUSH
ed EBP)有4个字节,还有返回地址。 Thus, we need to write 12 bytes of whatever and then our 4 byte return address ( 001D1000
) to "hijack" the execution flow. 因此,我们需要写入12个字节的内容,然后写入4个字节的返回地址(
001D1000
)以“劫持”执行流程。 Let's do just that - we'll prepare an input file with the bytes we need using a hex editor: 让我们开始吧-我们将使用十六进制编辑器准备一个包含所需字节的输入文件:
And indeed, when we run the program with that input, we get this: 确实,当我们使用该输入运行程序时,我们得到了:
After it prints that line, it will crash with an access violation since there was some garbage on the stack. 打印该行后,由于堆栈上有一些垃圾,它将因访问冲突而崩溃。 However, there's nothing stopping you from carefully analyzing the code and preparing such bytes in your input that the program will appear to function as normal (we could overwrite the next bytes with the address of
ExitProcess
, so that someFunc
would jump there). 但是,没有什么可以阻止您仔细分析代码并准备输入内容中的字节,以使程序看起来可以正常运行(我们可以使用
ExitProcess
的地址覆盖下一个字节,以便someFunc
跳到那里)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.