题目背景
靶场信息
- 平台:棉花糖靶场 环境:Ubuntu 22.04 LTS 凭据:
root / P@ssw0rd - 参考:(https://mp.weixin.qq.com/s/cMj5vZqF4hBSeMSmqpSqZw)
你是一名初级安全工程师。运维团队报告:一台核心开发服务器 CPU 使用率异常飙高触发告警,安全设备同时检出该服务器存在外联挖矿行为。需要你登录服务器完成排查与处置,并找出事件根源。
任务清单
| # | 任务 | flag 格式 |
|---|---|---|
| 1 | 提交挖矿文件的绝对路径 | flag{/xxx/xxx} |
| 2 | 提交挖矿文件外联的 IP 与端口 | flag{ip:port} |
| 3 | 停止挖矿进程并删除挖矿程序,提交守护进程脚本的绝对路径 | flag{/xxx/xxx/xxx/xxx} |
| 4 | 以人为本,用环境内浏览器访问 http://chat.internal-dev.net:8081,获取可疑网址 | flag{http://...} |
| 5 | 分析病毒文件,按病毒文件中的顺序提交其感染的所有程序 | flag{md5(...)} |
| 6 | 用 /deb_final 下的离线 deb 包恢复被感染程序,随后读取 /var/flag/1 | — |
| 7 | 删除挖矿程序、计划任务、守护进程并清除相关进程,读取 /var/flag/2 | — |
背景知识:挖矿木马靠什么暴露自己
安全设备并不认识”挖矿”这个抽象概念,它抓的是行为特征:
- 对外连接:挖矿的本质是向矿池证明工作量,进程必须持续与矿池通信(领取任务、提交结果),因此一定会主动发起出网连接,且矿池通信协议(如 Stratum)的报文格式相对固定,流量侧有特征可抓。
- 资源占用:没有 GPU 的服务器只能靠 CPU 算力挖矿,”CPU 占用异常”因此成为最经典的告警来源。但如今的挖矿木马大多学乖了——不再吃满 CPU,而是限制线程数、控制占用比例,模仿正常业务负载,用”细水长流”的方式躲避阈值类告警。
- 其他强特征:在
/tmp等临时目录释放文件、把进程名伪装成内核线程(如kworker*)、感染系统命令实现持久化、写入计划任务等,都是可以叠加佐证的线索。
任务 1:定位挖矿程序
上机排查第一步,先看资源占用。直接敲 top,结果输出为空:

命令”不对劲”时,先想想这条命令的执行链路有没有被劫持,常见可能性有三类:
- 别名劫持:shell 配置里被写入了
alias top=...,执行 top 时实际运行的是别名指向的内容; - PATH 劫持:系统按
$PATH顺序查找 top,如果攻击者把/tmp之类靠前的目录插进 PATH,并放一个同名假程序,执行的就是假的; - 二进制被感染:top 本体被篡改,原有功能之外附加了恶意逻辑。
先从最容易验证的别名下手,用 alias 一查,发现 top 确实被设置了别名——别名实际的效果就是让输出为空:

unalias top
恢复后 top 正常工作,看到一个可疑进程 kworkerds 占用 24.8% CPU:
357 root 20 0 19072 1092 1092 S 24.8 0.0 18:32.54 kworkerds

两点观察:
- 24.8% 这个数字在”业务正常波动”的边缘,很容易被放过。现在的挖矿木马普遍不再吃满 CPU,低占用慢速挖矿是主流,因此任何来历不明的持续占用都值得追;
- 进程名
kworkerds在模仿内核工作线程kworker/0:0这类命名,让人在ps里扫一眼就滑过去。
接下来顺着 PID 定位可执行文件的真实位置:
lsof -p 357
# 列出 PID 357 打开的所有文件/资源:可执行文件本身、工作目录、加载的库、socket 等

输出显示该进程对应的程序位于 /tmp/kworkerds——正常系统进程不应该住在 /tmp,基本可以锁定。
再用 strings 提取二进制里的可读字符串,了解它的性质:
root@solar-abc:~# strings /tmp/kworkerds
/dev/null
/tmp/kworkerds.pid
{"id": 1, "method": "login", "params": {"login": "%s", "pass": "x", "agent": "%s"}}
JxCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`\]^_`abcdefghij
9*3$"
KJNTHKTLTCC
GCC: (Ubuntu 13.3.0-6ubuntu2~24.04) 13.3.0
逐条解读:
/tmp/kworkerds.pid:PID 文件写在/tmp——权限宽松、任何人可写,是恶意程序偏爱的落点;{"id":1,"method":"login",...}:一段 JSON 登录报文,字段结构与矿池通信常用的 Stratum 协议握手一致(login/pass/agent),说明程序会主动连接矿池;JxCDEFGH...与KJNTHKTLTCC:两串疑似经过异或等编码处理的乱码,形态像被加密的钱包地址或运行时配置(这点在任务 2 解释”沙箱查不出外联”时会再次呼应);setsid / fork / umask / dup2 / /dev/null:标准的守护进程化套路——脱离终端、后台常驻、输出重定向到黑洞,目的就是隐藏自己;pthread_create / pthread_join:多线程,用于并发挖矿/发包;GCC: (Ubuntu 13.3.0...):攻击者自行编译的产物,而非发行版官方二进制。
综合 CPU 占用、/tmp 落点、伪装进程名、矿池握手报文等特征,可以判定该文件就是挖矿程序本体。
[!success] Flag
flag{/tmp/kworkerds}
任务 2:揪出外联的矿池地址
先走捷径:在线沙箱。 把样本提交到微步、360 等沙箱,结果没有报出任何外联 IP 和端口。结合 strings 里那两串疑似加密的乱码推测:通信配置(矿池地址)是运行时才解密的,静态提交样本自然查不出。捷径走不通,回到主机上看真实连接。
方法一:ss 查看当前 TCP 连接
ss -tanpan | grep "kworker"
# -t 只看 TCP;-a 同时列出监听与非监听;-n 不做反解,直接显示 IP:端口;-p 显示占用连接的进程

方法二:lsof 顺着进程看 socket
lsof -p <PID>

两种方式都拿到了外联地址。
[!tip] 如果 ss 一时抓不到
挖矿程序和 C2 一样往往带”心跳”机制:每隔一段时间连一次、传完就断。这样一是避免长连接被流量设备盯上,二是矿池任务本身就是短交互(领取任务→提交结果)。抓不到时多执行几次 ss,或者用 tcpdump 在后台挂抓包,等它下一次上线。另外实战中不要为了抓包主动去运行样本触发外联——生产环境可能影响业务,勒索类样本尤其如此。
[!success] Flag
flag{104.21.6.99:10235}
任务 3:删不掉的木马——挖出守护机制
任务要求:停止挖矿进程、删除挖矿程序,然后找出让它”复活”的守护脚本。
root 也删不掉文件。 直接动手:
root@solar-abc:/tmp# rm -rf /tmp/kworkerds
rm: cannot remove '/tmp/kworkerds': Operation not permitted
root 权限报 Operation not permitted,第一反应是文件被加了不可变锁。查扩展属性:
root@solar-abc:/tmp# lsattr /tmp/kworkerds
--------------e------- /tmp/kworkerds
只有 e(extent 格式,ext4 的正常属性),没有 i(immutable)也没有 a(append-only),排除 chattr 锁文件。
那剩下的解释就只有一个:rm 命令本身被动了手脚,这条报错是它伪造的,不是内核给的。 这个猜想稍后会在任务 4、5 得到实锤——病毒主程序里就藏着 rm: cannot remove '%s': Operation not permitted 这个格式化字符串。
用 busybox 绕过被感染的系统命令。 busybox 是把常用 Linux 命令全部内置的静态多合一工具,它的 rm 是自己实现的,完全不经过系统的 /bin/rm,所以拦截不了:
root@solar-abc:/tmp# ./busybox rm -rf /tmp/kworkerds
root@solar-abc:/tmp#
删除成功。但没过多久再看,文件又回来了:
root@solar-abc:/tmp# ls
busybox
dbus-Zk83EsFUni
kworkerds
删得掉又原地复活,说明存在自动 resurrect 机制,往两个方向排查:
- 计划任务:定时把挖矿文件写回来;
- 被感染的系统命令:命令在执行时”顺手”检查并重新释放挖矿程序。
排查计划任务。 先看用户级 crontab:
root@solar-abc:/tmp# crontab -l
no crontab for root
root 没有用户级定时任务。再看系统级 cron:
[!example]-
/etc/crontab全文(均为系统默认,无异常)SHELL=/bin/sh 17 * * * * root cd / && run-parts --report /etc/cron.hourly 25 6 * * * root test -x /usr/sbin/anacron || { cd / && run-parts --report /etc/cron.daily; } 47 6 * * 7 root test -x /usr/sbin/anacron || { cd / && run-parts --report /etc/cron.weekly; } 52 6 1 * * root test -x /usr/sbin/anacron || { cd / && run-parts --report /etc/cron.monthly; }
/etc/crontab 干净,继续翻 /etc/cron* 下的各个目录。这些目录里的脚本会分别按分钟/天/周/月周期执行,作用类似 Windows 的计划任务。逐个过的时候重点比对时间戳和文件名是否属于已知软件包:
[!example]-
ls -la /etc/cron*完整输出-rw-r--r-- 1 root root 1136 Mar 31 2024 /etc/crontab /etc/cron.d: total 40 drwxr-xr-x 2 root root 4096 Sep 22 2025 . drwxr-xr-x 148 root root 12288 Oct 13 2025 .. -rw-r--r-- 1 root root 35 Sep 22 2025 0guardian -rw-r--r-- 1 root root 219 Nov 17 2023 anacron -rw-r--r-- 1 root root 201 Apr 8 2024 e2scrub_all -rw-r--r-- 1 root root 712 Jan 19 2024 php -rw-r--r-- 1 root root 102 Mar 31 2024 .placeholder -rw-r--r-- 1 root root 396 Jan 10 2024 sysstat /etc/cron.daily: total 52 drwxr-xr-x 2 root root 4096 Oct 3 2025 . drwxr-xr-x 148 root root 12288 Oct 13 2025 .. -rwxr-xr-x 1 root root 311 Sep 25 2023 0anacron -rwxr-xr-x 1 root root 376 Oct 26 2024 apport -rwxr-xr-x 1 root root 1478 Mar 22 2024 apt-compat -rwxr-xr-x 1 root root 595 Feb 25 2020 debsums -rwxr-xr-x 1 root root 123 Feb 5 2024 dpkg -rwxr-xr-x 1 root root 377 Apr 9 2024 logrotate -rwxr-xr-x 1 root root 1395 Mar 30 2024 man-db -rw-r--r-- 1 root root 102 Mar 31 2024 .placeholder -rwxr-xr-x 1 root root 518 Jan 10 2024 sysstat /etc/cron.hourly: total 20 drwxr-xr-x 2 root root 4096 Feb 15 2025 . drwxr-xr-x 148 root root 12288 Oct 13 2025 .. -rw-r--r-- 1 root root 102 Mar 31 2024 .placeholder /etc/cron.monthly: total 28 drwxr-xr-x 2 root root 4096 Sep 17 2025 . drwxr-xr-x 148 root root 12288 Oct 13 2025 .. -rwxr-xr-x 1 root root 313 Sep 25 2023 0anacron -rwxr-xr-x 1 root root 597 Feb 25 2020 debsums -rw-r--r-- 1 root root 102 Mar 31 2024 .placeholder /etc/cron.weekly: total 32 drwxr-xr-x 2 root root 4096 Sep 17 2025 . drwxr-xr-x 148 root root 12288 Oct 13 2025 .. -rwxr-xr-x 1 root root 312 Sep 25 2023 0anacron -rwxr-xr-x 1 root root 596 Feb 25 2020 debsums -rwxr-xr-x 1 root root 1055 Mar 30 2024 man-db -rw-r--r-- 1 root root 102 Mar 31 2024 .placeholder /etc/cron.yearly: total 20 drwxr-xr-x 2 root root 4096 Feb 15 2025 . drwxr-xr-x 148 root root 12288 Oct 13 2025 .. -rw-r--r-- 1 root root 102 Mar 31 2024 .placeholder
一对比就很明显:只有 /etc/cron.d/0guardian 的修改时间是 2025 年 9 月,和周围系统文件(2023~2024)明显不符,而且这个名字不属于任何正常软件包:
root@solar-abc:/tmp# cat /etc/cron.d/0guardian
* * * * * root /usr/bin/.0guardian
每分钟执行一次 /usr/bin/.0guardian(注意是个以 . 开头的隐藏文件)。看脚本内容:
root@solar-abc:/tmp# cat /usr/bin/.0guardian
#!/bin/bash
# Guardian Script: Periodically triggers an infected command
# to ensure the core service is checked and revived if needed.
/usr/bin/stat /tmp > /dev/null 2>&1
脚本本体只有一个动作:以 /usr/bin/stat /tmp 的方式调用 stat,输出丢弃。stat 不是查文件时间戳的吗?每分钟对 /tmp 这个目录 stat 一次图什么?
验证 stat 的异常。 查正常文件时输出完全正常:
root@solar-abc:/tmp# stat /etc/passwd
File: /etc/passwd
Size: 2951 Blocks: 8 IO Block: 4096 regular file
Device: 8,2 Inode: 946669 Links: 1
Access: (0644/-rw-r--r--) Uid: ( 0/ root) Gid: ( 0/ root)
Access: 2026-10-03 17:55:51.960999745 +0800
Modify: 2025-10-09 10:22:52.617054836 +0800
Change: 2025-10-09 10:22:52.617054836 +0800
Birth: 2025-10-09 10:22:52.616611637 +0800
但一旦查到木马相关路径,stat 就保持沉默——不报错、无输出:
root@solar-abc:/tmp# stat /tmp/kworkerds
root@solar-abc:/tmp# stat /etc/cron.d/0guardian
root@solar-abc:/tmp#
结论:stat 被感染后在原有功能之外附加了一套”黑名单”逻辑——涉及自身利益的路径拒绝显示;而被守护脚本以 /tmp 为参数调用时,则转入隐藏的检查流程:挖矿程序还在吗?进程活着吗?缺了就补。这正是守护脚本每分钟调用它的意义。
整条复活链路如下:
flowchart LR
A["crond 每分钟触发"] --> B["/usr/bin/.0guardian<br/>守护脚本"]
B --> C["被感染的 /usr/bin/stat /tmp"]
C --> D{"挖矿程序存在?<br/>进程存活?"}
D -- "都在" --> E["静默退出"]
D -- "缺了" --> F["重新释放 /tmp/kworkerds<br/>并拉起挖矿进程"]
[!success] Flag
flag{/usr/bin/.0guardian}
任务 4:从”人”找突破口——溯源感染入口
任务要求”以人为本”:用环境内浏览器访问 http://chat.internal-dev.net:8081。
漏洞利用并不是木马进来的唯一路径,很多事件的起点只是一次疏忽——通过捆绑安装包、钓鱼链接投递的银狐木马就是这类典型。这道题把入口埋在了”人”身上:用环境内浏览器打开那个内网聊天站,结合聊天记录逐个排查询问——有人表示从没碰过那台机器,有人当天请假,有人执行的脚本经核实只是查看进程状态的运维脚本,最终锁定到一位同事:因为急着处理问题,从 Google 搜索结果里直接下载了一个”日志排查工具”,没有核实是否官方渠道。追问下载来源,得到可疑网址:http://www.superlog-pro.com。
顺带看了一眼那个下载页面:排版正规、几乎看不出破绽。这正是仿冒站点的迷惑性所在——攻击者会刻意把页面做得和官方一样,等的就是不核实的访问者。
把该员工下载的工具拿来做静态分析,先 strings 看字符串:


这份字符串信息量很大,多个独立线索在此汇合:
- 有日志打印类字符串,符合”日志排查工具”的伪装人设;
- 出现了守护脚本的内容、挖矿文件路径
/tmp/kworkerds、守护脚本/usr/bin/.0guardian、计划任务文件0guardian——与前面排查到的落点一一对应; - 出现
rm: cannot remove '%s': Operation not permitted——正是任务 3 删除失败时看到的报错。%s是格式化占位符,说明这条”报错”是病毒自己实现的,坐实了 rm 被感染、删除失败是伪造的; - 另有多处与 stat 相关的字符串,对应 stat 的”黑名单”异常行为。
一个”日志工具”的字符串里藏着木马全家桶的路径和伪造报错,可以认定:这就是本次事件的病毒主程序(投递器),运行逻辑留待任务 5 逆向。
[!success] Flag
flag{http://www.superlog-pro.com}
任务 5:逆向确认感染清单
任务要求分析病毒文件、按病毒文件中的顺序提交其感染的所有程序(题干中的 flag{md5(/usr/bin/whoai,...)} 只是格式示意,并非真实答案)。
IDA 打开病毒主程序,从 main 函数 F5 进入伪代码:

main 中引用了 sub_1670,跟进去:

sub_1670 引用了字符串表 off_3CA8,双击过去——这就是病毒要感染的目标列表:

.data.rel.ro:0000000000003CA0 dq offset name ; "/bin/ls"
.data.rel.ro:0000000000003CA8 off_3CA8 dq offset aBinPs ; DATA XREF: sub_1670+52↑o
.data.rel.ro:0000000000003CA8 ; "/bin/ps"
.data.rel.ro:0000000000003CB0 dq offset aBinCat ; "/bin/cat"
.data.rel.ro:0000000000003CB8 dq offset aBinRm ; "/bin/rm"
.data.rel.ro:0000000000003CC0 dq offset aBinSs ; "/bin/ss"
.data.rel.ro:0000000000003CC8 dq offset aUsrBinStat ; "/usr/bin/stat"
.data.rel.ro:0000000000003CD0 dq offset aUsrBinTop ; "/usr/bin/top"
.data.rel.ro:0000000000003CD8 dq offset aUsrBinWget ; "/usr/bin/wget"
.data.rel.ro:0000000000003CE0 dq offset aUsrBinCurl ; "/usr/bin/curl"
.data.rel.ro:0000000000003CE8 dq offset aUsrBinVi ; "/usr/bin/vi"
.data.rel.ro:0000000000003CF0 dq offset aUsrBinSudo ; "/usr/bin/sudo"
共 11 个程序:/bin/ls、/bin/ps、/bin/cat、/bin/rm、/bin/ss、/usr/bin/stat、/usr/bin/top、/usr/bin/wget、/usr/bin/curl、/usr/bin/vi、/usr/bin/sudo。
逆向前的常规动作:先用 DIE 之类的工具确认样本未加壳、为 C 语言编写,这样可以直接从 main 入口 F5 审计,省去脱壳环节。
感染机制还原——这正是”特洛伊”之名的由来:
- main 入口:先循环打印伪造的”日志工具”输出维持伪装,随后进入核心逻辑;
sub_1670(感染函数):遍历off_3CA8中硬编码的目标命令列表(相比借助寄存器地址注入恶意代码的方式,硬编码列表实现简单、成功率高),对每个目标文件:把原文件内容读入内存 → 新建同名文件,依次写入原程序内容 + 恶意自检代码(检查挖矿进程/文件是否存在,即 unk_7900 那段)+ 挖矿程序本体 + 附加数据——效果类似echo 原程序 恶意代码 挖矿程序 > 原程序。被感染的命令外观和原有功能完全不变,只是暗地里多了一套”复活”逻辑;sub_18F0(持久化函数):负责写入计划任务/etc/cron.d/0guardian与守护脚本/usr/bin/.0guardian;- 收尾:主程序按自身文件名完成自删除,抹掉落地痕迹,加大溯源难度。
[!info] 前面的异常全部对上了
rm 删不掉(伪造报错)、stat 装哑巴(黑名单逻辑)——病毒把”我还在吗”的自检逻辑塞进这些运维每天要敲的命令里,等于借管理员的手保护自己。
把列表按病毒文件中的顺序拼接后取 MD5 提交(题目要求顺序以病毒文件中为准):
[!success] Flag
flag{dac48e98a53b81b0218e2156e364f7ba}
任务 6:离线修复系统
任务要求:用 /deb_final 下的离线 deb 包恢复所有被感染的程序,恢复后读取 /var/flag/1。
这里有两层原因决定了必须离线修:
- 服务器中招后的处置原则就是先断网——防止横向移动和二次感染;
- 任务 5 的逆向结果显示 wget 本身就在感染名单里,此时任何在线下载都不可信,apt 在线更新这条路不能走。
查看题目准备的官方离线包:
root@solar-abc:/deb_final# ls /deb_final/
coreutils_9.4-3ubuntu6.1_amd64.deb
iproute2_6.1.0-1ubuntu6.2_amd64.deb
procps_2%3a4.0.4-4ubuntu3.2_amd64.deb
sudo_1.9.15p5-3ubuntu5.24.04.1_amd64.deb
vim-tiny_2%3a9.1.0016-1ubuntu7.9_amd64.deb
wget_1.21.4-1ubuntu4.1_amd64.deb
包与感染名单正好一一对应:coreutils 管 ls/cat/rm,iproute2 管 ss,procps 管 ps/top,再加上 sudo、vim-tiny(vi)、wget。强制覆盖安装:
dpkg -i --force-overwrite *.deb
# -i 安装;--force-overwrite 遇到文件冲突时直接覆盖,用于把被篡改的二进制换回干净版本
修复完成后读取 flag:
root@solar-abc:/deb_final# cat /var/flag/1
flag{e510c5fca680b1b4bd5c9d8d6b3f4bdc}
顺手验证修复效果:stat 已恢复正常,现在能正常查看守护脚本的信息了。
root@solar-abc:/deb_final# stat /etc/cron.d/0guardian
File: /etc/cron.d/0guardian
Size: 35 Blocks: 8 IO Block: 4096 regular file
Device: 8,2 Inode: 974330 Links: 1
Access: (0644/-rw-r--r--) Uid: ( 0/ root) Gid: ( 0/ root)
Access: 2026-10-03 17:55:57.066999607 +0800
Modify: 2025-09-22 14:37:11.971534819 +0800
Change: 2025-09-22 14:37:11.971534819 +0800
Birth: 2025-09-22 14:37:11.971418529 +0800
[!success] Flag
flag{e510c5fca680b1b4bd5c9d8d6b3f4bdc}
任务 7:斩草除根——最终清理
系统命令恢复干净后做最终清理。盘点全部遗留项:
- 挖矿程序本体
/tmp/kworkerds(及其 pid 文件) - 挖矿进程
- 计划任务
/etc/cron.d/0guardian - 守护脚本
/usr/bin/.0guardian
rm -rf /tmp/kw* # 挖矿程序与 pid 文件
kill -9 <PID> # 杀挖矿进程(PID 以当前实际为准;进程可能已被守护脚本重新拉起,PID 会变)
rm -rf /etc/cron.d/0guardian
rm -rf /usr/bin/.0guardian
四项全部清掉后读取 flag:
root@solar-abc:/tmp# cat /var/flag/2
flag{081ce3688c6cd6e2946125081381087c}
[!success] Flag
flag{081ce3688c6cd6e2946125081381087c}
[!warning] 为什么重启没用
如果只杀进程、只删挖矿程序,重启是无效的:常用命令仍被感染,计划任务每分钟都会调用守护脚本去执行被感染的 stat,发现程序/进程缺失就重新释放拉起——形成事实上的死循环。处置的终点不是”看不到异常”,而是复活链路被彻底切断。
复盘:完整攻击链
flowchart TD
A["员工经搜索引擎下载<br/>伪装成日志工具的 setup"] --> B["运行 setup,病毒主程序落地"]
B --> C["感染 11 个常用系统命令<br/>附加自检/守护逻辑"]
B --> D["释放挖矿程序 /tmp/kworkerds<br/>伪装内核线程名"]
B --> E["写入计划任务 /etc/cron.d/0guardian<br/>+ 隐藏守护脚本 /usr/bin/.0guardian"]
D --> F["低占用挖矿<br/>心跳式外联矿池"]
C --> G["每分钟自检:<br/>程序/进程缺失则重新释放并拉起"]
E --> G
G --> F
几个环节的设计意图:
- 感染系统命令而不只是放一个挖矿程序:把存活检查塞进运维每天要敲的命令里,配合计划任务形成闭环,单纯删文件、杀进程、重启都跳不出去;而且不止守护脚本会触发自检——管理员平时每次执行这些被感染的命令,都会顺带跑一遍检查逻辑,等于全公司的人都在无意中帮木马”续命”;
- 低占用 + 心跳外联:资源上不触发阈值告警,网络上是间歇连接,规避流量检测,也让沙箱静态分析拿不到矿池配置;
- 伪造报错与黑名单:rm 的假报错、stat 的装聋作哑,都是为了在排查者面前隐身,拖延溯源。
经验沉淀
- 怀疑你的工具:命令输出不对劲时,先验证命令本身——
type/alias查别名 → 绝对路径执行绕过别名和 PATH → busybox 等静态工具兜底——再怀疑系统本身; - root 删不掉文件 ≠ 一定是 chattr 锁:
lsattr只能证明属性正常,不能证明命令干净;也可能是命令被感染、报错是伪造的; - 抓外联要多采样:心跳式外联需要多执行几次
ss/lsof,或用 tcpdump 挂后台等它上线;配置加密的样本在沙箱里也跑不出通信地址; - 持久化排查清单:用户 crontab、
/etc/crontab、/etc/cron.*、systemd timer(systemctl list-timers --all)、/etc/rc.local、用户 shell 配置文件;其中比对文件时间戳往往一眼锁定异类; - 恢复走离线官方包:连 wget 都可能被感染,在线修复不可信;
dpkg -i --force-overwrite适合覆盖被篡改的包文件,之后可用debsums/dpkg -V验证完整性; - 应急不止查机器:从 IM 沟通记录、软件下载来源等”人的行为”找入口,常常比在主机上继续抠细节更快;
- 清理要成体系:进程、文件、计划任务、守护机制、被感染的命令,缺一项都会死灰复燃。