Linuxシステムアーティファクト分析 は何をしますか?
使用すべきタイミング
- 侵害されたLinuxサーバーやワークステーションを調査する場合
- 永続化メカニズム(cron、systemd、SSH鍵)を特定する場合
- シェル履歴と認証ログを通じてユーザー活動を追跡する場合
- インシデント対応においてLinuxベースの侵害範囲を特定する場合
- ルートキット、バックドア、不正な変更を検出する場合
前提条件
- フォレンジックイメージまたはLinuxシステムへのライブアクセス(読み取り専用)
- Linuxファイルシステム階層(FHS)の理解
- 一般的なLinuxログ出力場所(/var/log/)の知識
- ツール: chkrootkit、rkhunter、AIDE、auditdログ
- systemd、cron、PAM設定に関する知識
- 完全なアーティファクト収集のためのルートアクセス
ワークフロー
ステップ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})")
# 持ちべきでないログインシェルを持つアカウントにフラグを立てる
if shell not in ('/bin/false', '/usr/sbin/nologin', '/bin/sync') and uid >= 1000:
print(f" ユーザー: {username} (UID:{uid}, シェル:{shell}, ホーム:{home})")
# ログインシェルを持つシステムアカウントにフラグを立てる
if uid < 1000 and uid > 0 and shell in ('/bin/bash', '/bin/sh', '/bin/zsh'):
print(f" 警告: シェルを持つシステムアカウント: {username} (UID:{uid}, シェル:{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ジョブを確認
echo "=== CRONジョブ ===" > /cases/case-2024-001/linux/persistence/cron_analysis.txt
# システム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
# ユーザーcronテーブル
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: シェル履歴とコマンド実行の分析
# 各ユーザーのbash履歴を分析
python3 << 'PYEOF'
import os, glob
print("=== シェル履歴分析 ===\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: ルートキットと改変バイナリの確認
# 既知のルートキット指標を確認
# システムバイナリのハッシュを既知の良好なものと比較
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システム用ルートキット検出スキャナー |
| rkhunter | ルートキット、バックドア、ローカルエクスプロイトを確認するRootkit Hunter |
| 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でウェブシェルを確認し、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 (UID 0を持つもの: 3 - うち1つは異常)
インタラクティブシェル: 8ユーザー
最近作成されたもの: admin2 (2024-01-15作成)
認証イベント:
成功したSSHログイン: 456
失敗したSSH試行: 12,345 (23のユニークIPから)
sudo実行: 89
見つかった永続化メカニズム:
Cronジョブ: 3つが疑わしい(リバースシェル、マイナー再起動)
Systemdサービス: 1つが不明(update-checker.service)
SSH鍵: rootのauthorized_keysに2つの不正な鍵
rc.local: ダウンロードクレードルで改変
疑わしいアクティビティ:
- bash_historyにpastebin URLへのwgetが含まれている
- SUIDバイナリ /t