第2章:沙箱架构剖析
聊沙箱逃逸,你得先懂沙箱怎么造的。
我见过太多人一上来就研究漏洞,结果连沙箱的隔离边界在哪都没搞清楚。说白了,你连墙在哪都不知道,怎么翻墙?
这一章,咱们就把常见沙箱的底裤扒开看看。Docker、Firejail、Sandboxie,这三兄弟代表了三种不同的设计哲学。
2.1 Docker:进程级虚拟化的代表
Docker 不是虚拟机。这是很多人第一个误区。
它共享宿主机的内核,只是通过 Namespace 和 Cgroups 把进程“关”进了一个独立空间。我刚开始接触时也犯过糊涂,以为 Docker 里跑的就是一个独立操作系统。其实不是,它只是看起来像。
隔离原理:Namespace
Namespace 是 Linux 内核提供的一种资源隔离机制。Docker 用了其中 6 种(现在更多了):
- PID Namespace:进程号隔离。容器里看到的 PID 1,在宿主机上可能是 12345。
- Network Namespace:网络栈隔离。每个容器有自己的 lo、eth0,互不干扰。
- Mount Namespace:文件系统隔离。容器里的 / 和宿主机的 / 不是一回事。
- UTS Namespace:主机名隔离。
- IPC Namespace:进程间通信隔离。
- User Namespace:用户 ID 映射。容器里的 root 在宿主机上可能是个普通用户。
嗯,这里要注意:User Namespace 默认没开启。很多逃逸漏洞就是利用了这个缺口。
资源限制:Cgroups
Cgroups 负责“别让容器把宿主机搞死”。它限制 CPU、内存、磁盘 IO、网络带宽等。
举个例子,你可以在启动容器时指定:
docker run --memory="512m" --cpus="1.5" myapp
这行命令的意思是:这个容器最多用 512MB 内存,最多用 1.5 个 CPU 核心。
我在项目中遇到过,有人没配内存限制,结果一个容器里的内存泄漏把整个宿主机拖垮了。Cgroups 不是摆设,一定要用。
关键点:Docker 的隔离强度取决于内核版本和配置。老内核的 Namespace 实现有漏洞,比如 CVE-2016-5195(脏牛)就能突破容器边界。
2.2 Firejail:SUID 沙箱的典型
Firejail 和 Docker 思路完全不同。它不搞 Namespace 那一套(虽然也用了),而是靠 SUID 二进制文件和 Seccomp 来限制程序行为。
说白了,Firejail 是个“看门狗”。它启动一个程序,然后盯着它,不让它干坏事。
工作原理
Firejail 本身是一个 SUID 程序。普通用户执行 firejail firefox 时,Firejail 会以 root 权限运行,创建隔离环境,然后把权限降回普通用户。
它主要做三件事:
- 文件系统隔离:通过 Mount Namespace 和 Bind Mount,把程序限制在特定目录。
- 网络隔离:默认禁止所有网络,除非你明确放行。
- 系统调用过滤:用 Seccomp 黑名单或白名单,禁止危险系统调用。
举个例子,你想让一个可疑程序不能写文件:
firejail --noprofile --read-only=/home/user ./suspicious_binary
这会把 /home/user 挂载为只读。程序想写文件?门都没有。
个人经验:Firejail 的配置文件(/etc/firejail/*.profile)非常值得研究。我曾在一次渗透测试中,发现目标用 Firejail 跑浏览器,但 profile 里忘了禁用 ptrace。结果我通过 ptrace 注入,直接拿到了宿主机 shell。
2.3 Sandboxie:Windows 下的隔离艺术
Sandboxie 是 Windows 平台的沙箱。它的设计思路和 Linux 下的完全不同,因为 Windows 内核没有 Namespace 这种原生支持。
Sandboxie 用的是“钩子(Hook)”技术。它把自己注入到目标进程里,拦截文件操作、注册表操作、进程创建等 API 调用。
隔离机制
当程序试图写文件时,Sandboxie 会拦截这个调用,把文件重定向到一个沙箱目录。程序以为自己写到了 C:\Users\xxx\Documents,实际上写到了 C:\Sandbox\xxx\DefaultBox\user\xxx\Documents。
注册表也一样。程序读注册表时,Sandboxie 会先检查沙箱内有没有这个键,有就返回沙箱内的值,没有才去读真实的注册表。
我举个例子,你双击一个病毒,它想写启动项:
HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Run
Sandboxie 会把它重定向到:
\REGISTRY\USER\S-1-5-21-...\Software\Sandboxie\...\Run
病毒以为自己成功了,其实啥也没干成。
注意:Sandboxie 的钩子技术有个致命弱点——它依赖 API 拦截。如果恶意软件直接调用系统调用(syscall),绕过 Win32 API,Sandboxie 就抓瞎了。我在分析一个样本时就遇到过,它用 ZwCreateFile 直接写文件,Sandboxie 完全没反应。
2.4 三种沙箱的对比
咱们用一张表总结一下:
| 特性 | Docker | Firejail | Sandboxie |
|---|---|---|---|
| 平台 | Linux | Linux | Windows |
| 隔离技术 | Namespace + Cgroups | Mount NS + Seccomp | API 钩子 + 重定向 |
| 性能开销 | 低 | 极低 | 中等 |
| 隔离强度 | 中等(依赖内核) | 中等(依赖配置) | 较低(可被绕过) |
| 典型用途 | 微服务、应用打包 | 浏览器、可疑程序 | 软件测试、病毒分析 |
你想想看,这三种沙箱的逃逸思路完全不同。Docker 要突破 Namespace,Firejail 要绕过 Seccomp,Sandboxie 要躲过钩子。后面几章,咱们会逐个击破。
一句话总结:沙箱的隔离边界,就是逃逸的攻击面。搞懂架构,你就知道该往哪使劲了。
我曾经在评估一个内部系统时,发现他们用 Docker 跑所有服务,但内核版本是 3.10。我查了一下,那个版本有 overlayfs 的逃逸漏洞。嗯,接下来的事就不细说了。
记住:没有绝对安全的沙箱。只有理解它怎么建的,你才知道怎么拆。