午前三時の一時間をたどり直す
目標
1件のインシデントの4種類のデータを受け取って、調査を一巡します。数え、選び出し、保全し、タイムラインにまとめ、ピボットを設定してクラスターまでたどり、対処の順序を決め、ポストモーテム報告書を書きます。
なぜ重要なのか
アラートが鳴ったあとの30分間に何をするかが、そのインシデントの結末を決めます。慌ててPodを削除してノードを再起動すると、侵入経路が一緒に消え、逆に、証拠を完璧に集めている間に、漏れた資格情報で別のネームスペースが侵害されます。
そのため、対応は「何が正しいか」ではなく「何を先にするか」の問題であり、その順序は、インシデントが起きる前に決めておく必要があります。揮発性が高いものから集める、元には触れない、時刻はUTCに統一する、資格情報の取り消しは先送りしない。こうしたルールは、すべて、誰かが一度ずつ失ってから生まれました。
このラボのデータは合成したものです。その代わり、形式は本物と同じです。FalcoのJSON出力、カーネル監査の原本レコード、journalctl -o jsonのフィールド、Kubernetesの監査イベントを、そのまま使います。
ステップ
- 4種類のデータの行数を数えて、
/root/ir/01-sources.tsvに保存してください。 - 最も早いFalcoのアラートの、ルール名・時刻・PIDを、
/root/ir/02-first.jsonに保存してください。 - 4種類のデータを
/root/ir/evidence/にコピーして、manifest.sha256を残してください。 - 4つのソースを1つの時間軸に載せたタイムラインを、
/root/ir/04-timeline.tsvに8行以上書いてください。 - ピボット4つ(
pid・cron-file・c2-host・k8s-identity)を、/root/ir/05-pivot.tsvに、値と根拠で書いてください。 - 6つの対処の時点と根拠を、
/root/ir/06-containment.tsvに書いてください。 - 盗まれたアイデンティティがクラスターで行ったことを、
/root/ir/07-k8s.tsvに書いてください。 - ポストモーテム報告書を、
/root/ir/08-postmortem.mdに書いてください。
参考
- データは
/opt/lab/fixtures/detection/incident/の下にあります:falco.jsonl、audit.log、cron.jsonl、kube-audit.jsonl。そして、ログではない参考資料として、host-facts.jsonがあります。 - ステップ4のソース名は、
falco・auditd・cron・kube-auditの4つのいずれかで書きます。時刻は2026-03-14T03:00:04Zの形です。 - ステップ6の対処名は、
메모리 수집・네트워크 차단・프로세스 종료・예약 작업 제거・자격증명 폐기・노드 재설치の6つで、時点は지금・나중・안함のいずれかです(韓国語で、対処名は順に「メモリの取得」「ネットワークの遮断」「プロセスの終了」「スケジュールされたジョブの削除」「資格情報の取り消し」「ノードの再インストール」、時点は順に「今」「あとで」「しない」を意味します)。 - ステップ7は、拒否された(403)リクエストも行為です。除かないでください。
- よくある間違い: カーネル監査の原本の時刻はエポック秒です。
date -u -d @<초>(プレースホルダーは秒数です)で変換してみてください。 - よくある間違い: 元のファイルをエディターで開いて直してしまう場合です。元は読み取り専用として扱い、コピーだけを見ます。
何があるかを数える
/opt/lab/fixtures/detection/incident/のfalco.jsonl・audit.log・cron.jsonl・kube-audit.jsonlの4つのファイルの行数を数えて、1行ずつ파일이름<탭>줄수の形式(プレースホルダーは順に、ファイル名、タブ、行数です)で保存してください(保存先: /root/ir/01-sources.tsv)。
wc -lでよいです。調査でこのステップを飛ばすと、あとで「そのログもあったのか」が出てきます。
最初のアラートを選び出す
falco.jsonlから最も早いアラートを探し、ルール名・時刻・PIDを{"rule": …, "time": …, "pid": …}の形で保存してください(保存先: /root/ir/02-first.json)。
jq -s 'min_by(.time)'で、最も早いものを選べます。PIDはoutput_fieldsの中にあります。時刻は、ファイルに書かれた値をそのまま使います。
元に触れずに保全する
4種類のデータを証拠用のディレクトリ(/root/ir/evidence/)にコピーし、そのディレクトリでsha256sum -cで検証できるマニフェスト(/root/ir/evidence/manifest.sha256)を作成してください。
sha256sum <파일들> > manifest.sha256は、相対パスで書きます(プレースホルダーはファイルです)。検証は、そのディレクトリの中でsha256sum -c manifest.sha256で行います。
1つの時間軸に載せる
4つのソースの記録を、시각<탭>출처<탭>행위자<탭>무슨 일の4列(プレースホルダーは、時刻・ソース・アクター・何が起きたかの各列と、その区切りのタブです)で、時刻の昇順に8行以上書いてください(保存先: /root/ir/04-timeline.tsv)。4つのソースがすべて1回以上出てくる必要があります。
ソース名はfalco・auditd・cron・kube-auditに統一します。カーネル監査の原本のエポック秒は、date -u -d @<초> +%Y-%m-%dT%H:%M:%SZで変換します(プレースホルダーは秒数です)。journaldの__REALTIME_TIMESTAMPは、マイクロ秒です。
ピボットを設定して飛び移る
4行を축<탭>값<탭>근거の形式(プレースホルダーは、軸・値・根拠の各列と、その区切りのタブです)で書いてください(保存先: /root/ir/05-pivot.tsv)。軸の名前はpid・cron-file・c2-host・k8s-identityで、根拠には、どのファイルの何を見てそう判断したのかを、10文字以上書きます。
pidは、一時ディレクトリで実行されたプロセスのものです。cron-fileは、その夜に新しくできたスケジュールされたジョブで、カーネル監査の原本のPATHレコードにあります。k8s-identityは、監査ログのuser.usernameです。
何を先にするか
6つの対処を、조치<탭>시점<탭>근거の形式(プレースホルダーは、対処・時点・根拠の各列と、その区切りのタブです)で書いてください(保存先: /root/ir/06-containment.tsv)。時点は지금・나중・안함(韓国語で、順に「今」「あとで」「しない」を意味する語です)のいずれかで、根拠は20文字以上です。
揮発性が高いものから集めます。そして、ノードを止めても有効なものが1つあります。それは先送りできません。
盗まれたアイデンティティがクラスターでしたこと
kube-audit.jsonlから、system:node:edge-07が行ったリクエストをすべて探し、verb<탭>리소스<탭>네임스페이스<탭>이름<탭>응답코드の5列(プレースホルダーは、verb・リソース・ネームスペース・名前・レスポンスコードの各列と、その区切りのタブです)で書いてください(保存先: /root/ir/07-k8s.tsv)。ネームスペースや名前がなければ、-と書きます。
jq -r 'select(.user.username == …)'で絞り込みます。拒否されたリクエスト(403)も行為です。何を試みたかが、意図を語ってくれます。
来週を変える文章
## 요약・## 타임라인・## 영향・## 원인・## 탐지 공백・## 재발 방지(韓国語の見出しで、順に「要約」「タイムライン」「影響」「原因」「検知ギャップ」「再発防止」という意味です)の6つの節を書いてください(保存先: /root/ir/08-postmortem.md)。本文には、コマンドアンドコントロールのアドレス、資格情報が使われたネームスペース、見つかった永続化手段のパスが出てくる必要があります。
## 탐지 공백(韓国語の見出しで、「検知ギャップ」という意味です)が、この報告書で最も重要な節です。ルールがなかったのか、アラートが誰も見ない場所に行ったのか、ログそのものがなかったのかは、まったく別の処方につながります。人の名前で終わる報告書は、来週に同じ事故を招きます。