Skip to content

16a|安全排查与应急:被攻了怎么查

上一篇做了加固,让机器更难被攻。但安全没有绝对——漏洞会出现、配置会漂移、人会被钓鱼。真怀疑机器被入侵时,要知道往哪查、怎么留证。

本篇讲三块:审计(平时记录谁干了什么)、入侵排查(怀疑被攻时怎么查痕迹)、漏洞响应(新出 CVE 怎么处理)。再加上异常登录的应急流程。

一、异常登录的应急流程

这是排查的起点。发现不明登录(陌生 IP、不认识的账号登录),不要立即 kill 对方进程。攻击者一旦察觉,可能立即销毁痕迹或加快攻击。

标准的应急流程是先留证、再上报、最后阻断:

bash
# 第 1 步:留证(屏幕截图 + 关键命令输出落盘)
{
  echo "=== 发现时间:$(date '+%F %T') ==="
  echo "=== w 输出 ==="
  w
  echo "=== last -F ==="
  last -F | head -20
  echo "=== 该用户当前进程 ==="
  ps -ef --forest -u <可疑用>
  echo "=== 该用户的 .bash_history ==="
  cat /home/<可疑用>/.bash_history 2>/dev/null
  echo "=== sshd 最近日志 ==="
  tail -100 /var/log/secure 2>/dev/null || tail -100 /var/log/auth.log
} > /tmp/incident-$(date +%s).log

# 第 2 步:上报安全/运维负责人
# 第 3 步:确认后再阻断(改密码、踢出会话、限制 IP)

保留证据优先于阻断。who --ips 可以看到具体的来源 IP 数字而不是反向解析后的域名,排查时更准确。

二、入侵痕迹排查

怀疑机器被入侵,按几个方向查痕迹。

登录记录

bash
last -n 20                 # 历史登录记录(成功登录)
lastb -n 20                # 失败登录(暴力破解痕迹,需要 root)

看异常 IP 来源,分组统计:

bash
last | awk '{print $3}' | sort | uniq -c | sort -nr | head

来自陌生海外 IP、或与机房地域不匹配的来源要重点查。

账号变动

bash
# UID 为 0 的账号(应该只有 root)
awk -F: '$3==0 {print $1}' /etc/passwd

# 最近创建的账号(按家目录时间戳)
ls -lt /home | head

# 看 passwd 文件的最后修改时间
stat /etc/passwd | grep Modify

被加了 UID=0 的账号、或最近突然多出的账号,都是入侵迹象。

可疑进程

bash
ps -ef --forest            # 看进程树,寻找可疑的父子关系
ss -lntp                   # 看监听的端口,寻找未授权的服务
ps -eo pid,pcpu,cmd --sort=-pcpu | head   # 占 CPU 高但又不认识的进程

进程可能被命名混淆,假装成系统进程(如 [kworker])。看完整启动命令:

bash
ls -l /proc/<PID>/exe       # 进程对应的真实可执行文件
tr '\0' ' ' < /proc/<PID>/cmdline    # 完整启动命令

持久化后门

攻击者会留下后门让自己能再次进入。常见位置:

bash
# 所有用户的 crontab
for user in $(cut -f1 -d: /etc/passwd); do crontab -u $user -l 2>/dev/null; done

# 系统级 cron 目录
ls -la /etc/cron.*
cat /etc/crontab

# systemd timer(新型计划任务)
systemctl list-timers --all

# 所有用户的 authorized_keys(攻击者可能加了免密登录)
find /home -name authorized_keys -exec cat {} \;
find /root -name authorized_keys -exec cat {} \;

文件篡改

bash
# 列出所有 SUID 文件,对比基线找新增
find / -perm -4000 -type f 2>/dev/null

# 关键文件 mtime 异常(最近被改过)
stat /etc/passwd /etc/shadow /etc/sudoers | grep -E "File|Modify"

如果之前保存过 SUID 文件基线,对比能找出新增的后门 SUID 程序。

异常网络连接

bash
ss -tnap                   # 所有 TCP 连接,看是否连到陌生 IP
ss -tn state established    # 看已建立的外连

出站连接到非业务必需的外部地址(如连到陌生海外 IP),可能是反弹 shell 或数据外传。

rootkit 检测

怀疑装了 rootkit(内核级后门),用专门工具:

bash
yum install chkrootkit rkhunter -y
chkrootkit
rkhunter --check

这些工具检查常见的 rootkit 特征。不过 rootkit 检测不是百分百可靠——高级 rootkit 能隐藏自己。如果怀疑但查不出,最稳妥的是重装系统、从可信备份恢复数据。

三、auditd:操作审计

auditd 是 Linux 内核级的审计系统,记录关键操作——谁改了配置文件、谁执行了 sudo、谁改了时间。这些日志在事后排查时是关键证据。

配置审计规则

规则写在 /etc/audit/rules.d/security.rules

bash
# === 关键文件修改审计 ===
-w /etc/passwd -p wa -k identity     # 监控 passwd 的写和属性修改
-w /etc/shadow -p wa -k identity
-w /etc/sudoers -p wa -k sudoers

# === sudo 命令执行审计 ===
-w /usr/bin/sudo -p x -k sudo

# === 提权动作审计 ===
-w /bin/su -p x -k privileged

# === 时间修改审计 ===
-w /etc/localtime -p wa -k time

# 锁定规则(必须放最后,锁定后只能重启修改)
-e 2

-w 监控文件,-p 监控操作类型(w 写、a 属性、x 执行),-k 打标签方便查询。

生效:

bash
systemctl restart auditd

查询审计日志

bash
# 按标签查询
ausearch -k identity

# 按用户查询
ausearch -ua <UID>

# 按时间范围
ausearch --start today --end now

# 生成报告
aureport --summary

auditd 的日志很详细,排查"谁在什么时候改了什么文件"时非常有用。

四、SELinux 与 AppArmor

SELinux(RHEL 系)和 AppArmor(Debian 系)是 Linux 的强制访问控制(MAC)系统,给程序加额外的权限约束。它们经常是"程序能跑但权限被拒"这类故障的根因。

SELinux 排查

服务能跑但某些操作被拒,先怀疑是 SELinux:

bash
# 第 1 步:看是否是 SELinux 拦截(临时切到 Permissive 模式不重启)
setenforce 0
# 如果应用立刻能用 = SELinux 拦的
# 如果还是不能用 = 不是 SELinux 的问题

# 第 2 步:看审计日志找出哪条规则拦的
ausearch -m avc -ts recent
# 或专门看 SELinux 拒绝
grep denied /var/log/audit/audit.log

SELinux 上下文

最常见的问题:文件用 mv 移过来后上下文不对,服务读不了:

bash
# 看文件上下文
ls -Z index.html
# -rw-r--r--. root root unconfined_u:object_r:httpd_sys_content_t:s0 index.html

# 强制恢复默认上下文
restorecon -Rv /var/www/html

# 临时改某文件上下文
chcon -t httpd_sys_content_t index.html

# 永久改(写入策略)
semanage fcontext -a -t httpd_sys_content_t "/var/www/html(/.*)?"
restorecon -Rv /var/www/html

排查完切回 Enforcing:

bash
setenforce 1

AppArmor

Debian/Ubuntu 用 AppArmor。看某个进程的 profile 状态:

bash
aa-status                    # AppArmor 整体状态
aa-status | grep <进程>    # 看某进程的 profile

# 把某 profile 切到 complain 模式(只记录不拦截,用于排查)
aa-complain /etc/apparmor.d/usr.bin.<>

# 切回 enforce
aa-enforce /etc/apparmor.d/usr.bin.<>

complain 模式只记录不拦截,适合排查"是不是 AppArmor 拦的"。

五、漏洞响应:从 CVE 到补丁

新出的 CVE(漏洞编号)要评估影响并打补丁。不要无脑全升级——生产环境升级要评估兼容性。

看可用的安全更新

bash
# RHEL 系
yum updateinfo list security all      # 列出所有安全更新
yum updateinfo info --cve CVE-2024-xxxx   # 看某 CVE 的影响

# Debian 系
apt list --upgradable                 # 看可升级的包

只装安全更新

只装安全更新,不动其他包,减少兼容性风险:

bash
# RHEL 系
yum update --security

# Debian 系
apt install --only-upgrade <>
# 或用 unattended-upgrades 配置只自动装安全更新

打补丁前先在测试机验证,确认不影响业务再推到生产。

六、安全基线检查清单

平时定期跑一遍检查清单,发现配置漂移:

bash
#!/bin/bash
# /usr/local/sbin/security-check.sh
echo "=== UID=0 账号 ==="
awk -F: '$3==0 {print $1}' /etc/passwd

echo "=== 有登录 shell 的账号 ==="
grep -v nologin /etc/passwd | grep -v /bin/false

echo "=== 监听端口 ==="
ss -lntp

echo "=== sudoers 免密规则 ==="
grep -r NOPASSWD /etc/sudoers /etc/sudoers.d/ 2>/dev/null

echo "=== 最近登录失败 ==="
lastb -n 10 2>/dev/null

echo "=== fail2ban 封禁数 ==="
fail2ban-client status 2>/dev/null

跑一遍能快速看出:有没有多余的管理员账号、有没有不该开的服务、sudo 有没有全权限免密。配置漂移(如有人图方便临时加了 NOPASSWD: ALL 忘了删)能及时发现。

排查的共同思路

安全排查和故障排查思路相通:

  1. 先留证再动手——发现异常不要急于阻断,先保存现场(日志、进程、网络连接)。
  2. 从登录入口查起——登录记录、账号变动是最常见的入侵痕迹。
  3. 查持久化——后门藏在 crontab、systemd timer、authorized_keys、SUID 文件里。
  4. 审计日志是证据——auditd 记录的关键操作,是事后追溯的依据。
  5. 不确定就重装——查不出但强烈怀疑被入侵,重装系统、从可信备份恢复是最稳的。

下一篇是系统初始化基线——把前几篇的加固和配置整合成一个可复用的初始化脚本。