hunting-threats について
アラートが見逃した可能性のある活動を能動的に探す、セキュリティチーム向けの脅威ハンティングスキルです。検証可能な仮説、テレメトリの確認、否定的な結果を含む記録を重視します。
主な機能
- 01検証可能なハンティング仮説の作成
- 02テレメトリ確認とスコープ設定
- 03頻度・外れ値・クラスタ分析
- 04脅威レポートに基づく攻撃手法の探索
- 05結果の記録と後続アクションへの転換
活用シーン
- 01アラートが見逃した侵害の探索
- 02環境内の特定の攻撃者行動の検証
- 03本番環境での制御や検知範囲の確認
- 04将来の異常分析に向けたベースライン作成
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ trilwu/ secskills --skill hunting-threatsインストール後、Claude Code で/hunting-threatsを入力して読み込まれたか確認します。
詳細
脅威ハンティング
ハンティングは、失敗を前提として始めます。制御は導入済みで、アラートは発生していませんが、攻撃者がまだ侵入している可能性があります。通常、その成果は侵害ではなく、検知、テレメトリーの欠落、または記録された否定的な結果です。何かを見つけたときだけ成功とみなすハンティングは、確証バイアスを強めてしまいます。
使用する場面
- 検知をすり抜けた侵害を積極的に探す場合
- 環境内の攻撃者の行動に関する特定の仮説を検証する場合
- 脅威インテリジェンスレポートを自組織のテレメトリーに適用する場合
- 制御や検知が本番環境で実際に機能するか検証する場合
- 今後の外れ値分析に備えて環境のベースラインを確立する場合
使用しない場面
- 仮説ではなく、アラートキューに対応する場合 —
triaging-security-alertsを使用します。ハンティングは疑問から始まり、トリアージはキューから始まります - インシデントが確認され、対応が進行中の場合 —
responding-to-incidentsを使用します - 見つかったものに対するルールを作成する場合 —
engineering-detectionsを使用します - サンプルを分析する場合 —
analyzing-malwareを使用します - 調査対象のパケットキャプチャがある場合 —
analyzing-network-trafficを使用します - AWS で確認された侵害を調査する場合 —
investigating-aws-incidentsを使用します - インジケーターを手掛かりに調査し、攻撃者を追跡する場合、または完成したインテリジェンス成果物を作成する場合 —
producing-threat-intelligenceを使用します。ハンティングはインテリジェンスを利用するものであり、作成するものではありません - 防御の攻撃的なテストを行う場合 — レッドチームのスキルを使用します
クエリの前に仮説を立てる
ログを無計画に検索するのは閲覧であり、ハンティングではありません。すべてのハンティングで、次の形式の仮説を文書化します。
仮説: [アクセスレベル] の攻撃者が [手法] を使って [目的] を達成しようとしており、[データソース] に [観測可能なもの] が現れるはずです。これは [判別要因] によって通常のものと区別できます。
仮説が正しい場合、次のものが見つかるはずです: ... 仮説が誤りの場合、次のようになるはずです: ... 必要なテレメトリー: ...(存在を確認済み:はい/いいえ)
判別要因、つまり悪意のある事例を何千もの無害な事例から区別する特徴を特定できない場合、ハンティングを始める準備はできていません。まず判別要因を見つけてください。その調査こそがハンティングです。
仮説の出発点となるのは、自組織の業界を標的とする攻撃者に関する最新のインテリジェンス、検知範囲に含まれていない ATT&CK の手法、最重要資産とそれらに至る経路、他の業務中に気付いた異常、そしてインシデント後に考える「この攻撃者はほかに何をしていた可能性があるか」です。
ハンティング手法
スタックカウント(頻度分析)
基本となる手法です。フィールドを集計して昇順に並べ、まれな値を調査します。悪意のある活動は通常まれであり、一般的なノイズはよく見られます。
-- Splunk: rarest parent-child process pairs
index=sysmon EventCode=1
| stats count dc(host) as hosts by ParentImage, Image
| where count < 10 AND hosts < 3
| sort count
// KQL: rarely-seen signed binaries making external connections
DeviceNetworkEvents
| where RemoteIPType == "Public"
| summarize Count=count(), Hosts=dcount(DeviceName) by InitiatingProcessFolderPath
| where Hosts <= 2 and Count < 20
| order by Count asc
適切なフィールドをスタックします。Image をスタックすると見慣れないバイナリが見つかり、ParentImage, Image をスタックすると見慣れない 関係性 が見つかります。そこに環境寄生型の悪用が現れます(winword.exe → powershell.exe)。
外れ値分析
同じ形式で、見る軸を変えます。このエンティティにとって何が通常なのかを調べます。
- 対話型ログオンを一度も使ったことのないサービスアカウントが、今それを行っている
- これまでアクセスしたことのない内部サブネットと通信するワークステーション
- 過去の利用時間帯や地域を外れて認証するユーザー
- 特定の日付以降、プロセス数のベースラインが変化したホスト
-- Elastic ES|QL: first-seen external destinations per host
FROM logs-network-*
| WHERE destination.ip NOT IN CIDR("10.0.0.0/8","172.16.0.0/12","192.168.0.0/16")
| STATS first_seen = MIN(@timestamp), n = COUNT(*) BY host.name, destination.domain
| WHERE first_seen > NOW() - 7 days AND n > 20
グループ化とクラスタリング
共通属性でクラスタリングして、キャンペーンを浮かび上がらせます。無関係なホスト間で共通する JA3/JA4、同じ珍しいユーザーエージェント、同じ証明書シリアル番号、同じ稼働時間帯、同じ実行ディレクトリなどが対象です。
インテリジェンス主導のハンティング
レポートから IOC ではなく TTP を抽出し、それらをハンティングします。レポートに記載されたハッシュや IP アドレスはすでに使えませんが、説明されている振る舞いは今も有効です。
Report says: "uses schtasks to create a task running a DLL via rundll32"
Bad hunt: search for the report's hash
Good hunt: every scheduled task created in the last 90 days whose action
references rundll32, stacked by task name and DLL path
高い成果が見込める調査対象
| 仮説の領域 | 調査する内容 |
|---|---|
| LOLBin による実行 | rundll32、regsvr32、mshta、certutil、bitsadmin、msiexec がネットワーク通信を伴う、または通常とは異なる引数を使用しているか。Linux で curl/wget の出力をシェルにパイプしているか |
| 永続化 | 最近作成されたスケジュールタスク/cron/systemd ユニット、WMI イベントサブスクリプション(まれで、ほぼ常に悪意があります)、Run キー、新しいサービス、authorized_keys の変更 |
| 認証情報へのアクセス | LSASS のハンドルオープン、ntds.dit のコピー、シャドウコピーの作成、Kerberos RC4 リクエスト(暗号化タイプ 0x17 の 4769)、DCSync レプリケーション権限の使用 |
| ラテラルムーブメント | 管理共有への書き込み後のサービス作成、非管理ホストからの WinRM/WMI、ワークステーションからサーバーへの SSH、RDP の連鎖 |
| C2 | ビーコンのタイミングの規則性、長時間続く接続、高エントロピーまたはサブドメイン数が多い DNS、まれな JA3/JA4 を使用する TLS |
| 情報の持ち出し | ホストごとの送信量の外れ値、アップロードに先行するアーカイブ作成、サーバーからのクラウドストレージドメインへのアクセス、DNS TXT の通信量 |
| ID/クラウド | 新しい OAuth 権限の付与と同意済みアプリ、サービスプリンシパルへの認証情報の追加、メール転送ルール、変更時間外のロール割り当て、StopLogging/証跡の削除 |
| 防御回避 | イベントログの消去(1102/104)、Sysmon または EDR サービスの停止、AMSI/ETW のパッチ適用を示す兆候、タイムスタンプの改ざん($SI と $FN の不一致) |
調査のループ
1. Hypothesis (written, with a discriminator)
2. Scope (data sources, time window, host population — decided up front)
3. Verify (does the telemetry exist and cover the population?)
4. Query (broad, then narrow — expect several iterations)
5. Investigate (every candidate resolved to benign-explained or escalated)
6. Conclude (found / not found / could-not-determine)
7. Convert (detection rule, telemetry gap ticket, or documented baseline)
8. Document (so the next person can re-run it, not re-derive it)
発見がなかった調査も含め、すべての調査で成果物を作成します。 範囲と制約を記録していれば、否定的な結果も知見になります。「4,200 台のエンドポイントを対象に90日間調査した結果、X の証拠はありません。ただし、620 台のホストには必要なテレメトリがありません。」この一文には、文書化されていない異常なしの報告よりも価値があります。
範囲と時間枠
- 利便性ではなく、実際の侵入滞留時間に合わせて期間を設定します。滞留時間の中央値が60日の攻撃者に対して過去7日間だけを調べても、問題が見つからなかったとしても意味がありません。
- 調査を確定する前に、データの保持期間を確認します。保持期間が30日なのに90日間の調査を行うと、気づかないうちに30日間の調査になってしまいます。
- 使用したテレメトリの対象外となるホスト群を記録します。次の侵入は、こうしたホスト群に潜んでいる可能性があります。
調査で脅威が見つかった場合
調査を中断し、対応モードに切り替えます。まず証拠を保全します。誰かがホストに触れる前に、メモリとトリアージ用パッケージを取得してください。その後、クエリ、生の結果、最初に確認した時刻を添えて responding-to-incidents に引き継ぎます。対応チームは、タイムラインが自分たちの作業で汚染されないよう、何にいつ触れたのかを把握する必要があります。
稼働中の不審なホストで「あと一つだけ確認」してはいけません。侵害された端末で対話型コマンドを実行すると証拠が変わり、攻撃者に気づかれる可能性があります。
避けるべき合理化
- 「何も見つからなかったから、安全です。」 調査したのは、1つのデータセットを対象に、1つの期間で、1つの仮説だけです。この3点すべてを書き留めてください。
- 「データが多すぎて調査できません。」 そのためにスタッキングがあります。まず集約し、ありふれたものを読むのではなく、まれなものを探します。
- 「EDR がアラートを出していたはずです。」 脅威ハンティングの前提は、EDR がアラートを出さなかったことです。
- 「それはただのノイズです。」 ノイズの特徴を明らかにしてください。「ただのノイズ」の中にインプラントは隠れます。良性と判断したクラスタの特徴を明らかにしていないなら、仮説を検証していないということです。
- 「検索した内容は覚えておきます。」 覚えていられませんし、後任者も覚えていません。文書化されていない調査は、拡張されるのではなく、繰り返されるだけです。
- 「不審なホストにログインして確認すればいい。」 その時点であなた自身がタイムラインの一部になり、トリップワイヤーに引っかかる可能性もあります。
- 「時間があるときに調査します。」 場当たり的な調査では、場当たり的な範囲しかカバーできません。優先順位を付けた手法のバックログに基づいて、調査を計画してください。
成果物
# Hunt: <name> Date: <UTC> Analyst: <name>
Hypothesis: <as written above>
ATT&CK: T####.###
Scope: <data sources, host population, time window>
Telemetry verified: <present / partial — name the gaps>
Queries: <verbatim, so this is reproducible>
Results: <candidates found, how each was resolved>
Conclusion: found / not found / could-not-determine
Outputs: <detection rule ID, telemetry gap ticket, baseline doc>
Limitations: <what this hunt could not have seen>
ATT&CK のカバレッジ
secskills-core/ttp-index.json から生成されています。このファイルを編集してから、
python3 scripts/sync_attack.py --write を実行してください。レポートで引用する前に、
ID が現在の ATT&CK リリースと一致することを再確認してください。
永続化(TA0003)
- T1546.003 Windows Management Instrumentation イベントサブスクリプション —
establishing-persistenceも参照
防御回避(TA0005)
- T1036 偽装 —
establishing-persistenceも参照 - T1070.001 Windows イベントログの消去 —
responding-to-incidentsも参照 - T1218 システムバイナリのプロキシ実行 —
escalating-windows-privilegesも参照 - T1218.011 Rundll32 —
analyzing-malwareも参照 - T1562 防御機能の妨害 —
responding-to-incidentsも参照 - T1562.001 ツールの無効化または変更 —
responding-to-incidentsも参照
収集(TA0009)
コマンド&コントロール(TA0011)
- T1071.004 DNS —
engineering-detections、analyzing-network-trafficも参照 - T1219 リモートアクセスソフトウェア
- T1568 動的解決 —
analyzing-malware、analyzing-network-trafficも参照 - T1572 プロトコルトンネリング —
transferring-filesも参照
情報の持ち出し(TA0010)
- T1030 データ転送サイズの制限
- T1048 代替プロトコル経由の情報の持ち出し —
transferring-files、analyzing-network-trafficも参照 - T1567 Web サービス経由の情報の持ち出し —
transferring-filesも参照
影響(TA0040)
これらのいずれかに関する検出コンテンツ:engineering-detections。プロアクティブな検索:hunting-threats。侵害後の対応:responding-to-incidents。
外部ソースを読む
公開されている勧告、仕様、ベンダーレポートを Markdown として取得します。
curl -sL "https://defuddle.md/<url>" # scheme in the path is optional
ページの余分な要素を取り除くため、文章中心のページではトークン数を約 78%削減できます。また、要約ではなく全文を返すため、grep で検索でき、見つからなかった場合も信頼できます。
この用途に向かないケースが3つあります。JSON と API レスポンスは、可読性抽出によって構造化データが損なわれるため、未加工のまま取得してください。認証が必要なページや JavaScript で描画されるページは匿名で取得されるため、直接取得してください。また、攻撃者のインフラ(フィッシングリンク、C2、マルウェアホスティング)、クライアント所有のホスト、エンゲージメント URLは、絶対にこの経由でアクセスしないでください。リクエストが第三者に送信されるうえ、稼働中の攻撃者インフラの場合は運用者に気付かれる可能性もあります。
サイトによっては抽出がブロックされ、ページではなくエラーの内容が返されます。たとえば、freedesktop.org からは {"error":"Failed to fetch: 418 I'm a teapot"} が返される場合があります。これは取得が拒否されたという意味であり、ソースがその内容の不存在を示しているわけではありません。そこから結論を導く前に、URL を直接再取得してください。
参考資料
engineering-detections— 成功したハンティングをテスト済みのルールに変換するresponding-to-incidents— ハンティングによって侵害が確認された場合の引き継ぎ- 仮説の生成には MITRE ATT&CK、ハンティングフレームワークには PEAK と TaHiTI
- 中核となるテレメトリとしての Sysmon、Zeek、osquery、Velociraptor、クラウド監査ログ