0

我正在学习 Linux 下的缓冲区溢出 shellcode 方法。https://seedsecuritylabs.org/Labs_16.04/Software/Buffer_Overflow/

我使用的 shellcode 以 movb $0x0b, %a1 和 int $0x80 结尾。shellcode 执行,我得到我的命令提示符。我读过很多地方 execve 和 int 0x80 “不返回”。好吧.. 好吧,但是当 execve 进程成功并退出时(也就是我在命令行提示符下输入“exit”),~does~ 程序执行流在哪里?

我认为调用程序的堆栈框架已替换为新的 execve 代码信息。新的 execve 代码是否保留了被覆盖进程的返回地址并返回到该地址,就好像它是它自己的一样?(所以它确实有点返回 .. 到借来的地址?)就 int $0x80 而言,在 int 0x80 指令之后的下一个字节处不会继续执行吗?如果不是,下一个字节是什么?

在缓冲区溢出问题和 int 0x80 的上下文中,比如说(例如)一个 517 字节的 hack 会覆盖一个 24 字节的缓冲区。字节将替换缓冲区之外的堆栈内存地址的值,包括指向堆栈中更高的可执行代码的返回地址。但是故意的代码会在内存中更高的 100 个其他堆栈字节上踩踏,破坏不相关的外部范围进程的堆栈帧。使用这些被破坏的堆栈帧,当......

1)当shell从int 0x80返回并执行更多不属于hack的堆栈数据时。现在有什么未指定的字节可能是无效的 CPU 操作码。

2)外部堆栈帧的上下文已被破坏,那么在我的shell命令提示符下输入“exit”后系统如何优雅地继续?

任何帮助表示赞赏!

4

1 回答 1

0

如果我们讨论它是什么execve以及它是如何工作的,我想你会明白发生了什么。

我读过很多地方 execve 和 int 0x80 “不返回”。好吧.. 好吧,但是当 execve 进程成功并退出时(也就是我在命令行提示符下输入“exit”),~does~ 程序执行流在哪里?

以下来自execve的手册页。

execve() executes the program pointed to by filename.  filename must be
       either a binary executable, or a script starting with  a  line  of  the
       form:

           #! interpreter [optional-arg]

execve是执行指定程序的系统调用。

继续,

execve() does not return on success, and the text, data, bss, and stack
       of the calling process are overwritten by that of the program loaded.

本声明涉及您的问题。

每个进程都有自己的内存布局。内存布局由文本段、数据段、堆栈、堆、依赖库等组成,参考/proc/PID/maps任何进程以获得清晰的内存布局图。

execve被执行并成功时,整个内存布局被擦除(调用者进程的内容永远丢失)并且新进程的内容被加载到内存中。新的文本段,新的数据段,新的堆栈,新的堆,一切都是新的。

因此,当您尝试exit使用命令行时,您将终止/bin/sh使用 execve 运行的程序。没有段错误,没有错误。

新的 execve 代码是否保留了被覆盖进程的返回地址并返回到该地址,就好像它是它自己的一样?(所以它确实会返回 .. 到借来的地址?)

不,这不会发生。execve 启动的新进程对旧进程一无所知。

就 int $0x80 而言,在 int 0x80 指令之后的下一个字节是否继续执行?如果不是,下一个字节是什么?

int 0x80存在指令以请求操作系统执行指定的系统调用。因此,int 0x80返回后是否继续执行完全取决于系统调用是什么

一般来说,读、写、打开、创建等,都执行并返回。但是,exec函数的类别(转到man exec)是不同的。这些功能中的每一个都不会成功返回。他们只在失败时返回。

问题的最后一部分,因为内存布局已被擦除并加载了新内容,所以这里没有缓冲区溢出的迹象,也没有内存损坏。

我希望这回答了你的问题。

于 2019-11-12T06:36:53.260 回答