diff --git a/pkg/filter/accessor_windows.go b/pkg/filter/accessor_windows.go index c4721ba75..d18ed4b44 100644 --- a/pkg/filter/accessor_windows.go +++ b/pkg/filter/accessor_windows.go @@ -673,6 +673,13 @@ func (l *fileAccessor) Get(f Field, e *event.Event) (params.Value, error) { switch f.Name { case fields.FilePath: return e.GetParamAsString(params.FilePath), nil + case fields.FilePathStem: + path := e.GetParamAsString(params.FilePath) + n := strings.LastIndexByte(path, '.') + if n == -1 { + return path, nil + } + return path[:n], nil case fields.FileName: return filepath.Base(e.GetParamAsString(params.FilePath)), nil case fields.FileExtension: @@ -821,6 +828,13 @@ func (i *imageAccessor) Get(f Field, e *event.Event) (params.Value, error) { switch f.Name { case fields.ImagePath: return e.GetParamAsString(params.ImagePath), nil + case fields.ImagePathStem: + path := e.GetParamAsString(params.ImagePath) + n := strings.LastIndexByte(path, '.') + if n == -1 { + return path, nil + } + return path[:n], nil case fields.ImageName: return filepath.Base(e.GetParamAsString(params.ImagePath)), nil case fields.ImageDefaultAddress: diff --git a/pkg/filter/fields/fields_windows.go b/pkg/filter/fields/fields_windows.go index ec3ab55d5..b74be50b8 100644 --- a/pkg/filter/fields/fields_windows.go +++ b/pkg/filter/fields/fields_windows.go @@ -394,6 +394,8 @@ const ( FileName Field = "file.name" // FilePath represents the file full path (e.g. C:\Windows\System32\cmd.exe) FilePath Field = "file.path" + // FilePathStem represents the full file path without extension (e.g. C:\Windows\System32\cmd) + FilePathStem Field = "file.path.stem" // FileExtension represents the file extension (e.g. .exe or .dll) FileExtension Field = "file.extension" // FileOperation represents the file operation (e.g. create) @@ -466,6 +468,8 @@ const ( ImageDefaultAddress Field = "image.default.address" // ImagePath is the module full path ImagePath Field = "image.path" + // ImagePathStem represents the full module path without extension + ImagePathStem Field = "image.path.stem" // ImageName is the module name ImageName Field = "image.name" // ImagePID is the pid of the process where the image was loaded @@ -916,6 +920,7 @@ var fields = map[Field]FieldInfo{ 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}, + ImagePathStem: {ImagePathStem, "full image path without extension", params.UnicodeString, []string{"image.path.stem = 'C:\\Windows\\System32\\advapi32'"}, 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}, @@ -938,6 +943,7 @@ var fields = map[Field]FieldInfo{ 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}, + FilePathStem: {FilePathStem, "full file path without extension", params.UnicodeString, []string{"file.path.stem = 'C:\\Windows\\System32\\cmd'"}, nil, nil}, FileName: {FileName, "full file name", params.UnicodeString, []string{"file.name contains 'mimikatz'"}, nil, nil}, FileOperation: {FileOperation, "file operation", params.AnsiString, []string{"file.operation = 'open'"}, nil, nil}, FileShareMask: {FileShareMask, "file share mask", params.AnsiString, []string{"file.share.mask = 'rw-'"}, nil, nil}, diff --git a/pkg/filter/filter_test.go b/pkg/filter/filter_test.go index cb00d0f5c..a658ad724 100644 --- a/pkg/filter/filter_test.go +++ b/pkg/filter/filter_test.go @@ -661,6 +661,7 @@ func TestFileFilter(t *testing.T) { {`file.path ifuzzy 'C:\\WINDOWS\\sYS\\32dll'`, true}, {`file.path fuzzy ('C:\\Windows\\system32\\kernel', 'C:\\Windows\\system32\\ser3ll')`, true}, {`file.path ifuzzynorm 'C:\\WINDOWS\\sÝS\\32dll'`, true}, + {`file.path.stem = 'C:\\Windows\\system32\\user32'`, true}, {`base(file.path) = 'user32.dll'`, true}, {`ext(base(file.path)) = '.dll'`, true}, {`base(file.path, false) = 'user32'`, true}, @@ -1004,6 +1005,7 @@ func TestImageFilter(t *testing.T) { {`image.signature.level = 'AUTHENTICODE'`, true}, {`image.pid = 1023`, true}, {`image.path endswith 'System32\\kernel32.dll'`, true}, + {`image.path.stem endswith 'System32\\kernel32'`, true}, {`image.name = 'kernel32.dll'`, true}, {`image.checksum = 2323432`, true}, {`image.base.address = '7ffb313833a3'`, true},