Linux入侵检测与应急响应:安全事件排查实战手册
一、概述
1.1 背景介绍
生产环境的安全防护不能只靠边界防火墙。攻击者一旦突破外层防线,在主机上的横向移动、权限提升、后门植入等行为,如果没有主机层面的检测能力,往往要到业务异常甚至数据泄露后才被发现。
入侵检测体系通常分三层:
网络层(NIDS):基于流量分析,典型工具 Suricata、Snort,擅长检测已知攻击特征,但对加密流量无能为力
主机层(HIDS):直接运行在目标主机上,监控文件变更、进程行为、用户操作,是最后一道防线
应用层:WAF、RASP 等,针对 Web 应用的攻击检测
主机入侵检测的核心能力包括五个方面:文件完整性检测(关键二进制和配置文件是否被篡改)、Rootkit 扫描(内核级和用户态后门检测)、日志审计(谁在什么时间做了什么操作)、进程监控(异常进程和隐藏进程发现)、网络连接异常检测(反弹 Shell、挖矿外联等)。
常见的攻击向量:SSH 暴力破解拿到初始权限、Web 漏洞(RCE/文件上传/反序列化)获取 Webshell、内核漏洞或 SUID 提权到 root、crontab/systemd 后门维持权限、挖矿木马消耗算力。
主流 HIDS 工具对比:
| 工具 | 文件完整性 | Rootkit检测 | 实时监控 | 中心化管理 | 部署复杂度 |
|---|---|---|---|---|---|
| AIDE | 强 | 无 | 否(定期扫描) | 无 | 低 |
| Tripwire | 强 | 无 | 否 | 商业版支持 | 中 |
| OSSEC | 中 | 有 | 是 | 有(C/S架构) | 中 |
| Wazuh | 强 | 有 | 是 | 有(ELK集成) | 高 |
| rkhunter | 无 | 强 | 否 | 无 | 低 |
实际生产中,单一工具无法覆盖所有场景。推荐组合方案:AIDE 负责文件完整性基线、rkhunter 定期扫描 Rootkit、auditd 提供内核级操作审计、ClamAV 处理恶意文件查杀。
1.2 技术特点
AIDE(Advanced Intrusion Detection Environment):基于文件属性数据库的完整性检测,支持多种哈希算法,配置灵活,资源占用低
rkhunter:专注 Rootkit、后门和本地漏洞检测,维护已知 Rootkit 签名库,支持自定义检查项
auditd:Linux 内核审计子系统的用户态守护进程,可记录系统调用级别的操作日志,满足等保/PCI-DSS 合规要求
ClamAV:开源杀毒引擎,病毒库社区维护更新,支持命令行扫描和守护进程模式
1.3 适用场景
等保合规审计:等保二级以上要求具备入侵检测和安全审计能力,auditd + AIDE 可满足技术检查项
安全基线检查:新服务器上线前的安全基线核查,确认系统未被预装后门
入侵事件响应:发现异常后的快速排查和取证,需要系统化的检查流程和工具链
日常安全巡检:定期自动化扫描,及时发现配置漂移和异常变更
1.4 环境要求
| 组件 | 版本要求 | 说明 |
|---|---|---|
| 操作系统 | Ubuntu 22.04+ / CentOS 8+ | 推荐 Ubuntu 22.04 LTS |
| AIDE | 0.18.x | apt 默认仓库版本即可 |
| rkhunter | 1.4.x | 安装后需更新签名库 |
| auditd | 3.x | 内核 4.x+ 支持完整审计特性 |
| ClamAV | 1.x | 需定期更新病毒库(freshclam) |
| 磁盘空间 | 审计日志预留 10GB+ | auditd 日志增长较快,需配置轮转 |
二、详细步骤
2.1 文件完整性检测(AIDE)
2.1.1 安装与初始化
# Ubuntu/Debian sudo apt update && sudo apt install -y aide # CentOS/RHEL sudo dnf install -y aide
2.1.2 AIDE 配置文件
# /etc/aide/aide.conf - AIDE 主配置文件 # 数据库路径配置 database_in=file:/var/lib/aide/aide.db # 当前基线数据库(只读) database_out=file:/var/lib/aide/aide.db.new # 检查后生成的新数据库 database_new=file:/var/lib/aide/aide.db.new # --update 时写入的目标 # 日志输出 report_url=file:/var/log/aide/aide.log report_url=stdout # 自定义检测规则组(按需组合文件属性) # p: 权限 i: inode n: 硬链接数 u: 属主 g: 属组 # s: 文件大小 b: 块数 m: mtime c: ctime a: atime # sha256: SHA-256 哈希 sha512: SHA-512 哈希 # S: 检查文件是否变大(只增长) acl: POSIX ACL xattrs: 扩展属性 # 关键二进制文件:全属性 + 强哈希 BINLIB = p+i+n+u+g+s+b+m+c+sha256+sha512 # 配置文件:关注内容变更和权限 CONFFILE = p+i+n+u+g+s+sha256 # 日志文件:只关注权限和属主,忽略内容变化(日志本身会增长) LOGFILE = p+u+g # 数据目录:关注权限和属主变更 DATAONLY = p+u+g+sha256 # ========== 监控目录定义 ========== # 关键系统二进制目录 - 这些目录的文件被篡改意味着系统已被入侵 /bin BINLIB /sbin BINLIB /usr/bin BINLIB /usr/sbin BINLIB /usr/lib BINLIB # 系统配置目录 - 监控配置篡改 /etc CONFFILE # 引导目录 - 防止 bootkit /boot BINLIB # 内核模块 - 防止恶意内核模块加载 /lib/modules BINLIB # ========== 排除目录(减少误报) ========== # 排除频繁变化的目录 !/var/log !/var/spool !/var/cache !/var/tmp !/tmp !/run !/proc !/sys !/dev # 排除包管理器数据库(安装/更新软件时会变化) !/var/lib/dpkg !/var/lib/apt !/var/lib/rpm
2.1.3 基线数据库生成与安全存储
# 初始化基线数据库(首次运行,耗时取决于监控目录大小) sudo aide --init # 将新生成的数据库设为当前基线 sudo cp /var/lib/aide/aide.db.new /var/lib/aide/aide.db # 安全存储:将基线数据库复制到只读介质或远程服务器 # 攻击者如果能修改基线数据库,AIDE 就失去意义 sudo cp /var/lib/aide/aide.db /mnt/readonly-backup/aide.db.$(date +%Y%m%d)
2.1.4 定期检查与基线更新
# 执行完整性检查(对比当前文件系统与基线数据库) sudo aide --check # 输出解读: # f: 文件 d: 目录 l: 符号链接 # added: 新增文件(基线中不存在) # removed: 删除文件(基线中存在但文件系统中没有) # changed: 属性变更(哈希、权限、属主等) # 合法变更后更新基线(如系统补丁、配置调整后) sudo aide --update sudo cp /var/lib/aide/aide.db.new /var/lib/aide/aide.db
配置 crontab 每日自动检查:
# /etc/cron.d/aide-check 0 3 * * * root /usr/bin/aide --check | mail -s "AIDE Report $(hostname) $(date +\%F)" security@company.com
2.2 Rootkit 检测(rkhunter + chkrootkit)
2.2.1 rkhunter 安装与配置
# 安装 sudo apt install -y rkhunter # 安装后立即更新签名库和文件属性数据库 sudo rkhunter --update sudo rkhunter --propupd
关键配置项调整:
# /etc/rkhunter.conf 关键配置
# 启用自动更新检查
UPDATE_MIRRORS=1
MIRRORS_MODE=0
WEB_CMD=""
# 邮件告警
MAIL-ON-WARNING=security@company.com
MAIL_CMD=mail -s "[rkhunter] {subject}" {recipient}
# 允许 SSH root 登录检查(根据实际策略调整)
ALLOW_SSH_ROOT_USER=no
# 允许 SSH 协议版本(只允许 v2)
ALLOW_SSH_PROT_V1=0
# 白名单配置 - 处理已知误报
# 系统更新后某些二进制文件哈希会变化,加入白名单避免误报
SCRIPTWHITELIST=/usr/bin/egrep
SCRIPTWHITELIST=/usr/bin/fgrep
SCRIPTWHITELIST=/usr/bin/which
SCRIPTWHITELIST=/usr/bin/ldd
# 允许隐藏目录(某些软件正常创建的隐藏目录)
ALLOWHIDDENDIR=/etc/.java
ALLOWHIDDENDIR=/dev/.udev
# 允许的 /dev 下非设备文件
ALLOWDEVFILE=/dev/shm/pulse-shm-*
ALLOWDEVFILE=/dev/shm/PostgreSQL.*
# 系统包管理器(用于验证文件属性)
PKGMGR=DPKG # Debian/Ubuntu 用 DPKG,CentOS 用 RPM
2.2.2 扫描执行与报告解读
# 完整扫描(交互模式,按回车跳过每个检查阶段) sudo rkhunter --check # 非交互模式(适合 cron 任务) sudo rkhunter --check --skip-keypress --report-warnings-only # 查看扫描日志 sudo cat /var/log/rkhunter.log # 日志中的关键字段: # [Found] - 发现可疑项,需要人工确认 # [Warning] - 警告项,可能是误报也可能是真实威胁 # [OK] - 检查通过 # [Not found] - 未发现对应 Rootkit 签名
2.2.3 chkrootkit 交叉验证
单一工具可能存在漏检,用 chkrootkit 做交叉验证:
# 安装 sudo apt install -y chkrootkit # 执行扫描 sudo chkrootkit # 静默模式(只输出可疑项) sudo chkrootkit -q # 两个工具的检测原理不同: # rkhunter: 基于签名匹配 + 文件属性检查 + 系统配置审计 # chkrootkit: 基于特征字符串搜索 + 系统命令输出分析 # 交叉验证可以降低漏检率
2.3 系统审计框架(auditd)
2.3.1 架构原理
auditd 是 Linux 内核审计子系统的用户态组件。内核中的 audit 模块在系统调用入口和出口处插入钩子,根据用户定义的规则决定是否记录该操作。审计事件通过 netlink socket 从内核传递到用户态的 auditd 守护进程,写入日志文件。
核心组件:
auditd:守护进程,负责接收内核审计事件并写入日志
auditctl:运行时管理工具,动态添加/删除/查看规则
ausearch:审计日志搜索工具
aureport:审计日志报告生成工具
audisp-remote:审计日志远程转发插件
# 安装 sudo apt install -y auditd audispd-plugins # 启动并设置开机自启 sudo systemctl enable --now auditd
2.3.2 企业级审计规则
# /etc/audit/rules.d/security.rules - 企业级安全审计规则集 # 加载方式:sudo augenrules --load # ========== 基础配置 ========== # 审计缓冲区大小(繁忙系统调大,避免丢事件) -b 8192 # 缓冲区满时的处理策略:1=打印警告并继续 2=立即关机(高安全环境) -f 1 # 忽略配置错误继续加载(避免单条规则错误导致全部失败) -c # ========== 身份与认证审计 ========== # 监控用户/组数据库文件的读写 -w /etc/passwd -p wa -k identity_mod -w /etc/shadow -p wa -k identity_mod -w /etc/group -p wa -k identity_mod -w /etc/gshadow -p wa -k identity_mod -w /etc/security/opasswd -p wa -k identity_mod # 监控 sudoers 配置变更 -w /etc/sudoers -p wa -k privilege_escalation -w /etc/sudoers.d/ -p wa -k privilege_escalation # ========== 权限变更审计 ========== # 监控文件权限修改(chmod/chown/fchmod/fchown) -a always,exit -F arch=b64 -S chmod,fchmod,fchmodat -F auid>=1000 -F auid!=4294967295 -k perm_mod -a always,exit -F arch=b64 -S chown,fchown,fchownat,lchown -F auid>=1000 -F auid!=4294967295 -k perm_mod # 监控 setuid/setgid 设置(提权关键操作) -a always,exit -F arch=b64 -S setuid,setgid,setreuid,setregid -F auid>=1000 -F auid!=4294967295 -k priv_cmd # ========== 用户操作审计 ========== # 监控登录相关配置 -w /etc/login.defs -p wa -k login_config -w /etc/securetty -p wa -k login_config -w /etc/pam.d/ -p wa -k pam_config # 监控 SSH 配置变更 -w /etc/ssh/sshd_config -p wa -k sshd_config -w /etc/ssh/ssh_config -p wa -k ssh_config # 监控 crontab 变更(后门常用持久化手段) -w /etc/crontab -p wa -k cron_mod -w /etc/cron.d/ -p wa -k cron_mod -w /var/spool/cron/ -p wa -k cron_mod # ========== 网络连接审计 ========== # 监控网络套接字创建(检测反弹 Shell 和异常外联) -a always,exit -F arch=b64 -S connect -F auid>=1000 -F auid!=4294967295 -k net_connect -a always,exit -F arch=b64 -S bind -F auid>=1000 -F auid!=4294967295 -k net_bind -a always,exit -F arch=b64 -S accept -F auid>=1000 -F auid!=4294967295 -k net_accept # ========== 可执行文件审计 ========== # 监控 /tmp 和 /var/tmp 下的程序执行(攻击者常在临时目录释放恶意文件) -a always,exit -F arch=b64 -S execve -F dir=/tmp -k exec_tmp -a always,exit -F arch=b64 -S execve -F dir=/var/tmp -k exec_tmp -a always,exit -F arch=b64 -S execve -F dir=/dev/shm -k exec_shm # 监控内核模块加载(防止 LKM Rootkit) -w /sbin/insmod -p x -k kernel_mod -w /sbin/rmmod -p x -k kernel_mod -w /sbin/modprobe -p x -k kernel_mod -a always,exit -F arch=b64 -S init_module,finit_module -k kernel_mod -a always,exit -F arch=b64 -S delete_module -k kernel_mod # ========== 规则锁定(放在最后) ========== # 锁定规则,防止运行时被篡改(重启后才能修改) -e 2
2.3.3 审计日志查询与报告
# ausearch - 按条件搜索审计事件 # 搜索所有身份文件变更事件 sudo ausearch -k identity_mod -ts today # 搜索指定用户的所有操作 sudo ausearch -ua 1001 -ts recent # 搜索指定时间范围内的提权操作 sudo ausearch -k privilege_escalation -ts "2024-01-15 0000" -te "2024-01-15 2359" # 搜索失败的系统调用(可能是攻击尝试) sudo ausearch --success no -ts today # aureport - 生成汇总报告 # 认证事件报告(登录成功/失败统计) sudo aureport -au --summary # 可执行文件报告 sudo aureport -x --summary # 异常事件报告 sudo aureport --anomaly # 失败事件汇总 sudo aureport --failed --summary
审计日志远程转发配置(防止攻击者清除本地日志):
# /etc/audit/plugins.d/au-remote.conf active = yes direction = out path = /sbin/audisp-remote type = always format = string
# /etc/audit/audisp-remote.conf remote_server = 192.168.1.100 # 远程日志服务器地址 port = 60 # 远程端口 transport = tcp # 传输协议 queue_depth = 1024 # 本地队列深度 fail_action = syslog # 远程不可达时写 syslog
2.4 应急响应流程
2.4.1 应急响应六步法
标准的应急响应流程分六个阶段:
准备:工具链就绪、响应预案制定、联系人清单维护
识别:确认安全事件是否真实发生,评估影响范围
遏制:阻止攻击扩散,短期遏制(断网/封 IP)和长期遏制(修补漏洞)
根除:清除攻击者留下的所有后门、恶意文件、异常账号
恢复:从可信备份恢复系统,逐步恢复业务
总结:复盘攻击路径,完善防护措施,更新响应预案
2.4.2 初始响应检查清单
发现疑似入侵后,按以下顺序采集信息(先采集易失性数据):
# ===== 1. 系统基本信息 =====
uname -a # 内核版本
cat /etc/os-release # 系统版本
uptime # 运行时间(判断是否被重启过)
date # 当前时间(确认时区)
timedatectl # NTP 同步状态
# ===== 2. 用户账号排查 =====
# 检查异常用户(UID=0 的非 root 用户是高危信号)
awk -F: '$3==0 {print $1}' /etc/passwd
# 检查近期新增用户
grep -v "nologin|false" /etc/passwd
# 检查空密码用户
awk -F: '($2=="") {print $1}' /etc/shadow
# 检查 sudo 权限用户
grep -v "^#" /etc/sudoers | grep -v "^$"
cat /etc/sudoers.d/*
# 当前登录用户和历史登录记录
w
last -20
lastb -20 # 失败的登录尝试
# ===== 3. 进程排查 =====
# 查看所有进程(关注异常进程名、异常路径)
ps auxf
# 查看进程打开的文件(定位恶意进程的文件和网络连接)
ls -la /proc/[PID]/exe # 查看进程对应的可执行文件
ls -la /proc/[PID]/fd # 查看进程打开的文件描述符
# 检查已删除但仍在运行的进程(攻击者常删除恶意文件但进程仍在)
ls -la /proc/*/exe 2>/dev/null | grep "(deleted)"
# ===== 4. 网络连接排查 =====
# 查看所有网络连接(关注 ESTABLISHED 和 LISTEN 状态)
ss -tulnp
netstat -tulnp
# 查看异常外联(排除已知业务 IP)
ss -tnp state established
# ===== 5. 文件排查 =====
# 查找最近 3 天内被修改的文件(排除日志和缓存目录)
find / -mtime -3 -type f ( ! -path "/var/log/*" ! -path "/var/cache/*" ! -path "/proc/*" ! -path "/sys/*" ! -path "/run/*" ) 2>/dev/null
# 查找 SUID/SGID 文件(提权常用)
find / -perm -4000 -type f 2>/dev/null
find / -perm -2000 -type f 2>/dev/null
# 查找隐藏文件和目录
find / -name ".*" -type f 2>/dev/null | grep -v -E "^/(proc|sys|run)"
# ===== 6. 定时任务排查 =====
# 系统级定时任务
cat /etc/crontab
ls -la /etc/cron.d/
ls -la /etc/cron.daily/
ls -la /etc/cron.hourly/
# 用户级定时任务
for user in $(cut -d: -f1 /etc/passwd); do
crontab -l -u "$user" 2>/dev/null && echo "=== $user ==="
done
# systemd 定时器(新型持久化手段)
systemctl list-timers --all
三、示例代码和配置
3.1 自动化安全巡检脚本
#!/bin/bash
# 文件名:security_audit.sh
# 功能:一键采集系统安全状态,生成巡检报告
# 用法:sudo bash security_audit.sh
set -euo pipefail
REPORT_DIR="/tmp/security_audit_$(hostname)_$(date +%Y%m%d_%H%M%S)"
mkdir -p "${REPORT_DIR}"
log() {
echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" | tee -a "${REPORT_DIR}/audit.log"
}
log "===== 安全巡检开始 ====="
log "主机名: $(hostname)"
log "IP 地址: $(hostname -I | awk '{print $1}')"
log "系统版本: $(cat /etc/os-release | grep PRETTY_NAME | cut -d'"' -f2)"
log "内核版本: $(uname -r)"
log "报告目录: ${REPORT_DIR}"
# ---------- 1. 用户账号检查 ----------
log "--- 采集用户账号信息 ---"
{
echo "=== UID=0 的用户(应该只有 root)==="
awk -F: '$3==0 {print $1}' /etc/passwd
echo -e "
=== 可登录的用户 ==="
grep -v "nologin|false|/bin/sync|/bin/halt|/bin/shutdown" /etc/passwd
echo -e "
=== 空密码用户 ==="
awk -F: '($2=="" || $2=="!") {print $1}' /etc/shadow 2>/dev/null || echo "无法读取 shadow 文件"
echo -e "
=== 最近 30 天登录记录 ==="
last -30 | head -50
echo -e "
=== 最近失败登录 ==="
lastb 2>/dev/null | head -30 || echo "无 lastb 记录"
} > "${REPORT_DIR}/01_users.txt"
# ---------- 2. 进程检查 ----------
log "--- 采集进程信息 ---"
{
echo "=== 进程树 ==="
ps auxf
echo -e "
=== 已删除但仍运行的进程 ==="
ls -la /proc/*/exe 2>/dev/null | grep "(deleted)" || echo "未发现"
echo -e "
=== CPU 占用 TOP 20 ==="
ps aux --sort=-%cpu | head -21
} > "${REPORT_DIR}/02_processes.txt"
# ---------- 3. 网络连接检查 ----------
log "--- 采集网络连接信息 ---"
{
echo "=== 监听端口 ==="
ss -tulnp
echo -e "
=== 已建立的连接 ==="
ss -tnp state established
echo -e "
=== 路由表 ==="
ip route
echo -e "
=== DNS 配置 ==="
cat /etc/resolv.conf
} > "${REPORT_DIR}/03_network.txt"
# ---------- 4. 定时任务检查 ----------
log "--- 采集定时任务 ---"
{
echo "=== 系统 crontab ==="
cat /etc/crontab 2>/dev/null
echo -e "
=== /etc/cron.d/ ==="
ls -la /etc/cron.d/ 2>/dev/null
for f in /etc/cron.d/*; do
[ -f "$f" ] && echo "--- $f ---" && cat "$f"
done
echo -e "
=== 用户 crontab ==="
for user in $(cut -d: -f1 /etc/passwd); do
cron_content=$(crontab -l -u "$user" 2>/dev/null) &&
echo "--- ${user} ---" && echo "$cron_content"
done
echo -e "
=== systemd 定时器 ==="
systemctl list-timers --all --no-pager 2>/dev/null
} > "${REPORT_DIR}/04_crontabs.txt"
# ---------- 5. SUID/SGID 文件 ----------
log "--- 扫描 SUID/SGID 文件 ---"
{
echo "=== SUID 文件 ==="
find / -perm -4000 -type f 2>/dev/null
echo -e "
=== SGID 文件 ==="
find / -perm -2000 -type f 2>/dev/null
} > "${REPORT_DIR}/05_suid_sgid.txt"
# ---------- 6. 最近修改的文件 ----------
log "--- 扫描最近 3 天修改的文件 ---"
find / -mtime -3 -type f
( ! -path "/proc/*" ! -path "/sys/*" ! -path "/run/*"
! -path "/var/log/*" ! -path "/var/cache/*" ! -path "/tmp/*" )
2>/dev/null > "${REPORT_DIR}/06_recent_files.txt"
log "===== 巡检完成,报告目录: ${REPORT_DIR} ====="
# 打包报告
tar czf "${REPORT_DIR}.tar.gz" -C /tmp "$(basename ${REPORT_DIR})"
log "报告已打包: ${REPORT_DIR}.tar.gz"
3.2 入侵痕迹自动化排查脚本
#!/bin/bash
# 文件名:intrusion_detect.sh
# 功能:自动化检测常见入侵痕迹
# 用法:sudo bash intrusion_detect.sh
set -euo pipefail
RED='�33[0;31m'
YELLOW='�33[1;33m'
GREEN='�33[0;32m'
NC='�33[0m'
ALERT_COUNT=0
alert() {
echo -e "${RED}[!] 告警: $1${NC}"
((ALERT_COUNT++)) || true
}
warn() {
echo -e "${YELLOW}[*] 注意: $1${NC}"
}
ok() {
echo -e "${GREEN}[+] 正常: $1${NC}"
}
echo "=========================================="
echo " 入侵痕迹自动化排查"
echo " 时间: $(date)"
echo " 主机: $(hostname)"
echo "=========================================="
# ---------- 1. 异常用户检测 ----------
echo -e "
--- 1. 用户账号检查 ---"
# 检查 UID=0 的非 root 用户
uid0_users=$(awk -F: '$3==0 && $1!="root" {print $1}' /etc/passwd)
if [ -n "$uid0_users" ]; then
alert "发现非 root 的 UID=0 用户: ${uid0_users}"
else
ok "无异常 UID=0 用户"
fi
# 检查空密码用户
empty_pass=$(awk -F: '($2=="" ) {print $1}' /etc/shadow 2>/dev/null)
if [ -n "$empty_pass" ]; then
alert "发现空密码用户: ${empty_pass}"
else
ok "无空密码用户"
fi
# 检查 /etc/passwd 和 /etc/shadow 的权限
passwd_perm=$(stat -c %a /etc/passwd)
shadow_perm=$(stat -c %a /etc/shadow)
[ "$passwd_perm" != "644" ] && alert "/etc/passwd 权限异常: ${passwd_perm}(应为 644)"
[ "$shadow_perm" != "640" ] && [ "$shadow_perm" != "600" ] && alert "/etc/shadow 权限异常: ${shadow_perm}(应为 640 或 600)"
# ---------- 2. 隐藏进程检测 ----------
echo -e "
--- 2. 隐藏进程检测 ---"
# 对比 ps 和 /proc 的进程列表
ps_pids=$(ps -eo pid --no-headers | sort -n)
proc_pids=$(ls -d /proc/[0-9]* 2>/dev/null | awk -F/ '{print $3}' | sort -n)
hidden=$(comm -13 <(echo "$ps_pids" | tr -d ' ') <(echo "$proc_pids"))
if [ -n "$hidden" ]; then
alert "发现隐藏进程 PID: ${hidden}"
else
ok "未发现隐藏进程"
fi
# 检查已删除但仍运行的可执行文件
deleted_procs=$(ls -la /proc/*/exe 2>/dev/null | grep "(deleted)" || true)
if [ -n "$deleted_procs" ]; then
alert "发现已删除但仍运行的进程:
${deleted_procs}"
else
ok "无已删除的运行进程"
fi
# ---------- 3. 异常网络连接检测 ----------
echo -e "
--- 3. 网络连接检查 ---"
# 检测常见挖矿矿池端口(3333, 4444, 5555, 8888, 14444)
mining_ports="3333|4444|5555|8888|14444"
mining_conn=$(ss -tnp state established 2>/dev/null | grep -E ":($mining_ports)" || true)
if [ -n "$mining_conn" ]; then
alert "发现疑似挖矿连接:
${mining_conn}"
else
ok "未发现挖矿端口连接"
fi
# 检测反弹 Shell 特征(进程关联了 socket 且连接外部)
reverse_shell=$(ss -tnp state established 2>/dev/null | grep -E "bash|sh|python|perl|nc|ncat" || true)
if [ -n "$reverse_shell" ]; then
alert "发现疑似反弹 Shell:
${reverse_shell}"
else
ok "未发现反弹 Shell 特征"
fi
# ---------- 4. Webshell 检测 ----------
echo -e "
--- 4. Webshell 扫描 ---"
# 常见 Web 目录
WEB_DIRS=("/var/www" "/usr/share/nginx" "/opt/tomcat/webapps" "/srv/http")
webshell_found=0
for dir in "${WEB_DIRS[@]}"; do
if [ -d "$dir" ]; then
# 检测 PHP Webshell 关键函数
php_shells=$(grep -rl --include="*.php" -E "evals*(|base64_decodes*(|systems*(|passthrus*(|shell_execs*(|asserts*(" "$dir" 2>/dev/null || true)
if [ -n "$php_shells" ]; then
alert "在 ${dir} 发现疑似 PHP Webshell:
${php_shells}"
webshell_found=1
fi
# 检测 JSP Webshell
jsp_shells=$(grep -rl --include="*.jsp" -E "Runtime.getRuntime|ProcessBuilder|execs*(" "$dir" 2>/dev/null || true)
if [ -n "$jsp_shells" ]; then
alert "在 ${dir} 发现疑似 JSP Webshell:
${jsp_shells}"
webshell_found=1
fi
fi
done
[ "$webshell_found" -eq 0 ] && ok "未发现 Webshell"
# ---------- 5. 挖矿进程检测 ----------
echo -e "
--- 5. 挖矿进程检测 ---"
# 按进程名匹配已知挖矿程序
mining_procs=$(ps aux | grep -iE "xmrig|cryptonight|stratum|minerd|kworkerds|kdevtmpfsi|solr.sh" | grep -v grep || true)
if [ -n "$mining_procs" ]; then
alert "发现疑似挖矿进程:
${mining_procs}"
else
ok "未发现已知挖矿进程"
fi
# CPU 使用率超过 90% 的进程(挖矿特征)
high_cpu=$(ps aux --sort=-%cpu | awk 'NR>1 && $3>90 {print $0}')
if [ -n "$high_cpu" ]; then
warn "发现 CPU 占用超过 90% 的进程:
${high_cpu}"
else
ok "无异常高 CPU 进程"
fi
# ---------- 汇总 ----------
echo -e "
=========================================="
if [ "$ALERT_COUNT" -gt 0 ]; then
echo -e "${RED}排查完成,共发现 ${ALERT_COUNT} 个告警项,请人工确认!${NC}"
else
echo -e "${GREEN}排查完成,未发现明显入侵痕迹。${NC}"
fi
echo "=========================================="
3.3 auditd 企业级规则集完整配置
# /etc/audit/rules.d/99-security-hardening.rules # 企业级安全审计规则集 - 完整版 # 适用于等保三级 / PCI-DSS 合规要求 # 加载:sudo augenrules --load && sudo auditctl -l # ========== 全局配置 ========== -D # 清除已有规则 -b 8192 # 内核审计缓冲区 -f 1 # 失败策略:1=printk 2=panic -c # 忽略错误继续 # ========== 时间变更审计(防止攻击者篡改时间掩盖痕迹) ========== -a always,exit -F arch=b64 -S adjtimex,settimeofday,clock_settime -k time_change -w /etc/localtime -p wa -k time_change # ========== 用户/组变更 ========== -w /etc/passwd -p wa -k identity -w /etc/shadow -p wa -k identity -w /etc/group -p wa -k identity -w /etc/gshadow -p wa -k identity -w /etc/security/opasswd -p wa -k identity -w /usr/sbin/useradd -p x -k user_mgmt -w /usr/sbin/userdel -p x -k user_mgmt -w /usr/sbin/usermod -p x -k user_mgmt -w /usr/sbin/groupadd -p x -k user_mgmt -w /usr/sbin/groupdel -p x -k user_mgmt # ========== 权限提升 ========== -w /etc/sudoers -p wa -k priv_esc -w /etc/sudoers.d/ -p wa -k priv_esc -w /usr/bin/sudo -p x -k priv_esc -w /usr/bin/su -p x -k priv_esc -a always,exit -F arch=b64 -S setuid,setgid,setreuid,setregid,seteuid,setegid -F auid>=1000 -F auid!=4294967295 -k priv_esc # ========== 网络配置变更 ========== -w /etc/hosts -p wa -k net_config -w /etc/hostname -p wa -k net_config -w /etc/resolv.conf -p wa -k net_config -w /etc/network/ -p wa -k net_config -w /etc/netplan/ -p wa -k net_config -a always,exit -F arch=b64 -S sethostname,setdomainname -k net_config # ========== SSH 与认证 ========== -w /etc/ssh/sshd_config -p wa -k sshd_config -w /etc/pam.d/ -p wa -k pam_mod -w /etc/security/limits.conf -p wa -k security_limits -w /var/log/faillog -p wa -k login_events -w /var/log/lastlog -p wa -k login_events # ========== 定时任务(持久化检测) ========== -w /etc/crontab -p wa -k cron_persist -w /etc/cron.d/ -p wa -k cron_persist -w /etc/cron.daily/ -p wa -k cron_persist -w /etc/cron.hourly/ -p wa -k cron_persist -w /etc/cron.weekly/ -p wa -k cron_persist -w /etc/cron.monthly/ -p wa -k cron_persist -w /var/spool/cron/ -p wa -k cron_persist # systemd 服务(另一种持久化手段) -w /etc/systemd/system/ -p wa -k systemd_persist -w /usr/lib/systemd/system/ -p wa -k systemd_persist # ========== 内核模块 ========== -w /sbin/insmod -p x -k kernel_module -w /sbin/rmmod -p x -k kernel_module -w /sbin/modprobe -p x -k kernel_module -a always,exit -F arch=b64 -S init_module,finit_module,delete_module -k kernel_module # ========== 文件删除审计(反取证检测) ========== -a always,exit -F arch=b64 -S unlink,unlinkat,rename,renameat -F auid>=1000 -F auid!=4294967295 -k file_delete # ========== 临时目录执行审计 ========== -a always,exit -F arch=b64 -S execve -F dir=/tmp -k exec_from_tmp -a always,exit -F arch=b64 -S execve -F dir=/var/tmp -k exec_from_tmp -a always,exit -F arch=b64 -S execve -F dir=/dev/shm -k exec_from_tmp # ========== 规则锁定(必须放在最后) ========== -e 2
四、最佳实践和注意事项
4.1 最佳实践
4.1.1 安全基线建设
安全基线不是装完系统就结束的一次性工作,而是持续维护的过程。CIS Benchmark 提供了各发行版的详细加固清单,直接拿来对照执行比自己拍脑袋靠谱得多。
核心加固动作:
#!/bin/bash
set -euo pipefail
# 最小化安装原则:清理不必要的包
dpkg --list | grep -E "^ii" | awk '{print $2}' > /tmp/installed_packages.txt
# 逐一审查,移除不需要的服务
sudo apt purge -y telnetd rsh-server xinetd
# 关闭不必要的服务
for svc in avahi-daemon cups bluetooth; do
sudo systemctl stop "$svc" 2>/dev/null || true
sudo systemctl disable "$svc" 2>/dev/null || true
sudo systemctl mask "$svc" 2>/dev/null || true
done
# SUID/SGID 文件清理:先摸底,再逐个确认是否需要
find / -type f ( -perm -4000 -o -perm -2000 ) -exec ls -la {} ; 2>/dev/null > /tmp/suid_sgid_audit.txt
# 对确认不需要 SUID 的文件去除权限
sudo chmod u-s /usr/bin/newgrp
sudo chmod u-s /usr/sbin/pppd
CIS Benchmark 关键检查项速查:
| 检查类别 | 具体项目 | 命令 |
|---|---|---|
| 文件系统 | /tmp 独立分区且 noexec | mount | grep /tmp |
| 网络参数 | 禁用 IP 转发 | sysctl net.ipv4.ip_forward |
| 访问控制 | SSH 禁止 root 登录 | grep PermitRootLogin /etc/ssh/sshd_config |
| 审计策略 | auditd 已启用 | systemctl is-active auditd |
| 密码策略 | 最小长度 ≥ 14 位 | grep minlen /etc/security/pwquality.conf |
4.1.2 日志集中管理
主机日志只存本地等于给攻击者留了灭证的机会。入侵者拿到 root 后第一件事往往就是清日志,所以日志必须实时转发到远端。
rsyslog 远程转发配置:
# /etc/rsyslog.d/50-remote.conf # 使用 TCP 保证可靠传输(@@表示TCP,@表示UDP) *.* @@logserver.internal:514 # 本地队列防止网络中断丢日志 $ActionQueueType LinkedList $ActionQueueFileName remote_fwd $ActionResumeRetryCount -1 $ActionQueueSaveOnShutdown on
日志防篡改——利用文件属性实现只追加:
# 设置只追加属性,即使 root 也无法删除或修改已有内容 sudo chattr +a /var/log/auth.log sudo chattr +a /var/log/syslog # 验证属性 lsattr /var/log/auth.log # 输出:-----a--------e----- /var/log/auth.log # 注意:logrotate 需要特殊处理,轮转前临时去除属性 # /etc/logrotate.d/rsyslog 中添加 prerotate/postrotate 脚本
日志保留策略建议:
| 日志类型 | 本地保留 | 远端保留 | 说明 |
|---|---|---|---|
| 认证日志 | 90 天 | 1 年 | 安全审计核心数据 |
| 系统日志 | 30 天 | 6 个月 | 故障排查依据 |
| 审计日志 | 90 天 | 1 年 | 合规要求通常 ≥ 180 天 |
| 应用日志 | 15 天 | 3 个月 | 按业务需求调整 |
4.1.3 纵深防御体系
单点防御在真实攻击面前不堪一击。纵深防御的核心思路:每一层都假设上一层已经被突破。
┌─────────────────────────────────────────────┐ │ 网络层:iptables/nftables + Suricata NIDS │ │ ┌─────────────────────────────────────────┐ │ │ │ 主机层:auditd + AIDE + rkhunter │ │ │ │ ┌─────────────────────────────────────┐│ │ │ │ │ 应用层:WAF + RASP + 输入校验 ││ │ │ │ │ ┌─────────────────────────────────┐││ │ │ │ │ │ 数据层:加密存储 + 访问控制 │││ │ │ │ │ └─────────────────────────────────┘││ │ │ │ └─────────────────────────────────────┘│ │ │ └─────────────────────────────────────────┘ │ └─────────────────────────────────────────────┘
各层防护措施对比:
| 防护层 | 工具/方案 | 检测能力 | 局限性 |
|---|---|---|---|
| 网络层 | iptables + Suricata | 已知攻击特征、端口扫描 | 加密流量无法深度检测 |
| 主机层 | auditd + AIDE + OSSEC | 文件篡改、提权操作、异常进程 | 内核级 Rootkit 可绕过 |
| 应用层 | ModSecurity + OpenRASP | SQL注入、XSS、命令注入 | 业务逻辑漏洞难以覆盖 |
| 数据层 | LUKS 磁盘加密 + GPG | 数据泄露后无法解密 | 运行时内存中数据仍为明文 |
4.1.4 自动化响应
手动响应在凌晨三点收到告警时基本等于没有响应。自动化是缩短 MTTR(平均恢复时间)的关键。
Wazuh + ELK 集成架构下的自动封禁方案:
#!/bin/bash
set -euo pipefail
# Wazuh Active Response 脚本:自动封禁暴力破解 IP
# 文件路径:/var/ossec/active-response/bin/block-ip.sh
LOCAL=$(dirname "$0")
LOCK="${LOCAL}/fw-drop"
LOCK_PID="${LOCK}/pid"
# 从 Wazuh 传入的参数中提取 IP
ACTION=$1
IP=$3
if [ "x${ACTION}" = "xadd" ]; then
# 封禁 IP,有效期 1 小时
iptables -I INPUT -s "${IP}" -j DROP
# 记录封禁日志
echo "$(date '+%Y-%m-%d %H:%M:%S') BLOCKED ${IP}" >> /var/log/active-response.log
elif [ "x${ACTION}" = "xdelete" ]; then
# 解封
iptables -D INPUT -s "${IP}" -j DROP
echo "$(date '+%Y-%m-%d %H:%M:%S') UNBLOCKED ${IP}" >> /var/log/active-response.log
fi
告警分级与升级机制:
| 级别 | 触发条件 | 响应动作 | 通知方式 |
|---|---|---|---|
| P3-低 | 单次 SSH 失败、端口扫描 | 记录日志,不告警 | 日报汇总 |
| P2-中 | 5 分钟内 ≥ 10 次 SSH 失败 | 自动封禁 IP 1 小时 | 企业微信/钉钉通知 |
| P1-高 | SUID 文件变更、新增 crontab | 封禁 + 隔离主机网络 | 电话告警 + 工单 |
| P0-紧急 | Rootkit 检出、内核模块加载 | 立即隔离 + 保留现场 | 电话 + 短信 + 启动应急预案 |
4.2 注意事项
4.2.1 配置注意事项
警告:应急响应中的操作失误可能比入侵本身造成更大的损失。
AIDE 基线数据库(/var/lib/aide/aide.db)必须离线存储或存放在只读介质上。攻击者拿到 root 后可以重新生成基线,让所有篡改"合法化"
auditd 规则不是越多越好。规则过多会显著增加系统调用开销,生产环境建议控制在 50 条以内,重点监控关键路径
应急响应时绝对不要直接关机或重启。内存中的恶意进程信息、网络连接状态、/proc 下的运行时数据会全部丢失,这些都是取证的关键证据
不要在被入侵的主机上直接运行杀毒工具或清理脚本。先做磁盘镜像,在镜像副本上操作
修改 SSH 配置后务必保持当前会话不断开,新开终端测试连接。配置错误导致 SSH 锁死是运维事故的经典场景
4.2.2 常见错误
| 错误现象 | 原因分析 | 解决方案 |
|---|---|---|
| AIDE 检查报告大量误报 | 未排除动态变化的文件(日志、缓存) | 在 aide.conf 中用 ! 排除 /var/log、/tmp 等目录 |
| auditd 导致系统卡顿 | 规则匹配范围过大,审计日志写入量爆炸 | 缩小规则范围,增加 -F auid>=1000 过滤系统进程 |
| rkhunter 报 "Warning: Hidden file found" | /dev/.udev 等是系统正常文件 | 在 /etc/rkhunter.conf 中加入白名单 ALLOWHIDDENFILE |
| ClamAV 扫描占满 CPU | 默认全盘扫描无资源限制 | 使用 nice -n 19 降低优先级,--max-filesize 限制单文件大小 |
| 日志转发丢失数据 | rsyslog 使用 UDP 协议,网络抖动丢包 | 改用 TCP(@@)并启用磁盘队列缓冲 |
4.2.3 取证注意事项
数字取证的核心原则:证据链完整性。任何操作都可能改变证据状态,所以要遵循严格的采集顺序。
易失性数据采集优先级(RFC 3227):
优先级从高到低: 1. CPU 寄存器、缓存 → 几乎无法采集,忽略 2. 内存内容 → volatility / /proc/PID/maps 3. 网络连接状态 → ss -tnp / netstat -tnp / /proc/net/tcp 4. 运行中的进程 → ps auxf / /proc/PID/ 5. 磁盘数据 → dd 镜像 6. 远程日志 → 日志服务器备份
取证操作规范:
#!/bin/bash
set -euo pipefail
# 取证数据采集脚本(在被入侵主机上执行,工具从只读U盘加载)
EVIDENCE_DIR="/mnt/usb/evidence/$(hostname)_$(date +%Y%m%d_%H%M%S)"
mkdir -p "${EVIDENCE_DIR}"
# 1. 采集内存信息
cp /proc/meminfo "${EVIDENCE_DIR}/meminfo.txt"
ps auxf > "${EVIDENCE_DIR}/ps_full.txt"
cat /proc/net/tcp > "${EVIDENCE_DIR}/proc_net_tcp.txt"
# 2. 采集网络连接
ss -tnp > "${EVIDENCE_DIR}/ss_connections.txt"
iptables -L -n -v > "${EVIDENCE_DIR}/iptables_rules.txt"
# 3. 采集用户和登录信息
last -aiF > "${EVIDENCE_DIR}/last_logins.txt"
lastlog > "${EVIDENCE_DIR}/lastlog.txt"
cat /etc/passwd > "${EVIDENCE_DIR}/passwd.txt"
# 4. 采集定时任务
for user in $(cut -d: -f1 /etc/passwd); do
crontab -l -u "$user" 2>/dev/null > "${EVIDENCE_DIR}/crontab_${user}.txt" || true
done
# 5. 计算哈希保证完整性
find "${EVIDENCE_DIR}" -type f -exec sha256sum {} ; > "${EVIDENCE_DIR}/checksums.sha256"
echo "取证数据已保存至 ${EVIDENCE_DIR}"
法律合规要点:
取证过程全程记录操作日志,包括时间、操作人、具体命令
证据文件计算 SHA256 哈希并由多人签字确认
磁盘镜像使用写保护设备,确保原始证据不被修改
涉及个人隐私数据时需遵循《数据安全法》和《个人信息保护法》相关规定
五、故障排查和监控
5.1 故障排查
5.1.1 日志查看
安全事件排查的第一步永远是看日志。不同发行版日志路径有差异,但核心日志就那几个:
# 认证日志:SSH 登录、sudo 操作、PAM 认证 # Debian/Ubuntu tail -100 /var/log/auth.log | grep -E "(Failed|Accepted|session opened)" # RHEL/CentOS tail -100 /var/log/secure | grep -E "(Failed|Accepted|session opened)" # 审计日志:auditd 记录的系统调用 # 查看最近的提权操作 ausearch -k privilege_escalation -ts recent # 查看文件篡改事件 ausearch -k etc_modification -ts today # journalctl 按优先级过滤(0=emerg 到 7=debug) # 只看 warning 及以上级别 journalctl -p 0..4 --since "1 hour ago" --no-pager # 查看特定服务的日志 journalctl -u sshd --since "2025-01-01" --until "2025-01-02" --no-pager
5.1.2 常见问题排查
可疑进程分析
发现 CPU 异常飙升或出现不认识的进程名时,/proc 目录是最直接的信息来源:
# 定位可疑进程(假设 PID 为 12345)
PID=12345
# 查看进程的真实可执行文件路径(即使进程名被伪装)
ls -la /proc/${PID}/exe
# 输出示例:/proc/12345/exe -> /tmp/.hidden/xmrig (deleted)
# "deleted" 说明文件已被删除但进程仍在运行
# 查看进程启动的完整命令行
cat /proc/${PID}/cmdline | tr '�' ' '
# 查看进程的环境变量(可能包含 C2 地址等关键信息)
cat /proc/${PID}/environ | tr '�' '
' | head -20
# 查看进程打开的文件描述符
ls -la /proc/${PID}/fd/
# 查看进程的网络连接
lsof -p ${PID} -i -n
# 实时跟踪进程的系统调用(谨慎使用,有性能开销)
strace -fp ${PID} -e trace=network,write -o /tmp/strace_${PID}.log &
# 跟踪 10 秒后停止
sleep 10 && kill %1
隐藏文件与后门检测
# 查找隐藏文件和目录(排除正常的 . 和 ..)
find / -name ".*" -not -path "/proc/*" -not -path "/sys/*"
-not -name "." -not -name ".." -ls 2>/dev/null | head -50
# 检查 LD_PRELOAD 劫持(用户态 Rootkit 常用手法)
# 如果有输出,说明存在全局共享库劫持
cat /etc/ld.so.preload 2>/dev/null
echo $LD_PRELOAD
# 对比系统命令是否被替换(用静态编译的 busybox 做对照)
# 正常的 ps 和被劫持的 ps 输出对比
/path/to/busybox ps auxf > /tmp/ps_clean.txt
ps auxf > /tmp/ps_system.txt
diff /tmp/ps_clean.txt /tmp/ps_system.txt
# 如果有差异,说明 ps 命令可能被篡改或存在进程隐藏
# 检查动态链接库是否被篡改
for cmd in ps ls netstat ss top; do
echo "=== ${cmd} ==="
ldd "$(which ${cmd})" 2>/dev/null
done
异常网络连接追踪
# 查看所有对外建立的 TCP 连接(重点关注非常规端口)
ss -tnp state established | awk '{print $4, $5, $6}' | sort -t: -k2 -n
# 从 /proc/net/tcp 解析连接(即使 ss/netstat 被篡改也能获取)
# 字段:本地地址:端口 远端地址:端口 状态(01=ESTABLISHED)
awk '$4 == "01" {print $2, $3}' /proc/net/tcp | while read local remote; do
# 十六进制转十进制 IP
local_ip=$(printf "%d.%d.%d.%d"
0x${local2} 0x${local2} 0x${local2} 0x${local2})
local_port=$((16#${local##*:}))
remote_ip=$(printf "%d.%d.%d.%d"
0x${remote2} 0x${remote2} 0x${remote2} 0x${remote2})
remote_port=$((16#${remote##*:}))
echo "${local_ip}:${local_port} -> ${remote_ip}:${remote_port}"
done
# 外联 IP 威胁情报查询(使用 VirusTotal API)
# 替换为实际的 API Key
VT_API_KEY="your_api_key_here"
SUSPECT_IP="1.2.3.4"
curl -s "https://www.virustotal.com/api/v3/ip_addresses/${SUSPECT_IP}"
-H "x-apikey: ${VT_API_KEY}" | jq '.data.attributes.last_analysis_stats'
挖矿木马清除流程
挖矿木马是当前最常见的入侵后行为,清除需要系统化操作:
#!/bin/bash
set -euo pipefail
# 挖矿木马清除流程
echo "===== 第一步:定位挖矿进程 ====="
# 按 CPU 使用率排序,挖矿进程通常占满 CPU
ps aux --sort=-%cpu | head -10
# 常见挖矿进程名(会伪装成系统进程)
MINERS="xmrig|kdevtmpfsi|kinsing|solrd|dbused|xmr-stak|minerd"
ps aux | grep -iE "${MINERS}" | grep -v grep
echo "===== 第二步:清除恶意文件 ====="
# 根据 /proc/PID/exe 找到实际文件路径并删除
# kill 进程前先记录完整信息
PID=$(pgrep -f "xmrig" || true)
if [ -n "${PID}" ]; then
ls -la /proc/${PID}/exe 2>/dev/null
cat /proc/${PID}/cmdline | tr '�' ' '
kill -9 ${PID}
fi
echo "===== 第三步:清理持久化机制 ====="
# 检查并清理 crontab
for user in $(cut -d: -f1 /etc/passwd); do
crontab -l -u "$user" 2>/dev/null | grep -iE "(curl|wget|.sh|mining|pool)" &&
echo "发现可疑 crontab 条目,用户: $user"
done
# 检查 systemd 服务
find /etc/systemd/system/ /usr/lib/systemd/system/ -name "*.service" -newer /etc/os-release -ls
# 检查 /etc/rc.local 和 /etc/profile.d/
cat /etc/rc.local 2>/dev/null
ls -la /etc/profile.d/
echo "===== 第四步:加固防止复发 ====="
# 修改被利用的入口(如 Redis 未授权访问)
# 更新系统补丁
# 重置所有可能泄露的凭据
echo "请手动完成加固操作"
5.1.3 内存取证基础
磁盘上的文件可以被删除,但只要进程还在运行,内存中就保留着关键信息:
# 查看进程的内存映射
cat /proc/${PID}/maps
# 从进程内存中提取可疑字符串(C2 地址、密钥等)
strings /proc/${PID}/mem 2>/dev/null | grep -iE "(http|https|.onion|password|pool.|stratum)" | sort -u
# 更安全的方式:dump 指定内存区域
# 从 maps 中找到可读写的堆区域
grep "heap" /proc/${PID}/maps
# 输出示例:01a00000-05000000 rw-p 00000000 00:00 0 [heap]
# 使用 gdb 导出内存段(需要 gdb 已安装)
gdb -batch -pid ${PID} -ex "dump memory /tmp/heap_dump.bin 0x01a00000 0x05000000" 2>/dev/null
strings /tmp/heap_dump.bin | grep -iE "(pool.|stratum|wallet)" | head -20
5.2 性能监控
5.2.1 关键安全指标
安全监控和性能监控的区别在于:性能监控关注"系统是否正常",安全监控关注"系统是否被控制"。以下指标需要持续采集:
# SSH 失败登录次数(最近 1 小时)
journalctl -u sshd --since "1 hour ago" --no-pager | grep -c "Failed password"
# SUID 文件数量变化(与基线对比)
find / -type f -perm -4000 2>/dev/null | wc -l
# 基线值记录在 /var/lib/security/suid_baseline.txt
# 异常外联连接数(排除已知业务端口)
ss -tnp state established | awk '{print $5}' | grep -v -E ":(80|443|53|123|514)$" | wc -l
# CPU 使用率 TOP5 进程(挖矿检测)
ps aux --sort=-%cpu | awk 'NR<=6{printf "%-10s %-6s %-6s %s
", $1, $2, $3, $11}'
5.2.2 监控指标说明
| 指标名称 | 正常范围 | 告警阈值 | 说明 |
|---|---|---|---|
| SSH 失败登录/小时 | < 5 | ≥ 20 | 超过阈值触发暴力破解告警 |
| SUID 文件数量 | 与基线一致 | 任何变化 | 新增 SUID 文件可能是提权后门 |
| 异常外联连接数 | 0 | ≥ 1 | 非业务端口外联需立即排查 |
| CPU 单进程占用 | < 80% | ≥ 95% 持续 5 分钟 | 挖矿木马典型特征 |
| /tmp 目录可执行文件数 | 0 | ≥ 1 | 攻击载荷常落地在 /tmp |
| 新增 crontab 条目 | 与基线一致 | 任何变化 | 持久化后门常用手段 |
| 内核模块数量 | 与基线一致 | 任何变化 | 内核级 Rootkit 检测 |
5.2.3 Prometheus 安全指标采集与告警
node_exporter 提供基础系统指标,安全相关的自定义指标需要通过 textfile collector 注入:
#!/bin/bash
set -euo pipefail
# 安全指标采集脚本,由 cron 每分钟执行
# 输出到 node_exporter 的 textfile 目录
TEXTFILE_DIR="/var/lib/prometheus/node-exporter"
PROM_FILE="${TEXTFILE_DIR}/security_metrics.prom"
TMP_FILE="${PROM_FILE}.tmp"
# SSH 失败登录次数(最近 5 分钟)
ssh_failures=$(journalctl -u sshd --since "5 min ago" --no-pager 2>/dev/null | grep -c "Failed password" || echo 0)
echo "security_ssh_failed_logins_5m ${ssh_failures}" > "${TMP_FILE}"
# SUID 文件数量
suid_count=$(find / -type f -perm -4000 2>/dev/null | wc -l)
echo "security_suid_file_count ${suid_count}" >> "${TMP_FILE}"
# 异常外联连接数
abnormal_conn=$(ss -tnp state established 2>/dev/null | awk '{print $5}' | grep -v -E ":(80|443|53|123|514)$" | grep -c "." || echo 0)
echo "security_abnormal_outbound_connections ${abnormal_conn}" >> "${TMP_FILE}"
# /tmp 下可执行文件数
tmp_exec=$(find /tmp /var/tmp /dev/shm -type f -executable 2>/dev/null | wc -l)
echo "security_tmp_executable_count ${tmp_exec}" >> "${TMP_FILE}"
# 原子替换,避免 node_exporter 读到半写文件
mv "${TMP_FILE}" "${PROM_FILE}"
Prometheus 告警规则:
# /etc/prometheus/rules/security_alerts.yml
groups:
- name: security_alerts
rules:
- alert: SSHBruteForceDetected
expr: security_ssh_failed_logins_5m > 20
for: 1m
labels:
severity: warning
annotations:
summary: "SSH 暴力破解检测 - {{ $labels.instance }}"
description: "5 分钟内 SSH 失败登录 {{ $value }} 次"
- alert: SUIDBinaryChanged
expr: changes(security_suid_file_count[1h]) > 0
for: 0m
labels:
severity: critical
annotations:
summary: "SUID 文件数量变化 - {{ $labels.instance }}"
description: "SUID 文件数量发生变化,当前 {{ $value }} 个,可能存在提权后门"
- alert: AbnormalOutboundConnection
expr: security_abnormal_outbound_connections > 0
for: 2m
labels:
severity: warning
annotations:
summary: "异常外联连接 - {{ $labels.instance }}"
description: "检测到 {{ $value }} 个非业务端口外联连接"
- alert: SuspiciousExecutableInTmp
expr: security_tmp_executable_count > 0
for: 1m
labels:
severity: critical
annotations:
summary: "临时目录发现可执行文件 - {{ $labels.instance }}"
description: "/tmp 或 /dev/shm 下存在 {{ $value }} 个可执行文件"
5.3 备份与恢复
5.3.1 系统快照与取证镜像
入侵发生后,第一时间制作磁盘镜像是取证的基础。镜像操作本身不能修改原始数据:
#!/bin/bash
set -euo pipefail
# 磁盘取证镜像脚本
SOURCE_DISK="/dev/sda"
IMAGE_DIR="/mnt/forensic"
TIMESTAMP=$(date +%Y%m%d_%H%M%S)
IMAGE_FILE="${IMAGE_DIR}/disk_image_${TIMESTAMP}.raw"
# dd 全盘镜像(适合离线取证)
# bs=4M 提升速度,conv=noerror,sync 遇到坏块不中断
sudo dd if="${SOURCE_DISK}" of="${IMAGE_FILE}" bs=4M conv=noerror,sync status=progress
# 计算镜像哈希
sha256sum "${IMAGE_FILE}" > "${IMAGE_FILE}.sha256"
echo "镜像完成:${IMAGE_FILE}"
echo "SHA256:$(cat "${IMAGE_FILE}.sha256")"
# LVM 快照方式(适合在线取证,对业务影响小)
# 前提:系统使用 LVM 且 VG 有剩余空间
sudo lvcreate -L 10G -s -n forensic_snap /dev/vg0/root
# 挂载快照为只读
sudo mount -o ro /dev/vg0/forensic_snap /mnt/snapshot
# 取证完成后删除快照
# sudo lvremove /dev/vg0/forensic_snap
5.3.2 入侵后恢复流程
恢复不是简单地"删掉恶意文件然后重启"。不彻底的清理只会让攻击者卷土重来。标准流程:
1. 评估影响范围 ├── 哪些主机被入侵(横向移动排查) ├── 哪些数据可能泄露 ├── 攻击者的入侵路径和驻留时间 └── 是否涉及供应链(被入侵主机是否作为跳板攻击了其他系统) 2. 隔离与遏制 ├── 网络隔离(iptables DROP 所有非管理流量,不要直接拔网线) ├── 保留现场(内存 dump、磁盘镜像) └── 冻结相关账号凭据 3. 清除恶意文件 ├── 根据取证结果定位所有恶意文件 ├── 清理持久化机制(crontab、systemd、rc.local、authorized_keys) ├── 检查并修复被篡改的系统命令 └── 清除内核模块后门(如有) 4. 修复漏洞 ├── 修补被利用的漏洞(系统补丁、应用更新) ├── 关闭不必要的服务和端口 └── 修复错误配置(弱密码、未授权访问) 5. 重建受损系统 ├── 严重入侵建议重装系统(从可信镜像) ├── 从干净备份恢复业务数据 └── 重新部署应用(不要从被入侵主机复制二进制文件) 6. 安全加固 ├── 部署 HIDS(AIDE + auditd + rkhunter) ├── 启用日志远程转发 ├── 实施网络分段 └── 所有凭据轮换(SSH 密钥、数据库密码、API Token) 7. 复盘总结 ├── 编写事件报告(时间线、影响、根因、改进措施) ├── 更新应急预案 └── 安全意识培训
六、总结
6.1 技术要点回顾
文件完整性检测(AIDE)+ Rootkit 扫描(rkhunter/chkrootkit)+ 内核审计(auditd)构成主机入侵检测的三驾马车,缺一不可
日志是安全事件排查的生命线,必须实时转发到远端并设置防篡改属性,本地日志在攻击者拿到 root 后毫无可信度
应急响应遵循"先取证后清除"原则,易失性数据(内存、网络连接、进程信息)的采集优先级高于磁盘数据
纵深防御体系覆盖网络层、主机层、应用层、数据层,每一层都假设上一层已被突破,单点防御在真实攻击面前不堪一击
自动化响应能力决定了 MTTR 的下限,Wazuh + ELK + 自定义 Active Response 脚本实现从检测到遏制的闭环
6.2 进阶学习方向
Wazuh 企业级 HIDS 平台
集成 AIDE 文件完整性、OSSEC 规则引擎、漏洞扫描、合规检查于一体
与 ELK Stack 深度集成,提供统一的安全事件可视化面板
学习资源:Wazuh 官方文档
实践建议:先在测试环境部署单节点,熟悉规则编写后再推广到生产集群
eBPF 实时入侵检测
Falco:CNCF 项目,基于系统调用的运行时威胁检测,规则语法直观
Tetragon:Cilium 团队出品,支持内核级策略执行(不只是检测,还能阻断)
学习资源:Falco 官方文档、Tetragon GitHub
实践建议:eBPF 对内核版本有要求(≥ 4.18),优先在容器化环境中落地
MITRE ATT&CK 框架映射
将检测规则与 ATT&CK 战术/技术编号对应,量化检测覆盖率
识别防御盲区,有针对性地补充检测能力
学习资源:ATT&CK for Linux
6.3 参考资料
CIS Benchmarks - 各操作系统安全基线配置标准
AIDE 官方手册 - 文件完整性检测工具文档
Linux Audit 系统文档 - Red Hat 审计系统配置指南
RFC 3227 - 证据收集指南 - 数字取证证据采集优先级标准
Wazuh 官方文档 - 开源 HIDS 平台部署与规则编写
附录
A. 命令速查表
# ==================== 应急响应命令速查 ====================
# ----- 用户排查 -----
cat /etc/passwd | awk -F: '$3==0{print $1}' # 查找 UID=0 的用户
cat /etc/passwd | awk -F: '$7!~/nologin|false/{print}' # 可登录用户
lastlog | grep -v "Never" # 有登录记录的用户
last -aiF | head -20 # 最近登录历史
grep "sudo" /var/log/auth.log | tail -20 # sudo 操作记录
# ----- 进程排查 -----
ps auxf # 进程树(含父子关系)
ps aux --sort=-%cpu | head -10 # CPU TOP10
ps aux --sort=-%mem | head -10 # 内存 TOP10
ls -la /proc/*/exe 2>/dev/null | grep deleted # 已删除但仍运行的进程
find /proc/*/fd -ls 2>/dev/null | grep deleted # 已删除但被进程持有的文件
# ----- 网络排查 -----
ss -tnlp # 监听端口
ss -tnp state established # 已建立连接
ss -tnp | awk '{print $5}' | sort | uniq -c | sort -rn # 外联 IP 统计
iptables -L -n -v --line-numbers # 防火墙规则
# ----- 文件排查 -----
find / -ctime -1 -type f 2>/dev/null | head -50 # 最近 24 小时变更的文件
find / -name ".*" -type f -not -path "/proc/*" 2>/dev/null # 隐藏文件
find /tmp /var/tmp /dev/shm -type f -executable # 临时目录可执行文件
rpm -Va 2>/dev/null || dpkg --verify 2>/dev/null # 包完整性校验
# ----- 日志排查 -----
grep "Failed password" /var/log/auth.log | tail -20 # SSH 失败登录
grep "Accepted" /var/log/auth.log | tail -20 # SSH 成功登录
ausearch -k privilege_escalation -ts recent # 提权审计事件
journalctl -p 0..3 --since "24 hours ago" --no-pager # 严重级别日志
B. 配置参数详解
auditd 规则语法:
| 参数 | 说明 | 示例 |
|---|---|---|
| -w | 监控文件/目录 | -w /etc/passwd |
| -p | 权限过滤(r读/w写/x执行/a属性变更) | -p wa |
| -k | 规则标签(用于 ausearch 过滤) | -k passwd_changes |
| -a | 追加规则到列表 | -a always,exit |
| -F arch= | CPU 架构过滤 | -F arch=b64 |
| -S | 系统调用过滤 | -S execve |
| -F auid>= | 审计 UID 过滤(排除系统进程) | -F auid>=1000 |
| -F dir= | 目录过滤 | -F dir=/tmp |
| -e 2 | 锁定规则(重启前不可修改) | 必须放在规则文件最后 |
AIDE 监控属性:
| 属性 | 含义 | 推荐使用场景 |
|---|---|---|
| p | 权限 | 所有关键文件 |
| i | inode 号 | 检测文件替换 |
| n | 链接数 | 检测硬链接攻击 |
| u | 用户属主 | 权限变更检测 |
| g | 组属主 | 权限变更检测 |
| s | 文件大小 | 二进制文件篡改检测 |
| sha256 | SHA256 哈希 | 高安全要求场景 |
| md5 | MD5 哈希 | 一般场景(速度快) |
| m | 修改时间 | 配置文件监控 |
| S | 检查文件是否变大 | 日志文件监控 |
常用组合:
NORMAL = p+i+n+u+g+s+m+sha256 — 关键系统文件
DATAONLY = p+n+u+g+s+sha256 — 数据文件(忽略时间戳)
LOG = p+u+g+S — 日志文件(只增不减)
C. 术语表
| 术语 | 英文 | 解释 |
|---|---|---|
| HIDS | Host-based Intrusion Detection System | 主机入侵检测系统,运行在目标主机上监控异常行为 |
| NIDS | Network-based Intrusion Detection System | 网络入侵检测系统,基于流量分析检测攻击 |
| IOC | Indicator of Compromise | 入侵指标,用于识别已发生的安全事件的技术特征 |
| C2/C&C | Command and Control | 命令与控制服务器,攻击者远程操控被入侵主机的通信节点 |
| TTPs | Tactics, Techniques and Procedures | 战术、技术和过程,描述攻击者行为模式的框架 |
| MTTR | Mean Time To Respond | 平均响应时间,从检测到安全事件到完成遏制的时间 |
| ATT&CK | Adversarial Tactics, Techniques & Common Knowledge | MITRE 提出的攻击行为知识库和分类框架 |
| Rootkit | Root Kit | 一组用于隐藏入侵痕迹并维持 root 权限的恶意工具集合 |
| SUID | Set User ID | 文件权限位,执行时以文件属主身份运行而非当前用户 |
| eBPF | extended Berkeley Packet Filter | Linux 内核虚拟机技术,可安全地在内核态运行自定义程序 |
| WAF | Web Application Firewall | Web 应用防火墙,针对 HTTP 层攻击的防护设备 |
| SIEM | Security Information and Event Management | 安全信息与事件管理平台,集中收集和分析安全日志 |
全部0条评论
快来发表一下你的评论吧 !