ログを消す攻撃者は「プロ」である。auditdで「見えない足跡」を可視化せよ
システムに侵入した攻撃者がまず行うこと、それは rm -rf /var/log/* だ。
初心者はログをファイルシステムに保存して安心するが、インシデント対応の現場に立つ我々からすれば、ローカルログなど「消してくださいと言わんばかりの脆弱な記録」に過ぎない。
今日は、Linuxの深淵、システムコールレベルでの監視を司る auditd を用いて、攻撃者が「何をしようとしたのか」を確実に記録し、それを即座にリモートへ退避させる「要塞化の極意」を授ける。
—
なぜ auditd なのか:特権操作は「嘘」をつく
WebアプリケーションのログやNginxのアクセスログは、あくまで「アプリケーション層」の記録だ。攻撃者が特権昇格(SUIDバイナリの悪用など)やカーネルモジュールのロードを行った場合、アプリ層のログには何も残らない。
auditd はカーネル内部で動作する。誰が execve を叩いたか、どのファイルに write 権限を行使したかを、システムコールレベルで捕捉する。これは攻撃者にとって「逃げ場のない監視網」となる。
ステップ1:重要操作を確実にフックする設定
まずは /etc/audit/rules.d/audit.rules を編集し、監視ルールを定義する。以下の設定は、インシデントの初動調査で必須となる「証拠の断片」を確実に記録する最小構成だ。
# -w: 監視対象のパス
# -p: 監視する操作 (w=書き込み, a=属性変更)
# -k: ログ検索時に使うキー文字列
# パスワードファイルへの不正な変更を監視
-w /etc/passwd -p wa -k identity_change
-w /etc/shadow -p wa -k identity_change
# 特権操作や実行ファイルの変更を監視
-w /usr/bin/sudo -p x -k privilege_escalation
-w /etc/sudoers -p wa -k sudoers_change
# 攻撃者がよく利用するディレクトリを監視
-w /tmp -p wa -k tmp_access
設定を反映するには auditctl -R /etc/audit/rules.d/audit.rules を実行する。これで、誰かが /etc/shadow に手を出せば、即座に監査ログに詳細が記録される。
—
ログを「盗ませない」:リモート転送の重要性
現場で最も多い失敗は、監査ログを同じサーバー内に溜め込んでいることだ。攻撃者は侵入後、まずログファイルを検索して消去する。これを防ぐには、audisp-remote を使い、ログをリアルタイムで外部(SIEMやログサーバー)に飛ばす必要がある。
auditdのリモート転送設定 (audit-remote.conf)
/etc/audisp/audisp-remote.conf を以下のように設定し、外部のログ収集サーバーへ転送する。
# ログサーバーのIPアドレスを指定
remote_server = 192.168.1.100
# 転送ポート(デフォルトは60)
port = 60
# 転送が途切れた時の挙動(ログ消失を防ぐため、送信不可ならシステムを停止させる設定)
mode = immediate
transport = tcp
queue_depth = 2048
※この設定により、万が一ログサーバーへの送信が遮断された場合、サーバー全体の動作を一時停止させることで、攻撃者の足跡が消えるのを防ぐことができる。
—
インシデント発生時の検知コード(Pythonサンプル)
監査ログは膨大になる。全てを人間が追うのは不可能だ。Pythonを用いて、特定の重要キー(例:privilege_escalation)がログに出力された瞬間にSlackへアラートを飛ばすスクリプトを常駐させておくと、初動が劇的に早まる。
import subprocess
import time
# 監査ログを監視するコマンド
cmd = ["ausearch", "-k", "privilege_escalation", "-i"]
def monitor_audit_logs():
while True:
# ログをポーリングして監視
process = subprocess.Popen(cmd, stdout=subprocess.PIPE)
output, _ = process.communicate()
if output:
# ここでSlack API等を叩いて通知する
print(f"警告: 特権操作を検知しました: {output.decode('utf-8')}")
time.sleep(10) # 10秒おきにチェック
if __name__ == "__main__":
monitor_audit_logs()
—
エンジニアへのアドバイス:過信は禁物
auditd を入れれば完璧、というのは幻想だ。攻撃者はログを消すだけでなく、監査プロセスそのものを一時的に無効化(auditctl -e 0)しようとする。
1. 監査ログの監査: auditd の設定ファイルそのものに誰がアクセスしたかを監視せよ。
2. 書き込み専用ストレージ: リモートログサーバー側では、受信したログを絶対に修正できないよう、WORM(Write Once Read Many)ストレージや、S3のオブジェクトロック機能を活用せよ。
「防壁を築くだけ」のエンジニアはすぐに見抜かれる。我々の仕事は、「侵入された後に、いかにして攻撃者を追い詰めるか」を前提とした設計をすることだ。
ログはサーバーの「遺言」である。その遺言を、攻撃者が握りつぶせない場所に保存することこそが、プロフェッショナルなセキュリティエンジニアの矜持だ。ぜひ今夜、君のサーバーの設定を見直してみてほしい。
コメント