做应急响应的,半夜被电话叫起来是常态。登录机器跑几条命令,发现后门早就种下了,还是一个藏得挺深的后门。后门攻击检测、Rootkit、内存马、权限维持这堆词,平时挂在嘴边,真到现场往往会发现无从下手——该查哪里、先查什么、哪些异常是真的、哪些是系统自带的正常行为,没有一套清晰的思路就容易白忙活。这篇文章算是我这几年做应急响应的一个系统总结,核心就一件事:当你怀疑一台Windows或者Linux机器已经被打了后门,怎么一层层把它挖出来,怎么在几千个进程、一堆服务、无数启动项里找到那个异常点,并且给你一套能直接复现的排查顺序。适合刚接手安全运营或运维的工程师,也适合一个人扛整个公司安全、需要快速出排查模板的人。
1. 先搞清后门检测的底层逻辑,应急才不慌
1.1 攻击者为什么必须做权限维持
很多人有一个误区:觉得后门攻击就是“能连上去就行”。实际上攻进来的方式五花八门,可能是漏洞打进来的,可能是账号密码泄露,也可能是某个组件被供应链污染。攻击者很清楚,这些入口都不稳定,漏洞会被修、密码会被改、进程会被杀,所以真正成熟的攻击者在拿到权限之后,几乎一定会做权限维持(Persistence)。这一步的目的就是让机器在自己离开之后,还能把权限拿回来。
这也是为什么应急响应永远绕不开权限维持这个话题。你看到的“后门”只是表象,真正要回答的是两件事:攻击者用了什么机制让后门可以在重启之后还能存在,以及攻击者还能不能通过其他入口回来。如果不把持久化机制找干净,排查结果就是“明明把那个exe删了,第二天又检测到外连”,这不是玄学,是持久化没清干净。
我的理解是,后门攻击检测本质上就是“找变异点 + 找连接 + 找启动关联”。变异点指的是机器上所有与默认状态不一致的文件、进程、账户、服务;连接指的是进程对外建立的网络连接、监听的端口、以及隐藏在系统关键进程里的模块;启动关联则决定了这个后门能不能在下一次开机后继续存活。整个排查过程,就是围绕这三件事展开的。
1.2 四个关键词之间的关系
标题里的四个词,分开看都是独立概念,合起来其实是同一条攻击链上的四个阶段:
- 后门攻击:攻击者植入的、用于绕过正常认证或窃取数据的通道,这是最终效果。
- 权限维持:后门能够存活的技术保障,常见手法有启动项、计划任务、服务、动态库注入、账户克隆等。
- Rootkit:一种更底层的后门技术,通过替换内核组件、劫持系统调用或者挂钩系统函数,把进程、文件、端口甚至驱动本身隐藏起来。Rootkit的目标就是让上面那些后门“看不见”。
- 内存马:一种不落盘的恶意代码,直接运行在内存中,文件系统里没有对应文件,所以传统的杀毒软件和文件层面的查杀基本失效。
换句话说,权限维持是手段,后门是结果,Rootkit负责隐身,内存马负责避开文件检测。应急响应时,任何一个环节漏掉,都可能让整个行动白费。下面我会按平台来讲排查细节,先从Windows开始,因为大部分企业内网的服务器和办公终端都是这个系统。
2. Windows 后门检测:从启动项到内核,一层层过
2.1 启动项与服务排查:注册表、启动目录、系统服务
Windows下最常见的权限维持方式就是启动项。攻击者只需要把一个exe或者dll路径写进注册表的启动项,重启后脚本就会自动跑起来。所以应急排查第一步,永远是拉出所有启动项列表,逐个过。
注册表里重点看这几个位置:
# 当前用户和本机所有用户的 Run 键 reg query HKCU\Software\Microsoft\Windows\CurrentVersion\Run reg query HKLM\Software\Microsoft\Windows\CurrentVersion\Run reg query HKLM\Software\WOW6432Node\Microsoft\Windows\CurrentVersion\Run # RunOnce、RunServices 同样要看 reg query HKCU\Software\Microsoft\Windows\CurrentVersion\RunOnce reg query HKLM\Software\Microsoft\Windows\CurrentVersion\RunOnce reg query HKCU\Software\Microsoft\Windows\CurrentVersion\RunServices reg query HKLM\Software\Microsoft\Windows\CurrentVersion\RunServices除了注册表,启动目录也别漏掉:
dir "C:\ProgramData\Microsoft\Windows\Start Menu\Programs\StartUp" dir "$env:APPDATA\Microsoft\Windows\Start Menu\Programs\StartUp"然后看系统服务。服务比启动项更隐蔽,因为很多服务名看起来跟正常系统服务几乎一样,比如攻击者会把服务名写成Windows Update Service。用下面的命令把全部服务拉出来,重点看启动类型为自动、图片路径指向非系统目录的可疑exe:
sc query type= service state= all | findstr /i "SERVICE_NAME" wmic service get name,displayname,pathname,startmode | findstr /vi "C:\\Windows\\System32"服务排查有个细节,有的恶意服务会直接以regsvr32、rundll32、powershell作为执行体,路径很难一眼看出问题。我习惯把wmic输出导出到CSV,然后按pathname列排序,凡是启动一个正常程序却带了一长串参数的都要留意。
2.2 计划任务与WMI事件订阅:藏在“正常功能”里的后门
计划任务是我见过被利用最多的持久化机制之一。因为计划任务就是Windows自带的正常功能,很多管理员自己都记不全机器上有哪些计划任务,攻击者往里塞一个“每天晚上三点执行一次”的恶意任务,非常难发现。
用schtasks导出全部任务,并通过/v拿详细参数:
schtasks /query /fo LIST /v > tasks.txt然后重点看两个特征:任务名伪装成Windows系统更新、Office自动更新这类常规名字,以及任务执行的程序路径不在C:\Windows目录下。如果机器上装了第三方任务管理界面,也可以对比界面里能看到的任务数和命令行导出的任务数,一旦数量对不上,就有隐藏任务。
比计划任务更隐蔽的是WMI事件订阅。WMI的__EventFilter加上ActiveScriptEventConsumer或CommandLineEventConsumer,可以在特定事件发生时自动执行脚本,整个过程完全不需要落盘。排查指令如下:
Get-CimInstance -Namespace root/subscription -ClassName __EventFilter Get-CimInstance -Namespace root/subscription -ClassName __EventConsumer Get-CimInstance -Namespace root/subscription -ClassName __EventSubscription只要这三条命令返回了内容,就要警惕。正常机器通常是空的,除非业务团队自己做过WMI相关的自动化。配合事件ID看最后修改时间,如果时间点对上攻击事件,基本可以确认。
2.3 驱动加载与内核层的检查思路
普通后门在用户态,用杀毒软件扫一遍可能就出来了。但Rootkit这类后门会直接进内核,通过替换驱动或者挂钩系统调用,把恶意进程和文件藏起来。在用户态看到的进程列表是失真的,因为Rootkit已经帮你过滤掉了。
对于驱动层面,第一步是用系统命令列出所有驱动:
driverquery /v > drivers.txt分析时重点看:加载时间是不是攻击时间窗口,驱动路径是否在常见驱动目录之外,以及驱动文件中是否有数字签名异常。签名校验很重要,攻击者自制的Rootkit驱动通常没有有效签名,或者签名主体跟厂商对不上。
光看驱动列表还不够,真遇到高级Rootkit时,我会用ARK工具做内核对象检测。这类工具能枚举内核驱动、SSDT、IDT、Inline Hook等情况,一旦发现系统关键函数被挂钩,那基本上就是内核后门了。注意,ARK工具需要管理员权限运行,最好在断网环境下做,避免工具自身被Rootkit干扰。
2.4 进程、网络与文件的交叉验证
后门做再多隐藏,最终总要做坏事:连外、监听端口、启动恶意进程。所以进程和网络是两个必须交叉验证的维度。
进程侧,先把所有进程列出来,并记录每个进程的可执行路径:
wmic process get processid,creationdate,name,executablepath,parentprocessid重点关注几类进程:没有父进程或父进程异常的;可执行路径位于临时目录、回收站目录、或用户桌面下的;以及同时出现多个同名进程,但路径各不同。恶意进程为了让宿主进程看起来正常,经常挂到svchost、lsass、explorer下面,看到这些关键进程加载了不认识的dll,就要做模块检查。
网络侧,用netstat列出现在活着的连接和监听端口:
netstat -ano | findstr ESTABLISHED netstat -ano | findstr LISTENING拿到PID后用tasklist或wmic process反查是哪个进程。如果看到PID一直在变、进程名反复更换,但端口不变,多半是后门在做端口复用或者进程伪装。还有一种常见情况:攻击者直接复用正常进程的网络连接,比如svchost.exe对外连了一个非标准端口的高频连接,这要单独标记。文件侧再补充一下:按修改时间排序,找出最近7天内新增或变异的exe、dll、ps1、bat、vbs,尤其是放在Users目录或Temp目录下的。
到这里,Windows的基础排查就算完整地走了一遍:注册表、启动目录、服务、计划任务、WMI、驱动、进程、网络、文件。没有哪一步是可以跳过的,因为攻击者通常会同时用多种机制,防止一种被清掉后失联。
3. Linux 后门检测:账户、SSH、计划任务、内核一个都别放过
3.1 账户、SSH授权文件和sudo信任关系
Linux服务器的后门攻击,第一高发的位置就是SSH。攻击者拿到了root权限之后,最省事的持久化手段是把自己生成的公钥写进/root/.ssh/authorized_keys,这样他随时可以用自己的私钥重新登录,完全不用密码。因为公钥文件是文本,量又不一定很大,很容易被忽略。
先检查所有账户的异常变化:
# 查看UID为0的账户,正常情况下只应该有root awk -F: '$3==0{print $1" "$3}' /etc/passwd # 查看登录shell且口令为空的账户 awk -F: '($7=="/bin/bash"||$7=="/bin/sh"){print $1" "$7}' /etc/passwd # 查看最近是否新增过用户 ls -l --time-style=long-iso /etc/passwd /etc/shadow然后逐个检查SSH授权文件,不要只看root用户的:
find / -name authorized_keys -type f 2>/dev/null cat /root/.ssh/authorized_keys如果发现多出来的公钥,尤其是注释(公钥末尾的注释字段)写得像随机字符串的,直接判定为后门。再有,检查/etc/ssh/sshd_config,看内容是否被改动过,比如新增了AuthorizedKeysFile指向别的路径,或者开启了异常端口监听。
sudo信任关系也要查,/etc/sudoers和多处/etc/sudoers.d/下的文件都要读一遍,重点看是否有某个非root账户被配置成ALL=(ALL) NOPASSWD: ALL。
3.2 计划任务、systemd 与开机启动脚本
Linux下的权限维持,绕不开cron和systemd。攻击者最喜欢往crontab里写一条“每分钟执行一次某个脚本”,脚本内容可能只是从C2服务器拉一个二进制下来执行。查的时候不能只执行crontab -l,因为那只能看到当前用户的计划任务。
把所有计划任务相关位置都过一遍:
# 当前用户任务 + root任务 + 系统任务 crontab -l cat /var/spool/cron/crontabs/* 2>/dev/null cat /var/spool/cron/* 2>/dev/null cat /etc/crontab ls -la /etc/cron.d/ cat /etc/cron.d/* 2>/dev/null重点看脚本路径,凡是位于/tmp、/var/tmp、/dev/shm这种临时目录下的,都要打开读一遍内容。
systemd服务是这几年更常见的维持手法。攻击者会在/etc/systemd/system/下放一个自定义服务单元文件,服务名伪装成ssh.service或者network-health.service,执行指令指向恶意脚本。排查命令:
systemctl list-unit-files --type=service | grep enabled find /etc/systemd/system/ -name "*.service" -newer /etc/hostname开机启动脚本里,/etc/rc.local、/etc/rc*.d/、/etc/profile、/etc/bash.bashrc、/root/.bashrc、/root/.profile也是藏脚本的常规位置。攻击者经常在这些文件末尾追加一行nohup /tmp/x.sh &,不开文件根本发现不了。
3.3 动态库劫持与 LD_PRELOAD 排查
Linux下有一种非常隐蔽的后门,不写计划任务、不加启动项,而是通过LD_PRELOAD环境变量或者/etc/ld.so.preload文件,在程序启动时抢先把恶意共享库加载进去。这种后门的特殊性在于,它不产生独立进程,所有表现都在正常进程里。
下面的命令用来检查预加载配置:
# 查看环境变量和系统预加载文件 env | grep -i LD_PRELOAD cat /etc/ld.so.preload # 检查动态库依赖,看有没有可疑库 ldd /bin/ls ldd /usr/bin/sshd如果/etc/ld.so.preload文件存在且有内容,99%是后门。正常Linux环境这个文件基本是空的或者不存在。定位到可疑so文件后,用strings看里面的函数名和路径,如果出现connect、socket、read、getdents这些和系统调用重名的导出函数,那就是在做系统调用劫持,用来隐藏进程和文件。
需要警惕的是,被预加载的库通常不会直接暴露文件路径,有些恶意so会隐藏自身。所以查出来的可疑库不要急着删,先把它的内容、属性时间、关联进程记录下来,再交给取证工具分析。
3.4 内核模块、隐藏进程与文件系统异常
Linux上的Rootkit比Windows更常见,原因是开源内核给攻击者提供了更多参考代码,加载一个恶意内核模块只需要insmod一条命令。
内核模块排查:
# 查看当前加载的模块 lsmod cat /proc/modules # 查看模块文件路径,重点找不在标准目录下的 find /lib/modules/$(uname -r) -name "*.ko" -newer /boot 2>/dev/null判定恶意内核模块时,看模块名是否跟正常模块重名,以及模块加载时间是否和攻击时间吻合。更考究的做法是rkhunter和chkrootkit这类开源检测工具跑一遍,它们会对比系统已知干净库和当前库的哈希,提前发现被替换的ls、ps、netstat、sshd等核心命令。
再配合一个手动校验:把系统中的ps、ls、netstat和静态编译的干净工具对比执行结果,数量不一致就说明存在隐藏。看进程可以用unhide proc这类工具枚举/proc目录,绕过被挂钩的ps。看网络可以用ss -antp和lsof -i交叉,因为Rootkit能藏住netstat的输出,但一般藏不住所有用户的socket遍历。文件隐藏检测则用find / -mtime -7 -type f对比基线,找异常新增文件。
4. 内存马检测:文件系统里查不到,就要去内存里翻
4.1 内存马为什么难查
内存马这个词在Web攻击场景里出现频率非常高。攻击者向运行中的Web容器(比如Tomcat、Spring Boot应用)注入恶意类,恶意代码只存在于Java虚拟机的内存中,没有对应的jsp、jar或者class文件落盘。使用传统的Webshell查杀脚本扫描web目录,结果永远是干净的。
Windows环境下的无文件后门也是同样的道理,恶意脚本通过PowerShell内存加载,不落地文件直接执行。所以内存马检测的关键是换思路:从文件扫描切换到内存视角,从运行进程、类加载器、网络回连这三个角度去抓它的痕迹。
4.2 Java Web 内存马的排查思路
检测Java内存马,核心不是查Web目录,而是查JVM里加载了哪些不该有的类。
第一步,找到运行Web服务的Java进程:
ps -ef | grep java ss -antp | grep :8080拿到PID后,用JDK自带的jmap导出一个堆历史,看类加载情况:
jmap -histo:live <PID> | head -100 jcmd <PID> GC.class_histogram | grep -i "filter\|servlet\|listener\|handler"如果堆里出现大量异常命名空间的类,尤其是包名看起来像工具生成的随机字符,基本可以判定有内存马。再用jcmd <PID> VM.command_line和jcmd <PID> VM.system_properties确认启动参数和类路径是否存在可疑的-javaagent参数。
第二步,查类加载器。正常Web应用的类加载器数量是有限的,如果发现一个名叫URLClassLoader的自定义加载器,它加载的jar不在任何业务目录里,那就是恶意注入点。可以用开源的Java诊断工具在线上环境里直接查看类加载器树和动态代理类,不用改代码,非常实用。
第三步,配合访问日志。内存马和普通Webshell一样有触发路径。打开Web容器访问日志,搜索访问频率异常、路径奇怪的URL,尤其是带UUID、随机字符串、或者看起来像加密数据的参数。拿到可疑URL后,在JVM堆里搜这个URL字符串,如果命中某个类,就坐实了来源。
4.3 Windows 和 Linux 进程内的无文件攻击排查
非Java场景下的内存马,本质是无文件恶意代码加进程注入。
Windows侧,PowerShell是最常用的载体。点开事件查看器的PowerShell日志,筛选事件ID 4104(脚本块日志),凡是脚本内容里出现IEX、DownloadString、Base64解码的,都要重点分析。命令行侧也可以用Get-CimInstance Win32_Process看所有PowerShell进程的命令行参数,攻击者的恶意载荷通常会明文出现在参数里。
Linux侧,反弹shell是最典型的无文件后门。查找方式很直接:
# 查看所有启动的shell进程及其命令行 ps aux | grep -E "bash|sh|nc|ncat|python|perl|php" # 查看进程动态链接的异常库 cat /proc/<PID>/maps | grep -v "^[0-9a-f]*-[0-9a-f]* .* /"反弹shell进程往往还没有完整的环境,命令参数里会有/dev/tcp、/tmp/x这类特征。真正藏得深的会通过进程替换或者memfd_create方式运行,这时/proc/<PID>/exe链接会显示memfd:或者被删除的路径(后缀带(deleted)),看到这种符号就要立刻抓内存取证。
4.4 内存取证:从易失数据里固定证据
内存马再隐蔽,也摆脱不了易失性。进程一重启,内存里的恶意类就没了,这对攻击者来说是不便,但对我们来说也一样:如果不及时取证,证据也会跟着消失。
遇到过一会就重启的情况,我先不动主机,优先采集内存快照。Windows环境用内存采集工具导出一份raw文件,Linux环境用LiME模块或者直接利用/proc下的进程信息做有限拷贝。拿到快照后,用字符串搜索的方式快速定位指标:搜/dev/tcp、powershell -enc、恶意命令行的片段,再结合进程列表做关联分析。
这里也提醒一句,内存取证对时间要求极高,很多应急工程师的教训是“看到恶意进程就迫不及待杀”,结果证据没固定,进程马也被重启干掉了,后门倒是消失了,但攻击者是怎么进来的,还是不知道。
5. 权限维持检测专项:把隐藏账户和隐蔽机制翻个底朝天
5.1 Windows 隐藏账户、服务关联和组策略脚本
权限维持里,隐藏账户是我见过最脏的手段之一。攻击者创建了一个用户名后面带$的账户,这个账户在普通命令里不显示,但实际上拥有完整权限。
# 检查组策略里的所有账户 net user wmic useraccount get name,sid,disabled,localaccount # 通过WMI查看所有管理员组成员 wmic group where name="Administrators" get name,member发现可疑账户之后,对照它的SID和注册表信息。更隐蔽的玩法是RID劫持,攻击者把普通账户的RID改成管理员的RID,这样即使你在net user里看到它只是一个普通用户,实际权限却是管理员。检测方法是调出注册表HKLM\SAM\SAM\Domains\Account\Users,逐个对比某个账户的RID是否跟管理员重复。不过这条路需要系统权限,现场如果条件受限,更稳妥的做法是优先检查账户的建户时间和最近修改时间。
另外,Windows域环境中,权限维持还经常出现在组策略启动脚本里。打开本地组策略编辑器,看“计算机配置-设置-脚本-启动”下有没有被塞入异常脚本;域控上还要检查行政容器里的AdminSDHolder对象,攻击者修改它后,每60分钟会强制重置所有受保护组的ACL,把自己重新加回管理员组。
5.2 Linux 后门账户、公钥与风险配置
Linux侧的权限维持,账户层面常见的有三种:新增一个看似无害的普通用户但UID为0;修改已有账户的shell为可登录shell;在某个高权限服务的配置文件里加上信任公钥。
排查命令可以合并成一条脚本执行:
# 列出所有可登录用户,并看最近修改时间 getent passwd | awk -F: '$3>=1000{print $1" "$3" "$6" "$7}' # 查看所有账户的SSH公钥 find /home /root -name authorized_keys -newer /etc/passwd 2>/dev/null # 检查空白口令账户 awk -F: '($2==""){print $1}' /etc/shadow还有一类很隐蔽的做法,攻击者在/etc/shadow里把某个账户的口令哈希字段直接改成已知哈希,这样即使管理员改了密码,攻击者用旧哈希仍然可以重新登录。这个问题仅靠passwd命令察觉不了,得比对DHCP审计记录或者定期做账户基线。
5.3 从清理痕迹反推权限维持的存在
有一个容易被忽略的指标:日志里留下了清理痕迹。攻击者在完成权限维持后,通常会用history -c清空bash历史,或者删掉/var/log/secure某几行,此时会造成日志空洞或者历史文件间不连续的时间戳。这些清理动作本身,就是一条线索。
发现历史记录被清理后,多问一句“为什么要清理”。配合排查who、last、lastlog的记录,看是否有攻击者从某个IP登录过但后面被删掉。还可以用文件系统取证工具扫描未分配空间中残留的命令历史,往往能恢复出攻击者执行过的完整命令序列,这比单纯心理博弈更有价值。
6. 从告警到闭环:一套能直接用的应急响应流程
6.1 隔离与证据保全:先保现场,再谈排查
不少应急现场被搞成一团乱麻,根源在于一开始没有稳住节奏。告警触发后,第一件事不是登录机器一顿操作,而是先把机器从网络中隔离出来。可以拔网线,也可以只断开外联保留内网,但要记住:断网之前,先采集现场数据。
需要保下来的证据至少包含:当前时间、所有活动网络连接、所有运行进程、登录用户列表、计划任务列表。用命令把这些输出到文件,文件名带上时间戳,然后连同对应的进程dump、内存镜像一起归档。这一步做完,后面的排查才有凭据。
6.2 时间线重建与日志关联:让攻击流程现形
证据保全之后,最快的切入点是时间线。先问自己三个问题:这台机器最后一次正常是什么时候?告警第一次出现是什么时候?两者之间有没有账户登录、服务安装、文件变化的记录?
Windows侧重点看安全日志的事件ID:4624表示登录成功,4625表示失败,7045表示安装了新服务,4720表示创建新账户。把这些时间点串起来就能看出攻击者的完整路径。Linux侧重点看/var/log/secure或/var/log/auth.log里的SSH登录记录、/var/log/cron里的计划任务执行记录、以及/var/log/messages里的系统异常。
对着时间线,把前面所有排查维度按时间过滤,只保留与时间线重叠的可疑项。一个诡异的现象是:很多攻击事件刚开始并没有直接证据,只有时间线重叠之后,原本看着正常的东西才开始露出破绽。
6.3 逐层清除与加固:处理要彻底,动作要留痕
确认后门和持久化机制之后,清除顺序有讲究。建议按“账户—启动项—进程—文件—内核”顺序来:先删除攻击者创建的账户和信任公钥,防止清除过程中攻击者远程连回来;再清除计划任务、服务、注册表项,让后门失去自启动能力;最后杀进程、清文件。Rootkit类后门因为可能挂钩了内核,清除前需要先在安全模式下(或者使用可靠的可信工具)完成内核对象检查,再考虑卸载模块。
清除过程每一步都记录到处置单里,命令、时间、结果都留底。加固定向明确:凡是攻击路径里涉及的边界设备、中间件、数据库、同一批密码的服务器,都纳入整改范围,只重置一台机器的密码等于白做。更新被利用组件的版本、收紧对外暴露的端口、开启必要的登录告警,这些工作要当场安排,不然后面大概率复发。
6.4 复盘报告怎么写才有价值
复盘报告不应该是“我们发现了一个木马,删除了一个木马”这种流水账。有价值的报告应该能回答:攻击入口是什么、用了哪个漏洞或哪组泄露的凭据、用什么方式做的权限维持、存在了多长时间、影响面有多大、哪些证据支持这些判断、加固动作是否阻断了所有已知路径。
而且复盘报告要能指导后续检测。比如这次攻击用到的是计划任务,那报告里就明确写“全网范围内排查计划任务,重点看伪装成系统服务的任务名”,这样其他主机可以拿着这份报告做自查。
7. 实战避坑:这些坑我都踩过,提前帮你趟过去了
7.1 常见误区:为什么你查了半天还是漏
第一个误区是只杀进程不查持久化。很多人看到恶意进程就立刻kill,结果进程是没了,但攻击者的持久化机制还完好无损,过几个小时进程又被拉起来。正确的思路是先找启动关联,找到之后再让进程死掉。
第二个误区是只查文件不查内存。遇到内存马就会懵,因为跑了一遍文件系统扫描全绿。这也是我为什么在前面反复强调,检测雷达必须覆盖内存维度,尤其是Web应用目录里找不到文件,但网络行为明显异常的Java进程。
第三个误区是忽略了伪装成正常系统功能的恶意对象。计划任务名叫Microsoft\Windows\Update你就不看了,服务名叫Windows Update Service就以为是系统服务,这正中攻击者下怀。任何启动项和服务,都要看实际执行体,不看显示名。
第四个误区是清理Rootkit时直接删文件。很多Rootkit模块一旦被检测到,就直接把内核模块卸载再删文件,但如果模块之间有保护机制,直接动文件可能引发蓝屏或者系统崩溃,取证证据也会丢。需要先完整分析模块的插入点,再稳妥处置。
7.2 常见问题速查表
症状|可能原因|优先排查命令/方向主机时不时向外发起大量连接,但找不到源头进程 | Rootkit隐藏进程 | 对比ps与/proc枚举、用可信工具列全部进程 SVCHOST对应进程内存占用异常升高 | 恶意dll注入 | 检查svchost加载的dll清单、使用进程模块检查工具 Java进程CPU居高不下且出现大量新网络连接 | Java内存马 | jmap查堆中异常类、jcmd查类加载器、分析Web访问日志 Linux机器重启后出现一个新SSH连接 | 公钥后门 / 计划任务 | 检查authorized_keys、crontab、systemd服务 访问的网站页面有时被插入异常脚本 | Web层后门/内存马 | 分析Web日志URL轨迹、查JVM内存、对比源文件哈希 netstat看不到监听端口,但外部能访问服务 | 防火墙层后门/Rootkit | 内核模块检测、ss命令交叉验证、抓包确认
7.3 我自己的几个独家习惯
第一,排查之前先做一次完整基线快照。每次应急都先把进程、网络、启动项、计划任务这些关键信息导出,然后才动任何东西。这样做的好处是后面每个步骤都能对照前一步,哪里变化了都能看到,也不怕误操作。
第二,遇到同版本正常机器先借用来做对比。运维环境里找一台同系统版本、同应用版本、没中招的机器,把两边llist、计划任务、服务列表对比一下,异常项会非常明显。这个方法比对着几十页命令输出硬猜高效得多。
第三,所有怀疑对象先记录再判断,不在命令里直接删。哪怕一个文件看起来像废话,也先把它hash保存下来再动手。只要把处置的每一个决策点都记录在案,即使判断错了,也能通过记录找回现场,不会把自己带入更混乱的境地。
搞应急响应干久了,我最大的体会是:后门攻击检测本质上不是在跟恶意代码作斗争,而是在跟攻击者的时间赛跑和覆盖赛跑。攻击者比你多做一步隐藏、多设一层维持机制,你要做的就是比他多一步排查、多一层验证。最后再分享一个很多人不看重的细节:防御侧的演练一定要定期做。平时在测试环境模拟几轮后门排查,把各环节命令跑熟,真到半夜告警响起来,你才有底气在最短时间内把问题按下去。