分析 Linux 系統遺留物 是做什麼的?
使用時機
- 調查受入侵的 Linux 伺服器或工作站時
- 用於識別持久化機制(cron、systemd、SSH 金鑰)
- 透過 Shell 歷史和身份驗證日誌追蹤用戶活動時
- 在事件應變中確定 Linux 漏洞的影響範圍
- 用於檢測 Rootkit、後門及未經授權的修改
前提條件
- 取證映像或對 Linux 系統的唯讀即時存取權限
- 了解 Linux 檔案系統層級標準(FHS)
- 熟悉常見 Linux 日誌存放位置(/var/log/)
- 工具:chkrootkit、rkhunter、AIDE、auditd 日誌
- 熟悉 systemd、cron 與 PAM 設定
- 完整的遺留物收集需要 root 權限
工作流程
步驟 1:掛載並收集系統遺留物
# 以唯讀模式掛載取證映像
mount -o ro,loop,offset=$((2048*512)) /cases/case-2024-001/images/linux_evidence.dd /mnt/evidence
# 建立收集目錄
mkdir -p /cases/case-2024-001/linux/{logs,config,users,persistence,network}
# 收集身份驗證日誌
cp /mnt/evidence/var/log/auth.log* /cases/case-2024-001/linux/logs/
cp /mnt/evidence/var/log/secure* /cases/case-2024-001/linux/logs/
cp /mnt/evidence/var/log/syslog* /cases/case-2024-001/linux/logs/
cp /mnt/evidence/var/log/kern.log* /cases/case-2024-001/linux/logs/
cp /mnt/evidence/var/log/audit/audit.log* /cases/case-2024-001/linux/logs/
cp /mnt/evidence/var/log/wtmp /cases/case-2024-001/linux/logs/
cp /mnt/evidence/var/log/btmp /cases/case-2024-001/linux/logs/
cp /mnt/evidence/var/log/lastlog /cases/case-2024-001/linux/logs/
cp /mnt/evidence/var/log/faillog /cases/case-2024-001/linux/logs/
# 收集用戶遺留物
for user_dir in /mnt/evidence/home/*/; do
username=$(basename "$user_dir")
mkdir -p /cases/case-2024-001/linux/users/$username
cp "$user_dir"/.bash_history /cases/case-2024-001/linux/users/$username/ 2>/dev/null
cp "$user_dir"/.zsh_history /cases/case-2024-001/linux/users/$username/ 2>/dev/null
cp -r "$user_dir"/.ssh/ /cases/case-2024-001/linux/users/$username/ 2>/dev/null
cp "$user_dir"/.bashrc /cases/case-2024-001/linux/users/$username/ 2>/dev/null
cp "$user_dir"/.profile /cases/case-2024-001/linux/users/$username/ 2>/dev/null
cp "$user_dir"/.viminfo /cases/case-2024-001/linux/users/$username/ 2>/dev/null
cp "$user_dir"/.wget-hsts /cases/case-2024-001/linux/users/$username/ 2>/dev/null
cp "$user_dir"/.python_history /cases/case-2024-001/linux/users/$username/ 2>/dev/null
done
# 收集 root 用戶遺留物
cp /mnt/evidence/root/.bash_history /cases/case-2024-001/linux/users/root/ 2>/dev/null
cp -r /mnt/evidence/root/.ssh/ /cases/case-2024-001/linux/users/root/ 2>/dev/null
# 收集系統設定
cp /mnt/evidence/etc/passwd /cases/case-2024-001/linux/config/
cp /mnt/evidence/etc/shadow /cases/case-2024-001/linux/config/
cp /mnt/evidence/etc/group /cases/case-2024-001/linux/config/
cp /mnt/evidence/etc/sudoers /cases/case-2024-001/linux/config/
cp -r /mnt/evidence/etc/sudoers.d/ /cases/case-2024-001/linux/config/
cp /mnt/evidence/etc/hosts /cases/case-2024-001/linux/config/
cp /mnt/evidence/etc/resolv.conf /cases/case-2024-001/linux/config/
cp -r /mnt/evidence/etc/ssh/ /cases/case-2024-001/linux/config/
步驟 2:分析用戶帳戶與身份驗證
# 分析帳戶異常
python3 << 'PYEOF'
print("=== 用戶帳戶分析 ===\n")
# 解析 /etc/passwd
with open('/cases/case-2024-001/linux/config/passwd') as f:
for line in f:
parts = line.strip().split(':')
if len(parts) >= 7:
username, _, uid, gid, comment, home, shell = parts[0], parts[1], int(parts[2]), int(parts[3]), parts[4], parts[5], parts[6]
# 標記 UID 0 帳戶(等同 root)
if uid == 0 and username != 'root':
print(f" 警報:UID 0 帳戶:{username}(Shell:{shell})")
# 標記擁有登入 Shell 但不應該有的帳戶
if shell not in ('/bin/false', '/usr/sbin/nologin', '/bin/sync') and uid >= 1000:
print(f" 用戶:{username}(UID:{uid},Shell:{shell},家目錄:{home})")
# 標記擁有登入 Shell 的系統帳戶
if uid < 1000 and uid > 0 and shell in ('/bin/bash', '/bin/sh', '/bin/zsh'):
print(f" 警告:系統帳戶含有 Shell:{username}(UID:{uid},Shell:{shell})")
# 解析 /etc/shadow 以取得帳戶狀態
print("\n=== 密碼狀態 ===")
with open('/cases/case-2024-001/linux/config/shadow') as f:
for line in f:
parts = line.strip().split(':')
if len(parts) >= 3:
username = parts[0]
pwd_hash = parts[1]
last_change = parts[2]
if pwd_hash and pwd_hash not in ('*', '!', '!!', ''):
hash_type = '未知'
if pwd_hash.startswith('$6$'): hash_type = 'SHA-512'
elif pwd_hash.startswith('$5$'): hash_type = 'SHA-256'
elif pwd_hash.startswith('$y$'): hash_type = 'yescrypt'
elif pwd_hash.startswith('$1$'): hash_type = 'MD5(弱)'
print(f" {username}:{hash_type} 雜湊,最後變更:第 {last_change} 天")
PYEOF
# 分析登入歷史
last -f /cases/case-2024-001/linux/logs/wtmp > /cases/case-2024-001/linux/analysis/login_history.txt
lastb -f /cases/case-2024-001/linux/logs/btmp > /cases/case-2024-001/linux/analysis/failed_logins.txt 2>/dev/null
步驟 3:檢查持久化機制
# 檢查所有用戶的 cron 任務
注:以下輸出內容已翻譯,但程式碼部分保持原樣
cat > /cases/case-2024-001/linux/persistence/cron_analysis.txt << 'EOF'
=== CRON 任務 ===
EOF
# 系統 cron
for cronfile in /mnt/evidence/etc/crontab /mnt/evidence/etc/cron.d/*; do
echo "--- $cronfile ---" >> /cases/case-2024-001/linux/persistence/cron_analysis.txt
cat "$cronfile" 2>/dev/null >> /cases/case-2024-001/linux/persistence/cron_analysis.txt
echo "" >> /cases/case-2024-001/linux/persistence/cron_analysis.txt
done
# 用戶 crontab
for cronfile in /mnt/evidence/var/spool/cron/crontabs/*; do
echo "--- 用戶 crontab:$(basename $cronfile) ---" >> /cases/case-2024-001/linux/persistence/cron_analysis.txt
cat "$cronfile" 2>/dev/null >> /cases/case-2024-001/linux/persistence/cron_analysis.txt
echo "" >> /cases/case-2024-001/linux/persistence/cron_analysis.txt
done
# 檢查 systemd 服務以取得持久化資訊
echo "=== SYSTEMD 服務 ===" > /cases/case-2024-001/linux/persistence/systemd_analysis.txt
find /mnt/evidence/etc/systemd/system/ -name "*.service" -newer /mnt/evidence/etc/os-release \
>> /cases/case-2024-001/linux/persistence/systemd_analysis.txt
for svc in /mnt/evidence/etc/systemd/system/*.service; do
echo "--- $(basename $svc) ---" >> /cases/case-2024-001/linux/persistence/systemd_analysis.txt
cat "$svc" >> /cases/case-2024-001/linux/persistence/systemd_analysis.txt
echo "" >> /cases/case-2024-001/linux/persistence/systemd_analysis.txt
done
# 檢查已授權的 SSH 金鑰(後門檢測)
echo "=== SSH 已授權金鑰 ===" > /cases/case-2024-001/linux/persistence/ssh_keys.txt
find /mnt/evidence/home/ /mnt/evidence/root/ -name "authorized_keys" -exec sh -c \
'echo "--- {} ---"; cat {}; echo ""' \; >> /cases/case-2024-001/linux/persistence/ssh_keys.txt
# 檢查 rc.local 與 init 腳本
cat /mnt/evidence/etc/rc.local 2>/dev/null > /cases/case-2024-001/linux/persistence/rc_local.txt
# 檢查 /etc/profile.d/ 中的登入觸發腳本
ls -la /mnt/evidence/etc/profile.d/ > /cases/case-2024-001/linux/persistence/profile_scripts.txt
# 檢查 LD_PRELOAD 劫持
grep -r "LD_PRELOAD" /mnt/evidence/etc/ 2>/dev/null > /cases/case-2024-001/linux/persistence/ld_preload.txt
cat /mnt/evidence/etc/ld.so.preload 2>/dev/null >> /cases/case-2024-001/linux/persistence/ld_preload.txt
步驟 4:分析 Shell 歷史與命令執行
# 分析每個用戶的 bash 歷史
python3 << 'PYEOF'
import os, glob
print("=== SHELL 歷史分析 ===\n")
suspicious_commands = [
'wget', 'curl', 'nc ', 'ncat', 'netcat', 'python -c', 'python3 -c',
'perl -e', 'base64', 'chmod 777', 'chmod +s', '/dev/tcp', '/dev/udp',
'nmap', 'masscan', 'hydra', 'john', 'hashcat', 'passwd', 'useradd',
'iptables -F', 'ufw disable', 'history -c', 'rm -rf /', 'dd if=',
'crontab', 'at ', 'systemctl enable', 'ssh-keygen', 'scp ', 'rsync',
'tar czf', 'zip -r', 'openssl enc', 'gpg --encrypt', 'shred',
'chattr', 'setfacl', 'awk', '/tmp/', '/dev/shm/'
]
for hist_file in glob.glob('/cases/case-2024-001/linux/users/*/.bash_history'):
username = hist_file.split('/')[-2]
print(f"用戶:{username}")
with open(hist_file, 'r', errors='ignore') as f:
lines = f.readlines()
print(f" 命令總數:{len(lines)}")
flagged = []
for i, line in enumerate(lines):
line = line.strip()
for cmd in suspicious_commands:
if cmd in line.lower():
flagged.append((i+1, line))
break
if flagged:
print(f" 可疑命令:{len(flagged)}")
for lineno, cmd in flagged:
print(f" 第 {lineno} 行:{cmd[:120]}")
print()
PYEOF
步驟 5:檢查 Rootkit 與被修改的二進位檔
# 檢查已知 Rootkit 指標
# 將系統二進位檔雜湊值與已知良好值比對
find /mnt/evidence/usr/bin/ /mnt/evidence/usr/sbin/ /mnt/evidence/bin/ /mnt/evidence/sbin/ \
-type f -executable -exec sha256sum {} \; > /cases/case-2024-001/linux/analysis/binary_hashes.txt
# 檢查 SUID/SGID 二進位檔(潛在的權限提升)
find /mnt/evidence/ -perm -4000 -type f 2>/dev/null > /cases/case-2024-001/linux/analysis/suid_files.txt
find /mnt/evidence/ -perm -2000 -type f 2>/dev/null > /cases/case-2024-001/linux/analysis/sgid_files.txt
# 檢查 /tmp 與 /dev/shm 中的可疑檔案
find /mnt/evidence/tmp/ /mnt/evidence/dev/shm/ -type f 2>/dev/null \
-exec file {} \; > /cases/case-2024-001/linux/analysis/tmp_files.txt
# 檢查隱藏檔案與目錄
find /mnt/evidence/ -name ".*" -not -path "*/\.." -type f 2>/dev/null | \
head -100 > /cases/case-2024-001/linux/analysis/hidden_files.txt
# 檢查核心模組
ls -la /mnt/evidence/lib/modules/$(ls /mnt/evidence/lib/modules/ | head -1)/extra/ 2>/dev/null \
> /cases/case-2024-001/linux/analysis/extra_modules.txt
# 檢查修改過的 PAM 設定(身份驗證後門)
diff /mnt/evidence/etc/pam.d/ /cases/baseline/pam.d/ 2>/dev/null \
> /cases/case-2024-001/linux/analysis/pam_changes.txt
關鍵概念
| 概念 | 說明 |
|---|---|
| /var/log/auth.log | Debian/Ubuntu 系統的主要身份驗證日誌 |
| /var/log/secure | RHEL/CentOS 系統的主要身份驗證日誌 |
| wtmp/btmp | 記錄成功與失敗登入會話的二進位日誌 |
| .bash_history | 用戶命令歷史檔案(可被攻擊者清除) |
| crontab | 常用於持久化的排程任務系統 |
| authorized_keys | 授予帳戶無密碼存取的 SSH 公鑰 |
| SUID 位元 | 允許以檔案擁有者身份執行的檔案權限(權限提升向量) |
| LD_PRELOAD | 在所有其他共享函式庫之前載入的環境變數(掛鉤技術) |
工具與系統
| 工具 | 用途 |
|---|---|
| chkrootkit | Linux 系統的 Rootkit 檢測掃描器 |
| rkhunter | Rootkit Hunter - 檢查 Rootkit、後門與本地漏洞 |
| AIDE | 進階入侵偵測環境 - 檔案完整性監控器 |
| auditd | 用於系統呼叫與檔案存取監控的 Linux 稽核框架 |
| last/lastb | 解析 wtmp/btmp 以取得登入與失敗登入歷史 |
| Plaso/log2timeline | 建立包含 Linux 遺留物的超級時間線 |
| osquery | 用於即時取證調查的 SQL 式系統查詢工具 |
| Velociraptor | 具備 Linux 遺留物收集能力的端點代理 |
常見情境
情境 1:SSH 暴力破解後遭入侵 分析 auth.log 中失敗的 SSH 嘗試後接成功,識別攻擊 IP,檢查 .bash_history 中的入侵後命令,檢查 authorized_keys 中新增的後門金鑰,檢查 crontab 以取得持久化資訊,審查網路連線。
情境 2:Web 伺服器因應用程式漏洞被入侵 檢查 Web 伺服器存取與錯誤日誌中的利用嘗試,檢查 /tmp 與 /dev/shm 中的 Webshell,分析 Web 伺服器用戶(www-data)的活動,檢查經由 SUID 二進位檔或核心漏洞的權限提升,審查對外連線。
情境 3:資料庫伺服器的內部威脅 分析可疑用戶的 bash_history 中的資料庫匯出命令,檢查家目錄或 /tmp 中的大型 tar/zip 檔案,檢查 scp/rsync 命令中的資料傳輸,審查 cron 任務中的自動化竊取行為,檢查 USB 裝置日誌。
情境 4:雲端實例中的加密貨幣挖礦程式 檢查 /proc(即時)或 systemd 服務檔案中的高 CPU 處理程序,檢查 crontab 項目中的挖礦程式中止重啟腳本,檢查 /tmp 中的挖礦二進位檔,分析網路連線中的礦池通訊,審查 authorized_keys 以取得攻擊者存取權。
輸出格式
Linux 取證摘要:
系統:webserver01(Ubuntu 22.04 LTS)
主機名稱:webserver01.corp.local
核心:5.15.0-91-generic
用戶帳戶:
總計:25(3 個 UID 0 - 1 異常)
互動式 Shell:8 個用戶
最近建立:admin2(建立於 2024-01-15)
身份驗證事件:
成功的 SSH 登入:456 次
失敗的 SSH 嘗試:12,345 次(來自 23 個不同 IP)
Sudo 執行次數:89 次
發現的持久化機制:
Cron 任務:3 個可疑(反向 shell、挖礦程式中止重啟)
Systemd 服務:1 個未知(update-checker.service)
SSH 金鑰:root 的 authorized_keys 中有 2 個未授權金鑰
rc.local:已修改,包含下載啟動器
可疑活動:
- bash_history 包含 wget 到 pastebin 網址
- SUID 二進位檔 /t
…(截斷以進行翻譯)