1. 课程导论:什么是沙箱?为什么需要绕过沙箱?异架构Pwn(ARM/MIPS/RISC-V)与x86的区别

各位同学好。我是这门课的主讲,做了十来年二进制安全,从x86一路折腾到ARM、MIPS,最近几年又开始跟RISC-V较劲。今天咱们先聊聊沙箱——这个在漏洞利用里绕不过去的坎。

说实话,我刚开始做Pwn那会儿,沙箱还没这么普及。那时候拿到一个漏洞,直接弹shell就完事了。现在?你想想看,一个浏览器漏洞,前面套着三层沙箱,后面还有seccomp过滤。不把沙箱研究透,你连漏洞的边都摸不着。

1.1 什么是沙箱?

沙箱,说白了就是一个隔离环境。它把不可信的代码关在笼子里,限制它能做什么、不能做什么。

核心思想:即使攻击者控制了某个进程,也无法影响系统其他部分。

我见过很多新手问:沙箱和虚拟机有什么区别?嗯,这里要注意——虚拟机是模拟一整台机器,沙箱只是限制一个进程的行为。轻量得多,也常见得多。

常见的沙箱实现方式有几种:

类型 原理 典型代表 绕过难度
系统调用过滤 拦截syscall,只允许白名单调用 seccomp-bpf 中
能力限制 删除进程的capability Linux capabilities 低-中
命名空间隔离 隔离文件系统、网络、PID等 Docker容器 中-高
代码执行限制 只允许执行特定区域的代码 CFI、XOM 高
系统服务沙箱 浏览器/PDF阅读器内置 Chrome Sandbox 高

我个人习惯把沙箱分成两类:内核级沙箱和用户态沙箱。内核级沙箱靠操作系统机制,比如seccomp;用户态沙箱靠运行时库,比如Java的SecurityManager。绕过思路完全不同。

1.2 为什么需要绕过沙箱?

你拿到了一个漏洞,控制了程序流程。然后呢?

如果程序没有沙箱,你可以直接:

  • 调用execve弹shell
  • 用open/read/write读写任意文件
  • 用mmap执行shellcode

但如果程序有沙箱,这些操作可能全被禁止。你只能做沙箱允许的事——比如只允许read、write、exit。这时候你就得想办法绕过沙箱。

我的经验:绕过沙箱往往比触发漏洞更难。我在一次CTF比赛中,花了3天研究一个seccomp规则,最后发现可以用ORW(open-read-write)链读flag。那之后我就养成了一个习惯——拿到二进制先看沙箱规则。

绕过沙箱的常见思路:

  1. 利用沙箱漏洞——沙箱本身也有bug
  2. 利用未过滤的系统调用——比如只禁了execve,但没禁open
  3. 利用文件描述符继承——父进程打开的fd,子进程还能用
  4. 利用共享内存——通过共享内存与未沙箱化的进程通信
  5. 利用内核漏洞——直接提权,沙箱就形同虚设

你想想看,沙箱本质上是一套规则。规则就有漏洞,有盲区。我们的工作就是找到这些盲区。

1.3 异架构Pwn与x86的区别

好,接下来聊聊异架构。ARM、MIPS、RISC-V,这些架构和x86到底差在哪?

我最早接触异架构Pwn是在一次IoT设备漏洞挖掘中。一个路由器,MIPS架构,远程命令执行漏洞。我拿着x86的shellcode往上怼,结果程序直接崩了。嗯,从那以后我就老老实实学异架构了。

1.3.1 指令集差异

特性 x86/x64 ARM MIPS RISC-V
指令长度 变长(1-15字节) 固定4字节(ARM)/2字节(Thumb) 固定4字节 固定4字节(基础指令集)
寄存器数量 16(通用)+ 段寄存器 16/31 32 32
寻址模式 复杂,多种组合 简单,Load/Store架构 简单,Load/Store架构 简单,Load/Store架构
条件执行 通过标志位+条件跳转 大部分指令可条件执行 通过条件跳转 通过条件跳转
栈使用 push/pop指令 手动管理sp 手动管理sp 手动管理sp

这里有个关键点:ARM和MIPS都是Load/Store架构。什么意思?就是内存操作必须通过专门的load/store指令,其他指令只能在寄存器上操作。x86就不一样,很多指令可以直接操作内存。

这对漏洞利用有什么影响?

  • ROP gadget的寻找方式不同——x86有大量内存操作指令,异架构相对少
  • shellcode的编写方式不同——异架构通常需要手动管理指令流水线
  • 栈布局不同——ARM有LR寄存器,MIPS有$ra寄存器,返回地址不总在栈上

1.3.2 调用约定差异

调用约定决定了参数怎么传、返回值怎么拿、寄存器谁保存。我整理了一个对比表:

架构 参数传递 返回值 调用者保存 被调用者保存
x86 栈 EAX EAX, ECX, EDX EBX, ESI, EDI, EBP
x64 RDI, RSI, RDX, RCX, R8, R9 → 栈 RAX RAX, RCX, RDX, RSI, RDI, R8-R11 RBX, RBP, R12-R15
ARM R0-R3 → 栈 R0 R0-R3, R12 R4-R11, LR
MIPS $a0-$a3 → 栈 $v0 $t0-$t9 $s0-$s7, $gp, $sp, $fp, $ra
RISC-V a0-a7 → 栈 a0 ra, t0-t6 s0-s11, sp, gp, tp

你看,x86用栈传参,ARM和MIPS先用寄存器。这意味着什么?

  • 构造ROP链时,x86需要大量pop指令来清理栈
  • ARM和MIPS只需要mov指令设置寄存器
  • 异架构的ROP链通常更短,但gadget更难找

避坑指南:我曾经在ARM上做ROP,以为LR寄存器保存的返回地址可以直接用。结果发现ARM的BL指令会把返回地址写到LR,但函数开头通常会push {lr}。如果你没注意到这个push,ROP链就会断掉。嗯,血的教训。

1.3.3 内存布局差异

不同架构的内存布局差异很大,直接影响漏洞利用:

  • x86/x64:代码段、数据段、栈、堆,地址随机化(ASLR)
  • ARM:类似x86,但有些嵌入式设备不开ASLR
  • MIPS:kseg0/kseg1映射,缓存一致性是个大坑
  • RISC-V:分S-mode和U-mode,页表结构不同

我记得有一次调试MIPS设备,shellcode写进去了,但死活执行不了。查了两天,发现是缓存一致性问题——指令缓存里还是旧数据。从那以后,我在MIPS上写shellcode都会加cache flush。

1.4 本章知识体系

下面这张图总结了本章的核心知识结构:

沙箱绕过与异架构Pwn知识体系 沙箱绕过与异架构Pwn — 知识体系 沙箱机制 seccomp-bpf 命名空间 能力限制 沙箱绕过 ORW链 fd继承 内核漏洞提权 异架构Pwn ARM MIPS RISC-V 核心思路:理解沙箱规则 → 找到规则盲区 → 利用异架构特性构造利用链 不同架构的指令集、调用约定、内存布局差异直接影响绕过策略

1.5 课程路线图

这门课一共30章,我按这个逻辑组织:

  1. 基础篇(1-5章):沙箱原理、seccomp深入、常见绕过手法
  2. ARM篇(6-12章):ARM指令集、ROP、shellcode、沙箱绕过实战
  3. MIPS篇(13-19章):MIPS特性、缓存问题、利用技巧
  4. RISC-V篇(20-25章):新兴架构、工具链、漏洞利用
  5. 综合实战(26-30章):多架构沙箱绕过、真实设备漏洞、CTF真题

学习建议:别急着跳到自己感兴趣的章节。沙箱基础不牢,后面异架构绕过你会很痛苦。我见过太多人一上来就搞ARM ROP,结果连seccomp规则都看不懂。嗯,稳扎稳打才是正道。

好,第一章就到这里。记住三个核心问题:沙箱是什么、为什么要绕过、异架构和x86差在哪。后面我们会一步步深入。