方括号进程(如[kthreadd])是内核线程的正常显示,无用户态可执行文件,/proc/pid/cmdline为空、/proc/pid/exe不存在、PPid为2且PF_KTHREAD标志置位;伪装者虽可伪造comm,但无法伪造Tgid=Pid、PPid=2及exe缺失等内核线程本质属性。
![ps aux 显示 [kthreadd] 风格隐藏进程的 /proc/pid/cmdline 检查](https://img.php.cn/upload/article/001/242/473/177047707476845.jpeg)
ps aux 里看到 [kthreadd] 这类方括号进程,不是隐藏,是内核线程的正常显示方式
方括号包裹的进程名(如 [kthreadd]、[ksoftirqd/0])是内核线程(kernel thread),由内核直接创建,没有用户态可执行文件,因此 /proc/pid/cmdline 为空或只含空字符。这不是隐藏进程,而是 Linux 的标准行为——内核线程不通过 execve() 启动,自然没有命令行参数。
检查 /proc/pid/cmdline 时遇到空输出,先确认是否为内核线程
执行 cat /proc/2/cmdline(假设 PID=2 是 [kthreadd])通常返回空或不可见字符。这不是异常,是预期结果。验证方法:
- 运行
ls -l /proc/2/exe→ 会显示exe -> /proc/2/exe: No such file or directory或指向[kernel.kthread] - 查看
cat /proc/2/stat第三字段(进程状态):若为S且第10字段(flags)包含0x200000(即PF_KTHREAD),就确认是内核线程 -
ps -o pid,comm,cmd -p 2中comm显示kthreadd,而cmd列为空或[kthreadd]
真正需要警惕的“伪装成内核线程”的恶意进程,关键看 /proc/pid/status 和路径一致性
攻击者可能伪造 comm 字段(通过 prctl(PR_SET_NAME))让用户态进程显示为 [kthreadd],但无法伪造内核线程的底层属性。排查要点:
-
cat /proc/PID/status | grep -E 'Tgid|PPid|State|Name':真实内核线程的Tgid等于Pid,且PPid为 2(kthreadd自身 PID 通常是 2) -
readlink /proc/PID/exe:用户态进程必有可读取的路径(即使被删,也显示deleted);内核线程返回No such file -
ls -la /proc/PID/root:内核线程的root是/的符号链接,但实际无挂载点;恶意进程的root可能指向异常路径或权限异常
用 ps + awk 快速筛出可疑“方括号进程”
仅靠 ps aux | grep '\[.*\]' 会淹没在合法内核线程中。更有效的命令:
ps -eo pid,ppid,comm,cmd --no-headers | awk '$3 ~ /^\[.*\]$/ && $2 != 2 {print "Suspicious:", $0}'
该命令筛选出:名称带方括号 且 父进程不是 PID 2 的进程——这类大概率是用户态进程伪造的,需重点查 /proc/PID/exe 和 /proc/PID/status。
真正难识别的是那些直接 hook 了 sys_getdents64 或使用 eBPF 隐藏自身目录的 rootkit,此时 /proc/PID/ 子目录本身都可能消失。这种场景下,/proc/pid/cmdline 检查已失效,得依赖内存取证或内核模块签名验证。










