289 строки
18 KiB
Plaintext
289 строки
18 KiB
Plaintext
// KQL Sysmon Event Parser
|
|
// Last Updated Date: Sept 25, 2020
|
|
// Sysmon Version: 10.42, Binary Version : 9.20 , Schema Version: 4.22
|
|
//
|
|
// Sysmon Instructions:
|
|
// If you want to print configuration schema definition of sysmon. Execute below command from command shell or powershell terminal
|
|
// Sysmon.exe -s
|
|
//
|
|
// You can further customize config XML definition and install sysmon with it via below command.
|
|
// Sample Sysmon config XML from Swift on Security's GitHub page : https://github.com/SwiftOnSecurity/sysmon-config/blob/master/sysmonconfig-export.xml
|
|
// To parse DNS Events with sysmon 10, use alpha version: https://github.com/SwiftOnSecurity/sysmon-config/blob/master/z-AlphaVersion.xml
|
|
// Sysmon.exe -i sysmonconfig-export.xml -accepteula -h sha1,md5,sha256 -n -l
|
|
// -n : Log all network connections and -l: log loading of modules.
|
|
//
|
|
// Parser Notes:
|
|
// 1. This parser works against the sysmon version 10, it may need updates if Sysmon is updated with new events or schema changes.
|
|
// 2. technique_id and technique_name will only be parsed/available if deployed via above mentioned sample sysmon XML config.
|
|
// 3. Make sure to use alpha version to parse DNS Events if you are using Sysmon v 10 or higher.
|
|
//
|
|
// Usage Instruction :
|
|
// Paste below query in log analytics, click on Save button and select as Function from drop down by specifying function name and alias (e.g. Sysmon_Normalized).
|
|
// Function usually takes 10-15 minutes to activate. You can then use function alias from any other queries (e.g. Sysmon_Normalized | take 10).
|
|
// References :
|
|
// Using functions in Azure monitor log queries : https://docs.microsoft.com/azure/azure-monitor/log-query/functions
|
|
// Tech Community Blog on KQL Functions : https://techcommunity.microsoft.com/t5/Azure-Sentinel/Using-KQL-functions-to-speed-up-analysis-in-Azure-Sentinel/ba-p/712381
|
|
//
|
|
//
|
|
let EventData = Event
|
|
| where Source == "Microsoft-Windows-Sysmon"
|
|
| extend RenderedDescription = tostring(split(RenderedDescription, ":")[0])
|
|
| project TimeGenerated, Source, EventID, Computer, UserName, EventData, RenderedDescription
|
|
| extend EvData = parse_xml(EventData)
|
|
| extend EventDetail = EvData.DataItem.EventData.Data
|
|
| project-away EventData, EvData
|
|
;
|
|
let SysmonEvent1_ProcessCreate=() {
|
|
let processEvents = EventData
|
|
| where EventID == 1
|
|
| extend RuleName = EventDetail.[0].["#text"], UtcTime = EventDetail.[1].["#text"], ProcessGuid = EventDetail.[2].["#text"], ProcessId = EventDetail.[3].["#text"], Image = EventDetail.[4].["#text"],
|
|
FileVersion = EventDetail.[5].["#text"], Description = EventDetail.[6].["#text"], Product = EventDetail.[7].["#text"], Company = EventDetail.[8].["#text"], OriginalFileName = EventDetail.[9].["#text"],
|
|
CommandLine = EventDetail.[10].["#text"], CurrentDirectory = EventDetail.[11].["#text"], User = EventDetail.[12].["#text"], LogonGuid = EventDetail.[13].["#text"],
|
|
LogonId = EventDetail.[14].["#text"], TerminalSessionId = EventDetail.[15].["#text"], IntegrityLevel = EventDetail.[16].["#text"], Hashes = EventDetail.[17].["#text"],
|
|
ParentProcessGuid = EventDetail.[18].["#text"], ParentProcessId = EventDetail.[19].["#text"], ParentImage = EventDetail.[20].["#text"], ParentCommandLine = EventDetail.[21].["#text"]
|
|
| parse RuleName with * 'technique_id=' TechniqueId ',' * 'technique_name=' TechniqueName
|
|
| extend Hashes = extract_all(@"(?P<key>\w+)=(?P<value>[a-zA-Z0-9]+)", dynamic(["key","value"]), Hashes)
|
|
| mv-apply Hashes on (
|
|
summarize ParsedHashes = make_bag(pack(tostring(Hashes[0]), tostring(Hashes[1])))
|
|
)
|
|
| project-away EventDetail, RuleName
|
|
;
|
|
processEvents;
|
|
};
|
|
let SysmonEvent2_FileCreateTime=() {
|
|
let processEvents = EventData
|
|
| where EventID == 2
|
|
| extend RuleName = EventDetail.[0].["#text"], UtcTime = EventDetail.[1].["#text"], ProcessGuid = EventDetail.[2].["#text"], ProcessId = EventDetail.[3].["#text"], Image = EventDetail.[4].["#text"],
|
|
TargetFilename = EventDetail.[5].["#text"], CreationUtcTime = EventDetail.[6].["#text"], PreviousCreationUtcTime = EventDetail.[7].["#text"]
|
|
| parse RuleName with * 'technique_id=' TechniqueId ',' * 'technique_name=' TechniqueName
|
|
| extend Hashes = extract_all(@"(?P<key>\w+)=(?P<value>[a-zA-Z0-9]+)", dynamic(["key","value"]), Hashes)
|
|
| mv-apply Hashes on (
|
|
summarize ParsedHashes = make_bag(pack(tostring(Hashes[0]), tostring(Hashes[1])))
|
|
)
|
|
| project-away EventDetail, RuleName
|
|
;
|
|
processEvents;
|
|
};
|
|
let SysmonEvent3_NetworkConnect=() {
|
|
let processEvents = EventData
|
|
| where EventID == 3
|
|
| extend RuleName = EventDetail.[0].["#text"], UtcTime = EventDetail.[1].["#text"], ProcessGuid = EventDetail.[2].["#text"], ProcessId = EventDetail.[3].["#text"], Image = EventDetail.[4].["#text"],
|
|
User = EventDetail.[5].["#text"], Protocol = EventDetail.[6].["#text"], Initiated = EventDetail.[7].["#text"], SourceIsIpv6 = EventDetail.[8].["#text"], SourceIp = EventDetail.[9].["#text"],
|
|
SourceHostname = EventDetail.[10].["#text"], SourcePort = EventDetail.[11].["#text"], SourcePortName = EventDetail.[12].["#text"], DestinationIsIpv6 = EventDetail.[13].["#text"],
|
|
DestinationIp = EventDetail.[14].["#text"], DestinationHostname = EventDetail.[15].["#text"], DestinationPort = EventDetail.[16].["#text"], DestinationPortName = EventDetail.[17].["#text"]
|
|
| parse RuleName with * 'technique_id=' TechniqueId ',' * 'technique_name=' TechniqueName
|
|
| project-away EventDetail, RuleName
|
|
;
|
|
processEvents;
|
|
};
|
|
let SysmonEvent4_ServiceStateChange=() {
|
|
let processEvents = EventData
|
|
| where EventID == 4
|
|
| extend UtcTime = EventDetail.[0].["#text"], State = EventDetail.[1].["#text"], Schema = EventDetail.[2].["#text"], SchemaVersion = EventDetail.[3].["#text"]
|
|
| project-away EventDetail
|
|
;
|
|
processEvents;
|
|
};
|
|
let SysmonEvent5_ProcessTerminate=() {
|
|
let processEvents = EventData
|
|
| where EventID == 5
|
|
| extend RuleName = EventDetail.[0].["#text"], UtcTime = EventDetail.[1].["#text"], ProcessGuid = EventDetail.[2].["#text"], ProcessId = EventDetail.[3].["#text"], Image = EventDetail.[4].["#text"]
|
|
| parse RuleName with * 'technique_id=' TechniqueId ',' * 'technique_name=' TechniqueName
|
|
| project-away EventDetail, RuleName
|
|
;
|
|
processEvents;
|
|
};
|
|
let SysmonEvent6_DriverLoad=() {
|
|
let processEvents = EventData
|
|
| where EventID == 6
|
|
| extend RuleName = EventDetail.[0].["#text"], UtcTime = EventDetail.[1].["#text"], ImageLoaded = EventDetail.[2].["#text"], Hashes = EventDetail.[3].["#text"],
|
|
Signed = EventDetail.[4].["#text"], Signature = EventDetail.[5].["#text"], SignatureStatus = EventDetail.[6].["#text"]
|
|
| parse RuleName with * 'technique_id=' TechniqueId ',' * 'technique_name=' TechniqueName
|
|
| extend Hashes = extract_all(@"(?P<key>\w+)=(?P<value>[a-zA-Z0-9]+)", dynamic(["key","value"]), Hashes)
|
|
| mv-apply Hashes on (
|
|
summarize ParsedHashes = make_bag(pack(tostring(Hashes[0]), tostring(Hashes[1])))
|
|
)
|
|
| project-away EventDetail, RuleName
|
|
;
|
|
processEvents;
|
|
};
|
|
let SysmonEvent7_ImageLoad=() {
|
|
let processEvents = EventData
|
|
| where EventID == 7
|
|
| extend RuleName = EventDetail.[0].["#text"], UtcTime = EventDetail.[1].["#text"], ProcessGuid = EventDetail.[2].["#text"], ProcessId = EventDetail.[3].["#text"], Image = EventDetail.[4].["#text"],
|
|
ImageLoaded = EventDetail.[5].["#text"], FileVersion = EventDetail.[6].["#text"], Description = EventDetail.[7].["#text"], Product = EventDetail.[8].["#text"], Company = EventDetail.[9].["#text"], OriginalFileName = EventDetail.[10].["#text"],
|
|
Hashes = EventDetail.[11].["#text"], Signed = EventDetail.[12].["#text"], Signature = EventDetail.[13].["#text"], SignatureStatus = EventDetail.[14].["#text"]
|
|
| parse RuleName with * 'technique_id=' TechniqueId ',' * 'technique_name=' TechniqueName
|
|
| extend Hashes = extract_all(@"(?P<key>\w+)=(?P<value>[a-zA-Z0-9]+)", dynamic(["key","value"]), Hashes)
|
|
| mv-apply Hashes on (
|
|
summarize ParsedHashes = make_bag(pack(tostring(Hashes[0]), tostring(Hashes[1])))
|
|
)
|
|
| project-away EventDetail, RuleName
|
|
;
|
|
processEvents;
|
|
};
|
|
let SysmonEvent8_CreateRemoteThread=() {
|
|
let processEvents = EventData
|
|
| where EventID == 8
|
|
| extend RuleName = EventDetail.[0].["#text"], UtcTime = EventDetail.[1].["#text"], SourceProcessGuid = EventDetail.[2].["#text"], SourceProcessId = EventDetail.[3].["#text"],
|
|
SourceImage = EventDetail.[4].["#text"], TargetProcessGuid = EventDetail.[5].["#text"], TargetProcessId = EventDetail.[6].["#text"], TargetImage = EventDetail.[7].["#text"],
|
|
NewThreadId = EventDetail.[8].["#text"], StartAddress = EventDetail.[9].["#text"], StartModule = EventDetail.[10].["#text"], StartFunction = EventDetail.[11].["#text"]
|
|
| parse RuleName with * 'technique_id=' TechniqueId ',' * 'technique_name=' TechniqueName
|
|
| project-away EventDetail, RuleName
|
|
;
|
|
processEvents;
|
|
};
|
|
let SysmonEvent9_RawAccessRead=() {
|
|
let processEvents = EventData
|
|
| where EventID == 9
|
|
| extend RuleName = EventDetail.[0].["#text"], UtcTime = EventDetail.[1].["#text"], ProcessGuid = EventDetail.[2].["#text"], ProcessId = EventDetail.[3].["#text"], Image = EventDetail.[4].["#text"], Device = EventDetail.[5].["#text"]
|
|
| parse RuleName with * 'technique_id=' TechniqueId ',' * 'technique_name=' TechniqueName
|
|
| project-away EventDetail, RuleName
|
|
;
|
|
processEvents;
|
|
};
|
|
let SysmonEvent10_ProcessAccess=() {
|
|
let processEvents = EventData
|
|
| where EventID == 10
|
|
| extend RuleName = EventDetail.[0].["#text"], UtcTime = EventDetail.[1].["#text"], SourceProcessGUID = EventDetail.[2].["#text"], SourceProcessId = EventDetail.[3].["#text"],
|
|
SourceThreadId = EventDetail.[4].["#text"], SourceImage = EventDetail.[5].["#text"], TargetProcessGUID = EventDetail.[6].["#text"], TargetProcessId = EventDetail.[7].["#text"],
|
|
TargetImage = EventDetail.[8].["#text"], GrantedAccess = EventDetail.[9].["#text"], CallTrace = EventDetail.[10].["#text"]
|
|
| parse RuleName with * 'technique_id=' TechniqueId ',' * 'technique_name=' TechniqueName
|
|
| project-away EventDetail, RuleName
|
|
;
|
|
processEvents;
|
|
};
|
|
let SysmonEvent11_FileCreate=() {
|
|
let processEvents = EventData
|
|
| where EventID == 11
|
|
| extend RuleName = EventDetail.[0].["#text"], UtcTime = EventDetail.[1].["#text"], ProcessGuid = EventDetail.[2].["#text"], ProcessId = EventDetail.[3].["#text"],
|
|
Image = EventDetail.[4].["#text"], TargetFilename = EventDetail.[5].["#text"], CreationUtcTime = EventDetail.[6].["#text"]
|
|
| parse RuleName with * 'technique_id=' TechniqueId ',' * 'technique_name=' TechniqueName
|
|
| project-away EventDetail, RuleName
|
|
;
|
|
processEvents;
|
|
};
|
|
let SysmonEvent12_RegistryObjectAddDel=() {
|
|
let processEvents = EventData
|
|
| where EventID == 12
|
|
| extend RuleName = EventDetail.[0].["#text"], EventType = EventDetail.[1].["#text"], UtcTime = EventDetail.[2].["#text"], ProcessGuid = EventDetail.[3].["#text"],
|
|
ProcessId = EventDetail.[4].["#text"], Image = EventDetail.[5].["#text"], TargetObject = EventDetail.[6].["#text"]
|
|
| parse RuleName with * 'technique_id=' TechniqueId ',' * 'technique_name=' TechniqueName
|
|
| project-away EventDetail, RuleName
|
|
;
|
|
processEvents;
|
|
};
|
|
let SysmonEvent13__RegistrySetValue=() {
|
|
let processEvents = EventData
|
|
| where EventID == 13
|
|
| extend RuleName = EventDetail.[0].["#text"], EventType = EventDetail.[1].["#text"], UtcTime = EventDetail.[2].["#text"], ProcessGuid = EventDetail.[3].["#text"],
|
|
ProcessId = EventDetail.[4].["#text"], Image = EventDetail.[5].["#text"], TargetObject = EventDetail.[6].["#text"], Details = EventDetail.[7].["#text"]
|
|
| parse RuleName with * 'technique_id=' TechniqueId ',' * 'technique_name=' TechniqueName
|
|
| project-away EventDetail, RuleName
|
|
;
|
|
processEvents;
|
|
};
|
|
let SysmonEvent14_RegistryObjectRename=() {
|
|
let processEvents = EventData
|
|
| where EventID == 14
|
|
| extend RuleName = EventDetail.[0].["#text"], EventType = EventDetail.[1].["#text"], UtcTime = EventDetail.[2].["#text"], ProcessGuid = EventDetail.[3].["#text"],
|
|
ProcessId = EventDetail.[4].["#text"], Image = EventDetail.[5].["#text"], TargetObject = EventDetail.[6].["#text"], NewName = EventDetail.[7].["#text"]
|
|
| parse RuleName with * 'technique_id=' TechniqueId ',' * 'technique_name=' TechniqueName
|
|
| project-away EventDetail, RuleName
|
|
;
|
|
processEvents;
|
|
};
|
|
let SysmonEvent15_FileCreateStreamHash=() {
|
|
let processEvents = EventData
|
|
| where EventID == 15
|
|
| extend RuleName = EventDetail.[0].["#text"], UtcTime = EventDetail.[1].["#text"], ProcessGuid = EventDetail.[2].["#text"], ProcessId = EventDetail.[3].["#text"],
|
|
Image = EventDetail.[4].["#text"], TargetFileName = EventDetail.[5].["#text"], CreationUtcTime = EventDetail.[6].["#text"], Hash = EventDetail.[7].["#text"]
|
|
| parse RuleName with * 'technique_id=' TechniqueId ',' * 'technique_name=' TechniqueName
|
|
| project-away EventDetail, RuleName
|
|
;
|
|
processEvents;
|
|
};
|
|
let SysmonEvent16_ConfigChange=() {
|
|
let processEvents = EventData
|
|
| where EventID == 16
|
|
| extend UtcTime = EventDetail.[0].["#text"], Configuration = EventDetail.[1].["#text"], ConfigurationFileHash = EventDetail.[2].["#text"]
|
|
| project-away EventDetail
|
|
;
|
|
processEvents;
|
|
};
|
|
let SysmonEvent17_CreateNamedPipe=() {
|
|
let processEvents = EventData
|
|
| where EventID == 17
|
|
| extend RuleName = EventDetail.[0].["#text"], EventType = EventDetail.[1].["#text"], UtcTime = EventDetail.[2].["#text"], ProcessGuid = EventDetail.[3].["#text"], ProcessId = EventDetail.[4].["#text"], PipeName = EventDetail.[5].["#text"],
|
|
Image = EventDetail.[6].["#text"]
|
|
| parse RuleName with * 'technique_id=' TechniqueId ',' * 'technique_name=' TechniqueName
|
|
| project-away EventDetail, RuleName
|
|
;
|
|
processEvents;
|
|
};
|
|
let SysmonEvent18_ConnectNamedPipe=() {
|
|
let processEvents = EventData
|
|
| where EventID == 18
|
|
| extend RuleName = EventDetail.[0].["#text"], EventType = EventDetail.[1].["#text"], UtcTime = EventDetail.[2].["#text"], ProcessGuid = EventDetail.[3].["#text"], ProcessId = EventDetail.[4].["#text"], PipeName = EventDetail.[5].["#text"],
|
|
Image = EventDetail.[6].["#text"]
|
|
| parse RuleName with * 'technique_id=' TechniqueId ',' * 'technique_name=' TechniqueName
|
|
| project-away EventDetail, RuleName
|
|
;
|
|
processEvents;
|
|
};
|
|
let SysmonEvent19_WMIEventFilter=() {
|
|
let processEvents = EventData
|
|
| where EventID == 19
|
|
| extend RuleName = EventDetail.[0].["#text"], EventType = EventDetail.[1].["#text"], UtcTime = EventDetail.[2].["#text"], Operation = EventDetail.[3].["#text"],
|
|
User = EventDetail.[4].["#text"], EventNamespace = EventDetail.[5].["#text"], Name = EventDetail.[6].["#text"], Query = EventDetail.[7].["#text"]
|
|
| parse RuleName with * 'technique_id=' TechniqueId ',' * 'technique_name=' TechniqueName
|
|
| project-away EventDetail, RuleName
|
|
;
|
|
processEvents;
|
|
};
|
|
let SysmonEvent20_WMIEventConsumer=() {
|
|
let processEvents = EventData
|
|
| where EventID == 20
|
|
| extend RuleName = EventDetail.[0].["#text"], EventType = EventDetail.[1].["#text"], UtcTime = EventDetail.[2].["#text"], Operation = EventDetail.[3].["#text"],
|
|
User = EventDetail.[4].["#text"], Name = EventDetail.[5].["#text"], Type = EventDetail.[6].["#text"], Destination = EventDetail.[7].["#text"]
|
|
| parse RuleName with * 'technique_id=' TechniqueId ',' * 'technique_name=' TechniqueName
|
|
| project-away EventDetail, RuleName
|
|
;
|
|
processEvents;
|
|
};
|
|
let SysmonEvent21_WMIEventConsumerToFilter=() {
|
|
let processEvents = EventData
|
|
| where EventID == 21
|
|
| extend RuleName = EventDetail.[0].["#text"], EventType = EventDetail.[1].["#text"], UtcTime = EventDetail.[2].["#text"], Operation = EventDetail.[3].["#text"],
|
|
User = EventDetail.[4].["#text"], Consumer = EventDetail.[5].["#text"], Filter = EventDetail.[6].["#text"]
|
|
| parse RuleName with * 'technique_id=' TechniqueId ',' * 'technique_name=' TechniqueName
|
|
| project-away EventDetail, RuleName
|
|
;
|
|
processEvents;
|
|
};
|
|
let SysmonEvent22_DNSEvents=() {
|
|
let processEvents = EventData
|
|
| where EventID == 22
|
|
| extend RuleName = EventDetail.[0].["#text"], UtcTime = EventDetail.[1].["#text"], ProcessGuid = EventDetail.[2].["#text"], ProcessId = EventDetail.[3].["#text"],
|
|
QueryName = EventDetail.[4].["#text"], QueryStatus = EventDetail.[5].["#text"], QueryResults = EventDetail.[6].["#text"], Image = EventDetail.[7].["#text"]
|
|
| parse RuleName with * 'technique_id=' TechniqueId ',' * 'technique_name=' TechniqueName
|
|
| project-away EventDetail, RuleName
|
|
;
|
|
processEvents;
|
|
};
|
|
(union isfuzzy=true
|
|
SysmonEvent1_ProcessCreate, SysmonEvent2_FileCreateTime, SysmonEvent3_NetworkConnect, SysmonEvent4_ServiceStateChange, SysmonEvent5_ProcessTerminate,
|
|
SysmonEvent6_DriverLoad, SysmonEvent7_ImageLoad, SysmonEvent8_CreateRemoteThread, SysmonEvent9_RawAccessRead, SysmonEvent10_ProcessAccess,
|
|
SysmonEvent11_FileCreate, SysmonEvent12_RegistryObjectAddDel, SysmonEvent13_RegistrySetValue, SysmonEvent14_RegistryObjectRename,
|
|
SysmonEvent15_FileCreateStreamHash, SysmonEvent16_ConfigChange, SysmonEvent17_CreateNamedPipe, SysmonEvent18_ConnectNamedPipe,
|
|
SysmonEvent19_WMIEventFilter, SysmonEvent20_WMIEventConsumer, SysmonEvent21_WMIEventConsumerToFilter, SysmonEvent22_DNSEvents)
|
|
| extend Details = column_ifexists("Details", ""), RuleName = column_ifexists("RuleName", ""), PreviousCreationUtcTime=column_ifexists("PreviousCreationUtcTime", "")
|
|
| project TimeGenerated, Source, EventID, Computer, UserName, RenderedDescription, UtcTime, ProcessGuid, ProcessId, Image, FileVersion, OriginalFileName,
|
|
Description, Product, Company, CommandLine, CurrentDirectory, User, LogonGuid, LogonId, TerminalSessionId, IntegrityLevel, ParentProcessGuid,
|
|
ParentProcessId, ParentImage, ParentCommandLine, TechniqueId, TechniqueName, ParsedHashes, State, Schema, SchemaVersion, ImageLoaded,
|
|
Hashes, Signed, Signature, SignatureStatus, SourceProcessGuid, SourceProcessId, SourceImage, TargetProcessGuid, TargetProcessId, TargetImage,
|
|
NewThreadId, StartAddress, StartModule, StartFunction, Device, SourceProcessGUID, SourceThreadId, TargetProcessGUID, GrantedAccess, CallTrace,
|
|
TargetFilename, CreationUtcTime, EventType, TargetObject, NewName, TargetFileName, Hash, Configuration, ConfigurationFileHash, PipeName, Operation,
|
|
EventNamespace, Name, Query, Type, Destination, Consumer, Filter, QueryName, QueryStatus, QueryResults, Protocol, Initiated, SourceIsIpv6, SourceIp, SourceHostname,
|
|
SourcePort, SourcePortName, DestinationIsIpv6, DestinationIp, DestinationHostname, DestinationPort, DestinationPortName, RuleName, PreviousCreationUtcTime, Details
|