
TWLogEye開発26日目:昨日見つけた難題をコツコツと解決しています
今朝は、4時前に起きました。コヒーを淹れに1階の台所に行くと、助手の猫さんも起きていて、暗闇で爪とぎしていました。猫さんは5時前に一度、かみさんを起こそうと騒いでいました。私が呼ばれてお世話したあと、かみさんの布団で寝たようです。
昨日見つけた難題を調べて解決しています。
Sigmaルールの判定時のエラー
読み込み時には、エラーはなかったのですが、判定する時に
2025/02/08 06:17:29 sigma matches err=error evaluating search keywords: keywords unsupported
2025/02/08 06:17:29 sigma matches err=error evaluating search filter_optional_generic: keywords unsupported
のようなエラーが出ている問題です。go-sigma
のソースコードを真面目に読んでみると、
if len(search.Keywords) > 0 {
return false, fmt.Errorf("keywords unsupported")
}
というエラーでした。フィールドを指定しないキーワードだけ指定したルールはサポートしていないということです。
エラーログが大量にでないように、このような定義はルールの読み込みの時にエラーにするよう修正しました。ついでに、
IDが重複するルールは複数読み込まない
IDとタイトルの重複をチェックできるようにした
ルールの動作をテストするコマンドを追加
を行いました。
WindowsイベントログのJSON化がおかしい
セキュリティーのログを監視してJSON化していますが、クライアントから読み出すと
2025-02-08T06:00:26.8822441+09:00 Security {"Event": {"-xmlns": "http://schemas.microsoft.com/win/2004/08/events/event", "System": {"Execution": {"-ProcessID": 4, "-ThreadID": 972}, "Security": "", "TimeCreated": {"-SystemTime": "2025-02-07T21:00:26.8822441Z"}, "EventRecordID": 13648186, "Computer": "YMIRYZ", "EventID": 4689, "Opcode": 0, "Keywords": "0x8020000000000000", "Correlation": "", "Channel": "Security", "Version": 0, "Level": 0, "Task": 13313, "Provider": {"-Name": "Microsoft-Windows-Security-Auditing", "-Guid": "{54849625-5478-4994-a5ba-3e3b0328c30d}"}}, "EventData": {"Data": [{"#content": "S-1-5-21-1734809770-1267934487-2188562794-1001", "-Name": "SubjectUserSid"}, {"#content": "ymi", "-Name": "SubjectUserName"}, {"#content": "YMIRYZ", "-Name": "SubjectDomainName"}, {"#content": "0x162cc6", "-Name": "SubjectLogonId"}, {"#content": "0x0", "-Name": "Status"}, {"#content": "0x2048", "-Name": "ProcessId"}, {"#content": "C:\\Windows\\System32\\conhost.exe", "-Name": "ProcessName"}]}}}
のような感じでJSON化がおかしい問題です。
こちらは、WindowsのイベントログのXMLからJSONに変換する処理を真面目に作ることにしました。

のような感じの処理です。
元のXMLは、
<Event xmlns='http://schemas.microsoft.com/win/2004/08/events/event'>
<System>
<Provider Name='Microsoft-Windows-HttpService' Guid='{dd5ef90a-6398-47a4-ad34-4dcecdef795f}' />
<EventID>113</EventID>
<Version>0</Version>
<Level>4</Level>
<Task>5</Task>
<Opcode>122</Opcode>
<Keywords>0x4000000000000040</Keywords>
<TimeCreated SystemTime='2023-08-18T00:24:21.1687683Z' />
<EventRecordID>9925</EventRecordID>
<Correlation />
<Execution ProcessID='4212' ThreadID='15676' />
<Channel>System</Channel>
<Computer>YMIRYZ</Computer>
<Security UserID='S-1-5-19' />
</System>
<EventData>
<Data Name='UrlGroupId'>18302628890465533987</Data>
<Data Name='Url'>http://*:2869/upnp/eventing/</Data>
<Data Name='Status'>0</Data>
<Data Name='ProcessId'>4212</Data>
<Data Name='ExecutablePath'>\Device\HarddiskVolume3\Windows\System32\svchost.exe</Data>
<Data Name='UserSid'>S-1-5-19</Data>
</EventData>
</Event>
のような感じです。このXMLからGo言語のデータ(struct)を作るよいツールを見つけました。
です。Webでできます。
変換したGo言語のデータ定義は、
// Event was generated 2025-02-09 05:23:05 by https://xml-to-go.github.io/ in Ukraine.
type Event struct {
XMLName xml.Name `xml:"Event"`
Text string `xml:",chardata"`
Xmlns string `xml:"xmlns,attr"`
System struct {
Text string `xml:",chardata"`
Provider struct {
Text string `xml:",chardata"`
Name string `xml:"Name,attr"`
Guid string `xml:"Guid,attr"`
} `xml:"Provider"`
EventID string `xml:"EventID"`
Version string `xml:"Version"`
Level string `xml:"Level"`
Task string `xml:"Task"`
Opcode string `xml:"Opcode"`
Keywords string `xml:"Keywords"`
TimeCreated struct {
Text string `xml:",chardata"`
SystemTime string `xml:"SystemTime,attr"`
} `xml:"TimeCreated"`
EventRecordID string `xml:"EventRecordID"`
Correlation string `xml:"Correlation"`
Execution struct {
Text string `xml:",chardata"`
ProcessID string `xml:"ProcessID,attr"`
ThreadID string `xml:"ThreadID,attr"`
} `xml:"Execution"`
Channel string `xml:"Channel"`
Computer string `xml:"Computer"`
Security string `xml:"Security"`
} `xml:"System"`
EventData struct {
Text string `xml:",chardata"`
Data []struct {
Text string `xml:",chardata"`
Name string `xml:"Name,attr"`
} `xml:"Data"`
} `xml:"EventData"`
}
です。これを
の例のようなJSONに変換するプログラムを作りました。
package main
import (
"encoding/json"
"encoding/xml"
"log"
"os"
)
type Event struct {
XMLName xml.Name `xml:"Event"`
Text string `xml:",chardata"`
Xmlns string `xml:"xmlns,attr"`
System struct {
Text string `xml:",chardata"`
Provider struct {
Text string `xml:",chardata"`
Name string `xml:"Name,attr"`
Guid string `xml:"Guid,attr"`
} `xml:"Provider"`
EventID string `xml:"EventID"`
Version string `xml:"Version"`
Level string `xml:"Level"`
Task string `xml:"Task"`
Opcode string `xml:"Opcode"`
Keywords string `xml:"Keywords"`
TimeCreated struct {
Text string `xml:",chardata"`
SystemTime string `xml:"SystemTime,attr"`
} `xml:"TimeCreated"`
EventRecordID string `xml:"EventRecordID"`
Correlation string `xml:"Correlation"`
Execution struct {
Text string `xml:",chardata"`
ProcessID string `xml:"ProcessID,attr"`
ThreadID string `xml:"ThreadID,attr"`
} `xml:"Execution"`
Channel string `xml:"Channel"`
Computer string `xml:"Computer"`
Security struct {
Text string `xml:",chardata"`
UserID string `xml:"UserID,attr"`
} `xml:"Security"`
} `xml:"System"`
EventData struct {
Text string `xml:",chardata"`
Data []struct {
Text string `xml:",chardata"`
Name string `xml:"Name,attr"`
} `xml:"Data"`
} `xml:"EventData"`
}
func main() {
b, err := os.ReadFile(os.Args[1])
if err != nil {
log.Fatalln(err)
}
var x Event
if err := xml.Unmarshal(b, &x); err != nil {
log.Fatalln(err)
}
edmap := make(map[string]interface{})
for _, d := range x.EventData.Data {
edmap[d.Name] = d.Text
}
m := map[string]interface{}{
"Event": map[string]interface{}{
"System": map[string]interface{}{
"Channel": x.System.Channel,
"Computer": x.System.Computer,
"Correlation": x.System.Correlation,
"EventID": x.System.EventID,
"EventRecordID": x.System.EventRecordID,
"Execution": map[string]interface{}{
"ProcessID": x.System.Execution.ProcessID,
"ThreadID": x.System.Execution.ThreadID,
},
"Keywords": x.System.Keywords,
"Level": x.System.Level,
"Opcode": x.System.Opcode,
"Provider": map[string]interface{}{
"Guid": x.System.Provider.Guid,
"Name": x.System.Provider.Name,
},
"Security": map[string]interface{}{
"UserID": x.System.Security.UserID,
},
"Task": x.System.Task,
"TimeCreated": map[string]interface{}{
"SystemTime": x.System.TimeCreated.SystemTime,
},
"Version": x.System.Version,
},
"EventData": edmap,
},
}
j, err := json.MarshalIndent(&m, "", " ")
if err != nil {
log.Fatalln(err)
}
log.Printf("j=%s", string(j))
}
です。変換結果は、
{
"Event": {
"EventData": {
"ProcessId": "0x4220",
"ProcessName": "C:\\Program Files\\Docker\\Docker\\resources\\bin\\docker.exe",
"Status": "0x0",
"SubjectDomainName": "YMIRYZ",
"SubjectLogonId": "0x162cc6",
"SubjectUserName": "ymi",
"SubjectUserSid": "S-1-5-21-1734809770-1267934487-2188562794-1001"
},
"System": {
"Channel": "Security",
"Computer": "YMIRYZ",
"Correlation": "",
"EventID": "4689",
"EventRecordID": "13971171",
"Execution": {
"ProcessID": "4",
"ThreadID": "15464"
},
"Keywords": "0x8020000000000000",
"Level": "0",
"Opcode": "0",
"Provider": {
"Guid": "{54849625-5478-4994-a5ba-3e3b0328c30d}",
"Name": "Microsoft-Windows-Security-Auditing"
},
"Security": {
"UserID": ""
},
"Task": "13313",
"TimeCreated": {
"SystemTime": "2025-02-08T17:04:32.8719251Z"
},
"Version": "0"
}
}
}
になりました。いい感じだと思いますが、EventIDなどは数値にしたほうがよいかもしれません。
調子がでてきましたが、今朝は、ここまで
明日に続く
いいなと思ったら応援しよう!
