QEMU 引入 NX 到 qemu-user 中(栈不可执行)
qemu-user的nx出现了?
在网鼎杯决赛,我还利用过qemu-user没有nx的特性,在栈上执行shellcode,
然而在最近的湾区杯,有师傅惊讶地发现本地的qemu-user不能在栈上执行shellcode了。
我写了一个简单的示例,用来复现这个问题(使用-z execstack来给栈加可执行权限)。
1 | int main(int argc, char **argv) { |
编译后运行,没开nx会正常退出,开了会 SIGSEGV ,这很正常。接下来使用qemu-x86_64
来运行,和直接运行没有区别,同样会 SIGSEGV 。可是去年我明明用这个特性做出过题啊,
这是怎么回事?
群里师傅发现,远程环境确实没有nx,而且qemu-user是没有ASLR的,因此甚至不用泄露信息。 然而,这些“优良的特性”在新版qemu上荡然无存。接下来的任务就是找到哪个版本引入了变更, 在目标靶机上安装的qemu版本是多少时,需要考虑更加复杂的方案。
拉取源码定位差异
从QEMU的仓库拉取最新的源码仓库,然后编译测试特性,
按大版本标签做二分查找,最后定位到v7.2.0的
b34b42
commit加入了对ELF中exec_stack flag的判断。也就是说,从 qemu-user v7.2.0 开始,就不能直接栈溢出,
跳到栈上运行了。那么对应到Ubuntu版本,我做了下面这张图,简而言之,从 Ubuntu 24.04 开始,
自动开启NX。
其他系统的qemu版本可以在Repology上找到。
ASLR也有影响?
在最近的变更中,加入了“ASLR”,照理来说原来的版本,程序基地址、库基地址都是固定的, 然而,在x86_64上是这样,aarch64上却不是,在手机上使用qemu-user,虽然是老版本, 但是基地址都不同。因此这里就不罗列信息了。
参考
- 标题: QEMU 引入 NX 到 qemu-user 中(栈不可执行)
- 作者: RocketDev
- 创建于 : 2025-10-15 19:00:00
- 更新于 : 2025-10-15 19:00:00
- 链接: https://rocketma.dev/2025/10/15/qemu-user-nx/
- 版权声明: 本文章采用 CC BY-NC-SA 4.0 进行许可。
评论