Skip to content

Commit 5620165

Browse files
committed
feat(filter): Add path stem filters
file.path.stem and module.path.stem/dll.path.stem fields return the file/module path but without the file extension.
1 parent a91720f commit 5620165

File tree

3 files changed

+26
-0
lines changed

3 files changed

+26
-0
lines changed

pkg/filter/accessor_windows.go

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -673,6 +673,13 @@ func (l *fileAccessor) Get(f Field, e *event.Event) (params.Value, error) {
673673
switch f.Name {
674674
case fields.FilePath:
675675
return e.GetParamAsString(params.FilePath), nil
676+
case fields.FilePathStem:
677+
path := e.GetParamAsString(params.FilePath)
678+
n := strings.LastIndexByte(path, '.')
679+
if n == -1 {
680+
return path, nil
681+
}
682+
return path[:n], nil
676683
case fields.FileName:
677684
return filepath.Base(e.GetParamAsString(params.FilePath)), nil
678685
case fields.FileExtension:
@@ -828,6 +835,13 @@ func (*moduleAccessor) Get(f Field, e *event.Event) (params.Value, error) {
828835
switch f.Name {
829836
case fields.ImagePath, fields.ModulePath, fields.DllPath:
830837
return e.GetParamAsString(params.ImagePath), nil
838+
case fields.ModulePathStem, fields.DllPathStem:
839+
path := e.GetParamAsString(params.ImagePath)
840+
n := strings.LastIndexByte(path, '.')
841+
if n == -1 {
842+
return path, nil
843+
}
844+
return path[:n], nil
831845
case fields.ImageName, fields.ModuleName, fields.DllName:
832846
return filepath.Base(e.GetParamAsString(params.ImagePath)), nil
833847
case fields.ImageDefaultAddress, fields.ModuleDefaultAddress:

pkg/filter/fields/fields_windows.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -447,6 +447,8 @@ const (
447447
FileName Field = "file.name"
448448
// FilePath represents the file full path (e.g. C:\Windows\System32\cmd.exe)
449449
FilePath Field = "file.path"
450+
// FilePathStem represents the full file path without extension (e.g. C:\Windows\System32\cmd)
451+
FilePathStem Field = "file.path.stem"
450452
// FileExtension represents the file extension (e.g. .exe or .dll)
451453
FileExtension Field = "file.extension"
452454
// FileOperation represents the file operation (e.g. create)
@@ -557,6 +559,8 @@ const (
557559
DllSize Field = "dll.size"
558560
// DllPath is the DLL full path
559561
DllPath Field = "dll.path"
562+
// DllPath is the DLL path stem field
563+
DllPathStem Field = "dll.path.stem"
560564
// DllName is the DLL name
561565
DllName Field = "dll.name"
562566
// DllPID is the pid of the process where the DLL was loaded
@@ -593,6 +597,8 @@ const (
593597
ModuleDefaultAddress Field = "module.default_address"
594598
// ModulePath is the module full path
595599
ModulePath Field = "module.path"
600+
// ModulePathStem is the module path stem field
601+
ModulePathStem Field = "module.path.stem"
596602
// ModuleName is the module name
597603
ModuleName Field = "module.name"
598604
// ModulePID is the pid of the process where the module was loaded
@@ -1124,6 +1130,7 @@ var fields = map[Field]FieldInfo{
11241130
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},
11251131
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},
11261132
ModulePath: {ModulePath, "full module path", params.UnicodeString, []string{"module.path = 'C:\\Windows\\System32\\advapi32.dll'"}, nil, nil},
1133+
ModulePathStem: {ModulePathStem, "module path stem", params.UnicodeString, []string{"module.path.stem = 'C:\\Windows\\System32\\advapi32'"}, nil, nil},
11271134
ModuleName: {ModuleName, "module name", params.UnicodeString, []string{"module.name = 'advapi32.dll'"}, nil, nil},
11281135
ModuleBase: {ModuleBase, "the base address of process in which the module is loaded", params.Address, []string{"module.base.address = 'a65d800000'"}, nil, nil},
11291136
ModuleChecksum: {ModuleChecksum, "module checksum", params.Uint32, []string{"module.checksum = 746424"}, nil, nil},
@@ -1146,6 +1153,7 @@ var fields = map[Field]FieldInfo{
11461153
ModuleIsExecutable: {ModuleIsExecutable, "indicates if the loaded module is an executable", params.Bool, []string{"module.is_exec'"}, nil, nil},
11471154
ModuleIsDotnet: {ModuleIsDotnet, "indicates if the loaded module is a .NET assembly", params.Bool, []string{"module.pe.is_dotnet'"}, nil, nil},
11481155
DllPath: {DllPath, "full dll path", params.UnicodeString, []string{"dll.path = 'C:\\Windows\\System32\\advapi32.dll'"}, nil, nil},
1156+
DllPathStem: {DllPathStem, "dll path stem", params.UnicodeString, []string{"dll.path.stem = 'C:\\Windows\\System32\\advapi32'"}, nil, nil},
11491157
DllName: {DllName, "module name", params.UnicodeString, []string{"dll.name = 'advapi32.dll'"}, nil, nil},
11501158
DllBase: {DllBase, "the base address of process in which the DLL is loaded", params.Address, []string{"dll.base = 'a65d800000'"}, nil, nil},
11511159
DllSize: {DllSize, "dll virtual mapped size", params.Uint32, []string{"dll.size > 1024"}, nil, nil},
@@ -1163,6 +1171,7 @@ var fields = map[Field]FieldInfo{
11631171

11641172
FileObject: {FileObject, "file object address", params.Uint64, []string{"file.object = 18446738026482168384"}, nil, nil},
11651173
FilePath: {FilePath, "full file path", params.UnicodeString, []string{"file.path = 'C:\\Windows\\System32'"}, nil, nil},
1174+
FilePathStem: {FilePathStem, "full file path without extension", params.UnicodeString, []string{"file.path.stem = 'C:\\Windows\\System32\\cmd'"}, nil, nil},
11661175
FileName: {FileName, "full file name", params.UnicodeString, []string{"file.name contains 'mimikatz'"}, nil, nil},
11671176
FileOperation: {FileOperation, "file operation", params.AnsiString, []string{"file.operation = 'open'"}, nil, nil},
11681177
FileShareMask: {FileShareMask, "file share mask", params.AnsiString, []string{"file.share.mask = 'rw-'"}, nil, nil},

pkg/filter/filter_test.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -663,6 +663,7 @@ func TestFileFilter(t *testing.T) {
663663
{`file.path ifuzzy 'C:\\WINDOWS\\sYS\\32dll'`, true},
664664
{`file.path fuzzy ('C:\\Windows\\system32\\kernel', 'C:\\Windows\\system32\\ser3ll')`, true},
665665
{`file.path ifuzzynorm 'C:\\WINDOWS\\sÝS\\32dll'`, true},
666+
{`file.path.stem = 'C:\\Windows\\system32\\user32'`, true},
666667
{`base(file.path) = 'user32.dll'`, true},
667668
{`ext(base(file.path)) = '.dll'`, true},
668669
{`base(file.path, false) = 'user32'`, true},
@@ -1014,6 +1015,8 @@ func TestModuleFilter(t *testing.T) {
10141015
{`module.signature.issuer icontains 'Microsoft Windows'`, true},
10151016
{`module.signature.subject icontains 'Microsoft Corporation'`, true},
10161017
{`module.pe.is_dotnet`, false},
1018+
{`module.path.stem endswith 'System32\\kernel32'`, true},
1019+
{`dll.path.stem endswith 'System32\\kernel32'`, true},
10171020
{`dll.signature.type = 'EMBEDDED'`, true},
10181021
{`dll.signature.level = 'AUTHENTICODE'`, true},
10191022
{`dll.signature.exists`, true},

0 commit comments

Comments
 (0)