我不太明白变量如何存储在文本部分以及如何操作它们。不应该所有变量都在.data部分中,并且.text部分的所有部分都不是只读的吗?那么这段代码是如何工作的呢?
[代码取自 Shellcoder&#39> s手册]
.as-console-wrapper { max-height: 100% !important; top: 0; }
答案 0 :(得分:5)
嗯,数据&代码只是字节。只有你如何解释它们才能使它们成为现实。代码可以解释为数据,反之亦然。在大多数情况下,它会产生无效的东西,但无论如何它都是可能的。
该部分的属性取决于链接器,默认情况下,大多数属性都会生成.text
部分RO,但这并不意味着它无法更改。
整个示例只是使用/bin/sh
获取call
地址的一种聪明方法。基本上call
在堆栈上放置下一条指令的地址(下一个字节),在这种情况下它将是该字符串的地址,因此pop esi
将从堆栈中获取该地址并使用它。
答案 1 :(得分:2)
顶级答案是,x86机器不知道" .text"和" .data"部分。现代x86 CPU为操作系统提供了创建具有特定权限的虚拟地址空间的工具(如只读,无执行和读写)。
但是内存的内容只是字节,可以读取,写入或执行,CPU无法猜测内存的哪一部分是数据,代码是什么,并且很乐意执行你指向的任何内容它来。
这些.text/.data/...
部分是编译器,链接器和OS(可执行加载器)支持的逻辑结构,它们一起合作以这种方式为代码准备运行时环境,.text
被读取 - 只有在现在,您需要将可写变量放入.data
或.bss
或类似的变量。某些操作系统和配置也可能提供不可执行的堆栈。
操作系统通常也有API,因此应用程序可以更改权限或内存映射,或者使用所需的属性分配更多内存(例如,如果JIT编译器无法首先将编译后的代码写入内存,则无处可寻,然后执行它。)
因此,如果您将在默认配置中使用常见Linux上的代码示例,则很可能会出现段错误,因为.text
将是只读的。其中许多"漏洞利用"书籍有完整的专用章节如何编译+为这些例子设置运行时环境,这样的几个保护(ASLR,NX,...)被关闭,从而允许他们的样本工作。
然后,野外的真正利用通常会在应用程序中使用某些错误/弱点来将其有效负载注入某处。取决于某些地方的敌意"真正的漏洞利用可能必须首先提升其权限以获得可写的+可执行内存(或者它必须以不写入代码部分并使用其他内存用于变量的方式编写),除非应用程序本身已经具有一些友好的利用环境由于其内部需求。
请记住,操作系统和应用程序的编写方式并不是为了确保漏洞利用能够完全相反。每个漏洞利用程序通常都针对特定版本的OS上的特定应用程序版本,这些版本很容易受到攻击,并且预计它将在以后破坏安全更新。因此,如果你知道你有可写和可执行的内存,你只需按原样利用它,而不必担心下一版本会发生什么,当他们修复应用程序以保持代码内存为止时。