运行 拥有缓冲区溢出漏洞的代码
Running own code with a buffer overflow exploit
我正在尝试了解缓冲区溢出漏洞,更具体地说,它如何用于 运行 自己的代码 - 例如通过启动我们自己的恶意应用程序或任何类似的东西。
虽然我确实理解使用 gets() 函数进行缓冲区溢出攻击的想法(用足够长的字符串覆盖 return 地址,然后跳转到所述地址),但有几件事我在实际应用中很难理解,它们是:
我是否将自己的代码放入 return 地址后面的字符串中?如果是这样,我怎么知道要跳转到的地址?如果没有,我应该跳到哪里,实际代码在哪里?
运行是我自己的软件代码 运行ning 的实际有效载荷,其他程序只是跳入其中,或者是有效载荷中提供的所有指令?或者更具体地说,缓冲区溢出漏洞利用实现实际上是什么样的?
当地址(或任何指令)包含0时我该怎么办? gets() 函数在读取 0 时停止读取,那么如何解决这个问题?
作为家庭作业,我正在尝试利用一个非常简单的程序,该程序仅使用 gets()(关闭 ASLR)请求输入,然后打印它。虽然我可以找到调用它的函数的内存地址和 return,但我无法弄清楚如何实际实施该漏洞。
您了解更改 return 地址如何让您跳转到任意位置。
但是由于您已经正确识别,您不知道在哪里加载了要执行的代码。您只是将其复制到本地缓冲区(主要是堆栈中的某个位置)。
但是有一个东西总是指向这个栈,它就是栈指针寄存器。 (假设 x64,它将是 %rsp
)。
假设您的自定义代码位于堆栈的顶部。 (它可能处于偏移状态,但也可以类似地进行管理)。
现在我们需要一条指令
1.允许我们跳转到esp
2. 位于固定地址。
所以大多数二进制文件都使用某种共享库。在 windows 你有 kernel32.dll
。在这个库被加载的所有程序中,它总是被映射到同一个地址。所以你知道这个库中每条指令的确切位置。
你所要做的就是反汇编一个这样的库并找到像
这样的指令
jmp *%rsp // or a sequence of instructions that lets you jump to an offset
那么这条指令的地址就是你要放在return地址应该是的地方。
该函数将 return 然后跳转到堆栈(当然你需要一个可执行堆栈)。然后它会执行你的任意代码。
希望这能消除一些关于如何获得漏洞的困惑 运行。
回答您的其他问题-
是的,您可以将代码直接放入缓冲区。或者,如果您可以找到要执行的确切代码(同样在共享库中),您可以直接跳转到那个。
是的,gets
会在 \n
和 0 处停止。但通常您可以通过稍微更改指令以编写根本不使用这些字节的代码来摆脱困境。
您尝试不同的指令并检查组装的字节。
我正在尝试了解缓冲区溢出漏洞,更具体地说,它如何用于 运行 自己的代码 - 例如通过启动我们自己的恶意应用程序或任何类似的东西。
虽然我确实理解使用 gets() 函数进行缓冲区溢出攻击的想法(用足够长的字符串覆盖 return 地址,然后跳转到所述地址),但有几件事我在实际应用中很难理解,它们是:
我是否将自己的代码放入 return 地址后面的字符串中?如果是这样,我怎么知道要跳转到的地址?如果没有,我应该跳到哪里,实际代码在哪里?
运行是我自己的软件代码 运行ning 的实际有效载荷,其他程序只是跳入其中,或者是有效载荷中提供的所有指令?或者更具体地说,缓冲区溢出漏洞利用实现实际上是什么样的?
当地址(或任何指令)包含0时我该怎么办? gets() 函数在读取 0 时停止读取,那么如何解决这个问题?
作为家庭作业,我正在尝试利用一个非常简单的程序,该程序仅使用 gets()(关闭 ASLR)请求输入,然后打印它。虽然我可以找到调用它的函数的内存地址和 return,但我无法弄清楚如何实际实施该漏洞。
您了解更改 return 地址如何让您跳转到任意位置。
但是由于您已经正确识别,您不知道在哪里加载了要执行的代码。您只是将其复制到本地缓冲区(主要是堆栈中的某个位置)。
但是有一个东西总是指向这个栈,它就是栈指针寄存器。 (假设 x64,它将是 %rsp
)。
假设您的自定义代码位于堆栈的顶部。 (它可能处于偏移状态,但也可以类似地进行管理)。
现在我们需要一条指令 1.允许我们跳转到esp 2. 位于固定地址。
所以大多数二进制文件都使用某种共享库。在 windows 你有 kernel32.dll
。在这个库被加载的所有程序中,它总是被映射到同一个地址。所以你知道这个库中每条指令的确切位置。
你所要做的就是反汇编一个这样的库并找到像
这样的指令jmp *%rsp // or a sequence of instructions that lets you jump to an offset
那么这条指令的地址就是你要放在return地址应该是的地方。 该函数将 return 然后跳转到堆栈(当然你需要一个可执行堆栈)。然后它会执行你的任意代码。
希望这能消除一些关于如何获得漏洞的困惑 运行。
回答您的其他问题-
是的,您可以将代码直接放入缓冲区。或者,如果您可以找到要执行的确切代码(同样在共享库中),您可以直接跳转到那个。
是的,gets
会在 \n
和 0 处停止。但通常您可以通过稍微更改指令以编写根本不使用这些字节的代码来摆脱困境。
您尝试不同的指令并检查组装的字节。