TT Lab
はじめる
学ぶ 学習パス コース

cron が午前三時に curl を叩いた

午前三時の一時間をたどり直す

TT Labで続きを見る

目標

1件のインシデントの4種類のデータを受け取って、調査を一巡します。数え、選び出し、保全し、タイムラインにまとめ、ピボットを設定してクラスターまでたどり、対処の順序を決め、ポストモーテム報告書を書きます。

なぜ重要なのか

アラートが鳴ったあとの30分間に何をするかが、そのインシデントの結末を決めます。慌ててPodを削除してノードを再起動すると、侵入経路が一緒に消え、逆に、証拠を完璧に集めている間に、漏れた資格情報で別のネームスペースが侵害されます。

そのため、対応は「何が正しいか」ではなく「何を先にするか」の問題であり、その順序は、インシデントが起きる前に決めておく必要があります。揮発性が高いものから集める、元には触れない、時刻はUTCに統一する、資格情報の取り消しは先送りしない。こうしたルールは、すべて、誰かが一度ずつ失ってから生まれました。

このラボのデータは合成したものです。その代わり、形式は本物と同じです。FalcoのJSON出力、カーネル監査の原本レコード、journalctl -o jsonのフィールド、Kubernetesの監査イベントを、そのまま使います。

ステップ

  1. 4種類のデータの行数を数えて、/root/ir/01-sources.tsvに保存してください。
  2. 最も早いFalcoのアラートの、ルール名・時刻・PIDを、/root/ir/02-first.jsonに保存してください。
  3. 4種類のデータを/root/ir/evidence/にコピーして、manifest.sha256を残してください。
  4. 4つのソースを1つの時間軸に載せたタイムラインを、/root/ir/04-timeline.tsvに8行以上書いてください。
  5. ピボット4つ(pid・cron-file・c2-host・k8s-identity)を、/root/ir/05-pivot.tsvに、値と根拠で書いてください。
  6. 6つの対処の時点と根拠を、/root/ir/06-containment.tsvに書いてください。
  7. 盗まれたアイデンティティがクラスターで行ったことを、/root/ir/07-k8s.tsvに書いてください。
  8. ポストモーテム報告書を、/root/ir/08-postmortem.mdに書いてください。

参考

何があるかを数える

/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)。本文には、コマンドアンドコントロールのアドレス、資格情報が使われたネームスペース、見つかった永続化手段のパスが出てくる必要があります。

## 탐지 공백(韓国語の見出しで、「検知ギャップ」という意味です)が、この報告書で最も重要な節です。ルールがなかったのか、アラートが誰も見ない場所に行ったのか、ログそのものがなかったのかは、まったく別の処方につながります。人の名前で終わる報告書は、来週に同じ事故を招きます。