
高速なWindowsフォレンジックトリアージプラットフォームであり、Hayabusaエンジンをオーケストレーションして、生のEVTXログをSigmaルール検出とMITRE ATT&CKマッピングを備えた優先順位付けされた脅威のタイムラインに変換します。
Windowsのイベントログから攻撃を検出するキュレーションされたSigmaルールをまとめているリポジトリです。
主にHayabusaの検知ルールや設定ファイル、Velociraptor内蔵のSigma検知などに使用されています。
上流のSigmaリポジトリよりもこのリポジトリを使う利点は、ほとんどのSigmaネイティブツールがパースできるはずのルールだけを含んでいることです。
また、必要なChannel、EventID等々のフィールドをルールに追加することで、logsourceフィールドの抽象化を解除し、ルールが何をフィルタリングしているのかを理解しやすくし、さらに重要なこととして、過検出を減らすようにしています。
また、process_creationルールとregistryベースのルールのフィールド名と値を変換した新しいルールを作成し、SigmaルールがSysmonのログを検知するだけでなく、組み込みのWindowsログも検知できるようにしています。
evtxクレートのよりメンテナンスされたフォーク。Hayabusaの検知ルールはYAML形式で記述され、ファイル拡張子は必ず.ymlにしてください。(.yamlファイルは無視されます。)
Sigmaルールのサブセットでありながら、いくつかの付加的な機能を含んでいます。
HayabusaのルールをSigmaに修正し、コミュニティに還元しやすいように、できるだけSigmaルールに近いものを作ろうとしています。
単純な文字列のマッチングだけでなく、正規表現やAND、ORなどの条件を組み合わせて複雑な検知ルールを表現することができます。
本節ではHayabusaの検知ルールの書き方について説明します。
記述例:
#作者セクション
author: Zach Mathis
date: 2022-03-22
modified: 2022-04-17
#アラートセクション
title: Possible Timestomping
details: 'Path: %TargetFilename% ¦ Process: %Image% ¦ CreationTime: %CreationUtcTime% ¦ PreviousTime: %PreviousCreationUtcTime% ¦ PID: %PID% ¦ PGUID: %ProcessGuid%'
description: |
The Change File Creation Time Event is registered when a file creation time is explicitly modified by a process.
This event helps tracking the real creation time of a file.
Attackers may change the file creation time of a backdoor to make it look like it was installed with the operating system.
Note that many processes legitimately change the creation time of a file; it does not necessarily indicate malicious activity.
#ルールセクション
id: f03e34c4-6432-4a30-9ae2-76ae6329399a
level: low
status: stable
logsource:
product: windows
service: sysmon
definition: Sysmon needs to be installed and configured.
detection:
selection_basic:
Channel: Microsoft-Windows-Sysmon/Operational
EventID: 2
condition: selection_basic
falsepositives:
- unknown
tags:
- t1070.006
- attack.defense-evasion
references:
- https://docs.microsoft.com/en-us/sysinternals/downloads/sysmon
- https://attack.mitre.org/techniques/T1070/006/
ruletype: Hayabusa
#XMLイベントのサンプル
sample-message: |
File creation time changed:
RuleName: technique_id=T1099,technique_name=Timestomp
UtcTime: 2022-04-12 22:52:00.688
ProcessGuid: {43199d79-0290-6256-3704-000000001400}
ProcessId: 9752
Image: C:\TMP\mim.exe
TargetFilename: C:\Users\IEUser\AppData\Local\Temp\Quest Software\PowerGUI\51f5c69c-5d16-47e1-9864-038c8510d919\mk.ps1
CreationUtcTime: 2016-05-16 09:13:50.950
PreviousCreationUtcTime: 2022-04-12 22:52:00.563
User: ZACH-LOG-TEST\IEUser
sample-evtx: |
<Event xmlns="http://schemas.microsoft.com/win/2004/08/events/event">
<System>
<Provider Name="Microsoft-Windows-Sysmon" Guid="{5770385f-c22a-43e0-bf4c-06f5698ffbd9}" />
<EventID>2</EventID>
<Version>5</Version>
<Level>4</Level>
<Task>2</Task>
<Opcode>0</Opcode>
<Keywords>0x8000000000000000</Keywords>
<TimeCreated SystemTime="2022-04-12T22:52:00.689654600Z" />
<EventRecordID>8946</EventRecordID>
<Correlation />
<Execution ProcessID="3408" ThreadID="4276" />
<Channel>Microsoft-Windows-Sysmon/Operational</Channel>
<Computer>Zach-log-test</Computer>
<Security UserID="S-1-5-18" />
</System>
<EventData>
<Data Name="RuleName">technique_id=T1099,technique_name=Timestomp</Data>
<Data Name="UtcTime">2022-04-12 22:52:00.688</Data>
<Data Name="ProcessGuid">{43199d79-0290-6256-3704-000000001400}</Data>
<Data Name="ProcessId">9752</Data>
<Data Name="Image">C:\TMP\mim.exe</Data>
<Data Name="TargetFilename">C:\Users\IEUser\AppData\Local\Temp\Quest Software\PowerGUI\51f5c69c-5d16-47e1-9864-038c8510d919\mk.ps1</Data>
<Data Name="CreationUtcTime">2016-05-16 09:13:50.950</Data>
<Data Name="PreviousCreationUtcTime">2022-04-12 22:52:00.563</Data>
<Data Name="User">ZACH-LOG-TEST\IEUser</Data>
</EventData>
</Event>
作者セクション
アラートセクション
" ¦ " で区切られます。フィールドのプレースホルダは % で囲まれ (例: %MemberName%) 、rules/config_eventkey_alias.txt で定義する必要があります。(以下で説明します)ルールセクション
id [必須]: ルールを一意に識別するために使用される、ランダムに生成されたバージョン4のUUIDです。 ここ で生成することができます。
level [必須]: sigmaルールの定義に基づく重要度レベル。いずれかを記述してください: informational,low,medium,high,critical
status[必須]: sigmaルールの定義に基づくステータス。いずれかを記述してください: deprecated, experimental, test, stable
logsource [required]: Sigmaルールと互換性があるようにSigmaのlogsource定義と同様。
detection [必須]: 検知ロジックはここに入ります。(以下で説明します。)
falsepositives [必須]: 誤検知の可能性について記載を行います。例: system administrator, normal user usage, , , , 。 不明な場合は と記述してください。
Sample XML Event
できるだけ簡潔にするために、以下の略語を使用しています:
Acct -> AccountAddr -> AddressAuth -> AuthenticationCli -> ClientChan -> ChannelCmd -> CommandCnt -> CountComp -> ComputerConn -> Connection/ConnectedCreds -> CredentialsCrit -> CriticalDisconn -> Disconnection/DisconnectedDir -> DirectoryDrv -> Driverまず、selectionの作り方の基本を説明します。
ANDを表現するには辞書(YAMLでは辞書を:で表します)を使用します。
このルールでログが検知されるには、両方の条件が真である必要があります。
7040 であること。System であること。detection:
selection:
Event.System.EventID: 7040
Event.System.Channel: System
condition: selection
ORを表現するには、配列(YAMLでは配列を-で表します)を使用します。
このルールでログが検知されるには、片方の条件が真である必要があります。
7040 であること。System であること。detection:
selection:
- Event.System.EventID: 7040
- Event.System.Channel: System
condition: selection
また、以下のように「AND」と「OR」を組み合わせることも可能です。 この場合、以下の2つの条件が両方成立したときに、このルールでログが検知されます。
7040 または 7041 のどちらかであること。System であること。detection:
selection:
Event.System.EventID:
- 7040
- 7041
Event.System.Channel: System
condition: selection
WindowsイベントログをXML形式で出力すると下記のようになります。
上記のルールファイルの例にあるEvent.System.Channelフィールドは、元々のXMLタグを参照しています: <Event><System><Channel>System<Channel><System></Event>
ネストされたXMLタグはドット(.)で区切られたタグ名で置き換えられます。
Hayabusaのルールでは、このドットでつながれた文字列のことをイベントキーと呼んでいます。
<Event xmlns='http://schemas.microsoft.com/win/2004/08/events/event'>
<System>
<EventID>7040</EventID>
<Channel>System</Channel>
</System>
<EventData>
<Data Name='param1'>Background Intelligent Transfer Service</Data>
<Data Name='param2'>auto start</Data>
</EventData>
</Event>
.の区切りが多くて長いイベントキーが一般的であるため、Hayabusaはエイリアスを使って簡単に扱えるようにします。エイリアスは rules/config/eventkey_alias.txtファイルで定義されています。このファイルは alias と event_key のマッピングで構成されるCSVファイルです。以下に示すように、エイリアスを使用して上記のルールを書き直し、ルールを読みやすくすることができます。
detection:
selection:
Channel: System
EventID: 7040
condition: selection
すべてのイベントキーエイリアスが rules/config/eventkey_alias.txtに定義されているわけではありません。検知するはずのルールが検知しない場合や、details(アラートの詳細)メッセージにn/a (not available)が表示されている場合、rules/config/eventkey_alias.txtの設定を確認してください。
XMLのタグにはタグ名とは別に属性を設定できます。例えば、以下の Provider Name の Name は Provider タグの属性です。
<Event xmlns='http://schemas.microsoft.com/win/2004/08/events/event'>
<System>
<Provider Name='Microsoft-Windows-Security-Auditing' Guid='{54849625-5478-4994-a5ba-3e3b0328c30d}'/>
<EventID>4672</EventID>
<EventRecordID>607469</EventRecordID>
<Channel>Security</Channel>
<Security />
</System>
</Event>
イベントキーでXMLの属性を指定するには、{eventkey}_attributes.{attribute_name}という形式で記述します。例えば、ルールファイルの Provider 要素の Name 属性を指定する場合は、以下のようになります。
detection:
selection:
Channel: Security
EventID: 4672
Event.System.Provider_attributes.Name: 'Microsoft-Windows-Security-Auditing'
condition: selection
Hayabusaではeventkeyを指定せず、WindowsEventログに含まれる文字列にマッチするかどうかを判定する機能も用意されています。この機能をHayabusaではgrep検索と呼んでいます。
grep検索をするには下記のようにdetectionを指定します。この場合、mimikatzまたはmetasploitという文字列がWindowsEventログに含まれる場合に、ルールが検知されます。また、grep検索にはワイルドカードを指定することも可能です。
detection:
selection:
- `mimikatz`
- `metasploit`
※ Hayabusaでは内部的にWindowsEventログをJSON形式に変換しています。そのため、grep検索ではXMLのタグをマッチさせることはできません。
Windowsのイベントログは、基本データ(イベントID、タイムスタンプ、レコードID、ログ名(チャンネル))が書き込まれるSystemタグと、イベントIDに応じて任意のデータが書き込まれるEventDataもしくはUserDataタグの2つに分けられます。
その内、EventDataもしくはUserDataタグはネストされたタグの名前がすべてDataであり、これまで説明したイベントキーではSubjectUserSidとSubjectUserNameを区別できません。
<Event xmlns='http://schemas.microsoft.com/win/2004/08/events/event'>
<System>
<EventID>5379</EventID>
<TimeCreated SystemTime='2021-10-20T10:16:18.7782563Z' />
<EventRecordID>607469</EventRecordID>
<Channel>Security</Channel>
<Security />
</System>
<EventData>
<Data Name='SubjectUserSid'>S-1-1-11-1111111111-111111111-1111111111-1111</Data>
<Data Name='SubjectUserName'>Hayabusa</Data>
<Data Name='SubjectDomainName'>DESKTOP-Hayabusa</Data>
<Data Name='SubjectLogonId'>0x11111111</Data>
</EventData>
</Event>
この問題に対処するため、DataタグのName属性に指定された値をイベントキーとして利用できます。例えば、EventDataのSubjectUserNameとSubjectDomainName を条件として利用する場合、以下のように記述することが可能です。
detection:
selection:
Channel: System
EventID: 7040
Event.EventData.SubjectUserName: Hayabusa
Event.EventData.SubjectDomainName: DESKTOP-HAYBUSA
condition: selection
EventDataタグにネストされたいくつかのタグはName属性を持ちません。
<Event xmlns='http://schemas.microsoft.com/win/2004/08/events/event'>
<System>
<EventID>5379</EventID>
<Channel>Security</Channel>
<Security />
</System>
<EventData>
<Data>Available</Data>
<Data>None</Data>
<Data>NewEngineState=Available PreviousEngineState=None (省略)</Data>
</EventData>
</Event>
上記のようなイベントログを検知するには、Dataというイベントキーを指定します。
この場合、EventDataにネストされたタグの内、DataフィールドがNoneになっている場合は、条件にマッチすることになります。
detection:
selection:
Channel: Security
EventID: 5379
Data: None
condition: selection
いくつかのイベントは、前の例のように、データをすべてDataというフィールド名で保存します。
details:に%Data%を指定すると、すべてのデータが配列として出力されます。
例えば:
["rundll32.exe","6.1.7600.16385","4a5bc637","KERNELBASE.dll","6.1.7601.23392","56eb2fb9","c0000005"]
もし、最初のDataフィールドのデータだけを出力したい場合は、details:に %Data[1]% を指定すると rundll32.exeのみが出力されます。
イベントキーにはフィールド修飾子を指定することができます。
ここまで説明した書き方では完全一致しか表現できませんでしたが、パイプを使うことでより柔軟な検知ルールを記載できるようになります。
以下の例では、あるDataフィールドの値にEngineVersion=2という文字列が入っている場合、条件にマッチすることになります。
detection:
selection:
Channel: 'Windows PowerShell'
EventID: 400
Data|contains: 'EngineVersion=2'
condition: selection
通常は大文字小文字を区別しませんが、|reもしくは|equalsfieldのキーワードを指定した場合は大文字小文字を区別します。
Hayabusaは現在、Sigma仕様のすべてを完全にサポートする唯一のオープンソースツールです。
サポートされているフィールド修飾子、サポートされていないフィールド修飾子、およびこれらの修飾子がSigmaとはHayabusaのルールで使用されている回数の現在の状況は、https://github.com/Yamato-Security/hayabusa-rules/blob/main/doc/SupportedSigmaFieldModifiers.md で確認できます。 この文書は、SigmaやHayabusaのルールが更新されるたびに更新されます。
'|all':: このフィールド修飾子は、特定のフィールドに適用されるのではなく、すべてのフィールドに適用されるので、他の修飾子とは異なります
この例では、Keyword-1とKeyword-2という文字列の両方が存在する必要がありますが、任意のフィールドのどこにでも存在できます:
detection:
keywords:
'|all':
- 'Keyword-1'
- 'Keyword-2'
condition: keywords
|base64offset|contains: データは、エンコードされた文字列内の位置によって、3つの異なる方法でbase64にエンコードされます。この修飾子は、文字列を3つのバリエーションにエンコードし、その文字列がbase64文字列のどこかにエンコードされているかどうかをチェックします。
|cased: 大文字と小文字を区別して検索します。
|cidr: IPv4またはIPv6のCIDR表記をチェックします。(例:192.0.2.0/24)
|contains: 指定された文字列が含まれることをチェックします。
|contains|all: 指定された複数の文字列が含まれることをチェックします。
|contains|all|windash: と同じですが、すべてのキーワードが存在する必要があります。
以下の修飾子は非推奨となり、Sigma仕様の修飾子に置き換えられました。
|equalsfield: 現在は|fieldrefに置き換えられています。|endswithfield: 現在は |fieldref|endswithに置き換えられています。expandフィールド修飾子はユニークなもので、使用するために事前に設定を必要とする唯一のフィールド修飾子です。
例えば、%DC-MACHINE-NAME%のようなプレースホルダーを使用し、すべてのDCマシン名を含む/config/expand/DC-MACHINE-NAME.txtという名前の設定ファイルを必要とします。
この設定方法については、こちらでさらに詳しく説明しています。
Hayabusaルールではワイルドカードを使用することができます。以下の例では、ProcessCommandLine が "malware" という文字列で始まる場合、このルールでログが検知されます。この仕様はSigmaルールのワイルドカードと同じく、大文字小文字を区別しません。
detection:
selection:
Channel: Security
EventID: 4688
ProcessCommandLine: malware*
condition: selection
以下の2つのワイルドカードを使用することができます。
*: 0文字以上の任意の文字列にマッチします。(内部的には.*という正規表現に変換されます)。?: 任意の1文字にマッチします。(内部的には.という正規表現に変換されます)。ワイルドカードのエスケープについて
*と?)はバックスラッシュでエスケープできます: \* と \?.\\* または \\? と記述してください。nullを値に入れることで、フィールドが存在しないことを条件とすることができます。
detection:
selection:
EventID: 4688
ProcessCommandLine: null
condition: selection
注意: フィールド自体は存在するが、値がヌルであることを確認したい場合は、ProcessCommandLine: ''のように定義します。
これまで説明した記法では簡単なANDやORであれば表現可能ですが、複雑な条件は定義できません。そのような場合、condition キーワードを使用します。
detection:
SELECTION_1:
EventID: 3
SELECTION_2:
Initiated: 'true'
SELECTION_3:
DestinationPort:
- '4444'
- '666'
SELECTION_4:
Image: '*\Program Files*'
SELECTION_5:
DestinationIp:
- 10.*
- 192.168.*
- 172.16.*
- 127.*
SELECTION_6:
DestinationIsIpv6: 'false'
condition: (SELECTION_1 and (SELECTION_2 and SELECTION_3) and not ((SELECTION_4 or (SELECTION_5 and SELECTION_6))))
conditionには、以下の式を用いることができます。
{expression1} and {expression2}: {expression1} と {expression2} の両方が真である場合にマッチします。{expression1} or {expression2}: {expression1} または {expression2} のどちらかが真である場合にマッチします。not {expression}: {expression} の真偽を反転させます。( {expression} ): ()で囲まれた {expression} を先に評価します。数学と同じ優先順位に従います。上記の例では、 SELECTION_1、SELECTION_2などの名前が使用されていますが、名前には a-z A-Z 0-9 _の文字を使用可能です。ただし、selection_1、selection_2、 filter_1、filter_2などの標準的な規則の利用を推奨します。
ルールを作成する場合、誤検知を減らすためにフィルターを作成することはよくあります。以下に利用例を示します。
detection:
selection:
Channel: Security
EventID: 4673
filter:
- ProcessName: C:\Windows\System32\net.exe
- ProcessName: C:\Windows\System32\lsass.exe
- ProcessName: C:\Windows\System32\audiodg.exe
- ProcessName: C:\Windows\System32\svchost.exe
- ProcessName: C:\Windows\System32\mmc.exe
- ProcessName: C:\Windows\System32\net.exe
- ProcessName: C:\Windows\explorer.exe
- ProcessName: C:\Windows\System32\SettingSyncHost.exe
- ProcessName: C:\Windows\System32\sdiagnhost.exe
- ProcessName|startswith: C:\Program Files
- SubjectUserName: LOCAL SERVICE
condition: selection and not filter
こちらに定義されているSigmaバージョン2.0.0の相関ルールのすべてを実装しています。
サポートされている相関ルール:
event_count)value_count)temporal)temporal_ordered)2025年9月12日にSigmaバージョン2.1.0で追加された新しい「metrics」相関ルール(value_sum、value_avg、value_percentile)には、現在まだ対応していません。
これらは特定のイベントをカウントし、一定の時間内にそのイベントが多すぎるか、または少なすぎる場合にアラートを発するルールです。 一定の時間内に多数のイベントを検知する一般的な例として、パスワード推測攻撃、パスワードスプレー攻撃、サービス拒否攻撃の検出が挙げられます。 また、これらのルールを使用して、特定のイベントが特定の閾値を下回った場合など、ログソースの信頼性に関する問題を検出することも可能です。
次の例では、パスワード推測攻撃を検出するために2つのルールを使用しています。 参照されるルールが5分以内に5回以上一致し、これらのイベントのIpAddressフィールドが同じ場合にアラートが発生します。
概念を理解するために必要なフィールドのみを含めています。 この例に基づく完全なルールはこちら にありますので、ご参照ください。
title: PW Guessing
id: 23179f25-6fce-4827-bae1-b219deaf563e
correlation:
type: event_count
rules:
- 5b0b75dc-9190-4047-b9a8-14164cee8a31
group-by:
- IpAddress
timespan: 5m
condition:
gte: 5
title: Failed Logon - Incorrect Password
id: 5b0b75dc-9190-4047-b9a8-14164cee8a31
logsource:
product: windows
service: security
detection:
selection:
Channel: Security
EventID: 4625
SubStatus: "0xc000006a" #Wrong password
filter:
IpAddress: "-"
condition: selection and not filter
countルールの例:上記の相関ルールおよび参照されているルールは、従来のcount修飾子を使用した以下のルールと同じ結果を提供します。
title: PW Guessing
logsource:
product: windows
service: security
detection:
selection:
Channel: Security
EventID: 4625
SubStatus: "0xc000006a" #Wrong password
filter:
IpAddress: "-"
condition: selection and not filter | count() by IpAddress >= 5
timeframe: 5m
上記のルールは次の結果を出力します:
% ./hayabusa csv-timeline -d ../hayabusa-sample-evtx -r password-guessing-sample.yml -w
%
Timestamp · RuleTitle · Level · Computer · Channel · EventID · RecordID · Details · ExtraFieldInfo
2016-09-20 01:50:06.513 +09:00 · PW Guessing · med · DESKTOP-M5SN04R · Sec · 4625 · - · Count: 3558 ¦ IpAddress: 192.168.198.149 · -
これらのルールは、指定されたフィールドの異なる値を持つ同じイベントを一定の時間枠内でカウントします。
例:
次のルールは、攻撃者がユーザー名を推測しようとしている場合を検出します。
つまり、同じ送信元IPアドレス (IpAddress) が5分以内に3つ以上の異なるユーザー名 (TargetUserName) でログオンに失敗した場合です。
概念を理解するために必要なフィールドのみを含めています。 この例に基づく完全なルールはこちらにありますので、ご参照ください。
title: User Guessing
id: 0ae09af3-f30f-47c2-a31c-83e0b918eeee
correlation:
type: value_count
rules:
- b2c74582-0d44-49fe-8faa-014dcdafee62
group-by:
- IpAddress
timespan: 5m
condition:
gt: 3
field: TargetUserName
title: Failed Logon - Non-Existant User
id: b2c74582-0d44-49fe-8faa-014dcdafee62
logsource:
product: windows
service: security
detection:
selection:
Channel: Security
EventID: 4625
SubStatus: "0xc0000064" #Username does not exist
condition: selection
countルール:上記の相関ルールおよび参照されているルールは、従来のcount修飾子を使用した以下のルールと同じ結果を提供します:
title: User Guessing
logsource:
product: windows
service: security
detection:
selection:
Channel: Security
EventID: 4625
SubStatus: "0xc0000064" #Username does not exist
condition: selection | count(TargetUserName) by IpAddress > 3
timeframe: 5m
上記のルールは次の結果を出力します:
2018-08-23 23:24:22.523 +09:00 · User Guessing · med · dmz-ftp · Sec · 4625 · - · Count: 4 ¦ TargetUserName: ninja-labs/root/[email protected]/sarutobi ¦ IpAddress: - ¦ LogonType: 8 ¦ TargetDomainName: ¦ ProcessName: C:\\Windows\\System32\\svchost.exe ¦ LogonProcessName: Advapi ¦ WorkstationName: DMZ-FTP · -
2018-08-28 08:03:13.770 +09:00 · User Guessing · med · dmz-ftp · Sec · 4625 · - · Count: 4 ¦ TargetUserName: root/[email protected]/sarutobi/[email protected] ¦ IpAddress: - ¦ LogonType: 8 ¦ TargetDomainName: ¦ ProcessName: C:\\Windows\\System32\\svchost.exe ¦ LogonProcessName: Advapi ¦ WorkstationName: DMZ-FTP · -
2018-09-01 12:51:58.346 +09:00 · User Guessing · med · dmz-ftp · Sec · 4625 · - · Count: 4 ¦ TargetUserName: root/[email protected]/admin/[email protected] ¦ IpAddress: - ¦ LogonType: 8 ¦ TargetDomainName: ¦ ProcessName: C:\\Windows\\System32\\svchost.exe ¦ LogonProcessName: Advapi ¦ WorkstationName: DMZ-FTP · -
2018-09-02 03:55:13.007 +09:00 · User Guessing · med · dmz-ftp · Sec · 4625 · - · Count: 4 ¦ TargetUserName: root/[email protected]/[email protected]/admin ¦ IpAddress: - ¦ LogonType: 8 ¦ TargetDomainName: ¦ ProcessName: C:\\Windows\\System32\\svchost.exe ¦ LogonProcessName: Advapi ¦ WorkstationName: DMZ-FTP · -
ルールフィールドで参照されるルールで定義されたすべてのイベントは、timespanで定義された時間内に発生しなければならない。
group-by で定義されたフィールドの値はすべて同じ値でなければならない(例:同じホスト、ユーザーなど)。
例: 3つのSigmaルールで定義された偵察コマンドが、同一ユーザーによってシステム上で5分以内に任意の順序で起動される
correlation:
type: temporal
rules:
- recon_cmd_a
- recon_cmd_b
- recon_cmd_c
group-by:
- Computer
- User
timespan: 5m
temporal_ordered 相関タイプは temporal と同じように振る舞い、さらに rules 属性で指定された順番でイベントが現れることを要求する
例:上記で定義されたログイン失敗が多数あり、その後1時間以内に同じユーザーアカウントでログインが成功した場合:
correlation:
type: temporal_ordered
rules:
- many_failed_logins
- successful_login
group-by:
- User
timespan: 1h
すべての相関ルールおよび参照されているルールを1つのファイルに含め、YAMLの区切り文字である---で区切ってください
デフォルトでは、参照された相関ルールの出力は行われません。参照ルールの出力を確認したい場合は、correlationの下にgenerate: trueを追加する必要があります。相関ルールを作成する際に有効にして結果を確認すると非常に便利です。
例:
correlation:
generate: true
ルールを参照する際に、ルールIDの代わりにエイリアス名を使用して、より理解しやすくすることができます
複数のルールを参照することができます
group-byで複数のフィールドを使用することができます。その場合、これらのフィールドのすべての値が同じでないと、アラートは発生しません。多くの場合、誤検知を減らすために特定のフィールドをgroup-byでフィルタリングするルールを作成しますが、より汎用的なルールを作成するために group-byを省略することも可能です
相関ルールのタイムスタンプは攻撃の開始時点になるので、それ以降のイベントを確認し、過検知かどうかを判断する必要があります。
これらの機能はHayabusaでサポートされていますが、今後ルール内で使用されることはありません。
イベントキーには特定のキーワードをネストすることができます。
detection:
selection:
Channel: System
EventID: 7045
ServiceName:
- value: malicious-service
- regexes: ./rules/config/regex/detectlist_suspicous_services.txt
ImagePath:
min_length: 1000
allowlist: ./rules/config/regex/allowlist_legitimate_services.txt
condition: selection
value: 文字列によるマッチング (ワイルドカードやパイプも指定可能)。min_length: 指定された文字数以上の場合にマッチします。regexes: 指定されたファイルに定義された正規表現に1つ以上に一致する場合、条件にマッチしたものとして扱われます。allowlist: 指定されたファイルに定義された正規表現に1つ以上に一致する場合、条件にマッチしてないものとして扱われます。Hayabusaに./rules/hayabusa/default/alerts/System/7045_CreateOrModiftySystemProcess-WindowsService_MaliciousServiceInstalled.ymlのルールのために使う2つの正規表現ファイルが用意されています。
./rules/config/regex/detectlist_suspicous_services.txt: 怪しいサービス名を検知するためのものです。./rules/config/regex/allowlist_legitimate_services.txt: 正規のサービスを許可するためのものです。regexes と allowlist で定義されたファイルの正規表現を変更すると、それらを参照するすべてのルールの動作を一度に変更できます。
また、regexes と allowlist にはユーザーが独自で作成したファイルを指定することも可能です。
デフォルトの ./rules/config/detectlist_suspicous_services.txt と ./rules/config/allowlist_legitimate_services.txt を参考にして、独自のファイルを作成してください。
非推奨の特殊キーワードと count 集計は、Hayabusaではまだサポートされていますが、今後ルール内では使用されません。
上記の condition キーワードは AND や OR だけでなく、マッチしたイベントの集計も可能です。この機能を利用するにはaggregation conditionを利用します。指定するには条件をパイプでつなぎます。
以下のパスワードスプレー攻撃の例では、5分以内に同じ送信元のIpAddressで5個以上の TargetUserNameがあるかどうかを判断します。
detection:
selection:
Channel: Security
EventID: 4648
condition: selection | count(TargetUserName) by IpAddress > 5
timeframe: 5m
aggregation conditionは以下の形式で定義します。
count() {operator} {number}: パイプの前の最初の条件にマッチするログイベントに対して、マッチしたログの数が {operator} と {number} で指定した条件式を満たす場合に条件がマッチします。{operator} は以下のいずれかになります。
==: 指定された値と等しい場合、条件にマッチしたものとして扱われる。>=: 指定された値以上であれば、条件にマッチしたものとして扱われる。>: 指定された値以上であれば、条件にマッチしたものとして扱われる。<=: 指定された値以下の場合、条件にマッチしたものとして扱われる。<: 指定された値より小さい場合、条件にマッチしたものとして扱われる。{number} は数値である必要があります。
timeframe は以下のように定義することができます。
15s: 15秒30m: 30分12h: 12時間7d: 7日間3M: 3ヶ月by キーワード共に指定しないパターン。例: selection | count() > 10
selectionにマッチしたログが10件以上ある場合、このルールは検知します。
by キーワードはある。例: selection | count() by date > 10
selectionにマッチするログが10件以上あるかどうか、日付毎にチェックします。
by キーワードがない場合。例: selection | count(TargetUserName) > 10
selectionに一致するTargetUserNameが10人以上存在する場合、このルールは検知します。
by キーワードの両方が存在する。例: selection | count(TargetUserName) by date > 10
selectionに一致するが10人以上存在するかどうか、日付毎にチェックします。
これは最も基本的なパターンです:count() {operator} {number}. 以下のルールは、selectionにマッチしたログが3つ以上である場合、このルールが検知されます。

count() by {eventkey} {operator} {number}: selectionにマッチしたログは、{eventkey}の値が同じログ毎にグルーピングされます。各グループにおいて、マッチしたイベントの数が{operator}と{number}で指定した条件を満たした場合、このルールが検知されます。

count({eventkey}) {operator} {number}:selectionにマッチしたログの内、 {eventkey} が異なる値の数をカウントします。そのカウントされた値が{operator}と{number}で指定された条件式を満たす場合、このルールが検知されます。

count({eventkey_1}) by {eventkey_2} {operator} {number}: selectionにマッチしたログは、{eventkey}の値が同じログ毎にグルーピングし、各グループに含まれる{eventkey_1}が異なる値の数をカウントします。各グループでカウントされた値が{operator}と{number}で指定された条件式を満たした場合、このルールが検知されます。

CountルールのDetails出力は固定で、[condition]にcount条件と[result]に記録されたイベントキーが出力されます。
以下の例では、ブルートフォースされたTargetUserNameのユーザ名のリストと送信元のIpAddressが出力されます:
[condition] count(TargetUserName) by IpAddress >= 5 in timeframe [result] count:41 TargetUserName:jorchilles/jlake/cspizor/lpesce/bgalbraith/jkulikowski/baker/eskoudis/dpendolino/sarmstrong/lschifano/drook/rbowes/ebooth/melliott/econrad/sanson/dmashburn/bking/mdouglas/cragoso/psmith/bhostetler/zmathis/thessman/kperryman/cmoody/cdavis/cfleener/gsalinas/wstrzelec/jwright/edygert/ssims/jleytevidal/celgee/Administrator/mtoussain/smisenar/tbennett/bgreenwood IpAddress:10.10.2.22 timeframe:5m
アラートのタイムスタンプには、timeframe内で最初に検知されたイベントの時間が表示されます。
可能な場合は、常に ChannelもしくはProviderNameとEventIDを指定してください。 デフォルトでは、./rules/config/target_event_IDs.txtに記載されているイベントIDしかスキャンされません。スキャン対象にするためには、./rules/config/target_event_IDs.txtにイベントIDを追加する必要があります。
不要な場合は複数の selectionとfilterセクションを使用しないでください。
detection:
SELECTION_1:
Channnel: Security
SELECTION_2:
EventID: 4625
SELECTION_3:
LogonType: 3
FILTER_1:
SubStatus: "0xc0000064"
FILTER_2:
SubStatus: "0xc000006a"
condition: SELECTION_1 and SELECTION_2 and SELECTION_3 and not (FILTER_1 or FILTER_2)
detection:
selection:
Channel: Security
EventID: 4625
LogonType: 3
filter:
- SubStatus: "0xc0000064" #Non-existent user
- SubStatus: "0xc000006a" #Wrong password
condition: selection and not filter
section_basic セクションに、その他のセクションを section_ と filter_ の後に意味のある名前を付ける記法を用いてください。また、分かりにくいところはコメントを書いて説明してください。detection:
Takoyaki:
Channel: Security
EventID: 4648
Naruto:
TargetUserName|endswith: "$"
IpAddress: "-"
Sushi:
SubjectUserName|endswith: "$"
TargetUserName|endswith: "$"
TargetInfo|endswith: "$"
Godzilla:
SubjectUserName|endswith: "$"
Ninja:
TargetUserName|re: "(DWM|UMFD)-([0-9]|1[0-2])$"
IpAddress: "-"
Daisuki:
- ProcessName|endswith: "powershell.exe"
- ProcessName|endswith: "WMIC.exe"
condition: Takoyaki and Daisuki and not (Naruto and not Godzilla) and not Ninja and not Sushi
detection:
selection_basic:
Channel: Security
EventID: 4648
selection_TargetUserIsComputerAccount:
TargetUserName|endswith: "$"
IpAddress: "-"
filter_UsersAndTargetServerAreComputerAccounts: #Filter system noise
SubjectUserName|endswith: "$"
TargetUserName|endswith: "$"
TargetInfo|endswith: "$"
filter_SubjectUserIsComputerAccount:
SubjectUserName|endswith: "$"
filter_SystemAccounts:
TargetUserName|re: "(DWM|UMFD)-([0-9]|1[0-2])$" #Filter out default Desktop Windows Manager and User Mode Driver Framework accounts
IpAddress: "-" #Don't filter if the IP address is remote to catch attackers who created backdoor accounts that look like DWM-12, etc..
selection_SuspiciousProcess:
- ProcessName|endswith: "powershell.exe"
- ProcessName|endswith: "WMIC.exe"
condition: selection_basic and selection_SuspiciousProcess and not (selection_TargetUserIsComputerAccount
and not filter_SubjectUserIsComputerAccount) and not filter_SystemAccounts and not filter_UsersAndTargetServerAreComputerAccounts
SigmaルールからHayabusaルール形式に自動で変換するツールを作成しました。
@SecurityYamatoでHayabusa、ルール更新、その他の大和セキュリティツール等々について情報を提供しています。
normal system usagelegacy applicationsecurity teamnoneunknowntags [オプション]: LOLBINS/LOLBASという手法を利用している場合、lolbas タグを追加してください。アラートをMITRE ATT&CK フレームワークにマッピングできる場合は、以下のリストから該当するものを追加してください。戦術ID(例:attack.t1098)を指定することも可能です。
attack.reconnaissance -> Reconnaissance (Recon)attack.resource-development -> Resource Development (ResDev)attack.initial-access -> Initial Access (InitAccess)attack.execution -> Execution (Exec)attack.persistence -> Persistence (Persis)attack.privilege-escalation -> Privilege Escalation (PrivEsc)attack.defense-evasion -> Defense Evasion (Evas)attack.credential-access -> Credential Access (CredAccess)attack.discovery -> Discovery (Disc)attack.lateral-movement -> Lateral Movement (LatMov)attack.collection -> Collection (Collect)attack.command-and-control -> Command and Control (C2)attack.exfiltration -> Exfiltration (Exfil)attack.impact -> Impact (Impact)references [オプション]: 参考文献への任意のリンク。
ruletype [必須]: Hayabusaルールには Hayabusa を指定します。SigmaのWindowsルールから自動変換されたルールは Sigma になります。
Dst -> DestinationEID -> Event IDErr -> ErrorExec -> ExecutionFP -> False PositiveFW -> FirewallGTW -> GatewayGrp -> GroupImg -> ImageInj -> InjectionKrb -> KerberosLID -> Logon IDMed -> MediumNet -> NetworkObj -> ObjectOp -> Operational/OperationProto -> ProtocolPW -> PasswordReconn -> ReconnectionReq -> RequestRsp -> ResponseSess -> SessionSig -> SignatureSusp -> SuspiciousSrc -> SourceSvc -> ServiceSvr -> ServerTemp -> TemporaryTerm -> Termination/TerminatedTkt -> TicketTgt -> TargetUnkwn -> UnknownUsr -> UserPerm -> PermamentPkg -> PackagePriv -> PrivilegeProc -> ProcessPID -> Process IDPGUID -> Process GUID (Global Unique ID)Ver -> Versioncontains|windash|contains|cased: フィールドの値が指定された大文字小文字を区別する文字列を含むかをチェックします。
|contains|expand: フィールドの値に、/config/expand/内のexpand設定ファイルに定義された文字列が含まれているかをチェックします。
|contains|windash: 文字列をそのままチェックするだけでなく、最初の-文字を/文字に変換し、そのバリエーションもチェックします。
|endswith: 指定された文字列で終わることをチェックします。
|endswith|cased: フィールドの値が指定された大文字小文字を区別する文字列で終わることをチェックします。
|endswith|windash: 指定された文字列で終わることをチェックし、最初の-文字を/、– (en dash)、— (em dash)、― (horizontal bar)文字のバリエーションに変換し、チェックします。
|exists: フィールドが存在するかをチェックします。
|expand: フィールドの値が、/config/expand/内のexpand設定ファイルに定義された文字列と一致するかをチェックします。
|fieldref: 2つのフィールドの値が同じかどうかをチェックする。これは |equalsfield 修飾子と同じです。
|fieldref|contains: 一方のフィールドの値がもう一方のフィールドに含まれているかどうかをチェックします。
|fieldref|endswith: 左側のフィールドが右側のフィールドの文字列で終わっているかどうかをチェックします。condition で not を使用することで、それらが異なるかどうかをチェックできます。
|fieldref|startswith: 左側のフィールドが右側のフィールドの文字列で始まっているかどうかをチェックします。condition で not を使用することで、それらが異なるかどうかをチェックできます。
|gt: フィールドの値が指定した数値より大きいかどうかをチェックします。
|gte: フィールドの値が指定した数値以上かどうかをチェックします。
|lt: フィールドの値が指定した数値より小さいかどうかをチェックします。
|lte: フィールドの値が指定した数値以下かどうかをチェックします。
|re: 大文字と小文字を区別する正規表現を使用する。 (regexクレートを使用しているので、サポートされている正規表現の書き方は以下のドキュメントを参照してください。 https://docs.rs/regex/latest/regex/#syntax)
注意: Sigma ルールにおける正規表現の構文 PCREを使用しており、文字クラス、ルックビハインド、アトミック・グルーピングなどの特定のメタ文字はサポートされていません。Rust regex crateはSigmaルールですべての正規表現を使用できるはずですが、互換性がない可能性があります。
|re|i: (Insensitive) 大文字小文字を区別しない正規表現を使用する。
|re|m: (Multi-line) 複数行にまたがってマッチする。^ / $ は行頭/行末にマッチする。
|re|s: (Single-line) ドット (.) は改行文字を含むすべての文字にマッチする。
|startswith: 指定された文字列で始まることをチェックします。
|startswith|cased: フィールドの値が指定された大文字小文字を区別する文字列で始まるかをチェックします。
|utf16|base64offset|contains: UTF-16文字列がBase64文字列内にエンコードされているかどうかをチェックします。
|utf16be|base64offset|contains: UTF-16ビッグエンディアンの文字列がBase64文字列内にエンコードされているかどうかをチェックします。
|utf16le|base64offset|contains: UTF-16リトルエンディアン文字列がBase64文字列内にエンコードされているかどうかをチェックします。
|wide|base64offset|contains: utf16le|base64offset|contains のエイリアスで、UTF-16リトルエンディアンの文字列をチェックします。
TargetUserName