Files
Sec-Interview/Chapter15/15-3.md
T
2025-09-25 03:56:33 +08:00

36 lines
2.7 KiB
Markdown

### 脏牛漏洞提权原理
**1. 什么是写时复制(CoW)?**
在 Linux 系统中,当一个进程需要复制一个文件或共享内存区域时,内核并不会立刻为新进程分配独立的内存空间并复制数据。相反,它会让两个进程共享同一块物理内存
只有当其中一个进程**尝试修改**这块内存中的数据时,内核才会触发“写时复制”机制:
- 内核会为这个正在尝试写入的进程**创建一个新的物理内存副本**
- 这样,原始进程的数据保持不变,而新进程可以在自己的私有内存副本上进行修改,而互不影响
这个机制极大地节省了内存和时间,提高了系统的效率
**2. 漏洞是如何产生的?**
“脏牛”漏洞的本质就在于**写时复制(CoW)机制的一个缺陷**
当一个非特权用户尝试访问一个只读文件(例如 `/etc/passwd`)时,内核会映射这个文件的内存页。按照 CoW 机制,用户无法修改它
然而,内核在处理以下两个操作时,存在一个**竞争条件**:
- **操作一:** 一个线程使用 `madvise(MADV_DONTNEED)` 系统调用来**丢弃**一个内存页。这个调用告诉内核:我不需要这个页了,你可以把它从内存中释放掉
- **操作二:** 另一个线程尝试**执行写入操作**,触发 CoW 机制,申请一个新的私有内存页
正常的流程应该是:如果一个线程在尝试写入,内核会先为其分配新的内存,然后再进行写入。但是,这个漏洞的巧妙之处在于,通过精巧地控制这两个操作的执行时机,可以制造出一个“时间窗口”
攻击者利用这个时间窗口,在内核准备为写入操作分配新内存之前,通过 `madvise()` 使得内核错误地**取消了 CoW 的正常流程**。结果是,内核没有为写入操作创建一个私有的内存副本,而是**直接在原始的只读内存页上进行了写入**
**3. 如何利用这个漏洞?**
攻击者利用这个漏洞的流程通常如下:
1. **选择目标文件:** 攻击者选择一个具有 root 权限的只读文件,例如 `/etc/passwd`,该文件包含了系统用户的账户信息
2. **多线程并发:** 攻击者启动两个线程,一个线程不断地尝试对 `/etc/passwd` 进行写入操作(例如,写入一个新的 root 用户账户),另一个线程则持续调用 `madvise()` 来触发竞争条件
3. **成功写入:** 在竞争条件被触发的瞬间,写入操作会绕过 CoW 机制,直接修改 `/etc/passwd` 的内存内容
4. **获取权限:** 攻击者随后会利用修改后的文件,通过新的 root 用户账户成功登录系统,从而获得 root 权限