PWN的知识之如何通过栈溢出来利用后门函数进阶版
在之前的文章中PWN 的知识之如何利用栈溢出利用后门函数介绍了一下在文件中存在完整的后门函数来获取shell
,即存在system("/bin/sh")
完整的函数,但是大部分情况下都不会完整的存在这个函数,可能会存在有system
和/bin/sh
分开的情况比如:
这个时候就需要进一步的调试,具体方法:
1. 确定system 和 /bin/sh 的地址
system
地址:通过调试工具(如gdb
)或反汇编找到system
函数的地址。/bin/sh
地址:在内存中找到/bin/sh
字符串的地址,可通过gdb
的search
命令或程序中的字符串查找。
2. 构造栈溢出
- 溢出点:找到程序的溢出点,通常是缓冲区溢出漏洞。
- 覆盖返回地址:通过溢出覆盖返回地址,使其指向
system
函数。
3. 设置 system 的参数
- 参数传递:在栈上布置
system
的参数,使其指向/bin/sh
字符串的地址。 - 栈布局:确保栈布局正确,返回地址后紧跟参数。
4. 执行 system("/bin/sh")
- 触发漏洞:执行程序,触发栈溢出,跳转到
system
函数并执行/bin/sh
,从而获取 shell。
其中需要注意:
- 栈对齐:确保栈对齐符合系统要求。
- 保护机制:绕过 ASLR、DEP 等保护机制可能需要额外步骤。
- 调试:使用
gdb
调试,确保每一步正确执行。
事例:
题目来源ctfshow平台
下载附件,先check
一下
可以看到是32位程序,关闭了栈保护与PIE
IDA查看漏洞函数:
同样的,漏洞点还是在这,但是我们需要的东西发生了改变,跟进hint函数:
发现有“/bin/sh”字符串,有system函数打,但是直接把程序的流程劫持到这并不能得到我们想要
的,我们需要进一步进行构造来进行获取shell
payload = 'a'*(0x12+4) + p32(system) + p32(0) + p32(bin_sh)
我们构造的payload在先进行溢出后,填上system函数的地址,这里我们需要注意函数调用栈的结构,如果是正常调用 system 函数,我们调用的时候会有一个对应的返回地址,使用 p32 函 数将整数值0转换为4字节的字符串。这个字符串将作为 system 函数的第二个参数,用于提供一个指向 空值的指针作为 system 函数的第二个参数。当然在这里使用其他任意4个字符进行覆盖也可以 如‘aaaa’,’bbbb’等均可。 p32(bin_sh) : 这部分使用 p32 函数将 bin_sh 的地址转换为一个4字节的字符串。 bin_sh 通常是指向包含要执行的命令的字符串(如 /bin/sh )的指针。该字符串将作为 system函数的第一个参数。