简体   繁体   English

为什么在ret地址溢出后,作为函数参数给出的字符串的地址发生了变化?

[英]Why the address of a string given as argument to a function changed after overflowing the ret address?

I want to exploit a vulnerability of a C piece of code for educational purposes by controlling the stack. 我想通过控制堆栈来利用C代码段的漏洞来达到教育目的。 A simple stack based buffer overflow, overwriting the return address with the address where a shellcode should be executed. 一个简单的基于堆栈的缓冲区溢出,用应在其中执行shellcode的地址覆盖返回地址。 The code is a simple function which takes as arguments a buffer and tries to strcpy() the buffer into a fixed size. 该代码是一个简单的函数,将缓冲区作为参数并尝试将缓冲区的strcpy()设置为固定大小。 The parameter given from main is the argv[1] . main给定的参数是argv[1] So I think that if I found the exact amount of memory that I have to overwrite then I could simply give as input a string composed by \\x90 (NOP instructions) followed by the shellcode and in the end the address of this buffer. 因此,我认为,如果我找到了必须覆盖的确切内存量,那么我可以简单地输入一个由\\x90 (NOP指令)组成的字符串,后跟shellcode,最后是该缓冲区的地址。 Since this is the first argument its address is $ebp+8 and you can find this by running gdb , set a breakpoint in the begining of the function and just type i args gives you the address of the string which is passed as an argument. 由于这是第一个参数,因此它的地址是$ebp+8 ,您可以通过运行gdb来找到它,在函数的开头设置一个断点,只需键入i args为您提供作为参数传递的字符串的地址。 So I found that if I overwrite n bytes and then give the values of the address then this will exactly overwrite the return address. 所以我发现,如果我覆盖n个字节,然后给出地址的值,那么这将完全覆盖返回地址。 So I have an input like this: 所以我有这样的输入:

perl -e print(\x90 x n-sizeof(shellcode) . shellcode . address)'

It didn't work and I tried to understand why. 它没有用,我试图理解原因。 With gdb I run the program. 使用gdb我运行程序。 I put a breakpoint before the strcpy() function. 我在strcpy()函数之前放置了一个断点。 At that point I have an argument which is a string pointer that points to my input and its address is the same with that given at the end of my string input, I stepped forward 1 instruction. 此时,我有一个参数,它是一个指向我的输入的字符串指针,并且其地址与在字符串输入末尾给出的地址相同,因此我上了1条指令。 I examined the stack. 我检查了堆栈。 I have now the saved eip ( $ebp + 4 ) with the value of the address given at the end of argv[1] , which is the expected behavior (That implies that it doesn't overwrite other addresses above the ret address that is the value of the first argument). 现在,我有了保存的eip$ebp + 4 ),它具有argv[1]末尾给出的地址值,这是预期的行为(这意味着它不会覆盖ret地址上方的其他地址,即第一个参数的值)。 The weird thing is that now the content of $ebp+8 is not the "address" but something else? 奇怪的是,现在$ebp+8内容不是“地址”,而是其他内容吗? But the content of the saved eip is the address that points to my string that exploits the vuln. 但是保存的eip的内容是指向我利用漏洞的字符串的地址。 But it doesn't seem that the ret addr executes the content of that address. 但是ret addr似乎没有执行该地址的内容。

How stack frames are organized is part of the ABI. 堆栈框架的组织方式是ABI的一部分。 The description of the ABI used by Linux on x86-64 is here . Linux在x86-64上使用的ABI的描述在此处 You'll find there everything that you need (and then some more probably). 您会在这里找到所需的一切(然后可能更多)。 See section 3.2 for the stack frame organization. 有关堆栈框架组织,请参见第3.2节。

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

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