当前位置:首页>Linux>突破传统防御边界:Linux eBPF新型Rootkit攻防研究

突破传统防御边界:Linux eBPF新型Rootkit攻防研究

  • 2026-08-18 23:11:45
突破传统防御边界:Linux eBPF新型Rootkit攻防研究

近期,火绒安全实验室捕获一款基于Linux eBPF的Rootkit组件,该组件并非传统内核模块:样本本体为不可直接执行的ELF64可重定位对象,需由外部loader经libbpf标准加载流程注入内核,经verifier校验后,内核依据BTF信息创建10个BPF map,13个tracepoint程序附着到系统调用与调度事件。该过程不触碰内核文本段,不修改系统调用表,无LKM加载痕迹,基于模块签名与内核完整性校验的防线对此类组件天然失效。

该组件隐蔽能力来自“策略与逻辑分离”架构,隐藏目标未硬编码,存放在hidden_pids、hidden_names、hidden_inodes三个map内,攻击者可随时改写生效,无需重新编译加载。代码覆盖三个观测维度:枚举/proc时抹除指定进程;调试器attach隐藏进程时实施反制;读取/proc/net/tcp或查询netlink时抹除指定连接,覆盖管理员常用的三条自查路径。

由于该组件具备极强的内核隐身能力,传统杀毒、主机巡检工具很难发现被隐匿的进程、网络连接与文件,攻击者可长期驻留主机,持续窃取服务器业务数据、账号凭证、核心配置;依托可动态修改的隐藏策略,攻击者还能灵活规避运维排查,搭建持久后门、横向渗透内网,甚至篡改业务数据、植入勒索程序,大幅抬高安全事件的发现与溯源成本,给企业带来数据泄露、业务中断、合规追责等多重损失。

目前,火绒安全产品可对该行为进行拦截与查杀。

查杀图
01
样本身份与攻击链总览
威胁画像

eBPF本意为内核提供安全可编程接口,承载观测、网络与安全策略,该样本体现出攻击者可利用该机制篡改内核允许eBPF访问的数据、篡改用户态工具信任的数据源。

与LKM Rootkit相比,它的威胁在于攻击面不同:LKM需加载模块、改写内核结构,处于传统检测范围内;eBPF程序经BPF合法进入内核,挂载于观测用挂载点,行为与正常可观测性Agent高度相似,且隐藏目标由map动态维护,文件签名仅能标识样本,无法约束其运行行为。这造成检测困境:管理员常用自查手段均被其过滤,检测此类威胁需直接观测BPF子系统本身,核查加载的程序、创建的map、附着的事件。

样本基础信息

样本本体是一个ELF64小端可重定位文件,机器码EM_BPF。它并非可执行程序,而是一组待注入的内核字节码,须由外部loader通过BPF系统调用注入内核后方可激活。其稳定身份标识如表1-1所示。

字段

含义

文件名

raw.bin

分析用样本

文件大小

52,776 字节

ELF 文件总长度

SHA-256

3607de2597f8955f9a88f36ee43b64d3891b8ef536e99fa098e80169350f7b01

唯一身份锚点

SHA-1

50bc563e76995158fad99139ea78aa81be55f93f

辅助校验

MD5

36fed3e2cc68e7c6c9763cb9b1aa715e

辅助校验

ELF 类型

ET_REL (1)

可重定位对象

目标架构

EM_BPF (247)

eBPF 字节码

段数量

53

ELF section 头表计数

程序头数量

0

无可执行段

入口地址

0

无用户态入口

表1-1:样本身份标识与ELF头关键字段

ELF头的几个关键字段印证了上述判断:e_machine=247,即Linux为 eBPF分配的机器码;e_type=1,可重定位对象;e_entry=0且程序头为空——没有用户态入口,execve() 与 dlopen() 都对它无能为力。这一组合对防守方有直接含义:只扫描PE/ELF可执行文件的哈希黑名单,会漏过此类 .o文件。

此外,ELF .comment节区中保留了编译源路径 /cloud/scales/agent/../ebpf/scales.bpf.c,可作为样本来源与家族归属的辅助线索。

攻击链总览

将加载过程与运行行为关联分析,样本呈现出一条清晰的三段式攻击链。第一阶段,外部loader将对象注入内核并初始化10个BPF map;第二、三阶段,13个tracepoint handler分为两路执行,一路负责进程与调试器相关事件,一路负责网络连接的两个观测面。整条链路不包含独立的C2通道,也不含持久化逻辑——其本质是一款的后门隐蔽工具,目标集合完全依赖外部loader填充。

图1-1:三段式攻击链总览

Stage

触发事件

关键对象

对客户主机的可见影响

加载与初始化

loader 调用 bpf_object__open + bpf_object__load

10 个 BTF map、13 个 tracepoint program

对象被内核 verifier 接受,tracepoint 附着就绪

进程隐藏与反调试

getdents64 / ptrace / sched_process_exec

hidden_pids、hidden_names

ls /proc、ps 跳过目标 PID;调试器 attach 时被 SIGKILL

网络连接隐藏

openat / read / close / socket / recvmsg

hidden_inodes、net_fds、diag_fds

/proc/net/tcp 与 ss -tup/netstat 不显示目标 socket

表1-2:攻击链三阶段与对应可见影响

Stage-1是后两段的前提:hidden_pids、hidden_names、hidden_inodes被填充后,进程隐藏、反调试与网络隐藏才会生效。反之,只要这三个map为空,所有handler查表均未命中、直接返回0——样本进入内核后可以不产生任何可见异常,静默等待攻击者随时激活。Stage-2与 Stage-3并行监听不同系统调用,互不依赖,任一handler命中条件即独立改写用户态可见数据。

02
加载方式与BPF结构

该样本无法自主运行,必须依靠外部加载器注入内核。这一特性直接引出两个亟需解答的问题——它通过何种路径载入内核?以及载入后以怎样的形态驻留于内核之中?前者决定了加载过程中会留下哪些痕迹,后者则决定了在运行阶段可被观测到的对象。

加载方式与Loader ABI

加载方式本身即构成首条检测线索。节头解析结果表明,.maps段大小为 320字节且内容全为零,仅作为10个32字节的占位槽使用,所有map的实际定义均内嵌于BTF的.datasec记录中。该结构直接否定了通过legacy路径仅调用bpf_prog_load()的可能性:由于缺少bpf_map_def,旧接口必定拒绝加载。攻击者必须采用现代libbpf提供的bpf_object__open配合bpf_object__load流程,由内核在解析BTF后自动创建map。license段内容为b'GPL\x00',符合verifier对GPL-only helper函数的许可要求。

该对象的结构特征显示其兼容现代libbpf的标准加载流程:BTF-only的 .maps段、GPL许可证,以及由10 个BTF .datasec条目定义的map,均满足verifier的准入条件。加载完成后,内核将自动实例化10个 BPF_MAP_TYPE_HASH类型的map,13个tracepoint程序亦可按预期依次完成attach。

加载步骤

必需 API / 动作

失败条件

打开对象

bpf_object__open_file(path, NULL)

legacy bpf_prog_load 无法解析 BTF-only map

加载对象

bpf_object__load(obj)

.maps 非全零或 license 缺失

创建 map

内核依据 BTF .datasec 创建 10 个 map

BTF 解析失败

attach 程序

13 个 tracepoint 程序逐一 attach

verifier 拒绝任一程序

填充目标集合

loader 向 hidden_names/hidden_pids/hidden_inodes 写入初始值

map 为空时后续 handler 直接返回 0

表2-1:对象加载与初始化所需的最小loader ABI

五步流程的最后一步,决定恶意行为是否能够生效。当三个策略map未完成填充时,sys_exit_getdents64、sys_enter_ptrace、sys_exit_read等handler的查询结果为空,将直接返回0,进程隐藏与网络隐藏功能均不会触发。该特征对安全响应处置同样具备关键意义:仅删除磁盘上的.o文件而不清理已加载的内核对象,隐藏行为不会终止。

目标对象内部共包含718条Elf64_Rel重定位记录,分布于21个重定位节区,各类型分布如下:R_BPF_64_NODYLD32共445条、R_BPF_64_32共169条、R_BPF_64_ABS64共73条、R_BPF_64_64共31条。其中sym=0的UND引用为0条,表明helper调用并非通过重定位解析实现,而是直接编码于BPF_CALL指令的32位立即数中。

BTF定义的Map结构

进入系统内核后,其所有关键信息均存储于map中。10个map依据职责可划分为两类:3个策略map用于定义“隐藏对象”,由loader预先填充;7个状态map则用于记录“隐藏方式”,由BPF程序在系统调用间隙自行维护。具体分类结果如表2-2所示。

类别

Map 名称

作用

所属 Stage

策略 map

hidden_names

按进程 comm 匹配,决定哪些新进程自动隐藏

Stage-2

策略 map

hidden_pids

目标 PID 集合,getdents64 与 ptrace 均读取

Stage-2

策略 map

hidden_inodes

目标 socket inode 集合,/proc/net/tcp 与 ss/netstat 均读取

Stage-3

状态 map

scratch

getdents64 调用期间缓存 (tgid, bufptr),返回时清除

Stage-2

状态 map

net_open_temp

临时记录打开 /proc/net/tcp 的 (tgid, fd)

Stage-3

状态 map

net_fds

持续跟踪需要过滤的 /proc/net/tcp fd

Stage-3

状态 map

net_read_temp

sys_exit_read 处理时的临时状态

Stage-3

状态 map

sock_open_temp

临时记录创建 NETLINK_SOCK_DIAG 套接字的 (tgid, fd)

Stage-3

状态 map

diag_fds

持续跟踪 NETLINK_SOCK_DIAG 套接字 fd

Stage-3

状态 map

recvmsg_temp

sys_exit_recvmsg 处理时的临时状态

Stage-3

表2-2:10个BTF定义map按职责分类

该ELF对象包含49条map重定位记录,每条以32字节槽位格式引用.maps段。BTF信息中共定义了10个map,与内核加载后实际创建的10个BPF_MAP_TYPE_HASH一一对应,且key/value的尺寸与BTF重建结果相符。BTF中还携带了18条func_info和416条line_info记录,用于在加载后将 BPF字节码回溯到源文件的函数与行号。core_reloc记录数为0,说明该对象未启用BPF CO-RE机制,因此对运行内核的版本存在依赖。BTF解析得到的key/value尺寸与内核实际创建的map一致——hidden_pids的key为4 字节、value为1字节;hidden_names的value为1字节。

程序附加点与子程序内联

map构成样本的全部状态,tracepoint程序则构成样本的全部动作。13个 tracepoint程序分属五类功能;另有5个子程序置于.text段,不单独附着,加载时由libbpf内联进调用它们的父程序。全部附着点按功能分组列于表2-3。

功能分组

Tracepoint附着点

Handler名

触发与行为

进程枚举隐藏

tp/syscalls/sys_enter_getdents64

enter_getdents

读取目录前缓存 (tgid, bufptr) 到 scratch

进程枚举隐藏

tp/syscalls/sys_exit_getdents64

exit_getdents

返回时遍历目录项,按 hidden_pids 查询并抹除命中 PID;同时清除 scratch 中缓存的 getdents64 上下文

反调试

tp/syscalls/sys_enter_ptrace

enter_ptrace

调试器 attach 隐藏进程时,对调试器发送 SIGKILL

启动路径隐藏

tp/sched/sched_process_exec

on_exec

进程执行新程序时,comm 匹配 hidden_names 则将 PID 加入 hidden_pids

/proc/net/tcp 过滤

tp/syscalls/sys_enter_openat

net_enter_openat

匹配 /proc/net/tcp 路径并记录 (tgid, fd)

/proc/net/tcp 过滤

tp/syscalls/sys_exit_openat

net_exit_openat

openat 成功返回 fd 后,将 fd 晋升到 net_fds

/proc/net/tcp 过滤

tp/syscalls/sys_enter_read

net_enter_read

读取前缓存 (tgid, bufptr) 到 net_read_temp

/proc/net/tcp 过滤

tp/syscalls/sys_exit_read

net_exit_read

返回时调用 scan_net_byte/zero_net_tail 折叠命中 inode 行

/proc/net/tcp 过滤

tp/syscalls/sys_enter_close

net_enter_close

关闭被跟踪 fd 时,从 net_fds/diag_fds 删除条目

netlink 过滤

tp/syscalls/sys_enter_socket

enter_socket

创建 NETLINK_SOCK_DIAG 套接字时记录 (tgid, fd)

netlink 过滤

tp/syscalls/sys_exit_socket

exit_socket

socket 成功返回 fd 后,将 fd 晋升到 diag_fds

netlink 过滤

tp/syscalls/sys_enter_recvmsg

enter_recvmsg

接收前缓存 (tgid, msghdr) 到 recvmsg_temp

netlink 过滤

tp/syscalls/sys_exit_recvmsg

exit_recvmsg

返回时调用 walk_nlmsg 改写命中 inode 的 NLMSG

表2-3:13个tracepoint程序按功能分组

指令规模可以精确到段。BPF指令定长8字节,14个可执行代码段合计 6488字节,对应811个8字节指令槽,其中774条为有效BPF指令,各段分布如表2-4所示。全对象共有70条call指令,其中69条为helper调用,1条为BPF-to-BPF伪调用——后者正对应5个子程序的内联关系:walk_dirent 与name_to_pid并入exit_getdents,scan_net_byte与zero_net_tail并入 net_exit_read,walk_nlmsg并入exit_recvmsg。体量不大,功能却完整闭环;对象结构满足verifier准入条件,13个程序均可被内核接受。

需要特别指出的是,70条call指令中69条为经典BPF helper调用,余下1条为kfunc伪调用:位于.text段偏移0x100处,opcode为0x85、src_reg=1、imm=0x135(即 309),对应kfunc bpf_ktime_get_boot_ns。该调用不是通过helper ID解析,而是通过BTF kfunc机制在内核加载时动态绑定,对运行内核版本有明确要求。具体指令如下表所示:

代码段

字节数

指令数

.text

3232

404

tp/syscalls/sys_enter_getdents64

120

15

tp/syscalls/sys_exit_getdents64

264

33

tp/sched/sched_process_exec

200

25

tp/syscalls/sys_enter_ptrace

120

15

tp/syscalls/sys_enter_openat

368

46

tp/syscalls/sys_exit_openat

288

36

tp/syscalls/sys_enter_read

232

29

tp/syscalls/sys_exit_read

408

51

tp/syscalls/sys_enter_close

176

22

tp/syscalls/sys_enter_socket

160

20

tp/syscalls/sys_exit_socket

288

36

tp/syscalls/sys_enter_recvmsg

232

29

tp/syscalls/sys_exit_recvmsg

400

50

表2-4:14个可执行代码段的指令统计

03
进程隐藏与反调试

通过前述分析可知,13个handler中有四个直接决定进程维度的隐蔽效果:getdents64控制枚举通道的进出,ptrace阻断调试通道的入口,sched_process_exec负责向hidden_pids补充新成员。上述四个handler 共享同一份目标集合,且相互衔接,构成一个自维持的闭环,因此须将其作为整体进行分析。

getdents64目录项隐藏

进程隐藏要解决的核心问题,是让/proc/<pid>的目录项从枚举结果中消失。ps、top、ls /proc等工具都是通过getdents64枚举/proc目录,该样本正是针对这个通用入口实施hook。其实现分为两个步骤:

1、进入系统调用时,按线程将缓冲区指针缓存至scratch map;

2、系统调用返回后,取出该指针逐条遍历目录项,命中目标即予以抹除。

// 函数:enter_getdents / exit_getdents / walk_dirent / name_to_pid // 作用:缓存 bufptr、遍历 dirent 并隐藏 hidden_pids 中的 PID // 说明:基于样本静态反编译 // enter_getdents:缓存 (tgid, bufptr) 到 scratch local_8  = bpf_get_current_pid_tgid(); local_10 = *(undefined8 *)(param_1 + 0x18); bpf_map_update_elem(0, &local_8, &local_10, 0); // exit_getdents:返回值大于 0 时调用 walk_dirent 遍历缓冲区 puVar1 = (undefined8 *)bpf_map_lookup_elem(0, &local_8); if (puVar1 != 0) {     bpf_map_delete_elem(0, &local_8);     local_28 = *(longlong *)(param_1 + 0x10);   // ctx->ret     if (0 < local_28)         bpf_loop(0x400, (void *)0x0, &local_30, 0); } // walk_dirent:命中 hidden_pids 时合并 dirent 或清零 name[0] *(longlong *)(ctx + 0x18) = *(longlong *)(ctx + 0x10); *(ulonglong *)(ctx + 0x10) =     *(longlong *)(ctx + 0x10) + (ulonglong)local_rlen; // name_to_pid:将 dirent 名前导数字解析为 PID u32 name_to_pid(const char *name) {     u32 result = 0;     for (int i = 0; i < 7 && name[i]; i++) {         u8 c = name[i];         if (c < '0' || c > '9') return 0;         result = result * 10 + (c - '0');     }     return result; }

代码清单1:getdents64缓存、遍历与隐藏

代码清单1的关键环节在于返回阶段。exit_getdents在取出enter阶段所缓存的指针后,调用bpf_loop逐目录项执行回调函数walk_dirent。该函数将目录名前导数字解析为PID,并据此查询hidden_pids映射表。命中后的处理方式较为精细:优先采用合并d_reclen的方式,使前一条目录项覆盖目标目录项所占空间,从而保持缓冲区总长度不变且不留空缺;若无法合并,则将name[0]字段清零。此种实现方式旨在规避缓冲区中部出现异常空缺,此类空缺可被完整性校验机制检测。完整数据路径如图3-1所示:

图3-1:getdents64进程隐藏数据路径
进程反调试

进程一旦被隐藏,对其实施调试的行为几乎难以避免。该样本对ptrace的处理并非采取简单的拒绝策略,而是主动发起反制:当调试器尝试对隐藏进程执行PTRACE_ATTACH或PTRACE_SEIZE操作时,在attach尚未生效之前,调试器自身便会立即收到SIGKILL信号。

// 函数:syscalls_sys_enter_ptrace // 作用:对 hidden_pids 目标发起 ptrace 时 SIGKILL 调试器 // 说明:request 检查命中 PTRACE_ATTACH(0x10) 或 PTRACE_SEIZE(0xa9) undefined8 syscalls_sys_enter_ptrace(longlong param_1) {     longlong lVar1;     undefined4 local_4;     // request = ctx->args[0];仅处理 ATTACH(0x10) 与 SEIZE(0xa9)     if ((request == 0x10) || (request == 0xa9)) {         local_4 = (undefined4)ctx->args[1];      // target pid         lVar1 = bpf_map_lookup_elem(0, &local_4); // hidden_pids[pid]         if (lVar1 != 0) {             bpf_send_signal(9);  // SIGKILL the current process (tracer)         }     }     return 0; }

代码清单2:sys_enter_ptrace反调试逻辑

该样本在ptrace相关处理上呈现两项显著特征。首先,其对ptrace request 的过滤具有高度选择性:仅当request为PTRACE_ATTACH(0x10)或PTRACE_TRACEME(0xa9)时触发拦截逻辑,其余request类型均直接放行。这种设计将异常行为面压缩至极小范围,降低了被审计机制捕获的概率。其次,信号投递的目标存在误导性。样本通过bpf_send_signal发送的信号作用于当前进程,即发起ptrace调用的调试器进程本身,而非被调试的目标进程。目标进程的运行状态不受任何影响,外部表现为调试器异常终止,而非目标进程受到某种"保护"。由于调试器的崩溃与目标进程无直接关联,排查人员通常难以将调试器的异常退出归因于内核中的BPF程序。上述 request类型与目标PID均直接取自tracepoint 上下文ctx->args,无需额外解析或转换。拦截逻辑的实现机制参见图3-2。

图3-2:ptrace反调试实现原理
进程启动路径隐藏

基于进程标识符(PID)的人工维护机制存在固有缺陷:进程终止后其PID将被内核回收并重新分配,致使该方案在可扩展性与持续有效性方面均存在不足。该样本转而采用sched_process_exec跟踪点机制,以进程名称(comm)作为匹配维度实施隐藏策略,从而规避了对易变PID的依赖。

在辅助函数识别方面,Helper ID 16经与uapi/linux/bpf.h头文件交叉验证,最终确认为bpf_get_current_comm;同一样本中其余3个辅助函数标识符(36、112、181)亦通过同等复核流程完成校正,均以UAPI定义为最终判定依据。

// 函数:sched_sched_process_exec // 作用:按进程 comm 自动将新 PID 加入 hidden_pids // 说明:helper ID 16 经与内核 uapi 定义比对确认为 bpf_get_current_comm int sched_sched_process_exec(void) {     longlong lVar1;     undefined4 extraout_var;     undefined1 local_15;     undefined4 local_14;     char comm [16];     bpf_get_current_comm(comm, 0x10);      // 读取当前进程 comm     lVar1 = bpf_map_lookup_elem(0, comm);  // hidden_names[comm]     if (lVar1 != 0) {         bpf_get_current_pid_tgid();         local_15 = 1;         local_14 = extraout_var;           // pid = pid_tgid >> 32         bpf_map_update_elem(0, &local_14, &local_15, 0); // hidden_pids[pid] = 1     }     return 0; }

代码清单3:sched_process_exec自动隐藏逻辑

实现逻辑十分直接:当进程执行新程序时,系统获取当前进程的comm名称(16字节),并在hidden_names中进行查询若匹配成功,则将该进程的PID写入hidden_pids。攻击者只需使目标程序以约定名称启动,待进程执行新程序后,系统即自动将其加入隐藏集合,并由前述目录项过滤机制接管。该机制按名称触发,进程启动即被隐藏,整个闭环无需攻击者执行任何运行时操作。

04
网络连接隐藏

进程维度的隐藏仅解决了部分问题:已隐藏的进程仍会产生网络连接,而连接记录是入侵排查的另一标准路径。/proc/net/tcp与 NETLINK_SOCK_DIAG是用户态获取本机连接的两个入口。样本对二者的处理方式与前述进程隐藏技术同源,即仍在系统调用返回阶段实施改写,仅是改写目标由目录项换作连接记录。

数据链路隐藏

/proc/net/tcp是查看本机连接最经典的数据源。样本未对内核网络栈实施任何修改,而是在数据被读入用户态缓冲区之后进行删改——内核中的连接记录完好无损,被篡改的仅是用户态获得的副本。这一原则贯穿样本的全部隐藏逻辑:不修改内核数据本身,仅污染用户态的观测结果。

// 函数:net_enter_openat / net_exit_openat / syscalls_sys_exit_read / scan_net_byte // 作用:识别 /proc/net/tcp 打开事件并隐藏 hidden_inodes 命中的行 // 说明:基于样本静态反编译 // sys_enter_openat:匹配 "/proc/net/tcp" 关键字节 bpf_probe_read_user(path, 0xe, ctx->args[1]); if (path[0]=='/' && path[1]=='p' && path[4]=='c' &&     path[6]=='n' && path[9]=='/' && path[10]=='t' && path[12]=='p') {     local_1 = 1;     bpf_map_update_elem(0, &tgid, &local_1, 0);   // net_open_temp } // sys_exit_openat:fd 有效则晋升到 net_fds if (bpf_map_lookup_elem(0, &tgid) != 0) {          // net_open_temp     bpf_map_delete_elem(0, &tgid);     if (ctx->ret >= 0) {         key = (tgid & ~0xffffffffULL) | (ctx->ret & 0xffffffffULL);         bpf_map_update_elem(0, &key, &local_1, 0);   // net_fds     } } // sys_exit_read:仅处理 net_fds 中记录的 fd,按字段扫描 inode 列 if (bpf_map_lookup_elem(net_fds, &tgid) != 0) {     bpf_map_delete_elem(net_fds, &tgid);     n = ctx->ret;     if (0 < n && n < 0x10000) {         bpf_loop(0x10000, &LAB_5b8, &ctx1, 0);         if (wpos < n)             bpf_loop(n - wpos, &scan_net_byte, &ctx2, 0);     } } // scan_net_byte:十进制累计 inode 值,空白处递增字段计数 ctx->inode_val = ctx->inode_val * 10 + (ch - '0'); ctx->field     = ctx->field + 1;

代码清单4/proc/net/tcp路径匹配、fd跟踪与行折叠

三个handler各自承担明确职责。sys_enter_openat逐字节比对路径,仅对若干关键偏移进行抽查,因此开销极小;sys_exit_openat在确认打开操作成功后,将tgid与fd拼接为64位复合键,并记录于net_fds中sys_exit_read对返回缓冲区执行两轮bpf_loop扫描,scan_net_byte按字段计数定位第10列的inode值。一旦命中hidden_inodes,写指针即回退至行首,折叠整行,并将剩余空间清零。对于执行cat /proc/net/tcp的操作者而言,目标连接自始至终未曾出现。链路A的完整过程如图4-1所示。

图 4-1:网络连接隐藏双链路
网络连接状态隐藏

仅过滤/proc/net/tcp并不完整:ss与较新版本的netstat使用另一条数据通道NETLINK_SOCK_DIAG,绕开/proc文件系统直接查询内核。样本在该链路上复用了同一套手法——识别fd、拦截返回、就地改写,仅改写对象由文本行变为netlink消息。

// 函数:enter_socket / exit_socket / syscalls_sys_exit_recvmsg / walk_nlmsg // 作用:识别 NETLINK_SOCK_DIAG 套接字并将 hidden_inodes 命中项改为 NOOP // 说明:基于样本静态反编译 // sys_enter_socket:检测 AF_NETLINK(0x10) + NETLINK_SOCK_DIAG(4) if ((ctx->args[0] == 0x10) && ((ctx->args[2] & 0xffffffff) == 4)) {     local_1 = 1;     bpf_map_update_elem(0, &tgid, &local_1, 0);   // sock_open_temp } // sys_exit_socket:fd 有效则晋升到 diag_fds if (bpf_map_lookup_elem(0, &tgid) != 0) {          // sock_open_temp     bpf_map_delete_elem(0, &tgid);     if (ctx->ret >= 0) {         key = (tgid & ~0xffffffffULL) | (ctx->ret & 0xffffffffULL);         bpf_map_update_elem(0, &key, &local_1, 0);   // diag_fds     } } // sys_exit_recvmsg:读取 msghdr -> iov[0].iov_base,调用 walk_nlmsg if (bpf_map_lookup_elem(0, &tgid) != 0) {          // diag_fds     bpf_map_delete_elem(0, &tgid);     if (ctx->ret > 0) {         bpf_probe_read_user(&iov_base, 8, msghdr + 0x10);         if (iov_base != 0) {             bpf_probe_read_user(&buf, 8, iov_base);             if (buf != 0)                 bpf_loop(0x100, &walk_nlmsg, &ctx_nl, 0);         }     } } // walk_nlmsg:对 SOCK_DIAG_BY_FAMILY 消息改写 nlmsg_type if (nlmsg_type == SOCK_DIAG_BY_FAMILY) {     inode = *(u32 *)(msg + IDIAG_INODE_OFF);     if (hidden_inodes[inode])         bpf_probe_write_user(nlmsg + offset, &NLMSG_NOOP, 2); }

代码清单5:NETLINK_SOCK_DIAG跟踪与NLMSG改写

walk_nlmsg遍历recvmsg返回的消息序列,对类型为 SOCK_DIAG_BY_FAMILY的消息取出inode查hidden_inodes,命中即用bpf_probe_write_usernlmsg_type改写为NLMSG_NOOP。用户态解析器将NOOP视为填充消息直接跳过,连接就此消失。需要指出的是,两条链路共用同一个hidden_inodes:攻击者维护一份目标清单,/proc与netlink 两个观测面同时失效,如图4-1链路B所示。

FD状态清理

文件描述符(fd)关闭后,必须同步清除相关跟踪状态,否则net_fdsdiag_fds将持续累积陈旧条目。此举不仅浪费映射表(map)容量,还可能对复用同一fd编号的无关会话造成误判。

// 函数:syscalls_sys_enter_close // 作用:关闭 fd 时从 net_fds 与 diag_fds 删除 tgid|fd 条目 // 说明:基于样本静态反编译 undefined8 syscalls_sys_enter_close(longlong param_1) {     ulonglong uVar1;     ulonglong local_8;     uVar1 = bpf_get_current_pid_tgid();     // 构造复合 key:高 32 位为 tgid,低 32 位为 fd     local_8 = (*(ulonglong *)(param_1 + 0x10) & 0xffffffff) |               (uVar1 & 0xffffffff00000000);     bpf_map_delete_elem(0, &local_8);   // net_fds     bpf_map_delete_elem(0, &local_8);   // diag_fds     return 0; }

代码清单6:sys_enter_close清理fd跟踪状态

两条过滤链路共用同一种tgid|fd复合键,sys_enter_close连续两次删除即完成清理。一次close操作,两类过滤同时终止。状态管理的严谨程度,表明作者对该机制理解深入、实现考虑周全,并非临时拼凑。

05
证据边界与能力推断
加载验证

通过构建加载器,并在隔离的分析环境中使用最小化的libbpf加载器,我们成功复现了加载过程,所得结果如下所示:

bpf_object__open_file: SUCCESS bpf_object__load: SUCCESS (zero verifier rejections; 10 maps type=1) 13 tracepoint programs attached:   enter_getdents, exit_getdents, on_exec,   enter_ptrace,   net_enter_openat, net_exit_openat, net_enter_read, net_exit_read, net_enter_close,   enter_socket, exit_socket, enter_recvmsg, exit_recvmsg 5 subprogs inlined:   walk_dirent + name_to_pid      -> exit_getdents   scan_net_byte + zero_net_tail  -> net_exit_read   walk_nlmsg                     -> exit_recvmsg Map dimensions (key/value/max_entries) match BTF reconstruction Loader exit code: 0

记录5-1:loader加载结果摘要

根据上述加载日志分析,可得出如下结论:验证结果表明,该BPF对象符合标准libbpf加载流程要求,可直接完成bpf_object__load操作并通过内核验证器(Verifier)的合规性审查,无需借助任何规避手段即可成功注入内核。在映射结构方面,内核成功实例化10个BPF_MAP_TYPE_HASH类型的BPF映射,其键值尺寸与BTF(BPF Type Format)元数据重建结果一致,数据结构定义正确。在挂载点方面,13个跟踪点全部成功完成附着,进程隐藏、调试器对抗、网络过滤及Netlink干扰四条功能路径的入口点均已激活,Hook机制运行正常。在程序结构方面,静态分析所识别的子程序内联关系与运行时行为一致:walk_direntname_to_pid内联至exit_getdentsscan_net_bytezero_net_tail内联至 net_exit_readwalk_nlmsg内联至exit_recvmsg,调用图结构符合预期。综上所述,该样本可在标准libbpf框架下完成完整部署,无需采用额外的加载规避策略。

06
检测与响应建议

针对此类威胁,可从三个层面构建观测依据:加载阶段的BPF调用序列、运行阶段的附着关系与map命名特征、取证阶段的文件实体与字节码指纹。上述指标在特异性与可获取性上存在显著差异,该差异直接决定了指标的分层策略、取证调查的切入点选择,以及响应处置的优先级排序。

检测指标

样本的行为特征在检测上可分为五层。加载路径决定loader必然留下10次 BPF_MAP_CREATE与13次BPF_LINK_CREATE的调用序列;附着行为决定 getdents64、ptrace、recvmsg等tracepoint会被同一对象同时注册;map命名与helper组合构成代码层面的指纹;文件哈希用于落盘样本的识别。任何单独一层都可能与正常的BPF可观测性工具产生特征重叠,五层叠加之后特异性才足够高。可直接作为IOC或审计关键词的指标如表6-1所示,整体框架如图6-1所示。

检测层

关键指标

证据来源

BPF 调用序列

连续 BPF_BTF_LOAD、BPF_MAP_CREATE×10、BPF_PROG_LOAD×13、BPF_LINK_CREATE×13

Docker 加载验证 strace 捕获

tracepoint 注册

tp/syscalls/sys_enter_getdents64、sys_exit_getdents64、sys_enter_ptrace、sys_enter_openat、sys_exit_read、sys_enter_socket、sys_exit_recvmsg、tp/sched/sched_process_exec 等同时附着

静态反编译 section/symtab + Docker 加载 attach 日志

map 名称异常

存在 hidden_names、hidden_pids、hidden_inodes、net_fds、diag_fds 等自解释型隐藏相关名称

BTF .datasec 解析

helper 组合

同一对象同时使用 bpf_probe_write_user、bpf_send_signal、bpf_loop

静态反编译与 Ghidra/uapi helper ID 统计

文件落盘

SHA-256 3607de25...50f7b01 的 ELF64 EM_BPF ET_REL 对象

ELF 头解析

表6-1:分层检测指标

五层指标的可得性并不相同:调用序列与附着组合可以在线审计,map名称与helper组合需要提取已加载对象的字节码或BTF,文件特征只适用于取证阶段。部署时应按层级组合告警,而非单点触发。

图6-1:分层检测指标与事件响应框架
威胁检测建议

由于该rootkit不修改内核数据,仅篡改用户态可见的副本,因此,当针对同一事实的两个独立信息源出现不一致时,即可将其作为该rootkit存在的重要判定依据。

猎捕方向

具体动作

预期异常

BPF 审计

审计 bpf(BPF_PROG_LOAD, prog_type=TRACEPOINT) 与 BPF_LINK_CREATE 日志

同一进程短时间内加载多个 tracepoint 程序

tracefs 监控

监控 /sys/kernel/debug/tracing/events/syscalls/*/enable 的写入;定期执行 bpftool link list

出现 getdents64/ptrace/openat/read/socket/recvmsg 等异常组合

/proc 一致性检查

对比 ps 与 /proc 目录枚举

ps 显示存在而 ls /proc 缺失的 PID

网络诊断一致性检查

对比 /proc/net/tcp 与 ss/netstat

同一连接在一种工具中可见、在另一种中消失

内存/磁盘 BPF 取证

提取 /sys/fs/bpf pin 的程序、map、BTF

存在 hidden_* 系列 map 名

表6-2:主动猎捕方向与预期异常

两类一致性检查适用于已产生怀疑的主机,可快速进行验证;而BPF审计与tracefs监控则适用于大范围终端上的长期部署。需要明确的是,上述动作仅提供线索,而非得出最终结论——最终确认仍需回归至字节码层面,与已知样本特征进行交叉比对。

响应动作

处置顺序至关重要:首先隔离,防止攻击者经其他通道重新连接或清理证据;其次卸载内核态的BPF程序与map——单纯删除磁盘上的.o文件无法终止已加载的逻辑;然后定位并终止loader,阻断其重新加载的途径;最后完成取证与加固。遗漏任何一步,都可能为攻击者留下重新入侵的通道。

阶段

动作

目的

隔离

断开受感染主机网络连接或放入只读隔离 VLAN

防止攻击者通过其他通道重新连接或清理证据

卸载 BPF

bpftool prog show 列出程序 ID;bpftool link list 列出 link ID;逐条执行 bpftool link set <LINK_ID> detached,必要时 bpftool prog detach <PROG_ID> tracepoint;执行 bpftool map list 定位 pin 的 map,再 rm /sys/fs/bpf/<pin_name> 删除属于该 rootkit 的 pin 文件

停止内核态隐藏行为

终止loader

执行 bpftool prog show id <ID> 查看 pids 字段中的创建者 PID,或审计 bpf(BPF_BTF_LOAD) 的调用进程;结束 loader 进程;检查 systemd 服务、crontab -l、/etc/rc.local、.bashrc、LD_PRELOAD 等启动项

阻止重新加载

取证

提取 BPF bytecode、map 内容、BTF;保存 /sys/kernel/debug/tracing/ 状态

保留加载证据与目标集合

加固

限制 CAP_BPF、CAP_SYS_ADMIN、ptrace 能力;审计 BPF 调用;禁用非必要 tracepoint attach

降低同类 rootkit 加载面

表6-3:事件响应阶段与动作

由于当前样本采用分离式架构,再阶段应特别留意loader进程、启动项与同源二进制,以便在横向环境中排查相同的加载机制。

火绒安全提示广大用户,使用Linux设备时,运维人员需持续监测系统运行异常,若出现进程、网络连接查询结果不一致,调试工具无故闪退等情况,可参照上文“检测与响应建议”开展排查,并全面加固系统防御,避免Rootkit长期潜伏窃取数据。

附录 A  IOC 与检测规则
IOC汇总表

类别

类型

内容

文件

SHA-256

3607de2597f8955f9a88f36ee43b64d3891b8ef536e99fa098e80169350f7b01

文件

ELF

ELF64, e_flags=0, e_type=ET_REL, machine=EM_BPF

Map

BTF .datasec

hidden_names, hidden_pids, hidden_inodes

Map

BTF .datasec

net_fds, diag_fds, net_open_temp, sock_open_temp

Map

BTF .datasec

scratch, net_open_temp, net_read_temp, diag_fds, sock_open_temp, recvmsg_temp

Tracepoint

syscall

sys_enter/exit_getdents64, sys_enter_ptrace, sys_enter_openat, sys_exit_openat, sys_enter_read, sys_exit_read, sys_enter_close

Tracepoint

sched

sched_process_exec

Tracepoint

socket

sys_enter_socket, sys_exit_socket, sys_enter_recvmsg, sys_exit_recvmsg

表 A-1:IOC 汇总

表A-1覆盖文件、map、tracepoint三个取证面,可直接作为YARA、Suricata或终端管控规则的输入项。SHA-256适用于落盘检测,map名称与tracepoint列表适用于在线审计。

行为级检测指标

指标

描述

tracepoint 注册

同一进程短时间内为 sys_enter_getdents64、sys_exit_getdents64、sys_enter_ptrace、sys_enter_openat、sys_exit_read、sys_enter_socket、sys_exit_recvmsg、sched_process_exec 同时启用 tracepoint

bpf() 调用序列

BPF_BTF_LOAD → BPF_MAP_CREATE × 10 → BPF_PROG_LOAD × 13 → BPF_LINK_CREATE × 13

map 命名异常

/sys/fs/bpf 或内存中出现 hidden_*、net_*、diag_*、sock_*、recvmsg_* 等语义明确的隐藏相关名称

helper 组合异常

同一段 BPF 字节码同时使用 bpf_probe_write_user、bpf_send_signal、bpf_loop

表A-2:行为级检测指标

 扩展信息
字段类型对照表

字段

样本中的类型

本报告引用的标准类型

BPF 寄存器 r0–r5、BPF 指针

ulonglong / longlong / undefined8 / undefined4

u64 / s64 / u32 / struct 指针

PID/TGID

ulonglong (pid_tgid 64 位)

u64 (高 32 位 TGID,低 32 位 PID)

d_reclen

ulonglong + 0x10 偏移访问

u16 字段写入

iovec

ulonglong iov_base

struct iovec.iov_base (void *)

nlmsghdr.nlmsg_type

undefined2

u16

表B-1:字段类型对照表

关于公司

火绒安全成立于2011年,是一家专注、纯粹的安全公司,致力于在终端安全领域为用户提供专业的产品和专注的服务,并持续对外赋能反病毒引擎等相关自主研发技术。多年来,火绒安全产品凭借“专业、干净、轻巧”的特点收获了广大用户的良好口碑。火绒企业版产品更是针对企业内外网脆弱的环节,拓展了企业对于终端管理的范围和方式,提升了产品的兼容性、易用性,最终实现更直观的将威胁可视化、让管理轻便化,充分达到保护企业信息安全的目的。

点点赞
点分享
点喜欢

最新文章

随机文章

基本 文件 流程 错误 SQL 调试
  1. 请求信息 : 2026-08-21 20:53:02 HTTP/2.0 GET : https://f.mffb.com.cn/a/509019.html
  2. 运行时间 : 0.115202s [ 吞吐率:8.68req/s ] 内存消耗:4,646.30kb 文件加载:140
  3. 缓存信息 : 0 reads,0 writes
  4. 会话信息 : SESSION_ID=e9b82d71a7b689296b359e8df9947128
  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.000416s ] mysql:host=127.0.0.1;port=3306;dbname=f_mffb;charset=utf8mb4
  2. SHOW FULL COLUMNS FROM `fenlei` [ RunTime:0.000583s ]
  3. SELECT * FROM `fenlei` WHERE `fid` = 0 [ RunTime:0.000294s ]
  4. SELECT * FROM `fenlei` WHERE `fid` = 63 [ RunTime:0.000272s ]
  5. SHOW FULL COLUMNS FROM `set` [ RunTime:0.000497s ]
  6. SELECT * FROM `set` [ RunTime:0.000192s ]
  7. SHOW FULL COLUMNS FROM `article` [ RunTime:0.000568s ]
  8. SELECT * FROM `article` WHERE `id` = 509019 LIMIT 1 [ RunTime:0.005601s ]
  9. UPDATE `article` SET `lasttime` = 1787316782 WHERE `id` = 509019 [ RunTime:0.006956s ]
  10. SELECT * FROM `fenlei` WHERE `id` = 67 LIMIT 1 [ RunTime:0.000247s ]
  11. SELECT * FROM `article` WHERE `id` < 509019 ORDER BY `id` DESC LIMIT 1 [ RunTime:0.000445s ]
  12. SELECT * FROM `article` WHERE `id` > 509019 ORDER BY `id` ASC LIMIT 1 [ RunTime:0.000369s ]
  13. SELECT * FROM `article` WHERE `id` < 509019 ORDER BY `id` DESC LIMIT 10 [ RunTime:0.004847s ]
  14. SELECT * FROM `article` WHERE `id` < 509019 ORDER BY `id` DESC LIMIT 10,10 [ RunTime:0.009913s ]
  15. SELECT * FROM `article` WHERE `id` < 509019 ORDER BY `id` DESC LIMIT 20,10 [ RunTime:0.018269s ]
0.116775s