简体   繁体   English

使用缓冲区溢出漏洞运行自己的代码

[英]Running own code with a buffer overflow exploit

I am trying to understand the buffer overflow exploit and more specifically, how it can be used to run own code - eg by starting our own malicious application or anything similar. 我正在尝试了解缓冲区溢出漏洞利用,更具体地说,是如何将其用于运行自己的代码-例如,通过启动我们自己的恶意应用程序或任何类似程序。

While I do understand the idea of the buffer overflow exploit using the gets() function (overwriting the return address with a long enough string and then jumping to the said address), there are a few things I am struggling to understand in real application, those being: 尽管我确实使用gets()函数理解了缓冲区溢出利用的思想(用足够长的字符串覆盖返回地址,然后跳转到所述地址),但在实际应用中,我仍在努力理解一些事情,那些是:

  • Do I put my own code into the string just behind the return address? 我是否将自己的代码放在返回地址后面的字符串中? If so, how do I know the address to jump to? 如果是这样,我怎么知道要跳转的地址? And if not, where do I jump and where is the actual code located? 如果没有,我应该跳到哪里,实际的代码在哪里?

  • Is the actual payload that runs the code my own software that's running and the other program just jumps into it or are all the instructions provided in the payload? 运行代码的实际有效载荷是我自己正在运行的软件,而另一个程序只是进入了该有效载荷,还是有效载荷中提供了所有指令? Or more specifically, what does the buffer overflow exploit implementation actually look like? 更具体地说,缓冲区溢出漏洞利用实现实际上是什么样的?

  • What can I do when the address (or any instruction) contains 0? 地址(或任何指令)包含0怎么办? gets() function stops reading when it reads 0 so how is it possible to get around this problem? gets()函数在读取为0时停止读取,那么如何解决这个问题呢?

As a homework, I am trying to exploit a very simple program that just asks for an input with gets() (ASLR turned off) and then prints it. 作为一项家庭作业,我试图利用一个非常简单的程序,该程序只要求使用gets()(关闭ASLR)来输入,然后打印它。 While I can find the memory address of the function which calls it and the return, I just can't figure out how to actually implement the exploit. 虽然我可以找到调用该函数和返回的函数的内存地址,但我仍然无法弄清楚如何真正实现该漏洞利用。

You understand how changing the return address lets you jump to an arbitrary location. 您了解更改寄信人地址如何使您跳到任意位置。

But as you have correctly identified you don't know where you have loaded the code you want to execute. 但是,当您正确识别了代码后,您将不知道要在哪里加载要执行的代码。 You just copied it into a local buffer(which was mostly some where on the stack). 您只需将其复制到本地缓冲区(通常在堆栈中的某些位置)。

But there is something that always points to this stack and it is the stack pointer register. 但是有些东西总是指向这个堆栈,它是堆栈指针寄存器。 (Lets assume x64 and it would be %rsp ). (假设x64将会是%rsp )。

Assuming your custom code is on the top of the stack. 假设您的自定义代码在堆栈的顶部。 (It could be at an offset but that too can be managed similarly). (它可以偏移,但是也可以类似地管理)。

Now we need an instruction that 1. Allows us to jump to the esp 2. Is located at a fixed address. 现在,我们需要一条指令:1.允许我们跳转到esp 2.位于固定地址。

So most binaries use some kind of shared libraries. 因此,大多数二进制文件都使用某种共享库。 On windows you have kernel32.dll . 在Windows上,您具有kernel32.dll In all the programs this library is loaded, it is always mapped at the same address. 在加载该库的所有程序中,它始终映射在同一地址。 So you know the exact location of every instruction in this library. 因此,您知道该库中每条指令的确切位置。

All you have to do is disassemble one such library and find an instruction like 您要做的就是反汇编一个这样的库,然后找到一条指令,例如

jmp *%rsp // or a sequence of instructions that lets you jump to an offset

Then the address of this instruction is what you will place where the return address is supposed to be. 然后,该指令的地址就是您应该将返回地址放在的地址。 The function will return then and then jump to the stack (ofcourse you need an executable stack for this). 函数将返回,然后跳转到堆栈(当然,您需要一个可执行的堆栈)。 Then it will execute your arbitrary code. 然后它将执行您的任意代码。

Hope that clears some confusion on how to get the exploit running. 希望这可以消除有关如何运行漏洞利用程序的困惑。

To answer your other questions - 要回答您的其他问题-

Yes you can place your code in the buffer directly. 是的,您可以将代码直接放在缓冲区中。 Or if you can find the exact code you want to execute (again in a shared library), you can simply jump to that. 或者,如果您可以找到想要执行的确切代码(同样在共享库中),则可以直接跳转到该代码。

Yes, gets would stop at \\n and 0. But usually you can get away by changing your instructions a bit to write code that doesn't use these bytes at all. 是的, gets会停在\\n和0。但是通常您可以通过稍微改变一下指令以编写完全不使用这些字节的代码来逃脱现实。

You try different instructions and check the assembled bytes. 您尝试使用不同的指令并检查汇编的字节。

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

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