From 96141d24daa04b53ef104866185d303a3eb20c84 Mon Sep 17 00:00:00 2001 From: rabbitstack Date: Tue, 27 Jan 2026 18:31:16 +0100 Subject: [PATCH 1/2] refactor(filter,field): Rename image.* fields --- pkg/filter/accessor.go | 12 +- pkg/filter/accessor_windows.go | 77 ++++--- pkg/filter/accessor_windows_test.go | 2 +- pkg/filter/fields/fields_windows.go | 341 +++++++++++++++++++--------- pkg/filter/filter.go | 2 +- pkg/filter/filter_test.go | 85 ++++--- pkg/filter/filter_windows.go | 5 +- pkg/filter/ql/function.go | 25 +- 8 files changed, 355 insertions(+), 194 deletions(-) diff --git a/pkg/filter/accessor.go b/pkg/filter/accessor.go index f18891c5c..470f636ff 100644 --- a/pkg/filter/accessor.go +++ b/pkg/filter/accessor.go @@ -156,7 +156,7 @@ func (f *filter) narrowAccessors() { removeEvtAccessor = true removePsAccessor = true removeThreadAccessor = true - removeImageAccessor = true + removeModuleAccessor = true removeFileAccessor = true removeRegistryAccessor = true removeNetworkAccessor = true @@ -169,7 +169,7 @@ func (f *filter) narrowAccessors() { for _, field := range f.fields { switch { - case field.Name.IsKevtField(), field.Name.IsEvtField(): + case field.Name.IsEvtField() || field.Name.IsKevtField(): removeEvtAccessor = false case field.Name.IsPeField(): removePEAccessor = false @@ -177,8 +177,8 @@ func (f *filter) narrowAccessors() { removePsAccessor = false case field.Name.IsThreadField(): removeThreadAccessor = false - case field.Name.IsImageField(): - removeImageAccessor = false + case field.Name.IsImageField() || field.Name.IsModuleField(): + removeModuleAccessor = false case field.Name.IsFileField(): removeFileAccessor = false case field.Name.IsRegistryField(): @@ -205,8 +205,8 @@ func (f *filter) narrowAccessors() { if removeThreadAccessor { f.removeAccessor(&threadAccessor{}) } - if removeImageAccessor { - f.removeAccessor(&imageAccessor{}) + if removeModuleAccessor { + f.removeAccessor(&moduleAccessor{}) } if removeFileAccessor { f.removeAccessor(&fileAccessor{}) diff --git a/pkg/filter/accessor_windows.go b/pkg/filter/accessor_windows.go index baacfd152..387416dee 100644 --- a/pkg/filter/accessor_windows.go +++ b/pkg/filter/accessor_windows.go @@ -59,7 +59,7 @@ func GetAccessors() []Accessor { newDNSAccessor(), newFileAccessor(), newEventAccessor(), - newImageAccessor(), + newModuleAccessor(), newThreadAccessor(), newHandleAccessor(), newNetworkAccessor(), @@ -616,7 +616,7 @@ func (t *threadAccessor) Get(f Field, e *event.Event) (params.Value, error) { return frame.Symbol, nil } return nil, nil - case fields.ThreadCallstackFinalUserModuleSignatureIsSigned, fields.ThreadCallstackFinalUserModuleSignatureIsTrusted: + case fields.ThreadCallstackFinalUserModuleSignatureExists, fields.ThreadCallstackFinalUserModuleSignatureTrusted: frame := e.Callstack.FinalUserFrame() if frame == nil || (frame != nil && frame.ModuleAddress.IsZero()) { return nil, nil @@ -627,12 +627,12 @@ func (t *threadAccessor) Get(f Field, e *event.Event) (params.Value, error) { return nil, nil } - if f.Name == fields.ThreadCallstackFinalUserModuleSignatureIsSigned { + if f.Name == fields.ThreadCallstackFinalUserModuleSignatureExists { return sign.IsSigned(), nil } return sign.IsTrusted(), nil - case fields.ThreadCallstackFinalUserModuleSignatureCertIssuer, fields.ThreadCallstackFinalUserModuleSignatureCertSubject: + case fields.ThreadCallstackFinalUserModuleSignatureIssuer, fields.ThreadCallstackFinalUserModuleSignatureSubject: frame := e.Callstack.FinalUserFrame() if frame == nil || (frame != nil && frame.ModuleAddress.IsZero()) { return nil, nil @@ -643,7 +643,7 @@ func (t *threadAccessor) Get(f Field, e *event.Event) (params.Value, error) { return nil, nil } - if sign.HasCertificate() && f.Name == fields.ThreadCallstackFinalUserModuleSignatureCertIssuer { + if sign.HasCertificate() && f.Name == fields.ThreadCallstackFinalUserModuleSignatureIssuer { return sign.Cert.Issuer, nil } @@ -737,24 +737,24 @@ func (l *fileAccessor) Get(f Field, e *event.Event) (params.Value, error) { return nil, nil } -// imageAccessor extracts image (DLL, executable, driver) event values. -type imageAccessor struct{} +// moduleAccessor extracts module (DLL, executable, driver) event values. +type moduleAccessor struct{} -func (imageAccessor) SetFields(fields []Field) { +func (moduleAccessor) SetFields(fields []Field) { initLOLDriversClient(fields) } -func (imageAccessor) SetSegments([]fields.Segment) {} +func (moduleAccessor) SetSegments([]fields.Segment) {} -func (imageAccessor) IsFieldAccessible(e *event.Event) bool { +func (moduleAccessor) IsFieldAccessible(e *event.Event) bool { return e.Category == event.Image } -func newImageAccessor() Accessor { - return &imageAccessor{} +func newModuleAccessor() Accessor { + return &moduleAccessor{} } -func (i *imageAccessor) Get(f Field, e *event.Event) (params.Value, error) { - if e.IsLoadImage() && (f.Name == fields.ImageSignatureType || f.Name == fields.ImageSignatureLevel || f.Name.IsImageCert()) { +func (*moduleAccessor) Get(f Field, e *event.Event) (params.Value, error) { + if e.IsLoadImage() && (f.Name.IsModuleSignature() || f.Name == fields.ImageSignatureType || f.Name == fields.ImageSignatureLevel || f.Name.IsImageCert()) { filename := e.GetParamAsString(params.ImagePath) addr := e.Params.MustGetUint64(params.ImageBase) typ := e.Params.MustGetUint32(params.ImageSignatureType) @@ -771,7 +771,7 @@ func (i *imageAccessor) Get(f Field, e *event.Event) (params.Value, error) { Filename: filename, } } - if f.Name.IsImageCert() { + if f.Name.IsImageCert() || f.Name.IsModuleCert() { err := sign.ParseCertificate() if err != nil { certErrors.Add(1) @@ -795,7 +795,7 @@ func (i *imageAccessor) Get(f Field, e *event.Event) (params.Value, error) { if sign.IsSigned() { sign.Verify() } - if f.Name.IsImageCert() { + if f.Name.IsImageCert() || f.Name.IsModuleCert() { err := sign.ParseCertificate() if err != nil { certErrors.Add(1) @@ -816,49 +816,56 @@ func (i *imageAccessor) Get(f Field, e *event.Event) (params.Value, error) { e.AppendParam(params.ImageCertNotAfter, params.Time, sign.Cert.NotAfter) e.AppendParam(params.ImageCertNotBefore, params.Time, sign.Cert.NotBefore) } + + switch f.Name { + case fields.ModuleSignatureExists, fields.DllSignatureExists: + return sign != nil && sign.IsSigned(), nil + case fields.ModuleSignatureTrusted, fields.DllSignatureTrusted: + return sign != nil && sign.IsTrusted(), nil + } } switch f.Name { - case fields.ImagePath: + case fields.ImagePath, fields.ModulePath, fields.DllPath: return e.GetParamAsString(params.ImagePath), nil - case fields.ImageName: + case fields.ImageName, fields.ModuleName, fields.DllName: return filepath.Base(e.GetParamAsString(params.ImagePath)), nil - case fields.ImageDefaultAddress: + case fields.ImageDefaultAddress, fields.ModuleDefaultAddress: return e.GetParamAsString(params.ImageDefaultBase), nil - case fields.ImageBase: + case fields.ImageBase, fields.ModuleBase, fields.DllBase: return e.GetParamAsString(params.ImageBase), nil - case fields.ImageSize: + case fields.ImageSize, fields.ModuleSize, fields.DllSize: return e.Params.GetUint64(params.ImageSize) - case fields.ImageChecksum: + case fields.ImageChecksum, fields.ModuleChecksum: return e.Params.GetUint32(params.ImageCheckSum) - case fields.ImagePID: + case fields.ImagePID, fields.ModulePID, fields.DllPID: return e.Params.GetPid() - case fields.ImageSignatureType: + case fields.ImageSignatureType, fields.ModuleSignatureType, fields.DllSignatureType: return e.GetParamAsString(params.ImageSignatureType), nil - case fields.ImageSignatureLevel: + case fields.ImageSignatureLevel, fields.ModuleSignatureLevel, fields.DllSignatureLevel: return e.GetParamAsString(params.ImageSignatureLevel), nil - case fields.ImageCertSubject: + case fields.ImageCertSubject, fields.ModuleSignatureSubject, fields.DllSignatureSubject: return e.GetParamAsString(params.ImageCertSubject), nil - case fields.ImageCertIssuer: + case fields.ImageCertIssuer, fields.ModuleSignatureIssuer, fields.DllSignatureIssuer: return e.GetParamAsString(params.ImageCertIssuer), nil - case fields.ImageCertSerial: + case fields.ImageCertSerial, fields.ModuleSignatureSerial, fields.DllSignatureSerial: return e.GetParamAsString(params.ImageCertSerial), nil - case fields.ImageCertBefore: + case fields.ImageCertBefore, fields.ModuleSignatureBefore, fields.DllSignatureBefore: return e.Params.GetTime(params.ImageCertNotBefore) - case fields.ImageCertAfter: + case fields.ImageCertAfter, fields.ModuleSignatureAfter, fields.DllSignatureAfter: return e.Params.GetTime(params.ImageCertNotAfter) - case fields.ImageIsDriverVulnerable, fields.ImageIsDriverMalicious: + case fields.ImageIsDriverVulnerable, fields.ImageIsDriverMalicious, fields.ModuleIsDriverVulnerable, fields.ModuleIsDriverMalicious: if e.IsLoadImage() { return isLOLDriver(f.Name, e) } return false, nil - case fields.ImageIsDLL: + case fields.ImageIsDLL, fields.ModuleIsDLL: return e.Params.GetBool(params.FileIsDLL) - case fields.ImageIsDriver: + case fields.ImageIsDriver, fields.ModuleIsDriver: return e.Params.GetBool(params.FileIsDriver) - case fields.ImageIsExecutable: + case fields.ImageIsExecutable, fields.ModuleIsExecutable: return e.Params.GetBool(params.FileIsExecutable) - case fields.ImageIsDotnet: + case fields.ImageIsDotnet, fields.ModuleIsDotnet, fields.DllIsDotnet: return e.Params.GetBool(params.FileIsDotnet) } diff --git a/pkg/filter/accessor_windows_test.go b/pkg/filter/accessor_windows_test.go index cedd97acb..2cce8da17 100644 --- a/pkg/filter/accessor_windows_test.go +++ b/pkg/filter/accessor_windows_test.go @@ -137,7 +137,7 @@ func TestIsFieldAccessible(t *testing.T) { true, }, { - newImageAccessor(), + newModuleAccessor(), &event.Event{Type: event.LoadImage, Category: event.Image}, true, }, diff --git a/pkg/filter/fields/fields_windows.go b/pkg/filter/fields/fields_windows.go index 4699b86c0..456d32568 100644 --- a/pkg/filter/fields/fields_windows.go +++ b/pkg/filter/fields/fields_windows.go @@ -247,14 +247,14 @@ const ( ThreadCallstackFinalKernelModulePath Field = "thread.callstack.final_kernel_module.path" // ThreadCallstackFinalKernelSymbolName represents the final kernel space stack frame symbol name ThreadCallstackFinalKernelSymbolName Field = "thread.callstack.final_kernel_symbol.name" - // ThreadCallstackFinalUserModuleSignatureIsSigned represents the signature status of the final user space stack frame module - ThreadCallstackFinalUserModuleSignatureIsSigned Field = "thread.callstack.final_user_module.signature.is_signed" - // ThreadCallstackFinalUserModuleSignatureIsTrusted represents the trust status of the final user space stack frame module signature - ThreadCallstackFinalUserModuleSignatureIsTrusted Field = "thread.callstack.final_user_module.signature.is_trusted" - // ThreadCallstackFinalUserModuleSignatureCertIssuer represents the final user space stack frame module certificate issuer - ThreadCallstackFinalUserModuleSignatureCertIssuer Field = "thread.callstack.final_user_module.signature.cert.issuer" - // ThreadCallstackFinalUserModuleSignatureCertSubject represents the final user space stack frame module certificate subject - ThreadCallstackFinalUserModuleSignatureCertSubject Field = "thread.callstack.final_user_module.signature.cert.subject" + // ThreadCallstackFinalUserModuleSignatureExists represents the signature status of the final user space stack frame module + ThreadCallstackFinalUserModuleSignatureExists Field = "thread.callstack.final_user_module.signature.exists" + // ThreadCallstackFinalUserModuleSignatureTrusted represents the trust status of the final user space stack frame module signature + ThreadCallstackFinalUserModuleSignatureTrusted Field = "thread.callstack.final_user_module.signature.trusted" + // ThreadCallstackFinalUserModuleSignatureIssuer represents the final user space stack frame module certificate issuer + ThreadCallstackFinalUserModuleSignatureIssuer Field = "thread.callstack.final_user_module.signature.issuer" + // ThreadCallstackFinalUserModuleSignatureSubject represents the final user space stack frame module certificate subject + ThreadCallstackFinalUserModuleSignatureSubject Field = "thread.callstack.final_user_module.signature.subject" // PeNumSections represents the number of sections PeNumSections Field = "pe.nsections" @@ -551,6 +551,84 @@ const ( // ImageIsDotnet indicates if the loaded image is a .NET assembly ImageIsDotnet Field = "image.is_dotnet" + // DllBase is the DLL base address + DllBase Field = "dll.base" + // DllSize is the DLL virtual mapped space size + DllSize Field = "dll.size" + // DllPath is the DLL full path + DllPath Field = "dll.path" + // DllName is the DLL name + DllName Field = "dll.name" + // DllPID is the pid of the process where the DLL was loaded + DllPID Field = "dll.pid" + // DllSignatureType represents the DLL signature type + DllSignatureType Field = "dll.signature.type" + // DllSignatureLevel represents the DLL signature level + DllSignatureLevel Field = "dll.signature.level" + // DllSignatureExists is the field that determines if the DLL signature exists + DllSignatureExists Field = "dll.signature.exists" + // DllSignatureTrusted is the filed that determines if the DLL signature is trusted + DllSignatureTrusted Field = "dll.signature.trusted" + // DllSignatureSubject is the field that indicates the subject of the certificate is the entity its public key is associated with. + DllSignatureSubject = "dll.signature.subject" + // DllSignatureIssuer is the field that represents the certificate authority (CA). + DllSignatureIssuer = "dll.signature.issuer" + // DllSignatureSerial is the field that represents the serial number MUST be a positive integer assigned + // by the CA to each certificate. + DllSignatureSerial = "dll.signature.serial" + // DllSignatureBefore is the field that specifies the certificate won't be valid before this timestamp. + DllSignatureBefore = "dll.signature.before" + // DllSignatureAfter is the field that specifies the certificate won't be valid after this timestamp. + DllSignatureAfter = "dll.signature.after" + // DllIsDotnet indicates if the DLL is a .NET assembly. + DllIsDotnet Field = "dll.pe.is_dotnet" + + // ModuleBase is the module base address + ModuleBase Field = "module.base" + // ModuleSize is the module size + ModuleSize Field = "module.size" + // ModuleChecksum represents the module checksum hash + ModuleChecksum Field = "module.checksum" + // ModuleDefaultAddress represents the module address + ModuleDefaultAddress Field = "module.default_address" + // ModulePath is the module full path + ModulePath Field = "module.path" + // ModuleName is the module name + ModuleName Field = "module.name" + // ModulePID is the pid of the process where the module was loaded + ModulePID Field = "module.pid" + // ModuleSignatureType represents the module signature type + ModuleSignatureType Field = "module.signature.type" + // ModuleSignatureLevel represents the module signature level + ModuleSignatureLevel Field = "module.signature.level" + // ModuleSignatureExists is the field that determines if the module signature exists + ModuleSignatureExists Field = "module.signature.exists" + // ModuleSignatureTrusted is the filed that determines if the module signature is trusted + ModuleSignatureTrusted Field = "module.signature.trusted" + // ModuleSignatureSubject is the field that indicates the subject of the certificate is the entity its public key is associated with. + ModuleSignatureSubject = "module.signature.subject" + // ModuleSignatureIssuer is the field that represents the certificate authority (CA). + ModuleSignatureIssuer = "module.signature.issuer" + // ModuleSignatureSerial is the field that represents the serial number MUST be a positive integer assigned + // by the CA to each certificate. + ModuleSignatureSerial = "module.signature.serial" + // ModuleSignatureBefore is the field that specifies the certificate won't be valid before this timestamp. + ModuleSignatureBefore = "module.signature.before" + // ModuleSignatureAfter is the field that specifies the certificate won't be valid after this timestamp. + ModuleSignatureAfter = "module.signature.after" + // ModuleIsDriverVulnerable represents the field that denotes whether loaded driver is vulnerable + ModuleIsDriverVulnerable Field = "module.is_driver_vulnerable" + // ModuleIsDriverMalicious represents the field that denotes whether the loaded driver is malicious + ModuleIsDriverMalicious Field = "module.is_driver_malicious" + // ModuleIsDLL indicates if the loaded module is a DLL + ModuleIsDLL Field = "module.is_dll" + // ModuleIsDriver indicates if the loaded module is a driver + ModuleIsDriver Field = "module.is_driver" + // ModuleIsExecutable indicates if the loaded module is an executable + ModuleIsExecutable Field = "module.is_exec" + // ModuleIsDotnet indicates if the loaded module is a .NET assembly + ModuleIsDotnet Field = "module.pe.is_dotnet" + // MemBaseAddress identifies the field that denotes the allocation base address MemBaseAddress Field = "mem.address" // MemRegionSize Field identifies the field that represents the allocated region size @@ -627,6 +705,9 @@ func (f Field) IsHandleField() bool { return strings.HasPrefix(string(f), "han func (f Field) IsPeField() bool { return strings.HasPrefix(string(f), "pe.") || strings.HasPrefix(string(f), "ps.pe.") || strings.HasPrefix(string(f), "ps.signature.") } +func (f Field) IsModuleField() bool { + return strings.HasPrefix(string(f), "module.") || strings.HasPrefix(string(f), "dll.") +} func (f Field) IsMemField() bool { return strings.HasPrefix(string(f), "mem.") } func (f Field) IsDNSField() bool { return strings.HasPrefix(string(f), "dns.") } func (f Field) IsThreadpoolField() bool { return strings.HasPrefix(string(f), "threadpool.") } @@ -653,6 +734,13 @@ func (f Field) IsPeCert() bool { return strings.HasPrefix(string(f), "pe.cert.") || f == PsSignatureIssuer || f == PsSignatureSubject || f == PsSignatureSerial || f == PsSignatureAfter || f == PsSignatureBefore } func (f Field) IsImageCert() bool { return strings.HasPrefix(string(f), "image.cert.") } +func (f Field) IsModuleCert() bool { + return f == ModuleSignatureSubject || f == ModuleSignatureIssuer || f == ModuleSignatureSerial || f == ModuleSignatureAfter || f == ModuleSignatureBefore || + f == DllSignatureSubject || f == DllSignatureIssuer || f == DllSignatureSerial || f == DllSignatureAfter || f == DllSignatureBefore +} +func (f Field) IsModuleSignature() bool { + return strings.HasPrefix(string(f), "module.signature.") || strings.HasPrefix(string(f), "dll.signature.") +} func (f Field) IsPeModified() bool { return f == PeIsModified || f == PsPeIsModified } @@ -703,51 +791,51 @@ const ( CallsiteLeadingAssemblySegment Segment = "callsite_leading_assembly" CallsiteTrailingAssemblySegment Segment = "callsite_trailing_assembly" - ModuleSignatureIsSignedSegment Segment = "module.signature.is_signed" - ModuleSignatureIsTrustedSegment Segment = "module.signature.is_trusted" - ModuleSignatureCertIssuerSegment Segment = "module.signature.cert.issuer" - ModuleSignatureCertSubjectSegment Segment = "module.signature.cert.subject" + ModuleSignatureExistsSegment Segment = "module.signature.exists" + ModuleSignatureTrustedSegment Segment = "module.signature.trusted" + ModuleSignatureIssuerSegment Segment = "module.signature.issuer" + ModuleSignatureSubjectSegment Segment = "module.signature.subject" ) var segments = map[Segment]bool{ - NameSegment: true, - PathSegment: true, - TypeSegment: true, - EntropySegment: true, - SizeSegment: true, - MD5Segment: true, - AddressSegment: true, - ChecksumSegment: true, - PIDSegment: true, - CmdlineSegment: true, - ExeSegment: true, - ArgsSegment: true, - CwdSegment: true, - SIDSegment: true, - SessionIDSegment: true, - UsernameSegment: true, - DomainSegment: true, - TokenIntegrityLevelSegment: true, - TokenIsElevatedSegment: true, - TokenElevationTypeSegment: true, - TidSegment: true, - StartAddressSegment: true, - UserStackBaseSegment: true, - UserStackLimitSegment: true, - KernelStackBaseSegment: true, - KernelStackLimitSegment: true, - OffsetSegment: true, - SymbolSegment: true, - ModuleSegment: true, - AllocationSizeSegment: true, - ProtectionSegment: true, - IsUnbackedSegment: true, - CallsiteLeadingAssemblySegment: true, - CallsiteTrailingAssemblySegment: true, - ModuleSignatureIsSignedSegment: true, - ModuleSignatureIsTrustedSegment: true, - ModuleSignatureCertIssuerSegment: true, - ModuleSignatureCertSubjectSegment: true, + NameSegment: true, + PathSegment: true, + TypeSegment: true, + EntropySegment: true, + SizeSegment: true, + MD5Segment: true, + AddressSegment: true, + ChecksumSegment: true, + PIDSegment: true, + CmdlineSegment: true, + ExeSegment: true, + ArgsSegment: true, + CwdSegment: true, + SIDSegment: true, + SessionIDSegment: true, + UsernameSegment: true, + DomainSegment: true, + TokenIntegrityLevelSegment: true, + TokenIsElevatedSegment: true, + TokenElevationTypeSegment: true, + TidSegment: true, + StartAddressSegment: true, + UserStackBaseSegment: true, + UserStackLimitSegment: true, + KernelStackBaseSegment: true, + KernelStackLimitSegment: true, + OffsetSegment: true, + SymbolSegment: true, + ModuleSegment: true, + AllocationSizeSegment: true, + ProtectionSegment: true, + IsUnbackedSegment: true, + CallsiteLeadingAssemblySegment: true, + CallsiteTrailingAssemblySegment: true, + ModuleSignatureExistsSegment: true, + ModuleSignatureTrustedSegment: true, + ModuleSignatureIssuerSegment: true, + ModuleSignatureSubjectSegment: true, } var allowedSegments = map[Field][]Segment{ @@ -757,7 +845,7 @@ var allowedSegments = map[Field][]Segment{ PsMmaps: {AddressSegment, TypeSegment, SizeSegment, ProtectionSegment, PathSegment}, PeSections: {NameSegment, SizeSegment, EntropySegment, MD5Segment}, PsPeSections: {NameSegment, SizeSegment, EntropySegment, MD5Segment}, - ThreadCallstack: {AddressSegment, OffsetSegment, SymbolSegment, ModuleSegment, AllocationSizeSegment, ProtectionSegment, IsUnbackedSegment, CallsiteLeadingAssemblySegment, CallsiteTrailingAssemblySegment, ModuleSignatureIsSignedSegment, ModuleSignatureIsTrustedSegment, ModuleSignatureCertIssuerSegment, ModuleSignatureCertSubjectSegment}, + ThreadCallstack: {AddressSegment, OffsetSegment, SymbolSegment, ModuleSegment, AllocationSizeSegment, ProtectionSegment, IsUnbackedSegment, CallsiteLeadingAssemblySegment, CallsiteTrailingAssemblySegment, ModuleSignatureExistsSegment, ModuleSignatureTrustedSegment, ModuleSignatureIssuerSegment, ModuleSignatureSubjectSegment}, } func (s Segment) IsEntropy() bool { return s == EntropySegment } @@ -978,63 +1066,100 @@ var fields = map[Field]FieldInfo{ PsPeAnomalies: {PsPeAnomalies, "contains PE anomalies detected during parsing", params.Slice, []string{"ps.pe.anomalies in ('number of sections is 0')"}, nil, nil}, PsPeIsModified: {PsPeIsModified, "indicates if disk and in-memory PE headers differ", params.Bool, []string{"ps.pe.is_modified"}, nil, nil}, - ThreadBasePrio: {ThreadBasePrio, "scheduler priority of the thread", params.Int8, []string{"thread.prio = 5"}, nil, nil}, - ThreadIOPrio: {ThreadIOPrio, "I/O priority hint for scheduling I/O operations", params.Int8, []string{"thread.io.prio = 4"}, nil, nil}, - ThreadPagePrio: {ThreadPagePrio, "memory page priority hint for memory pages accessed by the thread", params.Int8, []string{"thread.page.prio = 12"}, nil, nil}, - ThreadKstackBase: {ThreadKstackBase, "base address of the thread's kernel space stack", params.Address, []string{"thread.kstack.base = 'a65d800000'"}, nil, nil}, - ThreadKstackLimit: {ThreadKstackLimit, "limit of the thread's kernel space stack", params.Address, []string{"thread.kstack.limit = 'a85d800000'"}, nil, nil}, - ThreadUstackBase: {ThreadUstackBase, "base address of the thread's user space stack", params.Address, []string{"thread.ustack.base = '7ffe0000'"}, nil, nil}, - ThreadUstackLimit: {ThreadUstackLimit, "limit of the thread's user space stack", params.Address, []string{"thread.ustack.limit = '8ffe0000'"}, nil, nil}, - ThreadEntrypoint: {ThreadEntrypoint, "starting address of the function to be executed by the thread", params.Address, []string{"thread.entrypoint = '7efe0000'"}, &Deprecation{Since: "2.3.0", Fields: []Field{ThreadStartAddress}}, nil}, - ThreadStartAddress: {ThreadStartAddress, "thread start address", params.Address, []string{"thread.start_address = '7efe0000'"}, nil, nil}, - ThreadStartAddressSymbol: {ThreadStartAddressSymbol, "thread start address symbol", params.UnicodeString, []string{"thread.start_address.symbol = 'LoadImage'"}, nil, nil}, - ThreadStartAddressModule: {ThreadStartAddressModule, "thread start address module", params.UnicodeString, []string{"thread.start_address.module endswith 'kernel32.dll'"}, nil, nil}, - ThreadPID: {ThreadPID, "the process identifier where the thread is created", params.Uint32, []string{"evt.pid != thread.pid"}, nil, nil}, - ThreadTEB: {ThreadTEB, "the base address of the thread environment block", params.Address, []string{"thread.teb_address = '8f30893000'"}, nil, nil}, - ThreadAccessMask: {ThreadAccessMask, "thread desired access rights", params.AnsiString, []string{"thread.access.mask = '0x1fffff'"}, nil, nil}, - ThreadAccessMaskNames: {ThreadAccessMaskNames, "thread desired access rights as a string list", params.Slice, []string{"thread.access.mask.names in ('IMPERSONATE')"}, nil, nil}, - ThreadAccessStatus: {ThreadAccessStatus, "thread access status", params.UnicodeString, []string{"thread.access.status = 'success'"}, nil, nil}, - ThreadCallstackSummary: {ThreadCallstackSummary, "callstack summary", params.UnicodeString, []string{"thread.callstack.summary contains 'ntdll.dll|KERNELBASE.dll'"}, nil, nil}, - ThreadCallstackDetail: {ThreadCallstackDetail, "detailed information of each stack frame", params.UnicodeString, []string{"thread.callstack.detail contains 'KERNELBASE.dll!CreateProcessW'"}, nil, nil}, - ThreadCallstackModules: {ThreadCallstackModules, "list of modules comprising the callstack", params.Slice, []string{"thread.callstack.modules in ('C:\\WINDOWS\\System32\\KERNELBASE.dll')", "base(thread.callstack.modules[7]) = 'ntdll.dll'"}, nil, &Argument{Optional: true, Pattern: "[0-9]+", ValidationFunc: isNumber}}, - ThreadCallstackSymbols: {ThreadCallstackSymbols, "list of symbols comprising the callstack", params.Slice, []string{"thread.callstack.symbols in ('ntdll.dll!NtCreateProcess')", "thread.callstack.symbols[3] = 'ntdll!NtCreateProcess'"}, nil, &Argument{Optional: true, Pattern: "[0-9]+", ValidationFunc: isNumber}}, - ThreadCallstackAllocationSizes: {ThreadCallstackAllocationSizes, "allocation sizes of private pages", params.Slice, []string{"thread.callstack.allocation_sizes > 10000"}, nil, nil}, - ThreadCallstackProtections: {ThreadCallstackProtections, "page protections masks of each frame", params.Slice, []string{"thread.callstack.protections in ('RWX', 'WX')"}, nil, nil}, - ThreadCallstackCallsiteLeadingAssembly: {ThreadCallstackCallsiteLeadingAssembly, "callsite leading assembly instructions", params.Slice, []string{"thread.callstack.callsite_leading_assembly in ('mov r10,rcx', 'syscall')"}, nil, nil}, - ThreadCallstackCallsiteTrailingAssembly: {ThreadCallstackCallsiteTrailingAssembly, "callsite trailing assembly instructions", params.Slice, []string{"thread.callstack.callsite_trailing_assembly in ('add esp, 0xab')"}, nil, nil}, - ThreadCallstackIsUnbacked: {ThreadCallstackIsUnbacked, "indicates if the callstack contains unbacked regions", params.Bool, []string{"thread.callstack.is_unbacked"}, nil, nil}, - ThreadCallstackAddresses: {ThreadCallstackAddresses, "list of all stack return addresses", params.Slice, []string{"thread.callstack.addresses in ('7ffb5c1d0396')"}, nil, nil}, - ThreadCallstackFinalUserModuleName: {ThreadCallstackFinalUserModuleName, "final user space stack frame module name", params.UnicodeString, []string{"thread.callstack.final_user_module.name != 'ntdll.dll'"}, nil, nil}, - ThreadCallstackFinalUserModulePath: {ThreadCallstackFinalUserModulePath, "final user space stack frame module path", params.UnicodeString, []string{"thread.callstack.final_user_module.path imatches '?:\\Windows\\System32\\ntdll.dll'"}, nil, nil}, - ThreadCallstackFinalUserSymbolName: {ThreadCallstackFinalUserSymbolName, "final user space stack symbol name", params.UnicodeString, []string{"thread.callstack.final_user_symbol.name imatches 'CreateProcess*'"}, nil, nil}, - ThreadCallstackFinalKernelModuleName: {ThreadCallstackFinalKernelModuleName, "final kernel space stack frame module name", params.UnicodeString, []string{"thread.callstack.final_kernel_module.name = 'FLTMGR.SYS'"}, nil, nil}, - ThreadCallstackFinalKernelModulePath: {ThreadCallstackFinalKernelModulePath, "final kernel space stack frame module path", params.UnicodeString, []string{"thread.callstack.final_kernel_module.path imatches '?:\\WINDOWS\\System32\\drivers\\FLTMGR.SYS'"}, nil, nil}, - ThreadCallstackFinalKernelSymbolName: {ThreadCallstackFinalKernelSymbolName, "final kernel space stack symbol name", params.UnicodeString, []string{"thread.callstack.final_kernel_symbol.name = 'FltGetStreamContext'"}, nil, nil}, - ThreadCallstackFinalUserModuleSignatureIsSigned: {ThreadCallstackFinalUserModuleSignatureIsSigned, "signature status of the final user space stack frame module", params.Bool, []string{"thread.callstack.final_user_module.signature.is_signed = true"}, nil, nil}, - ThreadCallstackFinalUserModuleSignatureIsTrusted: {ThreadCallstackFinalUserModuleSignatureIsTrusted, "signature trust status of the final user space stack frame module", params.Bool, []string{"thread.callstack.final_user_module.signature.is_trusted = true"}, nil, nil}, - ThreadCallstackFinalUserModuleSignatureCertIssuer: {ThreadCallstackFinalUserModuleSignatureCertIssuer, "final user space stack frame module signature certificate issuer", params.UnicodeString, []string{"thread.callstack.final_user_module.signature.cert.issuer imatches '*Microsoft Corporation*'"}, nil, nil}, - ThreadCallstackFinalUserModuleSignatureCertSubject: {ThreadCallstackFinalUserModuleSignatureCertSubject, "final user space stack frame module signature certificate subject", params.UnicodeString, []string{"thread.callstack.final_user_module.signature.cert.subject imatches '*Microsoft Windows*'"}, nil, nil}, - - ImagePath: {ImagePath, "full image path", params.UnicodeString, []string{"image.patj = 'C:\\Windows\\System32\\advapi32.dll'"}, nil, nil}, - ImageName: {ImageName, "image name", params.UnicodeString, []string{"image.name = 'advapi32.dll'"}, nil, nil}, - ImageBase: {ImageBase, "the base address of process in which the image is loaded", params.Address, []string{"image.base.address = 'a65d800000'"}, nil, nil}, - ImageChecksum: {ImageChecksum, "image checksum", params.Uint32, []string{"image.checksum = 746424"}, nil, nil}, - ImageSize: {ImageSize, "image size", params.Uint32, []string{"image.size > 1024"}, nil, nil}, - ImageDefaultAddress: {ImageDefaultAddress, "default image address", params.Address, []string{"image.default.address = '7efe0000'"}, nil, nil}, - ImagePID: {ImagePID, "target process identifier", params.Uint32, []string{"image.pid = 80"}, nil, nil}, - ImageSignatureType: {ImageSignatureType, "image signature type", params.AnsiString, []string{"image.signature.type != 'NONE'"}, nil, nil}, - ImageSignatureLevel: {ImageSignatureLevel, "image signature level", params.AnsiString, []string{"image.signature.level = 'AUTHENTICODE'"}, nil, nil}, - ImageCertSerial: {ImageCertSerial, "image certificate serial number", params.UnicodeString, []string{"image.cert.serial = '330000023241fb59996dcc4dff000000000232'"}, nil, nil}, - ImageCertSubject: {ImageCertSubject, "image certificate subject", params.UnicodeString, []string{"image.cert.subject contains 'Washington, Redmond, Microsoft Corporation'"}, nil, nil}, - ImageCertIssuer: {ImageCertIssuer, "image certificate CA", params.UnicodeString, []string{"image.cert.issuer contains 'Washington, Redmond, Microsoft Corporation'"}, nil, nil}, - ImageCertAfter: {ImageCertAfter, "image certificate expiration date", params.Time, []string{"image.cert.after contains '2024-02-01 00:05:42 +0000 UTC'"}, nil, nil}, - ImageCertBefore: {ImageCertBefore, "image certificate enrollment date", params.Time, []string{"image.cert.before contains '2024-02-01 00:05:42 +0000 UTC'"}, nil, nil}, - ImageIsDriverMalicious: {ImageIsDriverMalicious, "indicates if the loaded driver is malicious", params.Bool, []string{"image.is_driver_malicious"}, nil, nil}, - ImageIsDriverVulnerable: {ImageIsDriverVulnerable, "indicates if the loaded driver is vulnerable", params.Bool, []string{"image.is_driver_vulnerable"}, nil, nil}, - ImageIsDLL: {ImageIsDLL, "indicates if the loaded image is a DLL", params.Bool, []string{"image.is_dll'"}, nil, nil}, - ImageIsDriver: {ImageIsDriver, "indicates if the loaded image is a driver", params.Bool, []string{"image.is_driver'"}, nil, nil}, - ImageIsExecutable: {ImageIsExecutable, "indicates if the loaded image is an executable", params.Bool, []string{"image.is_exec'"}, nil, nil}, - ImageIsDotnet: {ImageIsDotnet, "indicates if the loaded image is a .NET assembly", params.Bool, []string{"image.is_dotnet'"}, nil, nil}, + ThreadBasePrio: {ThreadBasePrio, "scheduler priority of the thread", params.Int8, []string{"thread.prio = 5"}, nil, nil}, + ThreadIOPrio: {ThreadIOPrio, "I/O priority hint for scheduling I/O operations", params.Int8, []string{"thread.io.prio = 4"}, nil, nil}, + ThreadPagePrio: {ThreadPagePrio, "memory page priority hint for memory pages accessed by the thread", params.Int8, []string{"thread.page.prio = 12"}, nil, nil}, + ThreadKstackBase: {ThreadKstackBase, "base address of the thread's kernel space stack", params.Address, []string{"thread.kstack.base = 'a65d800000'"}, nil, nil}, + ThreadKstackLimit: {ThreadKstackLimit, "limit of the thread's kernel space stack", params.Address, []string{"thread.kstack.limit = 'a85d800000'"}, nil, nil}, + ThreadUstackBase: {ThreadUstackBase, "base address of the thread's user space stack", params.Address, []string{"thread.ustack.base = '7ffe0000'"}, nil, nil}, + ThreadUstackLimit: {ThreadUstackLimit, "limit of the thread's user space stack", params.Address, []string{"thread.ustack.limit = '8ffe0000'"}, nil, nil}, + ThreadEntrypoint: {ThreadEntrypoint, "starting address of the function to be executed by the thread", params.Address, []string{"thread.entrypoint = '7efe0000'"}, &Deprecation{Since: "2.3.0", Fields: []Field{ThreadStartAddress}}, nil}, + ThreadStartAddress: {ThreadStartAddress, "thread start address", params.Address, []string{"thread.start_address = '7efe0000'"}, nil, nil}, + ThreadStartAddressSymbol: {ThreadStartAddressSymbol, "thread start address symbol", params.UnicodeString, []string{"thread.start_address.symbol = 'LoadImage'"}, nil, nil}, + ThreadStartAddressModule: {ThreadStartAddressModule, "thread start address module", params.UnicodeString, []string{"thread.start_address.module endswith 'kernel32.dll'"}, nil, nil}, + ThreadPID: {ThreadPID, "the process identifier where the thread is created", params.Uint32, []string{"evt.pid != thread.pid"}, nil, nil}, + ThreadTEB: {ThreadTEB, "the base address of the thread environment block", params.Address, []string{"thread.teb_address = '8f30893000'"}, nil, nil}, + ThreadAccessMask: {ThreadAccessMask, "thread desired access rights", params.AnsiString, []string{"thread.access.mask = '0x1fffff'"}, nil, nil}, + ThreadAccessMaskNames: {ThreadAccessMaskNames, "thread desired access rights as a string list", params.Slice, []string{"thread.access.mask.names in ('IMPERSONATE')"}, nil, nil}, + ThreadAccessStatus: {ThreadAccessStatus, "thread access status", params.UnicodeString, []string{"thread.access.status = 'success'"}, nil, nil}, + ThreadCallstackSummary: {ThreadCallstackSummary, "callstack summary", params.UnicodeString, []string{"thread.callstack.summary contains 'ntdll.dll|KERNELBASE.dll'"}, nil, nil}, + ThreadCallstackDetail: {ThreadCallstackDetail, "detailed information of each stack frame", params.UnicodeString, []string{"thread.callstack.detail contains 'KERNELBASE.dll!CreateProcessW'"}, nil, nil}, + ThreadCallstackModules: {ThreadCallstackModules, "list of modules comprising the callstack", params.Slice, []string{"thread.callstack.modules in ('C:\\WINDOWS\\System32\\KERNELBASE.dll')", "base(thread.callstack.modules[7]) = 'ntdll.dll'"}, nil, &Argument{Optional: true, Pattern: "[0-9]+", ValidationFunc: isNumber}}, + ThreadCallstackSymbols: {ThreadCallstackSymbols, "list of symbols comprising the callstack", params.Slice, []string{"thread.callstack.symbols in ('ntdll.dll!NtCreateProcess')", "thread.callstack.symbols[3] = 'ntdll!NtCreateProcess'"}, nil, &Argument{Optional: true, Pattern: "[0-9]+", ValidationFunc: isNumber}}, + ThreadCallstackAllocationSizes: {ThreadCallstackAllocationSizes, "allocation sizes of private pages", params.Slice, []string{"thread.callstack.allocation_sizes > 10000"}, nil, nil}, + ThreadCallstackProtections: {ThreadCallstackProtections, "page protections masks of each frame", params.Slice, []string{"thread.callstack.protections in ('RWX', 'WX')"}, nil, nil}, + ThreadCallstackCallsiteLeadingAssembly: {ThreadCallstackCallsiteLeadingAssembly, "callsite leading assembly instructions", params.Slice, []string{"thread.callstack.callsite_leading_assembly in ('mov r10,rcx', 'syscall')"}, nil, nil}, + ThreadCallstackCallsiteTrailingAssembly: {ThreadCallstackCallsiteTrailingAssembly, "callsite trailing assembly instructions", params.Slice, []string{"thread.callstack.callsite_trailing_assembly in ('add esp, 0xab')"}, nil, nil}, + ThreadCallstackIsUnbacked: {ThreadCallstackIsUnbacked, "indicates if the callstack contains unbacked regions", params.Bool, []string{"thread.callstack.is_unbacked"}, nil, nil}, + ThreadCallstackAddresses: {ThreadCallstackAddresses, "list of all stack return addresses", params.Slice, []string{"thread.callstack.addresses in ('7ffb5c1d0396')"}, nil, nil}, + ThreadCallstackFinalUserModuleName: {ThreadCallstackFinalUserModuleName, "final user space stack frame module name", params.UnicodeString, []string{"thread.callstack.final_user_module.name != 'ntdll.dll'"}, nil, nil}, + ThreadCallstackFinalUserModulePath: {ThreadCallstackFinalUserModulePath, "final user space stack frame module path", params.UnicodeString, []string{"thread.callstack.final_user_module.path imatches '?:\\Windows\\System32\\ntdll.dll'"}, nil, nil}, + ThreadCallstackFinalUserSymbolName: {ThreadCallstackFinalUserSymbolName, "final user space stack symbol name", params.UnicodeString, []string{"thread.callstack.final_user_symbol.name imatches 'CreateProcess*'"}, nil, nil}, + ThreadCallstackFinalKernelModuleName: {ThreadCallstackFinalKernelModuleName, "final kernel space stack frame module name", params.UnicodeString, []string{"thread.callstack.final_kernel_module.name = 'FLTMGR.SYS'"}, nil, nil}, + ThreadCallstackFinalKernelModulePath: {ThreadCallstackFinalKernelModulePath, "final kernel space stack frame module path", params.UnicodeString, []string{"thread.callstack.final_kernel_module.path imatches '?:\\WINDOWS\\System32\\drivers\\FLTMGR.SYS'"}, nil, nil}, + ThreadCallstackFinalKernelSymbolName: {ThreadCallstackFinalKernelSymbolName, "final kernel space stack symbol name", params.UnicodeString, []string{"thread.callstack.final_kernel_symbol.name = 'FltGetStreamContext'"}, nil, nil}, + ThreadCallstackFinalUserModuleSignatureExists: {ThreadCallstackFinalUserModuleSignatureExists, "signature status of the final user space stack frame module", params.Bool, []string{"thread.callstack.final_user_module.signature.exists = true"}, nil, nil}, + ThreadCallstackFinalUserModuleSignatureTrusted: {ThreadCallstackFinalUserModuleSignatureTrusted, "signature trust status of the final user space stack frame module", params.Bool, []string{"thread.callstack.final_user_module.signature.trusted = true"}, nil, nil}, + ThreadCallstackFinalUserModuleSignatureIssuer: {ThreadCallstackFinalUserModuleSignatureIssuer, "final user space stack frame module signature certificate issuer", params.UnicodeString, []string{"thread.callstack.final_user_module.signature.issuer imatches '*Microsoft Corporation*'"}, nil, nil}, + ThreadCallstackFinalUserModuleSignatureSubject: {ThreadCallstackFinalUserModuleSignatureSubject, "final user space stack frame module signature certificate subject", params.UnicodeString, []string{"thread.callstack.final_user_module.signature.subject imatches '*Microsoft Windows*'"}, nil, nil}, + + ImagePath: {ImagePath, "full image path", params.UnicodeString, []string{"image.path = 'C:\\Windows\\System32\\advapi32.dll'"}, &Deprecation{Since: "3.0.0", Fields: []Field{ModulePath}}, nil}, + ImageName: {ImageName, "image name", params.UnicodeString, []string{"image.name = 'advapi32.dll'"}, &Deprecation{Since: "3.0.0", Fields: []Field{ModuleName}}, nil}, + ImageBase: {ImageBase, "the base address of process in which the image is loaded", params.Address, []string{"image.base.address = 'a65d800000'"}, &Deprecation{Since: "3.0.0", Fields: []Field{ModuleBase}}, nil}, + ImageChecksum: {ImageChecksum, "image checksum", params.Uint32, []string{"image.checksum = 746424"}, &Deprecation{Since: "3.0.0", Fields: []Field{ModuleChecksum}}, nil}, + ImageSize: {ImageSize, "image size", params.Uint32, []string{"image.size > 1024"}, &Deprecation{Since: "3.0.0", Fields: []Field{ModuleSize}}, nil}, + ImageDefaultAddress: {ImageDefaultAddress, "default image address", params.Address, []string{"image.default.address = '7efe0000'"}, &Deprecation{Since: "3.0.0", Fields: []Field{ModuleDefaultAddress}}, nil}, + ImagePID: {ImagePID, "target process identifier", params.Uint32, []string{"image.pid = 80"}, &Deprecation{Since: "3.0.0", Fields: []Field{ModulePID}}, nil}, + ImageSignatureType: {ImageSignatureType, "image signature type", params.AnsiString, []string{"image.signature.type != 'NONE'"}, &Deprecation{Since: "3.0.0", Fields: []Field{ModuleSignatureType}}, nil}, + ImageSignatureLevel: {ImageSignatureLevel, "image signature level", params.AnsiString, []string{"image.signature.level = 'AUTHENTICODE'"}, &Deprecation{Since: "3.0.0", Fields: []Field{ModuleSignatureLevel}}, nil}, + ImageCertSerial: {ImageCertSerial, "image certificate serial number", params.UnicodeString, []string{"image.cert.serial = '330000023241fb59996dcc4dff000000000232'"}, &Deprecation{Since: "3.0.0", Fields: []Field{ModuleSignatureSerial}}, nil}, + ImageCertSubject: {ImageCertSubject, "image certificate subject", params.UnicodeString, []string{"image.cert.subject contains 'Washington, Redmond, Microsoft Corporation'"}, &Deprecation{Since: "3.0.0", Fields: []Field{ModuleSignatureSubject}}, nil}, + ImageCertIssuer: {ImageCertIssuer, "image certificate CA", params.UnicodeString, []string{"image.cert.issuer contains 'Washington, Redmond, Microsoft Corporation'"}, &Deprecation{Since: "3.0.0", Fields: []Field{ModuleSignatureIssuer}}, nil}, + ImageCertAfter: {ImageCertAfter, "image certificate expiration date", params.Time, []string{"image.cert.after contains '2024-02-01 00:05:42 +0000 UTC'"}, &Deprecation{Since: "3.0.0", Fields: []Field{ModuleSignatureAfter}}, nil}, + ImageCertBefore: {ImageCertBefore, "image certificate enrollment date", params.Time, []string{"image.cert.before contains '2024-02-01 00:05:42 +0000 UTC'"}, &Deprecation{Since: "3.0.0", Fields: []Field{ModuleSignatureBefore}}, nil}, + ImageIsDriverMalicious: {ImageIsDriverMalicious, "indicates if the loaded driver is malicious", params.Bool, []string{"image.is_driver_malicious"}, &Deprecation{Since: "3.0.0", Fields: []Field{ModuleIsDriverMalicious}}, nil}, + ImageIsDriverVulnerable: {ImageIsDriverVulnerable, "indicates if the loaded driver is vulnerable", params.Bool, []string{"image.is_driver_vulnerable"}, &Deprecation{Since: "3.0.0", Fields: []Field{ModuleIsDriverVulnerable}}, nil}, + ImageIsDLL: {ImageIsDLL, "indicates if the loaded image is a DLL", params.Bool, []string{"image.is_dll'"}, &Deprecation{Since: "3.0.0", Fields: []Field{ModuleIsDLL}}, nil}, + ImageIsDriver: {ImageIsDriver, "indicates if the loaded image is a driver", params.Bool, []string{"image.is_driver'"}, &Deprecation{Since: "3.0.0", Fields: []Field{ModuleIsDriver}}, nil}, + ImageIsExecutable: {ImageIsExecutable, "indicates if the loaded image is an executable", params.Bool, []string{"image.is_exec'"}, &Deprecation{Since: "3.0.0", Fields: []Field{ModuleIsExecutable}}, nil}, + ImageIsDotnet: {ImageIsDotnet, "indicates if the loaded image is a .NET assembly", params.Bool, []string{"image.is_dotnet'"}, &Deprecation{Since: "3.0.0", Fields: []Field{ModuleIsDotnet}}, nil}, + ModulePath: {ModulePath, "full module path", params.UnicodeString, []string{"module.path = 'C:\\Windows\\System32\\advapi32.dll'"}, nil, nil}, + ModuleName: {ModuleName, "module name", params.UnicodeString, []string{"module.name = 'advapi32.dll'"}, nil, nil}, + ModuleBase: {ModuleBase, "the base address of process in which the module is loaded", params.Address, []string{"module.base.address = 'a65d800000'"}, nil, nil}, + ModuleChecksum: {ModuleChecksum, "module checksum", params.Uint32, []string{"module.checksum = 746424"}, nil, nil}, + ModuleSize: {ModuleSize, "module size", params.Uint32, []string{"module.size > 1024"}, nil, nil}, + ModuleDefaultAddress: {ModuleDefaultAddress, "default module address", params.Address, []string{"module.default_address = '7efe0000'"}, nil, nil}, + ModulePID: {ModulePID, "target process identifier", params.Uint32, []string{"module.pid = 80"}, nil, nil}, + ModuleSignatureType: {ModuleSignatureType, "module signature type", params.AnsiString, []string{"module.signature.type != 'NONE'"}, nil, nil}, + ModuleSignatureLevel: {ModuleSignatureLevel, "module signature level", params.AnsiString, []string{"module.signature.level = 'AUTHENTICODE'"}, nil, nil}, + ModuleSignatureExists: {ModuleSignatureExists, "indicates if the module is signed", params.Bool, []string{"module.signature.exists = true"}, nil, nil}, + ModuleSignatureTrusted: {ModuleSignatureTrusted, "indicates if the module signature is trusted", params.Bool, []string{"module.signature.trusted = false"}, nil, nil}, + ModuleSignatureSerial: {ModuleSignatureSerial, "module certificate serial number", params.UnicodeString, []string{"module.signature.serial = '330000023241fb59996dcc4dff000000000232'"}, nil, nil}, + ModuleSignatureSubject: {ModuleSignatureSubject, "module certificate subject", params.UnicodeString, []string{"module.signature.subject contains 'Washington, Redmond, Microsoft Corporation'"}, nil, nil}, + ModuleSignatureIssuer: {ModuleSignatureIssuer, "module certificate CA", params.UnicodeString, []string{"module.signature.issuer contains 'Washington, Redmond, Microsoft Corporation'"}, nil, nil}, + ModuleSignatureAfter: {ModuleSignatureAfter, "module certificate expiration date", params.Time, []string{"module.signature.after contains '2024-02-01 00:05:42 +0000 UTC'"}, nil, nil}, + ModuleSignatureBefore: {ModuleSignatureBefore, "module certificate enrollment date", params.Time, []string{"module.signature.before contains '2024-02-01 00:05:42 +0000 UTC'"}, nil, nil}, + ModuleIsDriverMalicious: {ModuleIsDriverMalicious, "indicates if the loaded driver is malicious", params.Bool, []string{"module.is_driver_malicious"}, nil, nil}, + ModuleIsDriverVulnerable: {ModuleIsDriverVulnerable, "indicates if the loaded driver is vulnerable", params.Bool, []string{"module.is_driver_vulnerable"}, nil, nil}, + ModuleIsDLL: {ModuleIsDLL, "indicates if the loaded module is a DLL", params.Bool, []string{"module.is_dll'"}, nil, nil}, + ModuleIsDriver: {ModuleIsDriver, "indicates if the loaded module is a driver", params.Bool, []string{"module.is_driver'"}, nil, nil}, + ModuleIsExecutable: {ModuleIsExecutable, "indicates if the loaded module is an executable", params.Bool, []string{"module.is_exec'"}, nil, nil}, + ModuleIsDotnet: {ModuleIsDotnet, "indicates if the loaded module is a .NET assembly", params.Bool, []string{"module.pe.is_dotnet'"}, nil, nil}, + DllPath: {DllPath, "full dll path", params.UnicodeString, []string{"dll.path = 'C:\\Windows\\System32\\advapi32.dll'"}, nil, nil}, + DllName: {DllName, "module name", params.UnicodeString, []string{"dll.name = 'advapi32.dll'"}, nil, nil}, + DllBase: {DllBase, "the base address of process in which the DLL is loaded", params.Address, []string{"dll.base = 'a65d800000'"}, nil, nil}, + DllSize: {DllSize, "dll virtual mapped size", params.Uint32, []string{"dll.size > 1024"}, nil, nil}, + DllPID: {DllPID, "target process identifier", params.Uint32, []string{"dll.pid = 80"}, nil, nil}, + DllSignatureType: {DllSignatureType, "dll signature type", params.AnsiString, []string{"dll.signature.type != 'NONE'"}, nil, nil}, + DllSignatureLevel: {DllSignatureLevel, "dll signature level", params.AnsiString, []string{"dll.signature.level = 'AUTHENTICODE'"}, nil, nil}, + DllSignatureExists: {DllSignatureExists, "indicates if the dll is signed", params.Bool, []string{"dll.signature.exists = true"}, nil, nil}, + DllSignatureTrusted: {DllSignatureTrusted, "indicates if the dll signature is trusted", params.Bool, []string{"dll.signature.trusted = false"}, nil, nil}, + DllSignatureSerial: {DllSignatureSerial, "dll certificate serial number", params.UnicodeString, []string{"dll.signature.serial = '330000023241fb59996dcc4dff000000000232'"}, nil, nil}, + DllSignatureSubject: {DllSignatureSubject, "dll certificate subject", params.UnicodeString, []string{"dll.signature.subject contains 'Washington, Redmond, Microsoft Corporation'"}, nil, nil}, + DllSignatureIssuer: {DllSignatureIssuer, "dll certificate CA", params.UnicodeString, []string{"dll.signature.issuer contains 'Washington, Redmond, Microsoft Corporation'"}, nil, nil}, + DllSignatureAfter: {DllSignatureAfter, "moddllule certificate expiration date", params.Time, []string{"dll.signature.after contains '2024-02-01 00:05:42 +0000 UTC'"}, nil, nil}, + DllSignatureBefore: {DllSignatureBefore, "dll certificate enrollment date", params.Time, []string{"dll.signature.before contains '2024-02-01 00:05:42 +0000 UTC'"}, nil, nil}, + DllIsDotnet: {DllIsDotnet, "indicates if the loaded dll is a .NET assembly", params.Bool, []string{"dll.pe.is_dotnet'"}, nil, nil}, FileObject: {FileObject, "file object address", params.Uint64, []string{"file.object = 18446738026482168384"}, nil, nil}, FilePath: {FilePath, "full file path", params.UnicodeString, []string{"file.path = 'C:\\Windows\\System32'"}, nil, nil}, diff --git a/pkg/filter/filter.go b/pkg/filter/filter.go index b433e3527..9c662361e 100644 --- a/pkg/filter/filter.go +++ b/pkg/filter/filter.go @@ -100,7 +100,7 @@ func (b *BoundField) Accessor(f *filter) Accessor { case b.Field.Name.IsThreadField(): b.accessor = newThreadAccessor() case b.Field.Name.IsImageField(): - b.accessor = newImageAccessor() + b.accessor = newModuleAccessor() case b.Field.Name.IsFileField(): b.accessor = newFileAccessor() case b.Field.Name.IsRegistryField(): diff --git a/pkg/filter/filter_test.go b/pkg/filter/filter_test.go index 67140e559..cc02ee531 100644 --- a/pkg/filter/filter_test.go +++ b/pkg/filter/filter_test.go @@ -502,10 +502,10 @@ func TestThreadFilter(t *testing.T) { {`thread.callstack.final_kernel_module.name = 'FLTMGR.SYS'`, true}, {`thread.callstack.final_kernel_module.path = 'C:\\WINDOWS\\System32\\drivers\\FLTMGR.SYS'`, true}, {`thread.callstack.final_kernel_symbol.name = 'FltGetStreamContext'`, true}, - {`thread.callstack.final_user_module.signature.is_signed = true`, true}, - {`thread.callstack.final_user_module.signature.is_trusted = true`, true}, - {`thread.callstack.final_user_module.signature.cert.issuer imatches '*Microsoft Corporation*'`, true}, - {`thread.callstack.final_user_module.signature.cert.subject imatches '*Microsoft Windows*'`, true}, + {`thread.callstack.final_user_module.signature.exists = true`, true}, + {`thread.callstack.final_user_module.signature.trusted = true`, true}, + {`thread.callstack.final_user_module.signature.issuer imatches '*Microsoft Corporation*'`, true}, + {`thread.callstack.final_user_module.signature.subject imatches '*Microsoft Windows*'`, true}, {`foreach(thread._callstack, $frame, $frame.address = '2638e59e0a5' or $frame.address = '7ffb5c1d0396')`, true}, {`foreach(thread._callstack, $frame, $frame.address = 'fffff8072ebc1f6f' or $frame.address = 'fffff8072eb8961b')`, true}, @@ -520,9 +520,9 @@ func TestThreadFilter(t *testing.T) { {`foreach(thread._callstack, $frame, $frame.allocation_size = 0)`, true}, {`foreach(thread._callstack, $frame, $frame.protection = 'RWX')`, true}, {`foreach(thread._callstack, $frame, $frame.callsite_trailing_assembly matches '*mov r10, rcx|mov eax, 0x*|syscall*' and $frame.module = 'unbacked')`, true}, - {`foreach(thread._callstack, $frame, $frame.module.signature.is_signed and $frame.module.signature.is_trusted)`, true}, - {`foreach(thread._callstack, $frame, $frame.module.signature.cert.issuer imatches '*Microsoft Corporation*')`, true}, - {`foreach(thread._callstack, $frame, $frame.module.signature.cert.subject imatches '*Microsoft Windows*')`, true}, + {`foreach(thread._callstack, $frame, $frame.module.signature.exists and $frame.module.signature.trusted)`, true}, + {`foreach(thread._callstack, $frame, $frame.module.signature.issuer imatches '*Microsoft Corporation*')`, true}, + {`foreach(thread._callstack, $frame, $frame.module.signature.subject imatches '*Microsoft Windows*')`, true}, } for i, tt := range tests { @@ -980,7 +980,7 @@ func TestRegistryFilter(t *testing.T) { } } -func TestImageFilter(t *testing.T) { +func TestModuleFilter(t *testing.T) { e1 := &event.Event{ Type: event.LoadImage, Category: event.Image, @@ -1000,16 +1000,29 @@ func TestImageFilter(t *testing.T) { matches bool }{ - {`image.signature.type = 'EMBEDDED'`, true}, - {`image.signature.level = 'AUTHENTICODE'`, true}, - {`image.pid = 1023`, true}, - {`image.path endswith 'System32\\kernel32.dll'`, true}, - {`image.name = 'kernel32.dll'`, true}, - {`image.checksum = 2323432`, true}, - {`image.base.address = '7ffb313833a3'`, true}, - {`image.cert.issuer icontains 'Microsoft Windows'`, true}, - {`image.cert.subject icontains 'Microsoft Corporation'`, true}, - {`image.is_dotnet`, false}, + {`module.signature.type = 'EMBEDDED'`, true}, + {`module.signature.level = 'AUTHENTICODE'`, true}, + {`module.signature.exists`, true}, + {`module.signature.trusted`, true}, + {`module.pid = 1023`, true}, + {`module.path endswith 'System32\\kernel32.dll'`, true}, + {`module.name = 'kernel32.dll'`, true}, + {`module.checksum = 2323432`, true}, + {`module.base = '7ffb313833a3'`, true}, + {`module.signature.issuer icontains 'Microsoft Windows'`, true}, + {`module.signature.subject icontains 'Microsoft Corporation'`, true}, + {`module.pe.is_dotnet`, false}, + {`dll.signature.type = 'EMBEDDED'`, true}, + {`dll.signature.level = 'AUTHENTICODE'`, true}, + {`dll.signature.exists`, true}, + {`dll.signature.trusted`, true}, + {`dll.pid = 1023`, true}, + {`dll.path endswith 'System32\\kernel32.dll'`, true}, + {`dll.name = 'kernel32.dll'`, true}, + {`dll.base = '7ffb313833a3'`, true}, + {`dll.signature.issuer icontains 'Microsoft Windows'`, true}, + {`dll.signature.subject icontains 'Microsoft Corporation'`, true}, + {`dll.pe.is_dotnet`, false}, } for i, tt := range tests { @@ -1051,14 +1064,25 @@ func TestImageFilter(t *testing.T) { matches bool }{ - {`image.signature.type = 'EMBEDDED'`, true}, - {`image.signature.level = 'AUTHENTICODE'`, true}, - {`image.pid = 1023`, true}, - {`image.name endswith 'kernel32.dll'`, true}, - {`image.checksum = 2323432`, true}, - {`image.base.address = '7ccb313833a3'`, true}, - {`image.cert.issuer icontains 'Microsoft Windows'`, true}, - {`image.cert.subject icontains 'Microsoft Corporation'`, true}, + {`module.signature.type = 'EMBEDDED'`, true}, + {`module.signature.level = 'AUTHENTICODE'`, true}, + {`module.signature.exists`, true}, + {`module.signature.trusted`, true}, + {`module.pid = 1023`, true}, + {`module.name endswith 'kernel32.dll'`, true}, + {`module.checksum = 2323432`, true}, + {`module.base = '7ccb313833a3'`, true}, + {`module.signature.issuer icontains 'Microsoft Windows'`, true}, + {`module.signature.subject icontains 'Microsoft Corporation'`, true}, + {`dll.signature.type = 'EMBEDDED'`, true}, + {`dll.signature.level = 'AUTHENTICODE'`, true}, + {`dll.signature.exists`, true}, + {`dll.signature.trusted`, true}, + {`dll.pid = 1023`, true}, + {`dll.name endswith 'kernel32.dll'`, true}, + {`dll.base = '7ccb313833a3'`, true}, + {`dll.signature.issuer icontains 'Microsoft Windows'`, true}, + {`dll.signature.subject icontains 'Microsoft Corporation'`, true}, } for i, tt := range tests1 { @@ -1094,9 +1118,12 @@ func TestImageFilter(t *testing.T) { matches bool }{ - {`image.pid = 1023`, true}, - {`image.name endswith 'mscorlib.dll'`, true}, - {`image.is_dotnet`, true}, + {`module.pid = 1023`, true}, + {`module.name endswith 'mscorlib.dll'`, true}, + {`module.pe.is_dotnet`, true}, + {`dll.pid = 1023`, true}, + {`dll.name endswith 'mscorlib.dll'`, true}, + {`dll.pe.is_dotnet`, true}, } for i, tt := range tests2 { diff --git a/pkg/filter/filter_windows.go b/pkg/filter/filter_windows.go index 007d14b76..46345d8b8 100644 --- a/pkg/filter/filter_windows.go +++ b/pkg/filter/filter_windows.go @@ -20,11 +20,12 @@ package filter import ( "fmt" + "strings" + "github.com/rabbitstack/fibratus/pkg/config" "github.com/rabbitstack/fibratus/pkg/filter/fields" "github.com/rabbitstack/fibratus/pkg/filter/ql" "github.com/rabbitstack/fibratus/pkg/ps" - "strings" ) type opts struct { @@ -64,7 +65,7 @@ func New(expr string, config *config.Config, options ...Option) Filter { accessors = append(accessors, newThreadAccessor()) } if config.EventSource.EnableImageEvents { - accessors = append(accessors, newImageAccessor()) + accessors = append(accessors, newModuleAccessor()) } if config.EventSource.EnableFileIOEvents { accessors = append(accessors, newFileAccessor()) diff --git a/pkg/filter/ql/function.go b/pkg/filter/ql/function.go index fa213415e..03a18fbb8 100644 --- a/pkg/filter/ql/function.go +++ b/pkg/filter/ql/function.go @@ -20,17 +20,18 @@ package ql import ( "fmt" + "maps" + "path/filepath" + "regexp" + "sort" + "strings" + "github.com/rabbitstack/fibratus/pkg/callstack" "github.com/rabbitstack/fibratus/pkg/filter/fields" "github.com/rabbitstack/fibratus/pkg/pe" pstypes "github.com/rabbitstack/fibratus/pkg/ps/types" "github.com/rabbitstack/fibratus/pkg/util/signature" "golang.org/x/sys/windows" - "maps" - "path/filepath" - "regexp" - "sort" - "strings" "github.com/rabbitstack/fibratus/pkg/filter/ql/functions" ) @@ -566,8 +567,8 @@ func (f *Foreach) callstackMapValuer(segments []*BoundSegmentLiteral, frame call valuer[key] = frame.CallsiteAssembly(proc, false) case fields.CallsiteLeadingAssemblySegment: valuer[key] = frame.CallsiteAssembly(proc, true) - case fields.ModuleSignatureIsSignedSegment, fields.ModuleSignatureIsTrustedSegment, - fields.ModuleSignatureCertIssuerSegment, fields.ModuleSignatureCertSubjectSegment: + case fields.ModuleSignatureExistsSegment, fields.ModuleSignatureTrustedSegment, + fields.ModuleSignatureIssuerSegment, fields.ModuleSignatureSubjectSegment: if frame.ModuleAddress.IsZero() { continue @@ -588,7 +589,7 @@ func (f *Foreach) callstackMapValuer(segments []*BoundSegmentLiteral, frame call sign.Verify() } - if segment == fields.ModuleSignatureCertIssuerSegment || segment == fields.ModuleSignatureCertSubjectSegment { + if segment == fields.ModuleSignatureIssuerSegment || segment == fields.ModuleSignatureSubjectSegment { if err := sign.ParseCertificate(); err != nil { continue } @@ -598,18 +599,18 @@ func (f *Foreach) callstackMapValuer(segments []*BoundSegmentLiteral, frame call } switch segment { - case fields.ModuleSignatureIsSignedSegment: + case fields.ModuleSignatureExistsSegment: valuer[key] = sign.IsSigned() - case fields.ModuleSignatureIsTrustedSegment: + case fields.ModuleSignatureTrustedSegment: valuer[key] = sign.IsTrusted() - case fields.ModuleSignatureCertIssuerSegment: + case fields.ModuleSignatureIssuerSegment: if err := sign.ParseCertificate(); err != nil { continue } if sign.HasCertificate() { valuer[key] = sign.Cert.Issuer } - case fields.ModuleSignatureCertSubjectSegment: + case fields.ModuleSignatureSubjectSegment: if err := sign.ParseCertificate(); err != nil { continue } From 56d2c77bf0eee93debe1bd76f177898d15472dac Mon Sep 17 00:00:00 2001 From: rabbitstack Date: Wed, 28 Jan 2026 11:43:47 +0100 Subject: [PATCH 2/2] refactor(rules): Adapt rules and macros to use new module/dll fields --- ..._lsass_access_from_unsigned_executable.yml | 4 +-- ...ccess_suspicious_vault_client_dll_load.yml | 4 +-- ...jection_via_clr_search_order_hijacking.yml | 10 +++---- ...fense_evasion_dll_loaded_via_apc_queue.yml | 4 +-- ...asion_dll_loaded_via_callback_function.yml | 6 ++--- ..._dll_loaded_via_ldrpkernel32_overwrite.yml | 6 ++--- ...sion_dll_sideloading_via_copied_binary.yml | 4 +-- ...ding_via_microsoft_office_dropped_file.yml | 6 ++--- ...t_assembly_loaded_by_unmanaged_process.yml | 8 +++--- ...vasion_image_load_via_ntfs_transaction.yml | 6 ++--- ...execution_from_hollowed_memory_section.yml | 6 ++--- ...ss_execution_from_self_deleting_binary.yml | 6 ++--- ...vasion_suspicious_xsl_script_execution.yml | 4 +-- ...signed_dll_injection_via_remote_thread.yml | 4 +-- ...sion_windows_defender_driver_unloading.yml | 6 ++--- ...macro_execution_via_script_interpreter.yml | 4 +-- ...dll_loaded_by_microsoft_office_process.yml | 4 +-- ..._via_wmi_from_microsoft_office_process.yml | 4 +-- rules/macros/macros.yml | 27 ++++++++----------- ...e_file_dropped_by_unsigned_service_dll.yml | 6 ++--- ...ia_startup_folder_executable_or_script.yml | 4 +-- ...spicious_microsoft_office_addin_loaded.yml | 6 ++--- ..._suspicious_netsh_helper_dll_execution.yml | 4 +-- ...ence_suspicious_print_processor_loaded.yml | 4 +-- ...e_escalation_via_phantom_dll_hijacking.yml | 4 +-- ..._vulnerable_or_malicious_driver_loaded.yml | 6 ++--- 26 files changed, 76 insertions(+), 81 deletions(-) diff --git a/rules/credential_access_lsass_access_from_unsigned_executable.yml b/rules/credential_access_lsass_access_from_unsigned_executable.yml index 2de3fd1a3..4958c614c 100644 --- a/rules/credential_access_lsass_access_from_unsigned_executable.yml +++ b/rules/credential_access_lsass_access_from_unsigned_executable.yml @@ -1,6 +1,6 @@ name: LSASS access from unsigned executable id: 348bf896-2201-444f-b1c9-e957a1f063bf -version: 1.0.1 +version: 1.0.2 description: | Detects attempts by an unsigned process to access the Local Security Authority Subsystem Service (LSASS). Adversaries may try to dump credential information stored in the process memory of LSASS. @@ -26,7 +26,7 @@ action: - name: kill output: > - Unsigned executable %1.image.path attempted to access Local Security Authority Subsystem Service + Unsigned executable %1.module.path attempted to access Local Security Authority Subsystem Service severity: high min-engine-version: 3.0.0 diff --git a/rules/credential_access_suspicious_vault_client_dll_load.yml b/rules/credential_access_suspicious_vault_client_dll_load.yml index cd35be615..c4fa4c515 100644 --- a/rules/credential_access_suspicious_vault_client_dll_load.yml +++ b/rules/credential_access_suspicious_vault_client_dll_load.yml @@ -1,6 +1,6 @@ name: Suspicious Vault client DLL load id: 64af2e2e-2309-4079-9c0f-985f1dd930f5 -version: 1.0.4 +version: 1.0.5 description: | Identifies loading of the Vault client DLL by an unusual process. Adversaries can abuse the functions provided by the Credential Vault Client Library to enumerate or harvest saved credentials. @@ -46,7 +46,7 @@ condition: > (ps.parent.exe imatches '?:\\Program Files\\Microsoft OneDrive\\OneDriveStandaloneUpdater.exe') ) | - |load_dll and image.name ~= 'vaultcli.dll'| + |load_dll and dll.name ~= 'vaultcli.dll'| output: > Suspicious process %2.ps.exe loaded the Credential Vault Client DLL for potential credentials harvesting diff --git a/rules/defense_evasion_appdomain_manager_injection_via_clr_search_order_hijacking.yml b/rules/defense_evasion_appdomain_manager_injection_via_clr_search_order_hijacking.yml index 2d08ef5a1..612ee69a6 100644 --- a/rules/defense_evasion_appdomain_manager_injection_via_clr_search_order_hijacking.yml +++ b/rules/defense_evasion_appdomain_manager_injection_via_clr_search_order_hijacking.yml @@ -1,6 +1,6 @@ name: AppDomain Manager injection via CLR search order hijacking id: 9319fafd-b7dc-4d85-b41a-54a8d4f1ab18 -version: 1.0.6 +version: 1.0.7 description: | Adversaries may execute their own malicious payloads by hijacking how the .NET AppDomainManager loads assemblies. The .NET framework uses the AppDomainManager class to create and manage one or more isolated runtime environments @@ -25,12 +25,12 @@ references: - https://www.rapid7.com/blog/post/2023/05/05/appdomain-manager-injection-new-techniques-for-red-teams/ condition: > - (load_unsigned_or_untrusted_module) - and ps.exe != '' and ((base(dir(image.path)) ~= base(image.path, false)) or (ps.envs[APPDOMAIN_MANAGER_ASM] istartswith image.name)) and - ps.pe.is_dotnet and (image.is_dotnet or thread.callstack.symbols imatches ('clr.dll!ParseManifest*')) + (load_unsigned_or_untrusted_module) and + ps.exe != '' and ((base(dir(module.path)) ~= base(module.path, false)) or (ps.envs[APPDOMAIN_MANAGER_ASM] istartswith module.name)) and + ps.pe.is_dotnet and (module.pe.is_dotnet or thread.callstack.symbols imatches ('clr.dll!ParseManifest*')) output: > - Process %ps.exe loaded untrusted .NET assembly %image.path from suspicious location + Process %ps.exe loaded untrusted .NET assembly %module.path from suspicious location severity: high min-engine-version: 3.0.0 diff --git a/rules/defense_evasion_dll_loaded_via_apc_queue.yml b/rules/defense_evasion_dll_loaded_via_apc_queue.yml index a5dff031f..de0f710fc 100644 --- a/rules/defense_evasion_dll_loaded_via_apc_queue.yml +++ b/rules/defense_evasion_dll_loaded_via_apc_queue.yml @@ -1,6 +1,6 @@ name: DLL loaded via APC queue id: e1ee3912-ad7c-4acb-80f4-84db87e54d5e -version: 1.0.3 +version: 1.0.4 description: | Identifies loading of a DLL with a callstack originating from the thread alertable state that led to the execution of an APC routine. This may be @@ -16,7 +16,7 @@ references: - https://github.com/Idov31/Cronos condition: > - load_dll and image.name iin + load_dll and dll.name iin ( 'winhttp.dll', 'clr.dll', 'bcrypt.dll', 'bcryptprimitives.dll', 'wininet.dll', 'taskschd.dll', 'dnsapi.dll', 'coreclr.dll', 'ws2_32.dll', diff --git a/rules/defense_evasion_dll_loaded_via_callback_function.yml b/rules/defense_evasion_dll_loaded_via_callback_function.yml index 1ab3e25ad..e4d8667e2 100644 --- a/rules/defense_evasion_dll_loaded_via_callback_function.yml +++ b/rules/defense_evasion_dll_loaded_via_callback_function.yml @@ -1,6 +1,6 @@ name: DLL loaded via a callback function id: c7f46d0a-10b2-421a-b33c-f4df79599f2e -version: 1.0.5 +version: 1.0.6 description: | Identifies module proxying as a method to conceal suspicious callstacks. Adversaries use module proxying the hide the origin of the LoadLibrary call from the callstack by loading the library from the callback @@ -21,7 +21,7 @@ condition: > maxspan 2m by ps.uuid |spawn_process| - |load_dll and image.name iin + |load_dll and dll.name iin ( 'winhttp.dll', 'clr.dll', 'bcrypt.dll', 'bcryptprimitives.dll', 'wininet.dll', 'taskschd.dll', 'dnsapi.dll', 'coreclr.dll', 'ws2_32.dll', @@ -36,7 +36,7 @@ condition: > | output: > - %2.image.path loaded from callback function by process %ps.exe + %2.module.path loaded from callback function by process %ps.exe severity: high min-engine-version: 3.0.0 diff --git a/rules/defense_evasion_dll_loaded_via_ldrpkernel32_overwrite.yml b/rules/defense_evasion_dll_loaded_via_ldrpkernel32_overwrite.yml index 5296c9c48..defaf4bc5 100644 --- a/rules/defense_evasion_dll_loaded_via_ldrpkernel32_overwrite.yml +++ b/rules/defense_evasion_dll_loaded_via_ldrpkernel32_overwrite.yml @@ -1,6 +1,6 @@ name: DLL loaded via LdrpKernel32 overwrite id: 56739eda-210f-4a30-a114-d55ca60976df -version: 1.0.3 +version: 1.0.4 description: | Detects attempts to bypass the standard NTDLL bootstrap process by loading a malicious DLL early through hijacking. The malicious DLL, containing attacker-controlled code, is loaded in place of the legitimate kernel32 DLL. @@ -20,7 +20,7 @@ references: condition: > (load_unsigned_or_untrusted_dll) and thread.callstack.symbols imatches ('*!BaseThreadInitThunk*') and - image.path not imatches '?:\\Windows\\assembly\\NativeImages_*\\System.Numerics.ni.dll' and + dll.path not imatches '?:\\Windows\\assembly\\NativeImages_*\\System.Numerics.ni.dll' and not foreach(thread._callstack, $frame, $frame.symbol imatches ('?:\\Windows\\System32\\kernel32.dll!BaseThreadInitThunk*', '?:\\Windows\\SysWOW64\\kernel32.dll!BaseThreadInitThunk*', @@ -31,7 +31,7 @@ action: - name: kill output: > - DLL %image.path loaded via LdrpKernel32 overwrite evasion by process %ps.exe + DLL %dll.path loaded via LdrpKernel32 overwrite evasion by process %ps.exe severity: high min-engine-version: 3.0.0 diff --git a/rules/defense_evasion_dll_sideloading_via_copied_binary.yml b/rules/defense_evasion_dll_sideloading_via_copied_binary.yml index b5039b24d..b732eff31 100644 --- a/rules/defense_evasion_dll_sideloading_via_copied_binary.yml +++ b/rules/defense_evasion_dll_sideloading_via_copied_binary.yml @@ -1,6 +1,6 @@ name: DLL Side-Loading via a copied binary id: 80798e2c-6c37-472b-936c-1d2d6b95ff3c -version: 1.0.5 +version: 1.0.6 description: | Identifies when a binary is copied to a directory and shortly followed by the loading of an unsigned DLL from the same directory. Adversaries may @@ -27,7 +27,7 @@ condition: > |(load_dll) and dir(image.path) ~= dir(ps.exe) and ps.signature.subject icontains 'Microsoft' and ps.signature.trusted and - (image.signature.type = 'NONE' or image.signature.level = 'UNCHECKED' or image.signature.level = 'UNSIGNED') + (dll.signature.exists = false or dll.signature.trusted = false) | by ps.exe min-engine-version: 3.0.0 diff --git a/rules/defense_evasion_dll_sideloading_via_microsoft_office_dropped_file.yml b/rules/defense_evasion_dll_sideloading_via_microsoft_office_dropped_file.yml index d10429f87..381672054 100644 --- a/rules/defense_evasion_dll_sideloading_via_microsoft_office_dropped_file.yml +++ b/rules/defense_evasion_dll_sideloading_via_microsoft_office_dropped_file.yml @@ -1,6 +1,6 @@ name: DLL Side-Loading via Microsoft Office dropped file id: d808175d-c4f8-459d-b17f-ca9a88890c04 -version: 1.0.3 +version: 1.0.4 description: | Identifies Microsoft Office process creating a DLL or other variant of an executable object which is later loaded by a trusted binary. Adversaries may exploit this behavior by delivering malicious @@ -25,14 +25,14 @@ condition: > | by file.path |(load_unsigned_or_untrusted_dll) and ps.name not iin msoffice_binaries and ps.signature.trusted = true and - image.path not imatches '?:\\Windows\\assembly\\NativeImages_*' and + dll.path not imatches '?:\\Windows\\assembly\\NativeImages_*' and ps.exe not imatches ( '?:\\Windows\\System32\\msiexec.exe', '?:\\Windows\\SysWOW64\\msiexec.exe', '?:\\Windows\\System32\\spoolsv.exe' ) - | by image.path + | by dll.path output: > Suspicious DLL %1.file.path dropped by Microsoft Office process %1.ps.exe and subsequently loaded by process %2.ps.exe diff --git a/rules/defense_evasion_dotnet_assembly_loaded_by_unmanaged_process.yml b/rules/defense_evasion_dotnet_assembly_loaded_by_unmanaged_process.yml index 57ac8b9e6..3ccb1c28f 100644 --- a/rules/defense_evasion_dotnet_assembly_loaded_by_unmanaged_process.yml +++ b/rules/defense_evasion_dotnet_assembly_loaded_by_unmanaged_process.yml @@ -1,6 +1,6 @@ name: .NET assembly loaded by unmanaged process id: 34be8bd1-1143-4fa8-bed4-ae2566b1394a -version: 1.0.9 +version: 1.0.10 description: | Identifies the loading of the .NET assembly by an unmanaged process. Adversaries can load the CLR runtime inside unmanaged process and execute the assembly via the ICLRRuntimeHost::ExecuteInDefaultAppDomain method. @@ -18,8 +18,8 @@ references: condition: > (load_unsigned_or_untrusted_module) and ps.exe != '' and ps.pe.is_dotnet = false and - (image.is_dotnet or thread.callstack.modules imatches ('*clr.dll')) and - image.path not imatches + (dll.pe.is_dotnet or thread.callstack.modules imatches ('*clr.dll')) and + dll.path not imatches ( '?:\\Windows\\assembly\\*\\*.ni.dll', '?:\\Program Files\\WindowsPowerShell\\Modules\\*\\*.dll', @@ -36,7 +36,7 @@ condition: > ) output: > - .NET assembly %image.path loaded by unmanaged process %ps.exe + .NET assembly %dll.path loaded by unmanaged process %ps.exe severity: high min-engine-version: 3.0.0 diff --git a/rules/defense_evasion_image_load_via_ntfs_transaction.yml b/rules/defense_evasion_image_load_via_ntfs_transaction.yml index eaf988a13..a093497a6 100644 --- a/rules/defense_evasion_image_load_via_ntfs_transaction.yml +++ b/rules/defense_evasion_image_load_via_ntfs_transaction.yml @@ -1,6 +1,6 @@ name: Image load via NTFS transaction id: ce8de3d0-0768-41a7-bab9-4eca27ed1e3c -version: 1.0.1 +version: 1.0.2 description: | Identifies image loading of a file written to disk via NTFS transaction. Adversaries may exploit the transactional API to execute code in the address space of the running process without committing @@ -19,10 +19,10 @@ condition: > sequence maxspan 2m |create_file and thread.callstack.symbols imatches ('kernel32.dll!CreateFileTransacted*', 'ntdll.dll!RtlSetCurrentTransaction')| by file.name - |load_module and evt.pid != 4| by image.name + |load_module and evt.pid != 4| by module.name output: > - Image %2.image.name written via transactional NTFS and loaded afterward + Image %2.module.name written via transactional NTFS and loaded afterward severity: high min-engine-version: 3.0.0 diff --git a/rules/defense_evasion_process_execution_from_hollowed_memory_section.yml b/rules/defense_evasion_process_execution_from_hollowed_memory_section.yml index 5ee70ad16..711e4c90c 100644 --- a/rules/defense_evasion_process_execution_from_hollowed_memory_section.yml +++ b/rules/defense_evasion_process_execution_from_hollowed_memory_section.yml @@ -1,6 +1,6 @@ name: Process execution from hollowed memory section id: 2a3fbae8-5e8c-4b71-b9da-56c3958c0d53 -version: 2.1.0 +version: 2.1.1 description: | Adversaries may inject malicious code into suspended and hollowed processes in order to evade process-based defenses. Process hollowing is a method of executing arbitrary code @@ -35,8 +35,8 @@ condition: > ) | by ps.uuid, file.view.base |load_executable and - image.path not imatches '?:\\Windows\\SoftwareDistribution\\Download\\*\\Package_for_RollupFix*\\*.exe' - | by ps.uuid, image.base.address + module.path not imatches '?:\\Windows\\SoftwareDistribution\\Download\\*\\Package_for_RollupFix*\\*.exe' + | by ps.uuid, module.base action: - name: kill diff --git a/rules/defense_evasion_process_execution_from_self_deleting_binary.yml b/rules/defense_evasion_process_execution_from_self_deleting_binary.yml index 911f657c6..408bca83c 100644 --- a/rules/defense_evasion_process_execution_from_self_deleting_binary.yml +++ b/rules/defense_evasion_process_execution_from_self_deleting_binary.yml @@ -1,6 +1,6 @@ name: Process execution from a self-deleting binary id: 0f0da517-b22c-4d14-9adc-36baeb621cf7 -version: 1.0.4 +version: 1.0.5 description: | Identifies the execution of the process from a self-deleting binary. The attackers can abuse undocumented API functions to create a process from a file-backed section. The file @@ -36,10 +36,10 @@ condition: > '?:\\Windows\\uus\\packages\\preview\\*' ) | by file.name - |load_module and ext(image.path) != '.dll'| by image.name + |load_module and ext(module.path) != '.dll'| by module.name output: > - Process %2.image.path spawned from self-deleting binary + Process %2.module.path spawned from self-deleting binary severity: high min-engine-version: 3.0.0 diff --git a/rules/defense_evasion_suspicious_xsl_script_execution.yml b/rules/defense_evasion_suspicious_xsl_script_execution.yml index f4af7e06c..f2d9024b9 100644 --- a/rules/defense_evasion_suspicious_xsl_script_execution.yml +++ b/rules/defense_evasion_suspicious_xsl_script_execution.yml @@ -1,6 +1,6 @@ name: Suspicious XSL script execution id: 65136b30-14ae-46dd-b8e5-9dfa99690d74 -version: 1.0.6 +version: 1.0.7 description: | Identifies a suspicious execution of XSL script via Windows Management Instrumentation command line tool or XSL transformation utility. Adversaries may bypass application control and obscure the execution of code by embedding @@ -39,7 +39,7 @@ condition: > ps.name ~= 'msxsl.exe' or ps.pe.file.name ~= 'msxsl.exe' ) | - |load_dll and image.name iin ('scrobj.dll', 'vbscript.dll', 'jscript.dll', 'jscript9.dll')| + |load_dll and dll.name iin ('scrobj.dll', 'vbscript.dll', 'jscript.dll', 'jscript9.dll')| output: > Suspicious XSL script executed by process %1.ps.name with command line arguments %1.ps.args diff --git a/rules/defense_evasion_unsigned_dll_injection_via_remote_thread.yml b/rules/defense_evasion_unsigned_dll_injection_via_remote_thread.yml index 9882138d8..7af4c6241 100644 --- a/rules/defense_evasion_unsigned_dll_injection_via_remote_thread.yml +++ b/rules/defense_evasion_unsigned_dll_injection_via_remote_thread.yml @@ -1,6 +1,6 @@ name: Unsigned DLL injection via remote thread id: 21bdd944-3bda-464b-9a72-58fd37ba9163 -version: 1.1.4 +version: 1.1.5 description: | Identifies unsigned DLL injection via remote thread creation. Adversaries may inject dynamic-link libraries (DLLs) into processes in order to evade process-based defenses @@ -33,7 +33,7 @@ condition: > (ps.cmdline imatches '"?:\\Windows\\Microsoft.NET\\Framework\\*\\ngen.exe" ExecuteQueuedItems /LegacyServiceBehavior')) | by thread.pid |(load_unsigned_or_untrusted_dll) and - image.path not imatches + dll.path not imatches ( '?:\\Program Files\\Git\\mingw64\\bin\\*.dll', '?:\\Windows\\assembly\\*\\*.ni.dll', diff --git a/rules/defense_evasion_windows_defender_driver_unloading.yml b/rules/defense_evasion_windows_defender_driver_unloading.yml index 77468eaf1..1b23c974c 100644 --- a/rules/defense_evasion_windows_defender_driver_unloading.yml +++ b/rules/defense_evasion_windows_defender_driver_unloading.yml @@ -1,6 +1,6 @@ name: Windows Defender driver unloading id: c9b93fbc-8845-4f39-a74b-26862615432c -version: 1.0.0 +version: 1.0.1 description: | Detects the unloading of Windows Defender kernel-mode drivers, such as WdFilter.sys or WdBoot.sys, which may indicate an attempt to impair or disable antivirus protections. @@ -19,10 +19,10 @@ labels: subtechnique.ref: https://attack.mitre.org/techniques/T1562/001 condition: > - unload_driver and image.path imatches ('?:\\Windows\\System32\\drivers\\wd\\*.sys', '?:\\Windows\\System32\\drivers\\Wd*.sys') + unload_driver and module.path imatches ('?:\\Windows\\System32\\drivers\\wd\\*.sys', '?:\\Windows\\System32\\drivers\\Wd*.sys') output: > - Windows Defender driver %image.path unloaded by process %ps.exe + Windows Defender driver %module.path unloaded by process %ps.exe severity: high min-engine-version: 3.0.0 diff --git a/rules/initial_access_macro_execution_via_script_interpreter.yml b/rules/initial_access_macro_execution_via_script_interpreter.yml index 9f6e65ebf..1137b87fb 100644 --- a/rules/initial_access_macro_execution_via_script_interpreter.yml +++ b/rules/initial_access_macro_execution_via_script_interpreter.yml @@ -1,6 +1,6 @@ name: Macro execution via script interpreter id: 845404de-df6f-472f-bd74-72148a7f5166 -version: 1.0.6 +version: 1.0.7 description: | Identifies the execution of the Windows scripting interpreter spawning a Microsoft Office process to execute suspicious Visual Basic macro. @@ -22,7 +22,7 @@ condition: > |spawn_process and ps.parent.name iin script_interpreters and ps.name iin msoffice_binaries| |ps.name iin msoffice_binaries and thread.callstack.modules imatches '*vbe?.dll' and (spawn_process or (create_remote_thread) or (modify_registry) or (create_file) or - (load_module and image.path not imatches ('?:\\Program Files\\*', '?:\\Program Files (x86)\\*'))) + (load_module and module.path not imatches ('?:\\Program Files\\*', '?:\\Program Files (x86)\\*'))) | min-engine-version: 3.0.0 diff --git a/rules/initial_access_suspicious_dll_loaded_by_microsoft_office_process.yml b/rules/initial_access_suspicious_dll_loaded_by_microsoft_office_process.yml index 47d7ab1a9..d1251a7ab 100644 --- a/rules/initial_access_suspicious_dll_loaded_by_microsoft_office_process.yml +++ b/rules/initial_access_suspicious_dll_loaded_by_microsoft_office_process.yml @@ -1,6 +1,6 @@ name: Suspicious DLL loaded by Microsoft Office process id: 5868518c-2a83-4b26-ad4b-f14f0b85e744 -version: 1.0.3 +version: 1.0.4 description: Identifies loading of recently dropped DLL by Microsoft Office process. labels: @@ -21,6 +21,6 @@ condition: > (file.extension iin module_extensions or file.is_dll) and ps.name iin msoffice_binaries and file.path not imatches '?:\\Program Files\\Microsoft Office\\Root\\Office*\\*.dll' | by file.name - |load_module and ps.name iin msoffice_binaries| by image.name + |load_module and ps.name iin msoffice_binaries| by module.name min-engine-version: 3.0.0 diff --git a/rules/initial_access_suspicious_execution_via_wmi_from_microsoft_office_process.yml b/rules/initial_access_suspicious_execution_via_wmi_from_microsoft_office_process.yml index 8e44d96b1..0f9ab9fd7 100644 --- a/rules/initial_access_suspicious_execution_via_wmi_from_microsoft_office_process.yml +++ b/rules/initial_access_suspicious_execution_via_wmi_from_microsoft_office_process.yml @@ -1,6 +1,6 @@ name: Suspicious execution via WMI from a Microsoft Office process id: cc3f0bbe-ec53-40a7-9eed-f0a8a3f7d7fa -version: 1.0.5 +version: 1.0.6 description: | Identifies a suspicious process execution via Windows Management Instrumentation (WMI) originated from the Microsoft Office process loading an unusual WMI DLL. This technique @@ -25,7 +25,7 @@ condition: > maxspan 1m by ps.sid |load_dll and - image.name iin ('wmiclnt.dll', 'wbemcomn.dll', 'wmiprov.dll', 'wbemprox.dll', 'wmutils.dll', 'fastprox.dll', 'WMINet_Utils.dll') and + dll.name iin ('wmiclnt.dll', 'wbemcomn.dll', 'wmiprov.dll', 'wbemprox.dll', 'wmutils.dll', 'fastprox.dll', 'WMINet_Utils.dll') and (ps.name iin msoffice_binaries or thread.callstack.modules imatches ('*vbe?.dll')) | |spawn_process and diff --git a/rules/macros/macros.yml b/rules/macros/macros.yml index 21446518a..f8169a236 100644 --- a/rules/macros/macros.yml +++ b/rules/macros/macros.yml @@ -123,17 +123,17 @@ - macro: load_driver expr: > - (load_module and (image.name iendswith '.sys' or image.is_driver)) + (load_module and (module.name iendswith '.sys' or module.is_driver)) description: | Detects the loading of the kernel driver. Image load events are published when executable images, DLLs, or driver PE objects are loaded. - macro: unload_driver - expr: unload_module and (image.name iendswith '.sys' or image.is_driver) + expr: unload_module and (module.name iendswith '.sys' or module.is_driver) - macro: load_unsigned_module expr: > - load_module and image.signature.type = 'NONE' + load_module and module.signature.exists = false description: | Detects when unsigned executable or DLL is loaded into process address space. The module is considered as unsigned if it lacks the cert in the PE security @@ -141,35 +141,31 @@ - macro: load_executable expr: > - load_module and (image.name iendswith '.exe' or image.is_exec) + load_module and (module.name iendswith '.exe' or module.is_exec) - macro: load_dll expr: > - load_module and (image.name iendswith '.dll' or image.is_dll) + load_module and (module.name iendswith '.dll' or module.is_dll) - macro: load_unsigned_executable expr: > - load_executable - and - image.signature.type = 'NONE' + load_executable and module.signature.exists = false - macro: load_untrusted_executable expr: > - load_executable and - (image.signature.level = 'UNCHECKED' or image.signature.level = 'UNSIGNED') + load_executable and module.signature.trusted = false description: Detects when untrusted executable is loaded into process address space. - macro: load_untrusted_dll expr: > - load_dll and - (image.signature.level = 'UNCHECKED' or image.signature.level = 'UNSIGNED') + load_dll and dll.signature.trusted = false description: Detects when untrusted DLL is loaded into process address space. - macro: load_unsigned_module expr: > - load_module and image.signature.type = 'NONE' + load_module and module.signature.exists = false description: | Detects when unsigned executable or DLL is loaded into process address space. The module is considered as unsigned if it lacks the cert in the PE security @@ -177,14 +173,13 @@ - macro: load_unsigned_dll expr: > - load_dll and image.signature.type = 'NONE' + load_dll and dll.signature.exists = false description: | Detects when unsigned executable DLL is loaded into process address space. - macro: load_untrusted_module expr: > - load_module and - (image.signature.level = 'UNCHECKED' or image.signature.level = 'UNSIGNED') + load_module and module.signature.trusted = false description: | Detects when untrusted executable or DLL is loaded into process address space. Windows must verify the trust chain by following the certificates to a trusted diff --git a/rules/persistence_executable_file_dropped_by_unsigned_service_dll.yml b/rules/persistence_executable_file_dropped_by_unsigned_service_dll.yml index bd531bc06..2a1140934 100644 --- a/rules/persistence_executable_file_dropped_by_unsigned_service_dll.yml +++ b/rules/persistence_executable_file_dropped_by_unsigned_service_dll.yml @@ -1,6 +1,6 @@ name: Executable file dropped by an unsigned service DLL id: 3e29da58-0fc4-44c0-91c0-0dfc6af87e9d -version: 1.0.2 +version: 1.0.3 description: | Identifies the loading of an unsigned DLL by svchost process followed by creating an executable file. Adversaries may rely on Windows Services to repeatedly execute malicious @@ -26,11 +26,11 @@ condition: > |create_file and evt.pid != 4 and ps.exe imatches ('?:\\Windows\\System32\\svchost.exe', '?:\\Windows\\SysWOW64\\svchost.exe') and (file.extension iin ('.exe', '.dll', '.com', '.js', '.vbs', '.cmd', '.bat', '.vbe') or file.is_exec or file.is_dll or file.is_driver) and - thread.callstack.symbols iin (concat($e1.image.name, '!ServiceMain')) + thread.callstack.symbols iin (concat($e1.module.name, '!ServiceMain')) | output: > - Service %1.ps.cmdline loaded an unsigned DLL %1.image.path and subsequently dropped an executable file %2.file.path + Service %1.ps.cmdline loaded an unsigned DLL %1.dll.path and subsequently dropped an executable file %2.file.path severity: high min-engine-version: 3.0.0 diff --git a/rules/persistence_network_connection_via_startup_folder_executable_or_script.yml b/rules/persistence_network_connection_via_startup_folder_executable_or_script.yml index 5da10923d..15126b860 100644 --- a/rules/persistence_network_connection_via_startup_folder_executable_or_script.yml +++ b/rules/persistence_network_connection_via_startup_folder_executable_or_script.yml @@ -1,6 +1,6 @@ name: Network connection via startup folder executable or script id: 09b7278d-42e3-4792-9f00-dee38baecfad -version: 1.0.4 +version: 1.0.5 description: | Identifies the execution of unsigned binary or script from the Startup folder followed by network inbound or outbound connection. @@ -19,7 +19,7 @@ condition: > sequence maxspan 5m by ps.uuid - |(load_untrusted_executable and image.path imatches startup_locations) or + |(load_untrusted_executable and module.path imatches startup_locations) or (load_executable and ps.name in script_interpreters and ps.cmdline imatches startup_locations) | |((inbound_network) or (outbound_network)) and ps.cmdline imatches startup_locations| diff --git a/rules/persistence_suspicious_microsoft_office_addin_loaded.yml b/rules/persistence_suspicious_microsoft_office_addin_loaded.yml index 5b9bdbb92..55db92478 100644 --- a/rules/persistence_suspicious_microsoft_office_addin_loaded.yml +++ b/rules/persistence_suspicious_microsoft_office_addin_loaded.yml @@ -1,6 +1,6 @@ name: Suspicious Microsoft Office add-in loaded id: fe4daff8-d8aa-48d3-bf09-a9d868375a3c -version: 1.0.2 +version: 1.0.3 description: | Identifies attempts to load unsigned executables from known Microsoft Office add-ins directories, which adversaries may exploit to maintain persistence. @@ -17,7 +17,7 @@ references: condition: > (load_unsigned_or_untrusted_module) and ps.name iin ('excel.exe', 'winword.exe', 'outlook.exe', 'powerpnt.exe') and - image.path imatches + module.path imatches ( '?:\\Users\\*\\AppData\\Roaming\\Microsoft\\AddIns\\*', '?:\\Users\\*\\AppData\\Roaming\\Microsoft\\Excel\\XLSTART\\*', @@ -26,7 +26,7 @@ condition: > ) output: - Microsoft Office process %ps.name loaded a suspicious add-in %image.path + Microsoft Office process %ps.name loaded a suspicious add-in %module.path severity: high min-engine-version: 3.0.0 diff --git a/rules/persistence_suspicious_netsh_helper_dll_execution.yml b/rules/persistence_suspicious_netsh_helper_dll_execution.yml index 45446b357..81db34a0d 100644 --- a/rules/persistence_suspicious_netsh_helper_dll_execution.yml +++ b/rules/persistence_suspicious_netsh_helper_dll_execution.yml @@ -1,6 +1,6 @@ name: Suspicious Netsh Helper DLL execution id: bd17781d-38ca-4b9a-a12a-f807a1eb45e0 -version: 1.0.4 +version: 1.0.5 description: | Identifies the execution of a suspicious Netsh Helper DLL. Adversaries may establish persistence by executing malicious content triggered by Netsh Helper DLLs. Netsh.exe is a command-line scripting @@ -28,7 +28,7 @@ condition: > (ps.name ~= 'netsh.exe' or ps.pe.file.name ~= 'netsh.exe') | |create_thread and - foreach(thread._callstack, $frame, $frame.symbol imatches '*!InitHelperDll' and ($frame.module.signature.is_signed = false or $frame.module.signature.is_trusted = false)) + foreach(thread._callstack, $frame, $frame.symbol imatches '*!InitHelperDll' and ($frame.module.signature.exists = false or $frame.module.signature.trusted = false)) | output: > diff --git a/rules/persistence_suspicious_print_processor_loaded.yml b/rules/persistence_suspicious_print_processor_loaded.yml index 8dcc7e2db..44525d68d 100644 --- a/rules/persistence_suspicious_print_processor_loaded.yml +++ b/rules/persistence_suspicious_print_processor_loaded.yml @@ -1,6 +1,6 @@ name: Suspicious print processor loaded id: 3e0f5ef7-8a0a-4604-b2bf-d09606f45483 -version: 1.0.2 +version: 1.0.3 description: | Identifies when the print spooler service loads unsigned or untrusted DLL and the callstack pattern indicates the print processor is loaded. Adversaries may abuse print processors to run malicious DLLs @@ -25,7 +25,7 @@ condition: > thread.callstack.symbols imatches ('localspl.dll!SplSetPrinterData') and thread.callstack.symbols not imatches ('KernelBase.dll!RegisterGPNotificationInternal') output: > - Print spooler service loaded suspicious print processor DLL %image.path + Print spooler service loaded suspicious print processor DLL %module.path severity: high min-engine-version: 3.0.0 diff --git a/rules/privilege_escalation_potential_privilege_escalation_via_phantom_dll_hijacking.yml b/rules/privilege_escalation_potential_privilege_escalation_via_phantom_dll_hijacking.yml index 95065aafe..85c406842 100644 --- a/rules/privilege_escalation_potential_privilege_escalation_via_phantom_dll_hijacking.yml +++ b/rules/privilege_escalation_potential_privilege_escalation_via_phantom_dll_hijacking.yml @@ -1,6 +1,6 @@ name: Potential privilege escalation via phantom DLL hijacking id: 5ccdb5c2-3a30-4e14-87d2-d7aeb4c45fad -version: 1.0.5 +version: 1.0.6 description: | Identifies the loading of the phantom DLL that was previously dropped to the System directory. Adversaries may exploit this flow to escalate @@ -56,6 +56,6 @@ condition: > '?:\\Windows\\System32\\winlogon.exe' ) | by file.path - |load_dll| by image.path + |load_dll| by module.path min-engine-version: 3.0.0 diff --git a/rules/privilege_escalation_vulnerable_or_malicious_driver_loaded.yml b/rules/privilege_escalation_vulnerable_or_malicious_driver_loaded.yml index a951b5205..aa6f2b378 100644 --- a/rules/privilege_escalation_vulnerable_or_malicious_driver_loaded.yml +++ b/rules/privilege_escalation_vulnerable_or_malicious_driver_loaded.yml @@ -1,6 +1,6 @@ name: Vulnerable or malicious driver loaded id: e8005f1d-b4ec-45ee-a3ea-4247eac123db -version: 1.0.3 +version: 1.0.4 description: | Detects when adversaries load a vulnerable/malicious driver into the compromised system to exploit the vulnerability and @@ -16,9 +16,9 @@ references: - https://www.loldrivers.io/ condition: > - (load_driver) and (image.is_driver_vulnerable or image.is_driver_malicious) + (load_driver) and (module.is_driver_vulnerable or module.is_driver_malicious) output: > - Vulnerable or malicious %image.path driver loaded + Vulnerable or malicious %module.path driver loaded min-engine-version: 3.0.0