writing-sigma-rules について
ログテレメトリー向けの移植可能な Sigma 検知ルールを作成・レビューするセキュリティ担当者向けの技能です。ルール構造、誤検知への対処、バックエンド変換、サンプルログや本番データによる検証を扱います。
主な機能
- 01YAML による Sigma ルールの構成
- 02選択条件、除外条件、条件式の作成
- 03誤検知の管理と重大度の調整
- 04SIEM バックエンド向けのルール変換
- 05ログを使ったルール検証
活用シーン
- 01脅威インテリジェンスを検知ルールに変換
- 02複数の SIEM 向けに移植可能な検知を作成
- 03既存ルールを調整して誤検知を削減
- 04EVTX や本番データでルールをテスト
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ trilwu/ secskills --skill writing-sigma-rulesインストール後、Claude Code で/writing-sigma-rulesを入力して読み込まれたか確認します。
詳細
Sigma ルールの作成
Sigma は検知ロジックの共通言語です。一度記述すれば、あらゆる SIEM に変換できます。その価値は移植性とレビューのしやすさにありますが、それはルールが正確な場合に限られます。何にでもマッチする Sigma ルールは、ルールがないよりも悪いものです。アナリストの時間を浪費し、チームにアラートを無視する習慣をつけてしまうためです。重要なのは、脆さを招かずに具体性を高めることです。
使用する場面
- TTP、脅威インテリジェンスレポート、またはインシデント調査結果を、移植可能な検知ルールに変換する
- 複数の SIEM バックエンドに変換できる、ベンダーに依存しない検知ロジックを記述する
- Sigma を中心とした検知をコードとして扱うパイプラインを構築または保守する
- 既存の Sigma ルールをレビューまたは調整し、精度を高めて誤検知を減らす
- Sigma ルールをバックエンド間で変換する(Splunk、Elastic、Sentinel、CrowdStrike、Chronicle)
- SigmaHQ にルールを上流提供する、またはプライベートなルールリポジトリを保守する
使用しない場面
- YARA、Suricata、検知ライフサイクル全体を含む、より広範な検知エンジニアリング —
engineering-detectionsを使用してください - シグネチャの対象がログテレメトリではなく、ファイルやメモリである場合 —
writing-yara-rulesを使用してください - ルール作成ではなく、仮説に基づく脅威ハンティング —
hunting-threatsを使用してください - ルール開発ではなく、進行中のインシデント対応 —
responding-to-incidentsを使用してください
Sigma ルールの構造
すべてのルールは、次のフィールドをこの順序で記述した YAML ドキュメントです。
仕様で必須なのは 3 つのフィールドだけです。 title、logsource、detection(condition を含む必要があります)です。それ以外は、仕様上はすべて任意です。これを SigmaHQ のルールリポジトリと混同しないでください。SigmaHQ にコントリビューションを受け入れてもらうには、id、status、description、author、date、level、ATT&CK の tags など、はるかに多くの項目が必要です。実際のパイプラインでは id や level のないルールは管理できないため、既定ではより厳格な SigmaHQ の規約に従ってください。ただし、コンバーターが受け入れたルールをレビュアーが拒否した場合に、どの要件を満たしていたのか把握しておきましょう。
title: Short Descriptive Name # REQUIRED by spec, max ~100 chars
id: a1b2c3d4-0000-4000-8000-000000000001 # optional to spec; UUIDv4, never reuse
related: # optional, link to predecessor rules
- id: <uuid>
type: derived | obsoletes | merged | renamed | similar
status: experimental # optional; see lifecycle below
description: > # optional to spec, expected by SigmaHQ
Detects X behaviour consistent with Y technique.
references: # optional, strongly recommended
- https://attack.mitre.org/techniques/T1059/001/
author: Your Name # optional to spec
date: 2026-07-26 # optional; ISO 8601 YYYY-MM-DD
modified: 2026-07-26 # optional; same format, on update
tags: # optional to spec, expected by SigmaHQ
- attack.execution # tactic (lowercase, dotted)
- attack.t1059.001 # technique (lowercase)
logsource: # REQUIRED by spec
category: process_creation
product: windows
detection: # REQUIRED by spec
selection:
CommandLine|contains: 'some-indicator'
condition: selection # REQUIRED inside detection
falsepositives: # optional to spec
- Legitimate admin scripts using the same flag
level: medium # optional; informational|low|medium|high|critical
日付形式。 仕様では、ハイフンを使用した ISO 8601 形式(YYYY-MM-DD)が必須です。古いルールやオンライン上の多くの資料では、レガシー形式の YYYY/MM/DD が使われていますが、この形式は旧式であり、現在は一部のツールで拒否されることがあります。
ステータスのライフサイクル。 使用できる値は experimental、test、stable、deprecated、unsupported です。実際の運用では、experimental は観察のみで、アラートは行いません。test はエミュレーションによる検証済みで、限定的なデプロイに適しています。stable は、本番環境で調整され、誤検知が記録されています。deprecated は置き換えられており、正確ではなくなっています。unsupported は、記述されたままでは使用できません(例:独自に作成したフィールドに依存しています)。必要な作業を済ませずに、ステータスを引き上げてはいけません。
ログソースの分類
logsource ブロックはデータソースを抽象化します。必要な項目だけを指定してください。
カテゴリ: process_creation、file_event、file_access、network_connection、registry_event、dns_query、image_load、pipe_created、process_access、driver_load、create_remote_thread。
製品: windows、linux、macos。
サービス: sysmon、security、system、powershell、powershell-classic、application、taskscheduler、windefend、firewall-as。
収集方法にかかわらずイベントの種類を指定する場合は、category を使用してください。特定のログチャネルを対象とする場合は、product と service を組み合わせて使用してください。バックエンドで必要とされない限り、category と service を組み合わせないでください。
検知ロジック
セレクションとフィルターパターン
マッチさせる対象(selection)と除外する対象(filter_*)を定義し、condition で組み合わせます。
detection:
selection:
ParentImage|endswith: '\explorer.exe'
CommandLine|contains|all:
- 'powershell'
- '-enc'
filter_legitimate:
CommandLine|contains: 'company-deploy-script'
User|startswith: 'SVC_'
condition: selection and not filter_legitimate
条件の構文
condition: selection # simple match
condition: selection and not filter # match minus exclusions
condition: selection1 or selection2 # either pattern
condition: (sel1 and sel2) and not (fp1 or fp2)
condition: all of selection* # all blocks starting with "selection"
condition: 1 of selection* # any one block
キーワード
ログイベント全体(すべてのフィールド)を対象にマッチさせます。大まかな方法のため、本番環境のルールではフィールドを指定したセレクションを優先してください。
detection:
keywords:
- 'Invoke-Mimikatz'
- 'sekurlsa::logonpasswords'
condition: keywords
修飾子
| で連結します。例:CommandLine|contains|all。
| 修飾子 | 効果 |
|---|---|
contains | 部分文字列の一致 |
startswith / endswith | 接頭辞/接尾辞の一致 |
re | 正規表現(PCRE) |
base64offset | 3 つすべてのオフセットで、Base64 エンコードされたバリエーションに一致 |
all | リスト内のすべての値が一致する必要があります(デフォルトは いずれか) |
cidr | IP フィールドで CIDR ネットワーク範囲に一致 |
windash | 引数の接頭辞として - と / の両方に一致 |
expand | %SystemRoot% のような環境変数を展開 |
wide / utf16le / utf16be / utf16 | 値のワイド(UTF-16)エンコードに一致します。wide は utf16le のエイリアスです。utf8 修飾子はありません |
exists | フィールドが存在する(true)または存在しない(false) |
よくある検出パターン
プロセス作成 -- 不審なコマンドライン
detection:
selection:
CommandLine|contains|windash|all: ['bypass', 'hidden', 'noprofile']
filter_admin:
ParentImage|endswith: ['\sccm.exe', '\intune_agent.exe']
condition: selection and not filter_admin
親子関係(Office がシェルを起動)
detection:
selection:
ParentImage|endswith: '\winword.exe'
Image|endswith: ['\cmd.exe', '\powershell.exe', '\wscript.exe', '\mshta.exe']
condition: selection
不審なパスでのファイル作成
detection:
selection:
TargetFilename|contains: ['\AppData\Local\Temp\', '\ProgramData\', '\Users\Public\']
TargetFilename|endswith: ['.exe', '.dll', '.scr', '.hta']
condition: selection
レジストリによる永続化(実行キー)
detection:
selection:
TargetObject|contains: ['\CurrentVersion\Run\', '\CurrentVersion\RunOnce\']
EventType: SetValue
filter_installers:
Image|startswith: 'C:\Windows\Installer\'
condition: selection and not filter_installers
名前付きパイプの作成(C2 の指標)
detection:
selection:
PipeName: ['\MSSE-*', '\postex_*', '\msagent_*', '\status_*']
condition: selection
WMI イベントサブスクリプションとスケジュールされたタスクの作成
WMI:ログソースは product: windows、service: sysmon、一致条件は EventID: 21、
Operation: Created です。スケジュールされたタスク:ログソースは category: process_creation、
一致条件は Image|endswith: '\schtasks.exe' と CommandLine|contains|all: ['/create', '/sc'] で、SYSTEM と既知の管理ツールでフィルターします。
誤検知への対処
フィルターパターン
除外条件は名前付きの filter_* ブロックに記述し、選択条件に直接含めないでください。
すべてのフィルターを適用するには、condition: selection and not 1 of filter_* を使用します。
既知の正常な動作の除外
攻撃者が制御できないプロパティでフィルターします。署名済みベンダーバイナリの完全なファイルパス(ファイル名だけではなく)、サービスアカウントの SID(ユーザー名ではなく)、特定のソフトウェアワークフローにおける親子プロセスの組み合わせ、検証済みの証明書サブジェクトなどです。ファイル名だけ、攻撃者が制御できるコマンドラインの断片、正当な理由のないホスト名では、決してフィルターしないでください。
重大度の調整
| レベル | 想定される対応 |
|---|---|
informational | 自動タグ付け、相関分析への入力のみ |
low | 一括レビュー、毎日のトリアージ |
medium | アナリストのキューに追加し、数時間以内に調査 |
high | 速やかに調査し、悪意がある可能性が高い |
critical | 直ちに対応し、侵害が進行中 |
手法がどれほど危険に聞こえるかではなく、想定される TP 率とビジネスへの影響に基づいてレベルを設定してください。誤検知の多い critical ルールは、精度の高い medium ルールよりも大きな損害をもたらします。
相関ルール
単一のイベントではアラートが多すぎる場合は、他のルールを ID で参照し、フィールド(例:ComputerName)でグループ化して、一定の時間枠内でしきい値を満たすことを要求する Sigma 相関ルールを使用します。
title: Correlation - Multiple Suspicious Events from Same Host
type: correlation
rules:
- id: <uuid-of-rule-1>
- id: <uuid-of-rule-2>
group-by: [ComputerName]
timespan: 15m
condition:
gte: 2
level: high
バックエンド変換
pySigma を使用した sigma-cli
pip install sigma-cli pySigma-backend-splunk pySigma-backend-elasticsearch \
pySigma-backend-kusto pySigma-backend-qradar
sigma convert -t splunk -p sysmon rules/rule.yml
sigma convert -t elasticsearch -p ecs_windows rules/rule.yml
sigma convert -t kusto -p microsoft_xdr rules/rule.yml
sigma convert -t qradar rules/rule.yml
sigma convert -t splunk -p sysmon rules/ # entire directory
sigma convert -t splunk -p sysmon -f savedsearches rules/ # output format
パイプラインの選択
| バックエンド | よく使われるパイプライン |
|---|---|
| Splunk | sysmon、splunk_windows、splunk_cim |
| Elastic | ecs_windows、ecs_zeek、filebeat |
| Sentinel/XDR | microsoft_xdr、azure_monitor |
| CrowdStrike | crowdstrike |
| Chronicle | chronicle_default |
変換結果は、実際のフィールド名と必ず照合してください。パイプラインのデフォルト設定は、カスタムの解析設定と一致しない場合があります。
テストと検証
スキーマの検証
sigma check rules/rule.yml # single rule
sigma check rules/ # entire directory
よくある失敗:id がない、または重複している、level が無効、YAML の形式が不正、未定義の修飾子、検出ブロックが空。
EVTX によるオフライン検証
hayabusa csv-timeline -d ./sample_evtx/ -r rules/rule.yml
chainsaw hunt ./sample_evtx/ -s rules/rule.yml --mapping mappings/sigma-mapping.yml
テストワークフロー
- サンプルログを収集します。 ラボで手法を実行し(Atomic Red Team、 Caldera)、EVTX または JSON を取得します。
- 検出を確認します。 Hayabusa/Chainsaw を実行します。TP ログでルールが発火する必要があります。
- 除外を確認します。 クリーンなベースラインに対して実行します。検出結果をすべて分類します。
- 変換してテストします。 本番データの 7 日分以上に対してバックエンドのクエリを実行します。すべての一致を分類します。
- 文書化します。 TP/FP 件数、FP の原因、追加したフィルターを記録します。ルールの
falsepositivesフィールドと PR の説明を更新します。
品質基準
SigmaHQ の要件: 有効な UUIDv4 id を設定し、status を適切に指定します
(新規の場合は experimental)。date/modified は YYYY/MM/DD 形式にします。ATT&CK タグを少なくとも 1 つ付けます。falsepositives は空にしません(Unknown でも構いません)。level は TP 率に基づいて設定します。description は具体的に記述し、references には情報源となるインテリジェンスへのリンクを記載します。
YAML の書式: インデントはスペース 2 つとし、タブは使いません。修飾子はスペースなしでパイプ区切りにします(field|contains|all)。リストにはダッシュとスペースを使います。特殊文字を含む文字列はシングルクォートで囲みます。長い説明には折りたたみスカラー(>)を使います。1 ファイルにつき 1 つのルールを記述し、タイトルに一致する snake_case のファイル名を付けます。
フィールド名: Sigma の標準名(Image、ParentImage、CommandLine、User、TargetFilename、TargetObject、DestinationIp、DestinationPort、SourceIp、PipeName、Hashes)を使います。バックエンド変換によって変換されます。バックエンド固有のフィールド名を使うと、移植性が損なわれます。
タグの準拠: attack.<tactic>(小文字、ハイフン区切り)および attack.t<number>(小文字、ドット区切りのサブテクニック)を使います。該当する場合は cve.YYYY.NNNNN を追加します。ID は最新の ATT&CK リリースと照合してください。廃止されたテクニックの古い ID は、後続処理でマッピングエラーを引き起こします。
退けるべき合理化
- 「ルールは十分シンプルだから、テストする必要はありません。」 シンプルなルールほど、マッチする範囲が広くなります。ロジックがシンプルであるほど、FP の分析が重要です。
- 「公開後にフィルターを追加します。」 ノイズの多いルールが本番環境で動くたびに、アナリストの信頼が損なわれます。デプロイ前にテストし、フィルターを設定してください。
- 「キーワードだけを使えばよく、フィールド固有のマッチングでは範囲が狭すぎます。」 キーワードはすべてのフィールドでマッチします。その文字列を含むホスト名にヒットしても、それはノイズです。
- 「変換後の出力は正しそうなので、テストする必要はありません。」 変換では、フィールドマッピングがパイプラインのデフォルトと一致していることが前提です。実際のデータで確認してください。
- 「テクニックごとにルールを 1 つ作れば十分です。」 テクニックには多くの手順があります。T1059 は PowerShell、cmd、bash、Python、VBScript を対象としており、それぞれに独自のロジックが必要です。
- 「Splunk で動くので、どこでも動きます。」 移植性を確保するには、正しいログソースの抽象化が必要です。バックエンド固有のフィールド名を使うと、移植性が損なわれます。
- 「認証情報のダンプは常に重大なので、重大に設定します。」 重大度はテクニックのカテゴリではなく、シグナルの品質を反映します。ノイズの多い重大ルールは、精度の高い中程度のルールよりも大きな損害をもたらします。
外部ソースを読む
公開されているアドバイザリ、仕様書、ベンダーレポートを 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-- YARA、Suricata、カバレッジ測定を含む、検知ライフサイクル全体hunting-threats-- ルールの基となる調査結果を生み出す、仮説主導のハンティングmapping-attack-techniques-- ATT&CK テクニックの特定と、パープルチームのサイクルreporting-security-findings-- 検知結果の報告書の作成