为何这段setreuid相关的Shellcode系统调用无任何作用?
问题分析与修复方案
你的shellcode没生效的核心问题是没有正确设置完整的%eax寄存器——在x86 Linux的int $0x80系统调用机制中,系统调用号是存放在整个32位的%eax寄存器里的,而不仅仅是低8位的%al。
问题拆解
你当前的代码只设置了%al的值:
0: b0 c9 mov $0xc9,%al
如果执行这段代码前%eax的高24位不为0,那么实际的系统调用号会是0xXXXXXC9(XX是残留的高24位值),这显然不是geteuid()的正确调用号(0xC9)。这会导致geteuid()没有被正确调用,返回的%eax是错误值,后续传给setreuid()的参数自然无效,最终整个setuid相关逻辑相当于没执行。
修复后的Shellcode
把设置%al的指令改成设置整个%eax的指令,确保系统调用号正确:
0: b8 c9 00 00 00 mov $0xc9,%eax ; 正确设置geteuid的系统调用号(0xC9) 5: cd 80 int $0x80 ; 调用geteuid(),返回值存在%eax中 7: 89 c3 mov %eax,%ebx ; 将euid赋值给setreuid的第一个参数(ruid) 9: 89 c1 mov %eax,%ecx ; 将euid赋值给setreuid的第二个参数(euid) b: b8 cb 00 00 00 mov $0xcb,%eax ; 正确设置setreuid的系统调用号(0xCB) 10: cd 80 int $0x80 ; 调用setreuid(euid, euid)
额外验证点
- 确保你在32位环境下运行这段shellcode——这段代码是x86 32位的系统调用逻辑,在64位环境下需要使用
syscall指令和不同的系统调用号。 - 检查进程的权限上下文:如果你的程序本身已经是root权限,
setreuid()不会有明显效果;如果是非root但有setuid位的程序,修复后的代码应该能正确切换权限。
另外,你可以在shellcode中加入错误检查逻辑(比如判断%eax是否为-1),但对于精简的shellcode来说,通常可以省略这一步,只要确保寄存器初始化正确即可。
内容的提问来源于stack exchange,提问作者Al Smith
相关产品推荐
相关产品推荐

