对一款Linux木马开源提示词的测评

admin 2026-09-30 05:35:58 网络安全文章 来源:ZONE.CI 全球网 0 阅读模式

文章总结: 本文测评一款Linux木马开源提示词生成的Rootkit样本,分析其基于Diamorphine增强的隐藏与持久化能力,指出网络隐藏可被ss检测、持久化暴露面大等缺陷,并给出检测建议,认为AI降低的是能跑门槛而非能用,双通道hook与关机回写有工程价值。 综合评分: 85 文章分类: 恶意软件,红队,逆向分析,安全运营


对一款 Linux 木马开源提示词的测评

huasec

2026年9月28日 18:05 北京

在小说阅读器读本章

去阅读

在公众号小说中沉浸阅读

一、引言

上一篇对一款Windows木马开源提示词的测评是Windows版提示词的分析,这一篇则是对Linux版提示词的测评和分析。

上一篇文章中对Windows版本的测试,从环境搭建到完成第一个Rootkit版本,花了3个多小时,而Linux版本则快得多,在给出了提示词文档后,只花了大概不到15分钟时间,就完成了整个项目的编写,当然代码量也小了很多,我这边第一次生成,代码量大概1700行。功能也齐全,可以进行进程、文件、网络以及内核模块自身的隐藏,同时也有持久化和关机回写功能。从能力上来说,和Windows版几乎如出一辙,只是因为所处操作系统不同,在实现原理上大相径庭。并且设置了兼容层和配置,可以轻易的通过修改.h源码实现后续兼容性问题和rootkit配置问题。


二、源码分析

2.1 样本功能

Linux 版的提示词文件为 crimson-kmod-agent-prompt.md。文档中并未直接指定生成的项目名称,因此命名随机性很强——本次测试中项目名为crimson。

其核心能力与实现原理概览:

| | | | — | — | | 能力 | 实现方式 | | 文件名前缀隐藏 | getdents/getdents64  syscall hook + 缓冲区压缩 | | 进程隐藏 | task->flags 置 PF_INVISIBLE + /proc 过滤 | | 模块自隐藏 | 模块链表摘除 + 名称过滤 | | TCP/UDP 端口隐藏 | ftrace hook {tcp,udp}{4,6}_seq_show | | 提权 | prepare_creds() + commit_creds() | | 持久化 | .ko 写回 + 启动脚本 + systemd unit |

对 LKM(可加载内核模块)的控制指令:

kill&nbsp;-34&nbsp;<pid> &nbsp; 切换进程在 /proc 中的可见性kill&nbsp;-35&nbsp;0&nbsp; &nbsp; &nbsp; &nbsp;把调用进程提升为 rootkill&nbsp;-36&nbsp;0&nbsp; &nbsp; &nbsp; &nbsp;切换模块在 lsmod 中的可见性kill&nbsp;-37&nbsp;<port> &nbsp;切换端口在 /proc/net 中的可见性(端口号经 pid 参数传入)

对于红队研发人员与蓝队资深取证人员而言,这套设计”眼熟”得很。分析完源码后几乎可以笃定:该项目脱胎于著名 Rootkit 工具Diamorphine(github.com/m0nad/Diamorphine)。

不过,Diamorphine 本身并不具备网络隐藏、持久化及关机回写能力。因此本样本可视为 Diamorphine 的一个增强变种。至于这种增强是否真有意义,值得深入探讨——文末将展开分析。

2.2 配置层

所有配置均集中于 config.h。这在便于统一配置的同时,也便于对固定取证线索的修改。从反取证角度看,是个不错的策略。

2.3 Hook 方式

整个项目采用两种 Hook 方式:syscall hook与ftrace hook。该 Rootkit 最核心的隐藏能力与通信能力,均建立在这两类 Hook 之上。

2.4 通信的实现

样本通过 syscall hook 内核的 kill 函数,拦截并过滤应用层 kill 命令的消息,从而构建出一条单向的内核通信通道。

真正的控制函数为 crimson_kill_ctl,通过传入的 pid 与 signal 进行分支判断。

2.5 进程隐藏

进程隐藏分两步:先标记,后过滤。

第一步,标记:发生在 kill 信号的拦截处,把目标进程的 task->flags 翻转一个 PF_INVISIBLE 位。

PF_INVISIBLE(0x10000000)取自老内核 sched.h 中已废弃的位定义,现代内核不再使用,复用不会冲突。反过来说——”进程 flags 里出现内核已不使用的位”本身就是一条明确的检测线索。

第二步,过滤:复用文件隐藏的 getdents 通道,只是对 /proc 根目录多加一层判定。

因此,进程隐藏本质是文件隐藏的特例——藏的是 /proc 下以 pid 命名的目录项。

2.6 网络隐藏

网络隐藏是 Diamorphine 所不具备的能力,走 ftrace 通道,Hook 的是 /proc/net/{tcp,tcp6,udp,udp6} 的渲染函数:

static&nbsp;struct&nbsp;ftrace_hook net_hooks[] = {&nbsp; &nbsp; HOOK("tcp4_seq_show", hacked_tcp4_seq_show, &orig_tcp4_seq_show),&nbsp; &nbsp; HOOK("tcp6_seq_show", hacked_tcp6_seq_show, &orig_tcp6_seq_show),&nbsp; &nbsp; HOOK("udp4_seq_show", hacked_udp4_seq_show, &orig_udp4_seq_show),&nbsp; &nbsp; HOOK("udp6_seq_show", hacked_udp6_seq_show, &orig_udp6_seq_show),};

kill -37 把端口号存进一张16 项的隐藏表;Hook 函数对每个 socket 比较源端口与目的端口,一旦命中就跳过该行不渲染。

关键缺口:对 /proc/net/tcp 这一个视图,隐藏是有效的。但 ss 走的是 netlink sock_diag,完全不经过 seq_show,因此该方式防不住ss的检测。

2.7 文件/目录隐藏

文件隐藏是全项目实现最细致的部分。getdents 的 Hook 拿到原始返回缓冲后,把名字以 crimson_ 魔术前缀开头的记录从缓冲区里”压”掉。压缩分首条与非首条两种情况处理。

值得一提的是,它妥善处理了”整批被隐藏”的边界情况。getdents 分批返回,若某批记录全部命中过滤,直接返回 0 会被用户态当成 EOF——后果不是”藏了几个文件”,而是目录被截断。实现上通过置 retry 标志重取下一批来规避:

if&nbsp;(ret ==&nbsp;0) {&nbsp; &nbsp; kfree(kdirent);&nbsp; &nbsp; *retry&nbsp;=&nbsp;1;&nbsp; &nbsp;&nbsp;return&nbsp;0;}

2.8 关机回写与持久化

关机回写与持久化是相对 Diamorphine 的另一处增强。触发点共有三个,互为关机回写和持久化是相对Diamorphine的另一处增强,触发点有三个,互为冗余:reboot系统调用hook(main.c:633)、优先级INT_MAX的重启通知链、以及rmmod卸载。三个入口都汇到do_persistence:

write_self_ko 把模块加载时读进内存的 .ko 原样写回 ko_path。攻击者加载完即可删除磁盘上的样本,模块在关机时自行把文件拼回来,达成”删文件不死”的效果。

setup_autostart 则铺设三层自启:/etc/crimson_load.sh、systemd unit 加启用链接、rc.local 追加。

比较有意思的是启用链接的做法:

call_usermodehelper(mkdir_argv[0], mkdir_argv, envp, UMH_WAIT_PROC);call_usermodehelper(ln_argv[0], ln_argv, envp, UMH_WAIT_PROC);

在 .wants/ 目录下放真实文件不算启用,必须是符号链接;它也没用 systemctl enable——那要求运行中的 manager 认识这个 unit,而从内核态直接 mkdir 加 ln -sf 建链接更稳。

实测:靶机重启7.5 秒后模块自动加载,自启与自隐藏无缝衔接。而 systemd 这条通道在提示词里只字未提(rc.local 出现 8 次、systemd 出现 0 次),是 AI 实测踩坑后自行补上的。

但这同样是全项目最大的暴露面:隐藏做到了getdents一级, /etc下三个文件却原样明摆在系统管理面上。持久化始终是这类木马脚印最大的一环。


三、如何检测

从整个实现这个木马把“枚举”堵得很严,除非直接知道隐藏了哪些文件、文件夹,或者知道模块名称,否则常规的枚举经检测不太容易发现端倪。

从之前的源码分析中可以发现,通过查看/etc目录下的可疑shell脚本以及查看rc.local是可以发现恶意持久化的,而且,通过ss与netstat的对比,也可以发现隐藏的网络连接。除此以外,通过测试,还发现有其他方式进行检测。在未知的情况下,可以尝试输入kill -36 0,查看有没有新的内核模块出现。

由于项目本身利用 ftrace hook 实现网络隐藏,完全可以通过查看当前内核已挂载的 ftrace 回调钩子来定位:

通过以上方式,可以快捷、方便地定位内核问题。


四、提示词中的坑

和上一篇一样,提示词的坑也不少。比如,syscall表改写静默失效的问题。内核6.11起x86分派改为x64_sys_call()内部switch直调__x64_sys_*,不再经过sys_call_table。表项确实写进去了(kcore读回是新值)、insmod成功、dmesg干净——三条“成功”信号全中,但其实功能是不生效的。


五、总结:增强是否有意义

回到开头留下的问题:相对Diamorphine的这些增强,是否有意义?我的看法是有限的。网络隐藏只挂seq_show一条通路,ss一比对就穿帮;持久化在/etc下留三处明文,是全项目暴露面积最大的一环。真正有工程价值的,反而是双通道syscall hook(表改写与ftrace wrapper并存,覆盖新旧两代内核)和“删盘不死”的关机回写。

对蓝队,这个样本把“单一数据源不可信”演练得很完整:ls对stat、ps对kill -0、/proc/net/tcp对ss、lsmod对/sys/module,每一组对照都是一条独立的发现路径。

而对”提示词生成木马”这件事本身,两篇测评的结论是一致的:

AI 把”写出能编译的代码”的成本压到了分钟级,但它写的世界,是提示词作者见过的世界——内核换了分派机制、CPU 换了安全特性、发行版换了自启方式,它统统不知道。

门槛降低的是”能跑”,不是”能用”;而蓝队要防的,从来都是”能用”。

本文所有测试均在隔离的虚拟机靶场中完成,仅用于授权环境下的安全研究与防御检测研究。


免责声明:

本文所载程序、技术方法仅面向合法合规的安全研究与教学场景,旨在提升网络安全防护能力,具有明确的技术研究属性。

任何单位或个人未经授权,将本文内容用于攻击、破坏等非法用途的,由此引发的全部法律责任、民事赔偿及连带责任,均由行为人独立承担,本站不承担任何连带责任。

本站内容均为技术交流与知识分享目的发布,若存在版权侵权或其他异议,请通过邮件联系处理,具体联系方式可点击页面上方的联系我。

本文转载自:huasec 《对一款 Linux 木马开源提示词的测评》

评论:0   参与:  0