analyzing-linux-system-artifacts について
インシデント対応担当者やフォレンジック調査者向けに、Linux のシステムアーティファクトを分析するスキルです。アカウント、認証ログ、永続化、コマンド履歴、不審なバイナリを対象に、読み取り専用の収集・分析手順と侵害事例を示します。
主な機能
- 01証拠を読み取り専用でマウントして収集
- 02アカウントと認証記録を確認
- 03cron、systemd、SSH の永続化を分析
- 04シェル履歴とコマンド実行を調査
- 05ルートキットや改変ファイルを検査
活用シーン
- 01侵害された Linux サーバーやワークステーションを調査
- 02SSH 総当たり攻撃後の活動を追跡
- 03Web サーバー侵害と権限昇格を調査
- 04クラウドインスタンスの暗号資産マイニングを調査
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ mukul975/ anthropic-cybersecurity-skills --skill analyzing-linux-system-artifactsインストール後、Claude Code で/analyzing-linux-system-artifactsを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
LICENSEreferences/api-reference.mdscripts/agent.py詳細
Linux システムアーティファクトの分析
使用する場面
- Linux サーバーまたはワークステーションが侵害された際の調査
- 永続化の仕組み(cron、systemd、SSH キー)の特定
- シェル履歴と認証ログを通じたユーザーアクティビティの追跡
- Linux ベースの侵害の範囲を特定するインシデント対応
- ルートキット、バックドア、不正な変更の検出
前提条件
- Linux システムのフォレンジックイメージ、または読み取り専用でのライブアクセス
- Linux ファイルシステム階層(FHS)の理解
- 一般的な Linux ログの保存場所(/var/log/)に関する知識
- ツール:chkrootkit、rkhunter、AIDE、auditd のログ
- systemd、cron、PAM の設定に関する知識
- アーティファクトを完全に収集するための root アクセス
ワークフロー
ステップ 1:システムアーティファクトのマウントと収集
# Mount forensic image read-only
mount -o ro,loop,offset=$((2048*512)) /cases/case-2024-001/images/linux_evidence.dd /mnt/evidence
# Create collection directories
mkdir -p /cases/case-2024-001/linux/{logs,config,users,persistence,network}
# Collect authentication logs
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/
# Collect user artifacts
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
# Collect root user artifacts
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
# Collect system configuration
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:ユーザーアカウントと認証の分析
# Analyze user accounts for anomalies
python3 << 'PYEOF'
print("=== USER ACCOUNT ANALYSIS ===\n")
# Parse /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]
# Flag accounts with UID 0 (root equivalent)
if uid == 0 and username != 'root':
print(f" ALERT: UID 0 account: {username} (shell: {shell})")
# Flag accounts with login shells that shouldn't have them
if shell not in ('/bin/false', '/usr/sbin/nologin', '/bin/sync') and uid >= 1000:
print(f" User: {username} (UID:{uid}, Shell:{shell}, Home:{home})")
# Flag system accounts with login shells
if uid < 1000 and uid > 0 and shell in ('/bin/bash', '/bin/sh', '/bin/zsh'):
print(f" WARNING: System account with shell: {username} (UID:{uid}, Shell:{shell})")
# Parse /etc/shadow for account status
print("\n=== PASSWORD STATUS ===")
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 = 'Unknown'
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 (WEAK)'
print(f" {username}: {hash_type} hash, last changed: day {last_change}")
PYEOF
# Analyze login history
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:永続化の仕組みの調査
# Check cron jobs for all users
echo "=== CRON JOBS ===" > /cases/case-2024-001/linux/persistence/cron_analysis.txt
# System 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
# User cron tabs
for cronfile in /mnt/evidence/var/spool/cron/crontabs/*; do
echo "--- User 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
# Check systemd services for persistence
echo "=== SYSTEMD SERVICES ===" > /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
# Check authorized SSH keys (backdoor detection)
echo "=== SSH AUTHORIZED KEYS ===" > /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
# Check rc.local and init scripts
cat /mnt/evidence/etc/rc.local 2>/dev/null > /cases/case-2024-001/linux/persistence/rc_local.txt
# Check /etc/profile.d/ for login-triggered scripts
ls -la /mnt/evidence/etc/profile.d/ > /cases/case-2024-001/linux/persistence/profile_scripts.txt
# Check for LD_PRELOAD hijacking
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:シェル履歴とコマンド実行の分析
# Analyze bash history for each user
python3 << 'PYEOF'
import os, glob
print("=== SHELL HISTORY ANALYSIS ===\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"User: {username}")
with open(hist_file, 'r', errors='ignore') as f:
lines = f.readlines()
print(f" Total commands: {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" Suspicious commands: {len(flagged)}")
for lineno, cmd in flagged:
print(f" Line {lineno}: {cmd[:120]}")
print()
PYEOF
ステップ 5:ルートキットと変更されたバイナリの確認
# Check for known rootkit indicators
# Compare system binary hashes against known-good
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
# Check for SUID/SGID binaries (potential privilege escalation)
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
# Check for suspicious files in /tmp and /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
# Check for hidden files and directories
find /mnt/evidence/ -name ".*" -not -path "*/\." -type f 2>/dev/null | \
head -100 > /cases/case-2024-001/linux/analysis/hidden_files.txt
# Check kernel modules
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
# Check for modified PAM configuration (authentication backdoors)
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 | Advanced Intrusion Detection Environment。ファイル整合性監視ツール |
| 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 シェルがないか確認します。Web サーバーユーザー(www-data)のアクティビティを分析し、SUID バイナリやカーネルエクスプロイトによる権限昇格がないか確認して、外部への接続を調査します。
シナリオ 3:データベースサーバーでの内部脅威 疑わしいユーザーの bash_history を分析してデータベースダンプのコマンドを確認し、ホームディレクトリや /tmp に大きな tar/zip ファイルがないか調べます。データ転送に scp/rsync コマンドが使われていないか確認し、自動的な情報窃取を目的とした cron ジョブを調査して、USB デバイスのログを確認します。
シナリオ 4:クラウドインスタンス上の暗号資産マイナー /proc 内の高 CPU 負荷プロセス(ライブ環境の場合)または systemd サービスファイルを確認します。マイナーの再起動スクリプトが crontab に登録されていないか調べ、/tmp にマイニング用バイナリがないか確認します。マイニングプールとの通信がないかネットワーク接続を分析し、攻撃者のアクセスに使われる authorized_keys を確認します。
出力形式
Linux Forensics Summary:
System: webserver01 (Ubuntu 22.04 LTS)
Hostname: webserver01.corp.local
Kernel: 5.15.0-91-generic
User Accounts:
Total: 25 (3 with UID 0 - 1 ANOMALOUS)
Interactive shells: 8 users
Recently created: admin2 (created 2024-01-15)
Authentication Events:
Successful SSH logins: 456
Failed SSH attempts: 12,345 (from 23 unique IPs)
Sudo executions: 89
Persistence Mechanisms Found:
Cron jobs: 3 suspicious (reverse shell, miner restart)
Systemd services: 1 unknown (update-checker.service)
SSH keys: 2 unauthorized keys in root authorized_keys
rc.local: Modified with download cradle
Suspicious Activity:
- bash_history contains wget to pastebin URL
- SUID binary /tmp/.hidden/escalate found
- /dev/shm/ contains compiled ELF binary
- LD_PRELOAD in /etc/ld.so.preload pointing to /lib/.hidden.so
Report: /cases/case-2024-001/linux/analysis/