From ae42af51fff0b1db8faf59be5ad2ef0114e47b38 Mon Sep 17 00:00:00 2001 From: rabbitstack Date: Wed, 18 Dec 2024 18:03:46 +0100 Subject: [PATCH 1/3] refactor(filter): Introduce *.path filter fields Historically, the file.name/image.name/registry.key.name filter fields were used to yield the full file path, image path, or registry key respectively. However, a better way to convey the referenced field is actually returning a fully-qualified path is to introduce a new set of fields. As a side effect, the previous fields return the base file/image/key names. --- internal/etw/processors/fs_windows.go | 22 ++-- internal/etw/processors/fs_windows_test.go | 20 ++-- internal/etw/processors/handle_windows.go | 4 +- internal/etw/processors/image_windows.go | 2 +- internal/etw/processors/image_windows_test.go | 4 +- internal/etw/processors/mem_windows.go | 4 +- internal/etw/processors/processor.go | 2 +- internal/etw/processors/ps_windows.go | 4 +- internal/etw/processors/registry_windows.go | 6 +- .../etw/processors/registry_windows_test.go | 20 ++-- internal/etw/source_test.go | 20 ++-- pkg/alertsender/eventlog/eventlog_test.go | 2 +- pkg/alertsender/mail/renderer_test.go | 2 +- pkg/filament/filament_test.go | 2 +- ..._error_reporting_and_wmi_provider_host.yml | 2 +- .../_fixtures/sequence_rule_bound_fields.yml | 2 +- ...uence_rule_bound_fields_with_functions.yml | 10 +- pkg/filter/_fixtures/sequence_rule_expire.yml | 4 +- .../_fixtures/sequence_rule_out_of_order.yml | 2 +- pkg/filter/_fixtures/sequence_rule_simple.yml | 4 +- .../sequence_rule_simple_max_span.yml | 2 +- .../powershell_created_temp_file.yml | 2 +- pkg/filter/_fixtures/simple_emit_alert.yml | 2 +- pkg/filter/_fixtures/simple_matches.yml | 2 +- .../_fixtures/simple_matches/filter3.yml | 2 +- pkg/filter/accessor_windows.go | 33 ++++-- pkg/filter/fields/fields_windows.go | 17 ++- pkg/filter/filter_test.go | 101 +++++++++--------- pkg/filter/rules_test.go | 42 ++++---- pkg/kcap/reader_windows.go | 2 +- pkg/kcap/writer_windows_test.go | 2 +- pkg/kevent/batch_test.go | 6 +- pkg/kevent/callstack_test.go | 10 +- pkg/kevent/kevent_windows.go | 46 ++++---- pkg/kevent/kevent_windows_test.go | 6 +- pkg/kevent/kparam.go | 2 +- pkg/kevent/kparam_test.go | 8 +- pkg/kevent/kparam_windows.go | 14 +-- pkg/kevent/kparams/fields_windows.go | 12 +-- pkg/kevent/kparams/types_windows.go | 8 +- pkg/kevent/marshaller_test.go | 18 ++-- pkg/kevent/marshaller_windows.go | 4 +- pkg/outputs/amqp/amqp_test.go | 6 +- .../elasticsearch/elasticsearch_test.go | 6 +- pkg/outputs/eventlog/eventlog_test.go | 2 +- pkg/outputs/http/http_test.go | 6 +- pkg/ps/snapshotter_windows.go | 4 +- pkg/ps/snapshotter_windows_test.go | 14 +-- pkg/symbolize/symbolizer.go | 9 +- pkg/symbolize/symbolizer_test.go | 8 +- pkg/yara/config/config.go | 2 +- pkg/yara/scanner.go | 8 +- pkg/yara/scanner_test.go | 16 +-- 53 files changed, 296 insertions(+), 264 deletions(-) diff --git a/internal/etw/processors/fs_windows.go b/internal/etw/processors/fs_windows.go index 15e2af2fa..40e0ad6f4 100644 --- a/internal/etw/processors/fs_windows.go +++ b/internal/etw/processors/fs_windows.go @@ -128,15 +128,15 @@ func (f *fsProcessor) processEvent(e *kevent.Kevent) (*kevent.Kevent, error) { case ktypes.FileRundown: // when the file rundown event comes in we store the file info // in internal state in order to augment the rest of file events - // that lack the file name field - filename := e.GetParamAsString(kparams.FileName) + // that lack the file path field + filepath := e.GetParamAsString(kparams.FilePath) fileObject, err := e.Kparams.GetUint64(kparams.FileObject) if err != nil { return nil, err } if _, ok := f.files[fileObject]; !ok { totalRundownFiles.Add(1) - f.files[fileObject] = &FileInfo{Name: filename, Type: fs.GetFileType(filename, 0)} + f.files[fileObject] = &FileInfo{Name: filepath, Type: fs.GetFileType(filepath, 0)} } case ktypes.MapFileRundown: // if the memory-mapped view refers to the image/data file @@ -166,7 +166,7 @@ func (f *fsProcessor) processEvent(e *kevent.Kevent) (*kevent.Kevent, error) { name := f.devMapper.Convert(sys.GetMappedFile(process, uintptr(addr))) f.mmaps[e.PID][fileKey] = &MmapInfo{File: name, BaseAddr: viewBase, Size: viewSize} } - e.AppendParam(kparams.FileName, kparams.FilePath, f.mmaps[e.PID][fileKey].File) + e.AppendParam(kparams.FilePath, kparams.Path, f.mmaps[e.PID][fileKey].File) return e, f.psnap.AddFileMapping(e) case ktypes.CreateFile: // we defer the processing of the CreateFile event until we get @@ -207,12 +207,12 @@ func (f *fsProcessor) processEvent(e *kevent.Kevent) (*kevent.Kevent, error) { if !ok { opts := ev.Kparams.MustGetUint32(kparams.FileCreateOptions) opts &= 0xFFFFFF - filename := ev.GetParamAsString(kparams.FileName) - fileinfo = f.getFileInfo(filename, opts) + filepath := ev.GetParamAsString(kparams.FilePath) + fileinfo = f.getFileInfo(filepath, opts) f.files[fileObject] = fileinfo } if f.config.Kstream.EnableHandleKevents { - f.devPathResolver.AddPath(ev.GetParamAsString(kparams.FileName)) + f.devPathResolver.AddPath(ev.GetParamAsString(kparams.FilePath)) } ev.AppendParam(kparams.NTStatus, kparams.Status, status) if fileinfo.Type != fs.Unknown { @@ -262,7 +262,7 @@ func (f *fsProcessor) processEvent(e *kevent.Kevent) (*kevent.Kevent, error) { } mmapinfo := f.mmaps[e.PID][fileKey] if mmapinfo != nil { - e.AppendParam(kparams.FileName, kparams.FilePath, mmapinfo.File) + e.AppendParam(kparams.FilePath, kparams.Path, mmapinfo.File) } totalMapRundownFiles.Add(-1) delete(f.mmaps[e.PID], fileKey) @@ -300,7 +300,7 @@ func (f *fsProcessor) processEvent(e *kevent.Kevent) (*kevent.Kevent, error) { name := f.devMapper.Convert(sys.GetMappedFile(process, uintptr(addr))) f.initMmap(e.PID) f.mmaps[e.PID][fileKey] = &MmapInfo{File: name, BaseAddr: viewBase, Size: viewSize} - e.AppendParam(kparams.FileName, kparams.FilePath, name) + e.AppendParam(kparams.FilePath, kparams.Path, name) return e, f.psnap.AddFileMapping(e) } @@ -313,7 +313,7 @@ func (f *fsProcessor) processEvent(e *kevent.Kevent) (*kevent.Kevent, error) { } if e.IsEnumDirectory() { if fileinfo != nil { - e.AppendParam(kparams.FileDirectory, kparams.FilePath, fileinfo.Name) + e.AppendParam(kparams.FileDirectory, kparams.Path, fileinfo.Name) } return e, nil } @@ -321,7 +321,7 @@ func (f *fsProcessor) processEvent(e *kevent.Kevent) (*kevent.Kevent, error) { if fileinfo.Type != fs.Unknown { e.AppendEnum(kparams.FileType, uint32(fileinfo.Type), fs.FileTypes) } - e.AppendParam(kparams.FileName, kparams.FilePath, fileinfo.Name) + e.AppendParam(kparams.FilePath, kparams.Path, fileinfo.Name) } if e.IsMapViewFile() { return e, f.psnap.AddFileMapping(e) diff --git a/internal/etw/processors/fs_windows_test.go b/internal/etw/processors/fs_windows_test.go index 6575226eb..260012601 100644 --- a/internal/etw/processors/fs_windows_test.go +++ b/internal/etw/processors/fs_windows_test.go @@ -50,7 +50,7 @@ func TestFsProcessor(t *testing.T) { Category: ktypes.File, Kparams: kevent.Kparams{ kparams.FileObject: {Name: kparams.FileObject, Type: kparams.Uint64, Value: uint64(124567380264)}, - kparams.FileName: {Name: kparams.FileName, Type: kparams.UnicodeString, Value: "C:\\Windows\\system32\\user32.dll"}, + kparams.FilePath: {Name: kparams.FilePath, Type: kparams.UnicodeString, Value: "C:\\Windows\\system32\\user32.dll"}, }, }, nil, @@ -106,7 +106,7 @@ func TestFsProcessor(t *testing.T) { kparams.FileObject: {Name: kparams.FileObject, Type: kparams.Uint64, Value: uint64(18446738026482168384)}, kparams.ThreadID: {Name: kparams.ThreadID, Type: kparams.Uint32, Value: uint32(1484)}, kparams.FileCreateOptions: {Name: kparams.FileCreateOptions, Type: kparams.Uint32, Value: uint32(1223456)}, - kparams.FileName: {Name: kparams.FileName, Type: kparams.UnicodeString, Value: "C:\\Windows\\system32\\kernel32.dll"}, + kparams.FilePath: {Name: kparams.FilePath, Type: kparams.UnicodeString, Value: "C:\\Windows\\system32\\kernel32.dll"}, kparams.FileShareMask: {Name: kparams.FileShareMask, Type: kparams.Uint32, Value: uint32(5)}, kparams.FileIrpPtr: {Name: kparams.FileIrpPtr, Type: kparams.Uint64, Value: uint64(1234543123112321)}, }, @@ -143,7 +143,7 @@ func TestFsProcessor(t *testing.T) { Kparams: kevent.Kparams{ kparams.FileObject: {Name: kparams.FileObject, Type: kparams.Uint64, Value: uint64(12446738026482168384)}, kparams.FileCreateOptions: {Name: kparams.FileCreateOptions, Type: kparams.Uint32, Value: uint32(18874368)}, - kparams.FileName: {Name: kparams.FileName, Type: kparams.UnicodeString, Value: "C:\\Windows\\temp\\idxx.exe"}, + kparams.FilePath: {Name: kparams.FilePath, Type: kparams.UnicodeString, Value: "C:\\Windows\\temp\\idxx.exe"}, kparams.FileShareMask: {Name: kparams.FileShareMask, Type: kparams.Uint32, Value: uint32(5)}, kparams.FileIrpPtr: {Name: kparams.FileIrpPtr, Type: kparams.Uint64, Value: uint64(1334543123112321)}, }, @@ -212,7 +212,7 @@ func TestFsProcessor(t *testing.T) { }, func(e *kevent.Kevent, t *testing.T, hsnap *handle.SnapshotterMock, p Processor) { fsProcessor := p.(*fsProcessor) - assert.True(t, e.Kparams.Contains(kparams.FileName)) + assert.True(t, e.Kparams.Contains(kparams.FilePath)) assert.Nil(t, fsProcessor.mmaps[3098][124567380264]) }, }, @@ -237,8 +237,8 @@ func TestFsProcessor(t *testing.T) { }, func(e *kevent.Kevent, t *testing.T, hsnap *handle.SnapshotterMock, p Processor) { assert.Equal(t, ktypes.WriteFile, e.Type) - assert.Contains(t, e.Kparams, kparams.FileName, kparams.FileType) - assert.Equal(t, "C:\\Windows\\temp\\idxx.exe", e.GetParamAsString(kparams.FileName)) + assert.Contains(t, e.Kparams, kparams.FilePath, kparams.FileType) + assert.Equal(t, "C:\\Windows\\temp\\idxx.exe", e.GetParamAsString(kparams.FilePath)) assert.Equal(t, "File", e.GetParamAsString(kparams.FileType)) }, }, @@ -262,8 +262,8 @@ func TestFsProcessor(t *testing.T) { func(e *kevent.Kevent, t *testing.T, hsnap *handle.SnapshotterMock, p Processor) { assert.Equal(t, ktypes.WriteFile, e.Type) hsnap.AssertNumberOfCalls(t, "FindByObject", 1) - assert.Contains(t, e.Kparams, kparams.FileName, kparams.FileType) - assert.Equal(t, "C:\\Windows\\temp\\doc.docx", e.GetParamAsString(kparams.FileName)) + assert.Contains(t, e.Kparams, kparams.FilePath, kparams.FileType) + assert.Equal(t, "C:\\Windows\\temp\\doc.docx", e.GetParamAsString(kparams.FilePath)) assert.Equal(t, "File", e.GetParamAsString(kparams.FileType)) }, }, @@ -275,7 +275,7 @@ func TestFsProcessor(t *testing.T) { Kparams: kevent.Kparams{ kparams.FileObject: {Name: kparams.FileObject, Type: kparams.Uint64, Value: uint64(18446738026482168384)}, kparams.FileKey: {Name: kparams.FileKey, Type: kparams.Uint64, Value: uint64(14446538026482168384)}, - kparams.FileName: {Name: kparams.FileName, Type: kparams.UnicodeString, Value: "*"}, + kparams.FilePath: {Name: kparams.FilePath, Type: kparams.UnicodeString, Value: "*"}, }, }, func(p Processor) { @@ -288,7 +288,7 @@ func TestFsProcessor(t *testing.T) { }, func(e *kevent.Kevent, t *testing.T, hsnap *handle.SnapshotterMock, p Processor) { assert.Equal(t, ktypes.EnumDirectory, e.Type) - assert.Contains(t, e.Kparams, kparams.FileName, kparams.FileDirectory) + assert.Contains(t, e.Kparams, kparams.FilePath, kparams.FileDirectory) assert.Equal(t, "C:\\Windows\\temp", e.GetParamAsString(kparams.FileDirectory)) }, }, diff --git a/internal/etw/processors/handle_windows.go b/internal/etw/processors/handle_windows.go index 495640111..e054a24a4 100644 --- a/internal/etw/processors/handle_windows.go +++ b/internal/etw/processors/handle_windows.go @@ -64,7 +64,7 @@ func (h *handleProcessor) processEvent(e *kevent.Kevent) (*kevent.Kevent, error) pid := e.Kparams.MustGetPid() proc := h.psnap.FindAndPut(pid) if proc != nil { - e.AppendParam(kparams.Exe, kparams.FilePath, proc.Exe) + e.AppendParam(kparams.Exe, kparams.Path, proc.Exe) e.AppendParam(kparams.ProcessName, kparams.AnsiString, proc.Name) } return e, nil @@ -93,7 +93,7 @@ func (h *handleProcessor) processEvent(e *kevent.Kevent) (*kevent.Kevent, error) driverPath = driverName } h.devPathResolver.RemovePath(driverName) - e.Kparams.Append(kparams.ImageFilename, kparams.FilePath, driverPath) + e.Kparams.Append(kparams.ImagePath, kparams.Path, driverPath) } // assign the formatted handle name if err := e.Kparams.SetValue(kparams.HandleObjectName, name); err != nil { diff --git a/internal/etw/processors/image_windows.go b/internal/etw/processors/image_windows.go index 57745a191..325862b0e 100644 --- a/internal/etw/processors/image_windows.go +++ b/internal/etw/processors/image_windows.go @@ -44,7 +44,7 @@ func (m *imageProcessor) ProcessEvent(e *kevent.Kevent) (*kevent.Kevent, bool, e } if e.IsUnloadImage() { pid := e.Kparams.MustGetPid() - mod := e.GetParamAsString(kparams.ImageFilename) + mod := e.GetParamAsString(kparams.ImagePath) if pid == 0 { pid = e.PID } diff --git a/internal/etw/processors/image_windows_test.go b/internal/etw/processors/image_windows_test.go index 7980945fc..9a4911d5e 100644 --- a/internal/etw/processors/image_windows_test.go +++ b/internal/etw/processors/image_windows_test.go @@ -44,7 +44,7 @@ func TestImageProcessor(t *testing.T) { &kevent.Kevent{ Type: ktypes.LoadImage, Kparams: kevent.Kparams{ - kparams.ImageFilename: {Name: kparams.ImageFilename, Type: kparams.UnicodeString, Value: filepath.Join(os.Getenv("windir"), "System32", "kernel32.dll")}, + kparams.ImagePath: {Name: kparams.ImagePath, Type: kparams.UnicodeString, Value: filepath.Join(os.Getenv("windir"), "System32", "kernel32.dll")}, kparams.ProcessID: {Name: kparams.ProcessID, Type: kparams.PID, Value: uint32(1023)}, kparams.ImageCheckSum: {Name: kparams.ImageCheckSum, Type: kparams.Uint32, Value: uint32(2323432)}, kparams.ImageBase: {Name: kparams.ImageBase, Type: kparams.Address, Value: uint64(0x7ffb313833a3)}, @@ -69,7 +69,7 @@ func TestImageProcessor(t *testing.T) { &kevent.Kevent{ Type: ktypes.UnloadImage, Kparams: kevent.Kparams{ - kparams.ImageFilename: {Name: kparams.ImageFilename, Type: kparams.UnicodeString, Value: "C:\\Windows\\system32\\kernel32.dll"}, + kparams.ImagePath: {Name: kparams.ImagePath, Type: kparams.UnicodeString, Value: "C:\\Windows\\system32\\kernel32.dll"}, kparams.ProcessName: {Name: kparams.ProcessName, Type: kparams.AnsiString, Value: "csrss.exe"}, kparams.ProcessID: {Name: kparams.ProcessID, Type: kparams.PID, Value: uint32(676)}, kparams.ImageBase: {Name: kparams.ImageBase, Type: kparams.Address, Value: uint64(0xfffb313833a3)}, diff --git a/internal/etw/processors/mem_windows.go b/internal/etw/processors/mem_windows.go index 525d60245..459aa9207 100644 --- a/internal/etw/processors/mem_windows.go +++ b/internal/etw/processors/mem_windows.go @@ -60,7 +60,7 @@ func (m memProcessor) ProcessEvent(e *kevent.Kevent) (*kevent.Kevent, bool, erro region := m.regionProber.Query(pid, addr) if region != nil { if region.IsMapped() { - e.AppendParam(kparams.FileName, kparams.FileDosPath, region.GetMappedFile()) + e.AppendParam(kparams.FilePath, kparams.DOSPath, region.GetMappedFile()) } e.AppendEnum(kparams.MemPageType, region.Type, MemPageTypes) e.AppendFlags(kparams.MemProtect, region.Protect, kevent.MemProtectionFlags) @@ -69,7 +69,7 @@ func (m memProcessor) ProcessEvent(e *kevent.Kevent) (*kevent.Kevent, bool, erro } proc := m.psnap.FindAndPut(pid) if proc != nil { - e.AppendParam(kparams.Exe, kparams.FilePath, proc.Exe) + e.AppendParam(kparams.Exe, kparams.Path, proc.Exe) e.AppendParam(kparams.ProcessName, kparams.AnsiString, proc.Name) } return e, false, nil diff --git a/internal/etw/processors/processor.go b/internal/etw/processors/processor.go index 39af986da..2ce69623a 100644 --- a/internal/etw/processors/processor.go +++ b/internal/etw/processors/processor.go @@ -93,7 +93,7 @@ func (typ ProcessorType) String() string { // executable image, or a Windows driver. func parseImageFileCharacteristics(e *kevent.Kevent) error { var pefile *pe.PE - filename := e.GetParamAsString(kparams.FileName) + filename := e.GetParamAsString(kparams.FilePath) f, err := os.Open(filename) if err != nil { // read file data blob from raw device diff --git a/internal/etw/processors/ps_windows.go b/internal/etw/processors/ps_windows.go index 7ef4984b8..8b58d34bf 100644 --- a/internal/etw/processors/ps_windows.go +++ b/internal/etw/processors/ps_windows.go @@ -73,7 +73,7 @@ func (p psProcessor) ProcessEvent(e *kevent.Kevent) (*kevent.Kevent, bool, error } proc := p.psnap.FindAndPut(pid) if proc != nil { - e.AppendParam(kparams.Exe, kparams.FilePath, proc.Exe) + e.AppendParam(kparams.Exe, kparams.Path, proc.Exe) e.AppendParam(kparams.ProcessName, kparams.AnsiString, proc.Name) } return e, false, nil @@ -97,7 +97,7 @@ func (p psProcessor) processEvent(e *kevent.Kevent) (*kevent.Kevent, error) { if exe == "" { exe = e.GetParamAsString(kparams.ProcessName) } - e.AppendParam(kparams.Exe, kparams.FilePath, exe) + e.AppendParam(kparams.Exe, kparams.Path, exe) if e.IsTerminateProcess() { return e, nil diff --git a/internal/etw/processors/registry_windows.go b/internal/etw/processors/registry_windows.go index 4b9f3eb63..759150258 100644 --- a/internal/etw/processors/registry_windows.go +++ b/internal/etw/processors/registry_windows.go @@ -88,7 +88,7 @@ func (r *registryProcessor) processEvent(e *kevent.Kevent) (*kevent.Kevent, erro case ktypes.RegKCBRundown, ktypes.RegCreateKCB: khandle := e.Kparams.MustGetUint64(kparams.RegKeyHandle) if _, ok := r.keys[khandle]; !ok { - r.keys[khandle], _ = e.Kparams.GetString(kparams.RegKeyName) + r.keys[khandle], _ = e.Kparams.GetString(kparams.RegPath) } kcbCount.Add(1) case ktypes.RegDeleteKCB: @@ -106,7 +106,7 @@ func (r *registryProcessor) processEvent(e *kevent.Kevent) (*kevent.Kevent, erro // last resort is to scan process' handles and check if any of the // key handles contain the partial key name. In this case we assume // the correct key is encountered. - keyName := e.Kparams.MustGetString(kparams.RegKeyName) + keyName := e.Kparams.MustGetString(kparams.RegPath) if khandle != 0 { if baseKey, ok := r.keys[khandle]; ok { keyName = baseKey + "\\" + keyName @@ -114,7 +114,7 @@ func (r *registryProcessor) processEvent(e *kevent.Kevent) (*kevent.Kevent, erro kcbMissCount.Add(1) keyName = r.findMatchingKey(e.PID, keyName) } - if err := e.Kparams.SetValue(kparams.RegKeyName, keyName); err != nil { + if err := e.Kparams.SetValue(kparams.RegPath, keyName); err != nil { return e, err } } diff --git a/internal/etw/processors/registry_windows_test.go b/internal/etw/processors/registry_windows_test.go index 26a5ab3fa..f7347a938 100644 --- a/internal/etw/processors/registry_windows_test.go +++ b/internal/etw/processors/registry_windows_test.go @@ -43,7 +43,7 @@ func TestRegistryProcessor(t *testing.T) { Type: ktypes.RegKCBRundown, Category: ktypes.Registry, Kparams: kevent.Kparams{ - kparams.RegKeyName: {Name: kparams.RegKeyName, Type: kparams.UnicodeString, Value: `\REGISTRY\MACHINE\SYSTEM\ControlSet001\Services\bthserv\Parameters`}, + kparams.RegPath: {Name: kparams.RegPath, Type: kparams.UnicodeString, Value: `\REGISTRY\MACHINE\SYSTEM\ControlSet001\Services\bthserv\Parameters`}, kparams.RegKeyHandle: {Name: kparams.RegKeyHandle, Type: kparams.Uint64, Value: uint64(18446666033549154696)}, }, }, @@ -64,7 +64,7 @@ func TestRegistryProcessor(t *testing.T) { Type: ktypes.RegDeleteKCB, Category: ktypes.Registry, Kparams: kevent.Kparams{ - kparams.RegKeyName: {Name: kparams.RegKeyName, Type: kparams.UnicodeString, Value: `\REGISTRY\MACHINE\SYSTEM\ControlSet001\Services\bthserv\Parameters`}, + kparams.RegPath: {Name: kparams.RegPath, Type: kparams.UnicodeString, Value: `\REGISTRY\MACHINE\SYSTEM\ControlSet001\Services\bthserv\Parameters`}, kparams.RegKeyHandle: {Name: kparams.RegKeyHandle, Type: kparams.Uint64, Value: uint64(18446666033549154696)}, }, }, @@ -86,7 +86,7 @@ func TestRegistryProcessor(t *testing.T) { Type: ktypes.RegOpenKey, Category: ktypes.Registry, Kparams: kevent.Kparams{ - kparams.RegKeyName: {Name: kparams.RegKeyName, Type: kparams.Key, Value: `\REGISTRY\MACHINE\SYSTEM\ControlSet001\Services\bthserv\Parameters`}, + kparams.RegPath: {Name: kparams.RegPath, Type: kparams.Key, Value: `\REGISTRY\MACHINE\SYSTEM\ControlSet001\Services\bthserv\Parameters`}, kparams.RegKeyHandle: {Name: kparams.RegKeyHandle, Type: kparams.Uint64, Value: uint64(0)}, }, }, @@ -96,7 +96,7 @@ func TestRegistryProcessor(t *testing.T) { return hsnap }, func(e *kevent.Kevent, t *testing.T, hsnap *handle.SnapshotterMock, p Processor) { - assert.Equal(t, `HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Services\bthserv\Parameters`, e.GetParamAsString(kparams.RegKeyName)) + assert.Equal(t, `HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Services\bthserv\Parameters`, e.GetParamAsString(kparams.RegPath)) }, }, { @@ -105,7 +105,7 @@ func TestRegistryProcessor(t *testing.T) { Type: ktypes.RegOpenKey, Category: ktypes.Registry, Kparams: kevent.Kparams{ - kparams.RegKeyName: {Name: kparams.RegKeyName, Type: kparams.Key, Value: `Pid`}, + kparams.RegPath: {Name: kparams.RegPath, Type: kparams.Key, Value: `Pid`}, kparams.RegKeyHandle: {Name: kparams.RegKeyHandle, Type: kparams.Uint64, Value: uint64(18446666033549154696)}, }, }, @@ -117,7 +117,7 @@ func TestRegistryProcessor(t *testing.T) { return hsnap }, func(e *kevent.Kevent, t *testing.T, hsnap *handle.SnapshotterMock, p Processor) { - assert.Equal(t, `HKEY_LOCAL_MACHINE\SYSTEM\Setup\Pid`, e.GetParamAsString(kparams.RegKeyName)) + assert.Equal(t, `HKEY_LOCAL_MACHINE\SYSTEM\Setup\Pid`, e.GetParamAsString(kparams.RegPath)) }, }, { @@ -127,7 +127,7 @@ func TestRegistryProcessor(t *testing.T) { Category: ktypes.Registry, PID: 23234, Kparams: kevent.Kparams{ - kparams.RegKeyName: {Name: kparams.RegKeyName, Type: kparams.Key, Value: `Pid`}, + kparams.RegPath: {Name: kparams.RegPath, Type: kparams.Key, Value: `Pid`}, kparams.RegKeyHandle: {Name: kparams.RegKeyHandle, Type: kparams.Uint64, Value: uint64(18446666033549154696)}, }, }, @@ -140,7 +140,7 @@ func TestRegistryProcessor(t *testing.T) { }, func(e *kevent.Kevent, t *testing.T, hsnap *handle.SnapshotterMock, p Processor) { hsnap.AssertNumberOfCalls(t, "FindHandles", 1) - assert.Equal(t, `HKEY_LOCAL_MACHINE\SYSTEM\Setup\Pid`, e.GetParamAsString(kparams.RegKeyName)) + assert.Equal(t, `HKEY_LOCAL_MACHINE\SYSTEM\Setup\Pid`, e.GetParamAsString(kparams.RegPath)) }, }, { @@ -150,7 +150,7 @@ func TestRegistryProcessor(t *testing.T) { Category: ktypes.Registry, PID: 23234, Kparams: kevent.Kparams{ - kparams.RegKeyName: {Name: kparams.RegKeyName, Type: kparams.Key, Value: `\REGISTRY\MACHINE\SYSTEM\CurrentControlSet\Control\Windows\Directory`}, + kparams.RegPath: {Name: kparams.RegPath, Type: kparams.Key, Value: `\REGISTRY\MACHINE\SYSTEM\CurrentControlSet\Control\Windows\Directory`}, kparams.RegKeyHandle: {Name: kparams.RegKeyHandle, Type: kparams.Uint64, Value: uint64(0)}, }, }, @@ -160,7 +160,7 @@ func TestRegistryProcessor(t *testing.T) { return hsnap }, func(e *kevent.Kevent, t *testing.T, hsnap *handle.SnapshotterMock, p Processor) { - assert.Equal(t, `HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Windows\Directory`, e.GetParamAsString(kparams.RegKeyName)) + assert.Equal(t, `HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Windows\Directory`, e.GetParamAsString(kparams.RegPath)) assert.Equal(t, `REG_EXPAND_SZ`, e.GetParamAsString(kparams.RegValueType)) assert.Equal(t, `%SystemRoot%`, e.GetParamAsString(kparams.RegValue)) }, diff --git a/internal/etw/source_test.go b/internal/etw/source_test.go index 67d589169..d2143a88f 100644 --- a/internal/etw/source_test.go +++ b/internal/etw/source_test.go @@ -438,7 +438,7 @@ func TestEventSourceAllEvents(t *testing.T) { nil, func(e *kevent.Kevent) bool { img := filepath.Join(os.Getenv("windir"), "System32", "notepad.exe") - return e.IsLoadImage() && strings.EqualFold(img, e.GetParamAsString(kparams.ImageFilename)) + return e.IsLoadImage() && strings.EqualFold(img, e.GetParamAsString(kparams.ImagePath)) }, false, }, @@ -454,7 +454,7 @@ func TestEventSourceAllEvents(t *testing.T) { }, func(e *kevent.Kevent) bool { return e.CurrentPid() && e.Type == ktypes.CreateFile && - strings.HasPrefix(filepath.Base(e.GetParamAsString(kparams.FileName)), "fibratus-test") && + strings.HasPrefix(filepath.Base(e.GetParamAsString(kparams.FilePath)), "fibratus-test") && !e.IsOpenDisposition() }, false, @@ -539,7 +539,7 @@ func TestEventSourceAllEvents(t *testing.T) { return e.CurrentPid() && e.Type == ktypes.MapViewFile && e.GetParamAsString(kparams.MemProtect) == "EXECUTE_READWRITE|READONLY" && e.GetParamAsString(kparams.FileViewSectionType) == "IMAGE" && - strings.Contains(e.GetParamAsString(kparams.FileName), "_fixtures\\yara-test.dll") + strings.Contains(e.GetParamAsString(kparams.FilePath), "_fixtures\\yara-test.dll") }, false, }, @@ -911,7 +911,7 @@ func testCallstackEnrichment(t *testing.T, hsnap handle.Snapshotter, psnap ps.Sn "load image callstack", nil, func(e *kevent.Kevent) bool { - if e.IsLoadImage() && filepath.Ext(e.GetParamAsString(kparams.FileName)) == ".dll" { + if e.IsLoadImage() && filepath.Ext(e.GetParamAsString(kparams.FilePath)) == ".dll" { callstack := e.Callstack.String() return strings.Contains(strings.ToLower(callstack), strings.ToLower("\\WINDOWS\\System32\\KERNELBASE.dll!LoadLibraryExW")) && strings.Contains(strings.ToLower(callstack), strings.ToLower("\\WINDOWS\\system32\\ntoskrnl.exe!NtMapViewOfSection")) @@ -963,7 +963,7 @@ func testCallstackEnrichment(t *testing.T, hsnap handle.Snapshotter, psnap ps.Sn return nil }, func(e *kevent.Kevent) bool { - if e.CurrentPid() && e.Type == ktypes.RegCreateKey && e.GetParamAsString(kparams.RegKeyName) == "HKEY_CURRENT_USER\\Volatile Environment\\CallstackTest" { + if e.CurrentPid() && e.Type == ktypes.RegCreateKey && e.GetParamAsString(kparams.RegPath) == "HKEY_CURRENT_USER\\Volatile Environment\\CallstackTest" { callstack := e.Callstack.String() log.Infof("create key event %s: %s", e.String(), callstack) return callstackContainsTestExe(callstack) && @@ -1001,7 +1001,7 @@ func testCallstackEnrichment(t *testing.T, hsnap handle.Snapshotter, psnap ps.Sn return key.SetStringValue("FibratusCallstack", "Callstack") }, func(e *kevent.Kevent) bool { - if e.CurrentPid() && e.Type == ktypes.RegSetValue && strings.HasSuffix(e.GetParamAsString(kparams.RegKeyName), "FibratusCallstack") { + if e.CurrentPid() && e.Type == ktypes.RegSetValue && strings.HasSuffix(e.GetParamAsString(kparams.RegPath), "FibratusCallstack") { callstack := e.Callstack.String() log.Infof("set value event %s: %s", e.String(), callstack) return callstackContainsTestExe(callstack) && @@ -1049,7 +1049,7 @@ func testCallstackEnrichment(t *testing.T, hsnap handle.Snapshotter, psnap ps.Sn }, func(e *kevent.Kevent) bool { if e.CurrentPid() && e.Type == ktypes.CreateFile && - strings.HasPrefix(filepath.Base(e.GetParamAsString(kparams.FileName)), "fibratus-callstack") && + strings.HasPrefix(filepath.Base(e.GetParamAsString(kparams.FilePath)), "fibratus-callstack") && !e.IsOpenDisposition() { callstack := e.Callstack.String() log.Infof("create file event %s: %s", e.String(), callstack) @@ -1078,7 +1078,7 @@ func testCallstackEnrichment(t *testing.T, hsnap handle.Snapshotter, psnap ps.Sn }, func(e *kevent.Kevent) bool { if e.CurrentPid() && e.Type == ktypes.CreateFile && - strings.HasPrefix(filepath.Base(e.GetParamAsString(kparams.FileName)), "fibratus-file-transacted") && + strings.HasPrefix(filepath.Base(e.GetParamAsString(kparams.FilePath)), "fibratus-file-transacted") && !e.IsOpenDisposition() { callstack := e.Callstack.String() log.Infof("create transacted file event %s: %s", e.String(), callstack) @@ -1148,7 +1148,7 @@ func testCallstackEnrichment(t *testing.T, hsnap handle.Snapshotter, psnap ps.Sn }, func(e *kevent.Kevent) bool { if e.CurrentPid() && e.Type == ktypes.DeleteFile && - strings.HasPrefix(filepath.Base(e.GetParamAsString(kparams.FileName)), "fibratus-delete") { + strings.HasPrefix(filepath.Base(e.GetParamAsString(kparams.FilePath)), "fibratus-delete") { callstack := e.Callstack.String() log.Infof("delete file event %s: %s", e.String(), callstack) return callstackContainsTestExe(callstack) && @@ -1173,7 +1173,7 @@ func testCallstackEnrichment(t *testing.T, hsnap handle.Snapshotter, psnap ps.Sn }, func(e *kevent.Kevent) bool { if e.CurrentPid() && e.Type == ktypes.RenameFile && - strings.HasPrefix(filepath.Base(e.GetParamAsString(kparams.FileName)), "fibratus-rename") { + strings.HasPrefix(filepath.Base(e.GetParamAsString(kparams.FilePath)), "fibratus-rename") { callstack := e.Callstack.String() log.Infof("rename file event %s: %s", e.String(), callstack) return callstackContainsTestExe(callstack) && diff --git a/pkg/alertsender/eventlog/eventlog_test.go b/pkg/alertsender/eventlog/eventlog_test.go index 5f65fe127..894073910 100644 --- a/pkg/alertsender/eventlog/eventlog_test.go +++ b/pkg/alertsender/eventlog/eventlog_test.go @@ -53,7 +53,7 @@ func TestEventlogSender(t *testing.T) { Description: "Creates or opens a new file, directory, I/O device, pipe, console", Kparams: kevent.Kparams{ kparams.FileObject: {Name: kparams.FileObject, Type: kparams.Uint64, Value: uint64(12456738026482168384)}, - kparams.FileName: {Name: kparams.FileName, Type: kparams.UnicodeString, Value: "C:\\Windows\\system32\\user32.dll"}, + kparams.FilePath: {Name: kparams.FilePath, Type: kparams.UnicodeString, Value: "C:\\Windows\\system32\\user32.dll"}, kparams.FileType: {Name: kparams.FileType, Type: kparams.AnsiString, Value: "file"}, kparams.FileOperation: {Name: kparams.FileOperation, Type: kparams.Enum, Value: uint32(1)}, }, diff --git a/pkg/alertsender/mail/renderer_test.go b/pkg/alertsender/mail/renderer_test.go index 9253a10e4..32033f009 100644 --- a/pkg/alertsender/mail/renderer_test.go +++ b/pkg/alertsender/mail/renderer_test.go @@ -64,7 +64,7 @@ func TestRenderHTMLTemplate(t *testing.T) { Description: "Creates or opens a new file, directory, I/O device, pipe, console", Kparams: kevent.Kparams{ kparams.FileObject: {Name: kparams.FileObject, Type: kparams.Uint64, Value: uint64(12456738026482168384)}, - kparams.FileName: {Name: kparams.FileName, Type: kparams.UnicodeString, Value: "C:\\Windows\\system32\\user32.dll"}, + kparams.FilePath: {Name: kparams.FilePath, Type: kparams.UnicodeString, Value: "C:\\Windows\\system32\\user32.dll"}, kparams.FileType: {Name: kparams.FileType, Type: kparams.AnsiString, Value: "file"}, kparams.FileOperation: {Name: kparams.FileOperation, Type: kparams.Enum, Value: uint32(1)}, }, diff --git a/pkg/filament/filament_test.go b/pkg/filament/filament_test.go index f01fef660..c61c9751f 100644 --- a/pkg/filament/filament_test.go +++ b/pkg/filament/filament_test.go @@ -79,7 +79,7 @@ func TestOnNextKevent(t *testing.T) { Seq: uint64(i), Timestamp: time.Now(), Kparams: kevent.Kparams{ - kparams.RegKeyName: {Name: kparams.RegKeyName, Type: kparams.UnicodeString, Value: `HKEY_LOCAL_MACHINE\SYSTEM\Setup`}, + kparams.RegPath: {Name: kparams.RegPath, Type: kparams.UnicodeString, Value: `HKEY_LOCAL_MACHINE\SYSTEM\Setup`}, kparams.RegKeyHandle: {Name: kparams.RegKeyHandle, Type: kparams.Address, Value: uint64(18446666033449935464)}, kparams.NetDIP: {Name: kparams.NetDIP, Type: kparams.IPv4, Value: net.ParseIP("216.58.201.174")}, }, diff --git a/pkg/filter/_fixtures/default/windows_error_reporting_and_wmi_provider_host.yml b/pkg/filter/_fixtures/default/windows_error_reporting_and_wmi_provider_host.yml index 695fd1496..c6f5a1aca 100644 --- a/pkg/filter/_fixtures/default/windows_error_reporting_and_wmi_provider_host.yml +++ b/pkg/filter/_fixtures/default/windows_error_reporting_and_wmi_provider_host.yml @@ -1,7 +1,7 @@ name: Windows error reporting/telemetry, WMI provider host id: 0fe67e44-94e2-44cb-bc40-052bc2e0fdb2 version: 1.0.0 -condition: kevt.name = 'CreateProcess' and ps.comm startswith +condition: kevt.name = 'CreateProcess' and ps.comm startswith ( ' \"C:\\Windows\\system32\\wermgr.exe\\" \"-queuereporting_svc\" ', 'C:\\Windows\\system32\\DllHost.exe /Processid', diff --git a/pkg/filter/_fixtures/sequence_rule_bound_fields.yml b/pkg/filter/_fixtures/sequence_rule_bound_fields.yml index 84d421bfe..84dd55132 100644 --- a/pkg/filter/_fixtures/sequence_rule_bound_fields.yml +++ b/pkg/filter/_fixtures/sequence_rule_bound_fields.yml @@ -7,7 +7,7 @@ condition: > |kevt.name = 'CreateProcess' and ps.name = 'cmd.exe'| as e1 |kevt.name = 'CreateFile' and - file.name icontains 'temp' + file.path icontains 'temp' and $e1.ps.sid = ps.sid | as e2 diff --git a/pkg/filter/_fixtures/sequence_rule_bound_fields_with_functions.yml b/pkg/filter/_fixtures/sequence_rule_bound_fields_with_functions.yml index d1991277f..bc9bac25f 100644 --- a/pkg/filter/_fixtures/sequence_rule_bound_fields_with_functions.yml +++ b/pkg/filter/_fixtures/sequence_rule_bound_fields_with_functions.yml @@ -11,16 +11,16 @@ condition: > maxspan 5m |kevt.name = 'CreateFile' and - file.name imatches '?:\\Windows\\System32\\*.dll' + file.path imatches '?:\\Windows\\System32\\*.dll' | as e1 |kevt.name = 'RegSetValue' and - registry.key.name ~= 'HKEY_CURRENT_USER\\Volatile Environment\\Notification Packages' + registry.path ~= 'HKEY_CURRENT_USER\\Volatile Environment\\Notification Packages' and - get_reg_value(registry.key.name) iin (base($e1.file.name, false)) + get_reg_value(registry.path) iin (base($e1.file.path, false)) | output: > %1.ps.exe process dropped potentially malicious - %1.file.name password filter and %2.ps.name - registered the password filter DLL under %2.registry.key.name registry key + %1.file.path password filter and %2.ps.name + registered the password filter DLL under %2.registry.path registry key min-engine-version: 2.0.0 diff --git a/pkg/filter/_fixtures/sequence_rule_expire.yml b/pkg/filter/_fixtures/sequence_rule_expire.yml index f10aafd36..4fc3476f3 100644 --- a/pkg/filter/_fixtures/sequence_rule_expire.yml +++ b/pkg/filter/_fixtures/sequence_rule_expire.yml @@ -7,6 +7,6 @@ condition: > |kevt.name = 'OpenProcess' and ps.name = 'cmd.exe'| by ps.exe |kevt.name = 'CreateFile' and - file.name icontains 'temp' - | by file.name + file.path icontains 'temp' + | by file.path min-engine-version: 2.0.0 diff --git a/pkg/filter/_fixtures/sequence_rule_out_of_order.yml b/pkg/filter/_fixtures/sequence_rule_out_of_order.yml index d01a363b7..8d9f588b4 100644 --- a/pkg/filter/_fixtures/sequence_rule_out_of_order.yml +++ b/pkg/filter/_fixtures/sequence_rule_out_of_order.yml @@ -13,5 +13,5 @@ condition: > output: > Detected an attempt by `%1.ps.name` process to access and read the memory of the **Local Security And Authority Subsystem Service** - and subsequently write the `%2.file.name` dump file to the disk device + and subsequently write the `%2.file.path` dump file to the disk device min-engine-version: 2.0.0 diff --git a/pkg/filter/_fixtures/sequence_rule_simple.yml b/pkg/filter/_fixtures/sequence_rule_simple.yml index 2daf1cd9e..f3db5a11d 100644 --- a/pkg/filter/_fixtures/sequence_rule_simple.yml +++ b/pkg/filter/_fixtures/sequence_rule_simple.yml @@ -7,6 +7,6 @@ condition: > |kevt.name = 'CreateProcess' and ps.name = 'cmd.exe'| by ps.exe |kevt.name = 'CreateFile' and - file.name icontains 'temp' - | by file.name + file.path icontains 'temp' + | by file.path min-engine-version: 2.0.0 diff --git a/pkg/filter/_fixtures/sequence_rule_simple_max_span.yml b/pkg/filter/_fixtures/sequence_rule_simple_max_span.yml index 168448039..701c94c34 100644 --- a/pkg/filter/_fixtures/sequence_rule_simple_max_span.yml +++ b/pkg/filter/_fixtures/sequence_rule_simple_max_span.yml @@ -8,6 +8,6 @@ condition: > |kevt.name = 'CreateProcess' and ps.name = 'cmd.exe'| |kevt.name = 'CreateFile' and - file.name icontains 'temp' + file.path icontains 'temp' | min-engine-version: 2.0.0 diff --git a/pkg/filter/_fixtures/simple_and_sequence_rules/powershell_created_temp_file.yml b/pkg/filter/_fixtures/simple_and_sequence_rules/powershell_created_temp_file.yml index 2ea87ffa3..36a906513 100644 --- a/pkg/filter/_fixtures/simple_and_sequence_rules/powershell_created_temp_file.yml +++ b/pkg/filter/_fixtures/simple_and_sequence_rules/powershell_created_temp_file.yml @@ -7,6 +7,6 @@ condition: > |kevt.name = 'CreateProcess' and ps.name = 'powershell.exe'| by ps.pid |kevt.name = 'CreateFile' and - file.name icontains 'temp' + file.path icontains 'temp' | by ps.pid min-engine-version: 2.0.0 diff --git a/pkg/filter/_fixtures/simple_emit_alert.yml b/pkg/filter/_fixtures/simple_emit_alert.yml index fa71221d4..4adf619e2 100644 --- a/pkg/filter/_fixtures/simple_emit_alert.yml +++ b/pkg/filter/_fixtures/simple_emit_alert.yml @@ -1,7 +1,7 @@ name: match https connections id: 50ffc2a8-0bde-45c4-9e20-46158250fa91 version: 1.0.0 -condition: kevt.name = 'Recv' and net.dport = 443 +condition: kevt.name = 'Recv' and net.dport = 443 output: "%ps.name process received data on port %net.dport" severity: critical min-engine-version: 2.0.0 diff --git a/pkg/filter/_fixtures/simple_matches.yml b/pkg/filter/_fixtures/simple_matches.yml index cafb81509..0e40c4985 100644 --- a/pkg/filter/_fixtures/simple_matches.yml +++ b/pkg/filter/_fixtures/simple_matches.yml @@ -1,5 +1,5 @@ name: match https connections id: 60ffc2a8-0bde-45c4-9e20-46158250fa91 version: 1.0.0 -condition: kevt.name = 'Recv' and net.dport = 443 +condition: kevt.name = 'Recv' and net.dport = 443 min-engine-version: 2.0.0 diff --git a/pkg/filter/_fixtures/simple_matches/filter3.yml b/pkg/filter/_fixtures/simple_matches/filter3.yml index 002d9ef24..08602edef 100644 --- a/pkg/filter/_fixtures/simple_matches/filter3.yml +++ b/pkg/filter/_fixtures/simple_matches/filter3.yml @@ -1,5 +1,5 @@ name: src ip address is not a loopback address id: 7155539d-31bd-429e-81f9-c17ee1c01f93 version: 1.0.0 -condition: kevt.name = 'Recv' and net.sip != 127.0.0.1 +condition: kevt.name = 'Recv' and net.sip != 127.0.0.1 min-engine-version: 2.0.0 diff --git a/pkg/filter/accessor_windows.go b/pkg/filter/accessor_windows.go index d360acfc2..59756585e 100644 --- a/pkg/filter/accessor_windows.go +++ b/pkg/filter/accessor_windows.go @@ -756,8 +756,12 @@ func newFileAccessor() Accessor { func (l *fileAccessor) Get(f fields.Field, kevt *kevent.Kevent) (kparams.Value, error) { switch f { + case fields.FilePath: + return kevt.GetParamAsString(kparams.FilePath), nil case fields.FileName: - return kevt.GetParamAsString(kparams.FileName), nil + return filepath.Base(kevt.GetParamAsString(kparams.FilePath)), nil + case fields.FileExtension: + return filepath.Ext(kevt.GetParamAsString(kparams.FilePath)), nil case fields.FileOffset: return kevt.Kparams.GetUint64(kparams.FileOffset) case fields.FileIOSize: @@ -770,8 +774,6 @@ func (l *fileAccessor) Get(f fields.Field, kevt *kevent.Kevent) (kparams.Value, return kevt.Kparams.GetUint64(kparams.FileObject) case fields.FileType: return kevt.GetParamAsString(kparams.FileType), nil - case fields.FileExtension: - return filepath.Ext(kevt.GetParamAsString(kparams.FileName)), nil case fields.FileAttributes: return kevt.GetFlagsAsSlice(kparams.FileAttributes), nil case fields.FileStatus: @@ -835,7 +837,7 @@ func newImageAccessor() Accessor { func (i *imageAccessor) Get(f fields.Field, kevt *kevent.Kevent) (kparams.Value, error) { if kevt.IsLoadImage() && (f == fields.ImageSignatureType || f == fields.ImageSignatureLevel || f.IsImageCert()) { - filename := kevt.GetParamAsString(kparams.FileName) + filename := kevt.GetParamAsString(kparams.ImagePath) addr := kevt.Kparams.MustGetUint64(kparams.ImageBase) typ := kevt.Kparams.MustGetUint32(kparams.ImageSignatureType) level := kevt.Kparams.MustGetUint32(kparams.ImageSignatureLevel) @@ -899,8 +901,10 @@ func (i *imageAccessor) Get(f fields.Field, kevt *kevent.Kevent) (kparams.Value, } switch f { + case fields.ImagePath: + return kevt.GetParamAsString(kparams.ImagePath), nil case fields.ImageName: - return kevt.GetParamAsString(kparams.ImageFilename), nil + return filepath.Base(kevt.GetParamAsString(kparams.ImagePath)), nil case fields.ImageDefaultAddress: return kevt.GetParamAsString(kparams.ImageDefaultBase), nil case fields.ImageBase: @@ -937,7 +941,7 @@ func (i *imageAccessor) Get(f fields.Field, kevt *kevent.Kevent) (kparams.Value, case fields.ImageIsExecutable: return kevt.Kparams.GetBool(kparams.FileIsExecutable) case fields.ImageIsDotnet: - p, err := pe.ParseFile(kevt.GetParamAsString(kparams.ImageFilename), pe.WithCLR()) + p, err := pe.ParseFile(kevt.GetParamAsString(kparams.ImagePath), pe.WithCLR()) if err != nil { return nil, err } @@ -960,8 +964,14 @@ func newRegistryAccessor() Accessor { func (r *registryAccessor) Get(f fields.Field, kevt *kevent.Kevent) (kparams.Value, error) { switch f { + case fields.RegistryPath: + return kevt.GetParamAsString(kparams.RegPath), nil case fields.RegistryKeyName: - return kevt.GetParamAsString(kparams.RegKeyName), nil + if kevt.IsRegSetValue() { + return filepath.Base(filepath.Dir(kevt.GetParamAsString(kparams.RegPath))), nil + } else { + return filepath.Base(kevt.GetParamAsString(kparams.RegPath)), nil + } case fields.RegistryKeyHandle: return kevt.GetParamAsString(kparams.RegKeyHandle), nil case fields.RegistryValue: @@ -1140,7 +1150,7 @@ func (pa *peAccessor) Get(f fields.Field, kevt *kevent.Kevent) (kparams.Value, e // from process' memory at the base address of the loaded // executable image if kevt.IsLoadImage() && f.IsPeModified() { - filename := kevt.GetParamAsString(kparams.FileName) + filename := kevt.GetParamAsString(kparams.ImagePath) isExecutable := filepath.Ext(filename) == ".exe" || kevt.Kparams.TryGetBool(kparams.FileIsExecutable) if !isExecutable { return nil, nil @@ -1360,7 +1370,12 @@ func captureInBrackets(s string) (string, fields.Segment) { // isLOLDriver interacts with the loldrivers client to determine // whether the loaded/dropped driver is malicious or vulnerable. func isLOLDriver(f fields.Field, kevt *kevent.Kevent) (kparams.Value, error) { - filename := kevt.GetParamAsString(kparams.FileName) + var filename string + if kevt.Category == ktypes.File { + filename = kevt.GetParamAsString(kparams.FilePath) + } else { + filename = kevt.GetParamAsString(kparams.ImagePath) + } isDriver := filepath.Ext(filename) == ".sys" || kevt.Kparams.TryGetBool(kparams.FileIsDriver) if !isDriver { return nil, nil diff --git a/pkg/filter/fields/fields_windows.go b/pkg/filter/fields/fields_windows.go index 20648c9a5..919eabe01 100644 --- a/pkg/filter/fields/fields_windows.go +++ b/pkg/filter/fields/fields_windows.go @@ -364,8 +364,10 @@ const ( // FileObject represents the address of the file object FileObject Field = "file.object" - // FileName represents the fie name + // FileName represents the file base name (e.g. cmd.exe) FileName Field = "file.name" + // FilePath represents the file full path (e.g. C:\Windows\System32\cmd.exe) + FilePath Field = "file.path" // FileExtension represents the file extension (e.g. .exe or .dll) FileExtension Field = "file.extension" // FileOperation represents the file operation (e.g. create) @@ -413,6 +415,8 @@ const ( // FileInfoIsDispositionDeleteFile represents the field that indicates if the file is deleted when its handle is closed FileInfoIsDispositionDeleteFile Field = "file.info.is_disposition_delete_file" + // RegistryPath represents the full registry path + RegistryPath Field = "registry.path" // RegistryKeyName represents the registry key name RegistryKeyName Field = "registry.key.name" // RegistryKeyHandle represents the registry KCB address @@ -432,7 +436,9 @@ const ( ImageChecksum Field = "image.checksum" // ImageDefaultAddress represents the module address ImageDefaultAddress Field = "image.default.address" - // ImageName is the module full name + // ImagePath is the module full path + ImagePath Field = "image.path" + // ImageName is the module name ImageName Field = "image.name" // ImagePID is the pid of the process where the image was loaded ImagePID Field = "image.pid" @@ -725,7 +731,8 @@ var fields = map[Field]FieldInfo{ ThreadCallstackCallsiteTrailingAssembly: {ThreadCallstackCallsiteTrailingAssembly, "callsite trailing assembly instructions", kparams.Slice, []string{"thread.callstack.callsite_trailing_assembly in ('add esp, 0xab')"}, nil}, ThreadCallstackIsUnbacked: {ThreadCallstackIsUnbacked, "indicates if the callstack contains unbacked regions", kparams.Bool, []string{"thread.callstack.is_unbacked"}, nil}, - ImageName: {ImageName, "full image name", kparams.UnicodeString, []string{"image.name contains 'advapi32.dll'"}, nil}, + ImagePath: {ImagePath, "full image path", kparams.UnicodeString, []string{"image.patj = 'C:\\Windows\\System32\\advapi32.dll'"}, nil}, + ImageName: {ImageName, "image name", kparams.UnicodeString, []string{"image.name = 'advapi32.dll'"}, nil}, ImageBase: {ImageBase, "the base address of process in which the image is loaded", kparams.Address, []string{"image.base.address = 'a65d800000'"}, nil}, ImageChecksum: {ImageChecksum, "image checksum", kparams.Uint32, []string{"image.checksum = 746424"}, nil}, ImageSize: {ImageSize, "image size", kparams.Uint32, []string{"image.size > 1024"}, nil}, @@ -746,6 +753,7 @@ var fields = map[Field]FieldInfo{ ImageIsDotnet: {ImageIsDotnet, "indicates if the loaded image is a .NET assembly", kparams.Bool, []string{"image.is_dotnet'"}, nil}, FileObject: {FileObject, "file object address", kparams.Uint64, []string{"file.object = 18446738026482168384"}, nil}, + FilePath: {FilePath, "full file path", kparams.UnicodeString, []string{"file.path = 'C:\\Windows\\System32'"}, nil}, FileName: {FileName, "full file name", kparams.UnicodeString, []string{"file.name contains 'mimikatz'"}, nil}, FileOperation: {FileOperation, "file operation", kparams.AnsiString, []string{"file.operation = 'open'"}, nil}, FileShareMask: {FileShareMask, "file share mask", kparams.AnsiString, []string{"file.share.mask = 'rw-'"}, nil}, @@ -771,7 +779,8 @@ var fields = map[Field]FieldInfo{ FileInfoEOFSize: {FileInfoEOFSize, "file EOF size", kparams.Uint64, []string{"file.info.eof_size > 1000"}, nil}, FileInfoIsDispositionDeleteFile: {FileInfoIsDispositionDeleteFile, "indicates if the file is deleted when its handle is closed", kparams.Bool, []string{"file.info.is_disposition_file_delete = true"}, nil}, - RegistryKeyName: {RegistryKeyName, "fully qualified key name", kparams.UnicodeString, []string{"registry.key.name contains 'HKEY_LOCAL_MACHINE'"}, nil}, + RegistryPath: {RegistryPath, "fully qualified registry path", kparams.UnicodeString, []string{"registry.path = 'HKEY_LOCAL_MACHINE\\SYSTEM'"}, nil}, + RegistryKeyName: {RegistryKeyName, "registry key name", kparams.UnicodeString, []string{"registry.key.name = 'CurrentControlSet'"}, nil}, RegistryKeyHandle: {RegistryKeyHandle, "registry key object address", kparams.Address, []string{"registry.key.handle = 'FFFFB905D60C2268'"}, nil}, RegistryValue: {RegistryValue, "registry value content", kparams.UnicodeString, []string{"registry.value = '%SystemRoot%\\system32'"}, nil}, RegistryValueType: {RegistryValueType, "type of registry value", kparams.UnicodeString, []string{"registry.value.type = 'REG_SZ'"}, nil}, diff --git a/pkg/filter/filter_test.go b/pkg/filter/filter_test.go index aae29344f..d20dde011 100644 --- a/pkg/filter/filter_test.go +++ b/pkg/filter/filter_test.go @@ -397,7 +397,7 @@ func TestFileFilter(t *testing.T) { Description: "Creates or opens a new file, directory, I/O device, pipe, console", Kparams: kevent.Kparams{ kparams.FileObject: {Name: kparams.FileObject, Type: kparams.Uint64, Value: uint64(12456738026482168384)}, - kparams.FileName: {Name: kparams.FileName, Type: kparams.UnicodeString, Value: "C:\\Windows\\system32\\user32.dll"}, + kparams.FilePath: {Name: kparams.FilePath, Type: kparams.UnicodeString, Value: "C:\\Windows\\system32\\user32.dll"}, kparams.FileType: {Name: kparams.FileType, Type: kparams.AnsiString, Value: "file"}, kparams.FileOperation: {Name: kparams.FileOperation, Type: kparams.AnsiString, Value: "open"}, }, @@ -409,7 +409,8 @@ func TestFileFilter(t *testing.T) { matches bool }{ - {`file.name = 'C:\\Windows\\system32\\user32.dll'`, true}, + {`file.name = 'user32.dll'`, true}, + {`file.path = 'C:\\Windows\\system32\\user32.dll'`, true}, {`file.extension = '.dll'`, true}, {`file.extension not contains '.exe'`, true}, {`file.extension contains '.exe' or (file.extension contains '.dll' and file.name endswith 'user32.dll')`, true}, @@ -419,31 +420,31 @@ func TestFileFilter(t *testing.T) { {`file.extension not contains '.exe' and file.extension not contains '.com' and file.extension not in ('.vba', '.exe')`, true}, {`file.extension not in ('.exe', '.com')`, true}, {`file.extension not in ('.exe', '.dll')`, false}, - {`file.name matches 'C:\\*\\user32.dll'`, true}, - {`file.name not matches 'C:\\*.exe'`, true}, - {`file.name imatches 'C:\\*\\USER32.dll'`, true}, - {`file.name matches ('C:\\*\\user3?.dll', 'C:\\*\\user32.*')`, true}, - {`file.name contains ('C:\\Windows\\system32\\kernel32.dll', 'C:\\Windows\\system32\\user32.dll')`, true}, - {`file.name not matches ('C:\\*.exe', 'C:\\Windows\\*.com')`, true}, - {`file.name endswith ('.exe', 'kernel32.dll', 'user32.dll')`, true}, - {`file.name iendswith ('.EXE', 'KERNEL32.dll', 'user32.dll')`, true}, - {`file.name istartswith ('C:\\WINDOWS', 'KERNEL32.dll', 'user32.dll')`, true}, - {`file.name iin ('C:\\WINDOWS\\system32\\user32.dll')`, true}, - {`file.name fuzzy 'C:\\Windows\\system32\\ser3ll'`, true}, - {`file.name ifuzzy 'C:\\WINDOWS\\sYS\\ser3ll'`, true}, - {`file.name ifuzzy 'C:\\WINDOWS\\sYS\\32dll'`, true}, - {`file.name fuzzy ('C:\\Windows\\system32\\kernel', 'C:\\Windows\\system32\\ser3ll')`, true}, - {`file.name ifuzzynorm 'C:\\WINDOWS\\sÝS\\32dll'`, true}, - {`base(file.name) = 'user32.dll'`, true}, - {`ext(base(file.name)) = '.dll'`, true}, - {`base(file.name, false) = 'user32'`, true}, - {`dir(file.name) = 'C:\\Windows\\system32'`, true}, - {`ext(file.name) = '.dll'`, true}, - {`ext(file.name, false) = 'dll'`, true}, - {`is_abs(file.name)`, true}, - {`is_abs(base(file.name))`, false}, - {`file.name iin glob('C:\\Windows\\System32\\*.dll')`, true}, - {`volume(file.name) = 'C:'`, true}, + {`file.path matches 'C:\\*\\user32.dll'`, true}, + {`file.path not matches 'C:\\*.exe'`, true}, + {`file.path imatches 'C:\\*\\USER32.dll'`, true}, + {`file.path matches ('C:\\*\\user3?.dll', 'C:\\*\\user32.*')`, true}, + {`file.path contains ('C:\\Windows\\system32\\kernel32.dll', 'C:\\Windows\\system32\\user32.dll')`, true}, + {`file.path not matches ('C:\\*.exe', 'C:\\Windows\\*.com')`, true}, + {`file.path endswith ('.exe', 'kernel32.dll', 'user32.dll')`, true}, + {`file.path iendswith ('.EXE', 'KERNEL32.dll', 'user32.dll')`, true}, + {`file.path istartswith ('C:\\WINDOWS', 'KERNEL32.dll', 'user32.dll')`, true}, + {`file.path iin ('C:\\WINDOWS\\system32\\user32.dll')`, true}, + {`file.path fuzzy 'C:\\Windows\\system32\\ser3ll'`, true}, + {`file.path ifuzzy 'C:\\WINDOWS\\sYS\\ser3ll'`, true}, + {`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}, + {`base(file.path) = 'user32.dll'`, true}, + {`ext(base(file.path)) = '.dll'`, true}, + {`base(file.path, false) = 'user32'`, true}, + {`dir(file.path) = 'C:\\Windows\\system32'`, true}, + {`ext(file.path) = '.dll'`, true}, + {`ext(file.path, false) = 'dll'`, true}, + {`is_abs(file.path)`, true}, + {`is_abs(base(file.path))`, false}, + {`file.path iin glob('C:\\Windows\\System32\\*.dll')`, true}, + {`volume(file.path) = 'C:'`, true}, } for i, tt := range tests { @@ -557,7 +558,7 @@ func TestKeventFilter(t *testing.T) { Kparams: kevent.Kparams{ kparams.ProcessID: {Name: kparams.ProcessID, Type: kparams.PID, Value: uint32(3434)}, kparams.FileObject: {Name: kparams.FileObject, Type: kparams.Uint64, Value: uint64(12456738026482168384)}, - kparams.FileName: {Name: kparams.FileName, Type: kparams.UnicodeString, Value: "\\Device\\HarddiskVolume2\\Windows\\system32\\user32.dll"}, + kparams.FilePath: {Name: kparams.FilePath, Type: kparams.UnicodeString, Value: "\\Device\\HarddiskVolume2\\Windows\\system32\\user32.dll"}, kparams.FileType: {Name: kparams.FileType, Type: kparams.AnsiString, Value: "file"}, kparams.FileOperation: {Name: kparams.FileOperation, Type: kparams.AnsiString, Value: "open"}, }, @@ -579,7 +580,7 @@ func TestKeventFilter(t *testing.T) { {`kevt.category = 'file'`, true}, {`kevt.host = 'archrabbit'`, true}, {`kevt.nparams = 5`, true}, - {`kevt.arg[file_name] = '\\Device\\HarddiskVolume2\\Windows\\system32\\user32.dll'`, true}, + {`kevt.arg[file_path] = '\\Device\\HarddiskVolume2\\Windows\\system32\\user32.dll'`, true}, {`kevt.arg[type] = 'file'`, true}, {`kevt.arg[pid] = 3434`, true}, @@ -594,15 +595,15 @@ func TestKeventFilter(t *testing.T) { {`upper(rtrim(kevt.name, 'File')) = 'CREATE'`, true}, {`replace(kevt.host, 'rabbit', '_bunny') = 'arch_bunny'`, true}, {`replace(kevt.host, 'rabbit', '_bunny', '_bunny', 'bunny') = 'archbunny'`, true}, - {`split(file.name, '\\') IN ('windows', 'system32')`, true}, - {`length(file.name) = 51`, true}, - {`indexof(file.name, '\\') = 0`, true}, - {`indexof(file.name, '\\', 'last') = 40`, true}, - {`indexof(file.name, 'h2', 'any') = 22`, true}, - {`substr(file.name, indexof(file.name, '\\'), indexof(file.name, '\\Hard')) = '\\Device'`, true}, + {`split(file.path, '\\') IN ('windows', 'system32')`, true}, + {`length(file.path) = 51`, true}, + {`indexof(file.path, '\\') = 0`, true}, + {`indexof(file.path, '\\', 'last') = 40`, true}, + {`indexof(file.path, 'h2', 'any') = 22`, true}, + {`substr(file.path, indexof(file.path, '\\'), indexof(file.path, '\\Hard')) = '\\Device'`, true}, {`substr(kevt.desc, indexof(kevt.desc, '\\'), indexof(kevt.desc, 'NOT')) = 'Creates or opens a new file, directory, I/O device, pipe, console'`, true}, - {`entropy(file.name) > 120`, true}, - {`regex(file.name, '\\\\Device\\\\HarddiskVolume[2-9]+\\\\.*')`, true}, + {`entropy(file.path) > 120`, true}, + {`regex(file.path, '\\\\Device\\\\HarddiskVolume[2-9]+\\\\.*')`, true}, } for i, tt := range tests { @@ -715,7 +716,7 @@ func TestRegistryFilter(t *testing.T) { PID: 859, Category: ktypes.Registry, Kparams: kevent.Kparams{ - kparams.RegKeyName: {Name: kparams.RegKeyName, Type: kparams.UnicodeString, Value: `HKEY_LOCAL_MACHINE\SYSTEM\Setup\Pid`}, + kparams.RegPath: {Name: kparams.RegPath, Type: kparams.UnicodeString, Value: `HKEY_LOCAL_MACHINE\SYSTEM\Setup\Pid`}, kparams.RegValue: {Name: kparams.RegValue, Type: kparams.Uint32, Value: uint32(10234)}, kparams.RegValueType: {Name: kparams.RegValueType, Type: kparams.AnsiString, Value: "DWORD"}, kparams.NTStatus: {Name: kparams.NTStatus, Type: kparams.AnsiString, Value: "success"}, @@ -729,10 +730,11 @@ func TestRegistryFilter(t *testing.T) { }{ {`registry.status startswith ('key not', 'succ')`, true}, - {`registry.key.name icontains ('hkey_local_machine', 'HKEY_LOCAL')`, true}, + {`registry.path = 'HKEY_LOCAL_MACHINE\\SYSTEM\\Setup\\Pid'`, true}, + {`registry.key.name icontains ('Setup', 'setup')`, true}, {`registry.value = 10234`, true}, {`registry.value.type in ('DWORD', 'QWORD')`, true}, - {`MD5(registry.key.name) = 'eab870b2a516206575d2ffa2b98d8af5'`, true}, + {`MD5(registry.path) = 'eab870b2a516206575d2ffa2b98d8af5'`, true}, } for i, tt := range tests { @@ -753,7 +755,7 @@ func TestImageFilter(t *testing.T) { Type: ktypes.LoadImage, Category: ktypes.Image, Kparams: kevent.Kparams{ - kparams.ImageFilename: {Name: kparams.ImageFilename, Type: kparams.UnicodeString, Value: filepath.Join(os.Getenv("windir"), "System32", "kernel32.dll")}, + kparams.ImagePath: {Name: kparams.ImagePath, Type: kparams.UnicodeString, Value: filepath.Join(os.Getenv("windir"), "System32", "kernel32.dll")}, kparams.ProcessID: {Name: kparams.ProcessID, Type: kparams.PID, Value: uint32(1023)}, kparams.ImageCheckSum: {Name: kparams.ImageCheckSum, Type: kparams.Uint32, Value: uint32(2323432)}, kparams.ImageBase: {Name: kparams.ImageBase, Type: kparams.Address, Value: uint64(0x7ffb313833a3)}, @@ -770,7 +772,8 @@ func TestImageFilter(t *testing.T) { {`image.signature.type = 'EMBEDDED'`, true}, {`image.signature.level = 'AUTHENTICODE'`, true}, {`image.pid = 1023`, true}, - {`image.name endswith 'kernel32.dll'`, 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}, @@ -802,7 +805,7 @@ func TestImageFilter(t *testing.T) { Type: ktypes.LoadImage, Category: ktypes.Image, Kparams: kevent.Kparams{ - kparams.ImageFilename: {Name: kparams.ImageFilename, Type: kparams.UnicodeString, Value: filepath.Join(os.Getenv("windir"), "System32", "kernel32.dll")}, + kparams.ImagePath: {Name: kparams.ImagePath, Type: kparams.UnicodeString, Value: filepath.Join(os.Getenv("windir"), "System32", "kernel32.dll")}, kparams.ProcessID: {Name: kparams.ProcessID, Type: kparams.PID, Value: uint32(1023)}, kparams.ImageCheckSum: {Name: kparams.ImageCheckSum, Type: kparams.Uint32, Value: uint32(2323432)}, kparams.ImageBase: {Name: kparams.ImageBase, Type: kparams.Address, Value: uint64(0x7ccb313833a3)}, @@ -844,7 +847,7 @@ func TestImageFilter(t *testing.T) { Type: ktypes.LoadImage, Category: ktypes.Image, Kparams: kevent.Kparams{ - kparams.ImageFilename: {Name: kparams.ImageFilename, Type: kparams.UnicodeString, Value: "_fixtures\\mscorlib.dll"}, + kparams.ImagePath: {Name: kparams.ImagePath, Type: kparams.UnicodeString, Value: "_fixtures\\mscorlib.dll"}, kparams.ProcessID: {Name: kparams.ProcessID, Type: kparams.PID, Value: uint32(1023)}, kparams.ImageCheckSum: {Name: kparams.ImageCheckSum, Type: kparams.Uint32, Value: uint32(2323432)}, kparams.ImageBase: {Name: kparams.ImageBase, Type: kparams.Address, Value: uint64(0xfff313833a3)}, @@ -933,7 +936,7 @@ func TestLazyPEFilter(t *testing.T) { }, Kparams: kevent.Kparams{ kparams.FileIsDLL: {Name: kparams.FileIsDLL, Type: kparams.Bool, Value: true}, - kparams.FileName: {Name: kparams.FileName, Type: kparams.UnicodeString, Value: "C:\\Windows\\system32\\user32.dll"}, + kparams.FilePath: {Name: kparams.FilePath, Type: kparams.UnicodeString, Value: "C:\\Windows\\system32\\user32.dll"}, }, } @@ -1104,7 +1107,7 @@ func TestInterpolateFields(t *testing.T) { { original: `Detected an attempt by %1.ps.name process to access and read the memory of the Local Security And Authority Subsystem Service -and subsequently write the %2.file.name dump file to the disk device`, +and subsequently write the %2.file.path dump file to the disk device`, interpolated: `Detected an attempt by taskmgr.exe process to access and read the memory of the Local Security And Authority Subsystem Service and subsequently write the C:\Users @@ -1127,7 +1130,7 @@ eo\Temp\lsass.dump dump file to the disk device`, Name: "WriteFile", PID: 1023, Kparams: kevent.Kparams{ - kparams.FileName: {Name: kparams.FileName, Type: kparams.UnicodeString, Value: "C:\\Users\neo\\Temp\\lsass.dump"}, + kparams.FilePath: {Name: kparams.FilePath, Type: kparams.UnicodeString, Value: "C:\\Users\neo\\Temp\\lsass.dump"}, }, PS: &pstypes.PS{ Name: "taskmgr.exe", @@ -1140,7 +1143,7 @@ eo\Temp\lsass.dump dump file to the disk device`, { original: `Detected an attempt by %ps.name process to access and read the memory of the Local Security And Authority Subsystem Service -and subsequently write the %2.file.name dump file to the disk device`, +and subsequently write the %2.file.path dump file to the disk device`, interpolated: `Detected an attempt by taskmgr.exe process to access and read the memory of the Local Security And Authority Subsystem Service and subsequently write the C:\Users @@ -1163,7 +1166,7 @@ eo\Temp\lsass.dump dump file to the disk device`, Name: "WriteFile", PID: 1023, Kparams: kevent.Kparams{ - kparams.FileName: {Name: kparams.FileName, Type: kparams.UnicodeString, Value: "C:\\Users\neo\\Temp\\lsass.dump"}, + kparams.FilePath: {Name: kparams.FilePath, Type: kparams.UnicodeString, Value: "C:\\Users\neo\\Temp\\lsass.dump"}, }, PS: &pstypes.PS{ Name: "taskmgr.exe", diff --git a/pkg/filter/rules_test.go b/pkg/filter/rules_test.go index 2a466271a..c698f38f8 100644 --- a/pkg/filter/rules_test.go +++ b/pkg/filter/rules_test.go @@ -200,7 +200,7 @@ func TestSequenceState(t *testing.T) { Exe: "C:\\Windows\\system32\\svchost.exe", }, Kparams: kevent.Kparams{ - kparams.FileName: {Name: kparams.FileName, Type: kparams.UnicodeString, Value: "C:\\Temp\\dropper"}, + kparams.FilePath: {Name: kparams.FilePath, Type: kparams.UnicodeString, Value: "C:\\Temp\\dropper"}, }, } @@ -220,10 +220,10 @@ func TestSequenceState(t *testing.T) { ss.addPartial("kevt.name = CreateProcess AND ps.name = cmd.exe", e1, false) require.NoError(t, ss.matchTransition("kevt.name = CreateProcess AND ps.name = cmd.exe", e1)) assert.False(t, ss.isInitialState()) - assert.Equal(t, "kevt.name = CreateFile AND file.name ICONTAINS temp", ss.currentState()) + assert.Equal(t, "kevt.name = CreateFile AND file.path ICONTAINS temp", ss.currentState()) - ss.addPartial("kevt.name = CreateFile AND file.name ICONTAINS temp", e2, false) - require.NoError(t, ss.matchTransition("kevt.name = CreateFile AND file.name ICONTAINS temp", e2)) + ss.addPartial("kevt.name = CreateFile AND file.path ICONTAINS temp", e2, false) + require.NoError(t, ss.matchTransition("kevt.name = CreateFile AND file.path ICONTAINS temp", e2)) assert.Len(t, ss.partials[1], 1) assert.Len(t, ss.partials[2], 1) @@ -237,7 +237,7 @@ func TestSequenceState(t *testing.T) { assert.Equal(t, "kevt.name = CreateProcess AND ps.name = cmd.exe", ss.currentState()) // deadline exceeded require.NoError(t, ss.matchTransition("kevt.name = CreateProcess AND ps.name = cmd.exe", e1)) - assert.Equal(t, "kevt.name = CreateFile AND file.name ICONTAINS temp", ss.currentState()) + assert.Equal(t, "kevt.name = CreateFile AND file.path ICONTAINS temp", ss.currentState()) time.Sleep(time.Millisecond * 120) assert.True(t, ss.isInitialState()) @@ -245,14 +245,14 @@ func TestSequenceState(t *testing.T) { require.False(t, ss.next(1)) if ss.next(1) { // this shouldn't happen - require.NoError(t, ss.matchTransition("kevt.name = CreateFile AND file.name ICONTAINS temp", e2)) + require.NoError(t, ss.matchTransition("kevt.name = CreateFile AND file.path ICONTAINS temp", e2)) } ss.clear() assert.True(t, ss.isInitialState()) require.NoError(t, ss.matchTransition("kevt.name = CreateProcess AND ps.name = cmd.exe", e1)) ss.addPartial("kevt.name = CreateProcess AND ps.name = cmd.exe", e2, false) - ss.addPartial("kevt.name = CreateFile AND file.name ICONTAINS temp", e2, false) + ss.addPartial("kevt.name = CreateFile AND file.path ICONTAINS temp", e2, false) require.False(t, ss.inDeadline.Load()) // test expiration @@ -277,7 +277,7 @@ func TestSequenceState(t *testing.T) { require.NoError(t, ss.matchTransition("kevt.name = CreateProcess AND ps.name = cmd.exe", e1)) require.False(t, ss.inExpired.Load()) - assert.Equal(t, "kevt.name = CreateFile AND file.name ICONTAINS temp", ss.currentState()) + assert.Equal(t, "kevt.name = CreateFile AND file.path ICONTAINS temp", ss.currentState()) } func TestSequenceStateNext(t *testing.T) { @@ -411,7 +411,7 @@ func TestSimpleSequenceRule(t *testing.T) { Exe: "C:\\Windows\\system32\\svchost.exe", }, Kparams: kevent.Kparams{ - kparams.FileName: {Name: kparams.FileName, Type: kparams.UnicodeString, Value: "C:\\Windows\\system32\\svchost-temp.exe"}, + kparams.FilePath: {Name: kparams.FilePath, Type: kparams.UnicodeString, Value: "C:\\Windows\\system32\\svchost-temp.exe"}, }, Metadata: map[kevent.MetadataKey]any{"foo": "bar", "fooz": "barzz"}, } @@ -459,7 +459,7 @@ func TestSimpleSequenceRuleMultiplePartials(t *testing.T) { Exe: "C:\\Windows\\system32\\cmd.exe", }, Kparams: kevent.Kparams{ - kparams.FileName: {Name: kparams.FileName, Type: kparams.UnicodeString, Value: "C:\\Windows\\system32\\svchost-temp.exe"}, + kparams.FilePath: {Name: kparams.FilePath, Type: kparams.UnicodeString, Value: "C:\\Windows\\system32\\svchost-temp.exe"}, }, Metadata: map[kevent.MetadataKey]any{"foo": "bar", "fooz": "barzz"}, } @@ -500,7 +500,7 @@ func TestSimpleSequenceRuleMultiplePartials(t *testing.T) { Exe: "C:\\Windows\\system32\\svchost.exe", }, Kparams: kevent.Kparams{ - kparams.FileName: {Name: kparams.FileName, Type: kparams.UnicodeString, Value: "C:\\Windows\\system32\\svchost-temp.exe"}, + kparams.FilePath: {Name: kparams.FilePath, Type: kparams.UnicodeString, Value: "C:\\Windows\\system32\\svchost-temp.exe"}, }, Metadata: map[kevent.MetadataKey]any{"foo": "bar", "fooz": "barzz"}, } @@ -543,7 +543,7 @@ func TestSimpleSequenceRuleWithMaxSpanReached(t *testing.T) { Exe: "C:\\Windows\\system32\\svchost.exe", }, Kparams: kevent.Kparams{ - kparams.FileName: {Name: kparams.FileName, Type: kparams.UnicodeString, Value: "C:\\Temp\\dropper"}, + kparams.FilePath: {Name: kparams.FilePath, Type: kparams.UnicodeString, Value: "C:\\Temp\\dropper"}, }, Metadata: map[kevent.MetadataKey]any{"foo": "bar", "fooz": "barzz"}, } @@ -592,7 +592,7 @@ func TestSimpleSequencePolicyWithMaxSpanNotReached(t *testing.T) { Exe: "C:\\Windows\\system32\\svchost.exe", }, Kparams: kevent.Kparams{ - kparams.FileName: {Name: kparams.FileName, Type: kparams.UnicodeString, Value: "C:\\Temp\\dropper"}, + kparams.FilePath: {Name: kparams.FilePath, Type: kparams.UnicodeString, Value: "C:\\Temp\\dropper"}, }, Metadata: map[kevent.MetadataKey]any{"foo": "bar", "fooz": "barzz"}, } @@ -640,7 +640,7 @@ func TestComplexSequenceRule(t *testing.T) { Cmdline: "C:\\Program Files\\Mozilla Firefox\\firefox.exe\" -contentproc --channel=\"10464.7.539748228\\1366525930\" -childID 6 -isF", }, Kparams: kevent.Kparams{ - kparams.FileName: {Name: kparams.FileName, Type: kparams.UnicodeString, Value: "C:\\Temp\\dropper.exe"}, + kparams.FilePath: {Name: kparams.FilePath, Type: kparams.UnicodeString, Value: "C:\\Temp\\dropper.exe"}, kparams.FileOperation: {Name: kparams.FileOperation, Type: kparams.Enum, Value: uint32(2), Enum: fs.FileCreateDispositions}, }, Metadata: map[kevent.MetadataKey]any{"foo": "bar", "fooz": "barzz"}, @@ -736,7 +736,7 @@ func TestSequencePsUUID(t *testing.T) { Cmdline: "C:\\Program Files\\Mozilla Firefox\\firefox.exe\" -contentproc --channel=\"10464.7.539748228\\1366525930\" -childID 6 -isF", }, Kparams: kevent.Kparams{ - kparams.FileName: {Name: kparams.FileName, Type: kparams.UnicodeString, Value: "C:\\Temp\\dropper.exe"}, + kparams.FilePath: {Name: kparams.FilePath, Type: kparams.UnicodeString, Value: "C:\\Temp\\dropper.exe"}, kparams.FileOperation: {Name: kparams.FileOperation, Type: kparams.Enum, Value: uint32(2), Enum: fs.FileCreateDispositions}, }, Metadata: map[kevent.MetadataKey]any{"foo": "bar", "fooz": "barzz"}, @@ -783,7 +783,7 @@ func TestSequenceOutOfOrder(t *testing.T) { Exe: "C:\\Windows\\system32\\svchost.exe", }, Kparams: kevent.Kparams{ - kparams.FileName: {Name: kparams.FileName, Type: kparams.UnicodeString, Value: "C:\\Windows\\system32\\lsass.dmp"}, + kparams.FilePath: {Name: kparams.FilePath, Type: kparams.UnicodeString, Value: "C:\\Windows\\system32\\lsass.dmp"}, kparams.FileOperation: {Name: kparams.FileOperation, Type: kparams.Enum, Value: uint32(2), Enum: fs.FileCreateDispositions}, }, Metadata: map[kevent.MetadataKey]any{"foo": "bar", "fooz": "barzz"}, @@ -875,7 +875,7 @@ func TestSequenceAndSimpleRuleMix(t *testing.T) { Exe: "C:\\Windows\\system32\\cmd.exe", }, Kparams: kevent.Kparams{ - kparams.FileName: {Name: kparams.FileName, Type: kparams.UnicodeString, Value: "C:\\Temp\\dropper.exe"}, + kparams.FilePath: {Name: kparams.FilePath, Type: kparams.UnicodeString, Value: "C:\\Temp\\dropper.exe"}, kparams.FileOperation: {Name: kparams.FileOperation, Type: kparams.Enum, Value: uint32(2)}, }, Metadata: map[kevent.MetadataKey]any{"foo": "bar", "fooz": "barzz"}, @@ -958,7 +958,7 @@ func TestSequenceRuleBoundsFields(t *testing.T) { SID: "nusret", }, Kparams: kevent.Kparams{ - kparams.FileName: {Name: kparams.FileName, Type: kparams.UnicodeString, Value: "C:\\Windows\\system32\\svchost-temp.exe"}, + kparams.FilePath: {Name: kparams.FilePath, Type: kparams.UnicodeString, Value: "C:\\Windows\\system32\\svchost-temp.exe"}, }, Metadata: map[kevent.MetadataKey]any{"foo": "bar", "fooz": "barzz"}, } @@ -1052,7 +1052,7 @@ func TestIsExpressionEvaluable(t *testing.T) { Exe: "C:\\Windows\\system32\\svchost.exe", }, Kparams: kevent.Kparams{ - kparams.FileName: {Name: kparams.FileName, Type: kparams.UnicodeString, Value: "C:\\Temp\\dropper"}, + kparams.FilePath: {Name: kparams.FilePath, Type: kparams.UnicodeString, Value: "C:\\Temp\\dropper"}, }, Metadata: map[kevent.MetadataKey]any{"foo": "bar", "fooz": "barzz"}, } @@ -1083,7 +1083,7 @@ func TestBoundFieldsWithFunctions(t *testing.T) { Exe: "C:\\Windows\\system32\\cmd.exe", }, Kparams: kevent.Kparams{ - kparams.FileName: {Name: kparams.FileName, Type: kparams.UnicodeString, Value: "C:\\Windows\\System32\\passwdflt.dll"}, + kparams.FilePath: {Name: kparams.FilePath, Type: kparams.UnicodeString, Value: "C:\\Windows\\System32\\passwdflt.dll"}, }, Metadata: map[kevent.MetadataKey]any{"foo": "bar", "fooz": "barzz"}, } @@ -1099,7 +1099,7 @@ func TestBoundFieldsWithFunctions(t *testing.T) { Exe: "C:\\Windows\\system32\\cmd.exe", }, Kparams: kevent.Kparams{ - kparams.RegKeyName: {Name: kparams.RegKeyName, Type: kparams.UnicodeString, Value: "HKEY_CURRENT_USER\\Volatile Environment\\Notification Packages"}, + kparams.RegPath: {Name: kparams.RegPath, Type: kparams.UnicodeString, Value: "HKEY_CURRENT_USER\\Volatile Environment\\Notification Packages"}, }, Metadata: map[kevent.MetadataKey]any{"foo": "bar", "fooz": "barzz"}, } diff --git a/pkg/kcap/reader_windows.go b/pkg/kcap/reader_windows.go index a01a97f90..3c2d95950 100644 --- a/pkg/kcap/reader_windows.go +++ b/pkg/kcap/reader_windows.go @@ -191,7 +191,7 @@ func (r *reader) updateSnapshotters(kevt *kevent.Kevent) error { } case ktypes.UnloadImage: pid := kevt.Kparams.MustGetPid() - mod := kevt.GetParamAsString(kparams.ImageFilename) + mod := kevt.GetParamAsString(kparams.ImagePath) if err := r.psnapshotter.RemoveModule(pid, mod); err != nil { return err } diff --git a/pkg/kcap/writer_windows_test.go b/pkg/kcap/writer_windows_test.go index 88e189d21..582569ebb 100644 --- a/pkg/kcap/writer_windows_test.go +++ b/pkg/kcap/writer_windows_test.go @@ -79,7 +79,7 @@ func TestWrite(t *testing.T) { Description: "Creates or opens a new file, directory, I/O device, pipe, console", Kparams: kevent.Kparams{ kparams.FileObject: {Name: kparams.FileObject, Type: kparams.Uint64, Value: uint64(12456738026482168384)}, - kparams.FileName: {Name: kparams.FileName, Type: kparams.UnicodeString, Value: "\\Device\\HarddiskVolume2\\Windows\\system32\\user32.dll"}, + kparams.FilePath: {Name: kparams.FilePath, Type: kparams.UnicodeString, Value: "\\Device\\HarddiskVolume2\\Windows\\system32\\user32.dll"}, kparams.FileType: {Name: kparams.FileType, Type: kparams.AnsiString, Value: "file"}, kparams.FileOperation: {Name: kparams.FileOperation, Type: kparams.AnsiString, Value: "open"}, }, diff --git a/pkg/kevent/batch_test.go b/pkg/kevent/batch_test.go index 1ad7f19e4..41960b6e4 100644 --- a/pkg/kevent/batch_test.go +++ b/pkg/kevent/batch_test.go @@ -46,7 +46,7 @@ func TestBatchMarshalJSON(t *testing.T) { Description: "Creates or opens a new file, directory, I/O device, pipe, console", Kparams: Kparams{ kparams.FileObject: {Name: kparams.FileObject, Type: kparams.Uint64, Value: uint64(12456738026482168384)}, - kparams.FileName: {Name: kparams.FileName, Type: kparams.UnicodeString, Value: "\\Device\\HarddiskVolume2\\Windows\\system32\\user32.dll"}, + kparams.FilePath: {Name: kparams.FilePath, Type: kparams.UnicodeString, Value: "\\Device\\HarddiskVolume2\\Windows\\system32\\user32.dll"}, kparams.FileType: {Name: kparams.FileType, Type: kparams.AnsiString, Value: "file"}, kparams.FileOperation: {Name: kparams.FileOperation, Type: kparams.AnsiString, Value: "open"}, kparams.BasePrio: {Name: kparams.BasePrio, Type: kparams.Int8, Value: int8(2)}, @@ -114,7 +114,7 @@ func TestBatchMarshalJSON(t *testing.T) { Description: "Creates or opens a new file, directory, I/O device, pipe, console", Kparams: Kparams{ kparams.FileObject: {Name: kparams.FileObject, Type: kparams.Uint64, Value: uint64(12456738026482168384)}, - kparams.FileName: {Name: kparams.FileName, Type: kparams.UnicodeString, Value: "\\Device\\HarddiskVolume2\\Windows\\system32\\user32.dll"}, + kparams.FilePath: {Name: kparams.FilePath, Type: kparams.UnicodeString, Value: "\\Device\\HarddiskVolume2\\Windows\\system32\\user32.dll"}, kparams.FileType: {Name: kparams.FileType, Type: kparams.AnsiString, Value: "file"}, kparams.FileOperation: {Name: kparams.FileOperation, Type: kparams.AnsiString, Value: "open"}, kparams.BasePrio: {Name: kparams.BasePrio, Type: kparams.Int8, Value: int8(2)}, @@ -182,7 +182,7 @@ func TestBatchMarshalJSON(t *testing.T) { Description: "Creates or opens a new file, directory, I/O device, pipe, console", Kparams: Kparams{ kparams.FileObject: {Name: kparams.FileObject, Type: kparams.Uint64, Value: uint64(12456738026482168384)}, - kparams.FileName: {Name: kparams.FileName, Type: kparams.UnicodeString, Value: "\\Device\\HarddiskVolume2\\Windows\\system32\\user32.dll"}, + kparams.FilePath: {Name: kparams.FilePath, Type: kparams.UnicodeString, Value: "\\Device\\HarddiskVolume2\\Windows\\system32\\user32.dll"}, kparams.FileType: {Name: kparams.FileType, Type: kparams.AnsiString, Value: "file"}, kparams.FileOperation: {Name: kparams.FileOperation, Type: kparams.AnsiString, Value: "open"}, kparams.BasePrio: {Name: kparams.BasePrio, Type: kparams.Int8, Value: int8(2)}, diff --git a/pkg/kevent/callstack_test.go b/pkg/kevent/callstack_test.go index 0d6f46f08..656bd056b 100644 --- a/pkg/kevent/callstack_test.go +++ b/pkg/kevent/callstack_test.go @@ -40,7 +40,7 @@ func TestCallstack(t *testing.T) { Category: ktypes.File, Kparams: Kparams{ kparams.FileObject: {Name: kparams.FileObject, Type: kparams.Uint64, Value: uint64(12456738026482168384)}, - kparams.FileName: {Name: kparams.FileName, Type: kparams.UnicodeString, Value: "C:\\Windows\\system32\\user32.dll"}, + kparams.FilePath: {Name: kparams.FilePath, Type: kparams.UnicodeString, Value: "C:\\Windows\\system32\\user32.dll"}, kparams.FileType: {Name: kparams.FileType, Type: kparams.AnsiString, Value: "file"}, kparams.FileOperation: {Name: kparams.FileOperation, Type: kparams.Enum, Value: uint32(1), Enum: fs.FileCreateDispositions}, }, @@ -77,7 +77,7 @@ func TestCallstackDecorator(t *testing.T) { Category: ktypes.File, Kparams: Kparams{ kparams.FileObject: {Name: kparams.FileObject, Type: kparams.Uint64, Value: uint64(12456738026482168384)}, - kparams.FileName: {Name: kparams.FileName, Type: kparams.UnicodeString, Value: "C:\\Windows\\system32\\user32.dll"}, + kparams.FilePath: {Name: kparams.FilePath, Type: kparams.UnicodeString, Value: "C:\\Windows\\system32\\user32.dll"}, kparams.FileType: {Name: kparams.FileType, Type: kparams.AnsiString, Value: "file"}, kparams.FileOperation: {Name: kparams.FileOperation, Type: kparams.Enum, Value: uint32(1), Enum: fs.FileCreateDispositions}, }, @@ -94,7 +94,7 @@ func TestCallstackDecorator(t *testing.T) { Category: ktypes.File, Kparams: Kparams{ kparams.FileObject: {Name: kparams.FileObject, Type: kparams.Uint64, Value: uint64(12456738026482168384)}, - kparams.FileName: {Name: kparams.FileName, Type: kparams.UnicodeString, Value: "C:\\Windows\\system32\\kernel32.dll"}, + kparams.FilePath: {Name: kparams.FilePath, Type: kparams.UnicodeString, Value: "C:\\Windows\\system32\\kernel32.dll"}, kparams.FileType: {Name: kparams.FileType, Type: kparams.AnsiString, Value: "file"}, kparams.FileOperation: {Name: kparams.FileOperation, Type: kparams.Enum, Value: uint32(1), Enum: fs.FileCreateDispositions}, }, @@ -122,7 +122,7 @@ func TestCallstackDecorator(t *testing.T) { assert.True(t, cd.deq.Len() == 1) assert.Equal(t, ktypes.CreateFile, evt.Type) assert.True(t, evt.Kparams.Contains(kparams.Callstack)) - assert.Equal(t, "C:\\Windows\\system32\\user32.dll", evt.GetParamAsString(kparams.FileName)) + assert.Equal(t, "C:\\Windows\\system32\\user32.dll", evt.GetParamAsString(kparams.FilePath)) } func init() { @@ -147,7 +147,7 @@ func TestCallstackDecoratorFlush(t *testing.T) { Category: ktypes.File, Kparams: Kparams{ kparams.FileObject: {Name: kparams.FileObject, Type: kparams.Uint64, Value: uint64(12456738026482168384)}, - kparams.FileName: {Name: kparams.FileName, Type: kparams.UnicodeString, Value: "C:\\Windows\\system32\\user32.dll"}, + kparams.FilePath: {Name: kparams.FilePath, Type: kparams.UnicodeString, Value: "C:\\Windows\\system32\\user32.dll"}, kparams.FileType: {Name: kparams.FileType, Type: kparams.AnsiString, Value: "file"}, kparams.FileOperation: {Name: kparams.FileOperation, Type: kparams.Enum, Value: uint32(1), Enum: fs.FileCreateDispositions}, }, diff --git a/pkg/kevent/kevent_windows.go b/pkg/kevent/kevent_windows.go index e4f8f83e8..0d0fdde27 100644 --- a/pkg/kevent/kevent_windows.go +++ b/pkg/kevent/kevent_windows.go @@ -281,7 +281,7 @@ func (e *Kevent) RundownKey() uint64 { return hashers.FnvUint64(b) case ktypes.ImageRundown: pid, _ := e.Kparams.GetPid() - mod, _ := e.Kparams.GetString(kparams.ImageFilename) + mod, _ := e.Kparams.GetString(kparams.ImagePath) b := make([]byte, 4+len(mod)) binary.LittleEndian.PutUint32(b, pid) @@ -302,7 +302,7 @@ func (e *Kevent) RundownKey() uint64 { return hashers.FnvUint64(b) case ktypes.RegKCBRundown: - key, _ := e.Kparams.GetString(kparams.RegKeyName) + key, _ := e.Kparams.GetString(kparams.RegPath) b := make([]byte, 4+len(key)) binary.LittleEndian.PutUint32(b, e.PID) @@ -323,7 +323,7 @@ func (e *Kevent) PartialKey() uint64 { case ktypes.MapViewFile, ktypes.UnmapViewFile: return e.Kparams.MustGetUint64(kparams.FileViewBase) + uint64(e.PID) case ktypes.CreateFile: - file, _ := e.Kparams.GetString(kparams.FileName) + file, _ := e.Kparams.GetString(kparams.FilePath) b := make([]byte, 4+len(file)) binary.LittleEndian.PutUint32(b, e.PID) b = append(b, []byte(file)...) @@ -373,7 +373,7 @@ func (e *Kevent) PartialKey() uint64 { case ktypes.RegOpenKey, ktypes.RegQueryKey, ktypes.RegQueryValue, ktypes.RegDeleteKey, ktypes.RegDeleteValue, ktypes.RegSetValue, ktypes.RegCloseKey: - key, _ := e.Kparams.GetString(kparams.RegKeyName) + key, _ := e.Kparams.GetString(kparams.RegPath) b := make([]byte, 4+len(key)) binary.LittleEndian.PutUint32(b, e.PID) b = append(b, key...) @@ -407,8 +407,8 @@ func (e *Kevent) BacklogKey() uint64 { func (e *Kevent) CopyState(evt *Kevent) { switch evt.Type { case ktypes.CloseHandle: - if evt.Kparams.Contains(kparams.ImageFilename) { - e.Kparams.Append(kparams.ImageFilename, kparams.UnicodeString, evt.GetParamAsString(kparams.ImageFilename)) + if evt.Kparams.Contains(kparams.ImagePath) { + e.Kparams.Append(kparams.ImagePath, kparams.UnicodeString, evt.GetParamAsString(kparams.ImagePath)) } _ = e.Kparams.SetValue(kparams.HandleObjectName, evt.GetParamAsString(kparams.HandleObjectName)) } @@ -447,63 +447,63 @@ func (e *Kevent) Summary() string { return printSummary(e, fmt.Sprintf("opened %s process' thread object with %s access right(s)", exe, access)) case ktypes.LoadImage: - filename := e.GetParamAsString(kparams.FileName) + filename := e.GetParamAsString(kparams.FilePath) return printSummary(e, fmt.Sprintf("loaded %s module", filename)) case ktypes.UnloadImage: - filename := e.GetParamAsString(kparams.FileName) + filename := e.GetParamAsString(kparams.FilePath) return printSummary(e, fmt.Sprintf("unloaded %s module", filename)) case ktypes.CreateFile: op := e.GetParamAsString(kparams.FileOperation) - filename := e.GetParamAsString(kparams.FileName) + filename := e.GetParamAsString(kparams.FilePath) return printSummary(e, fmt.Sprintf("%sed a file %s", strings.ToLower(op), filename)) case ktypes.ReadFile: - filename := e.GetParamAsString(kparams.FileName) + filename := e.GetParamAsString(kparams.FilePath) size, _ := e.Kparams.GetUint32(kparams.FileIoSize) return printSummary(e, fmt.Sprintf("read %d bytes from %s file", size, filename)) case ktypes.WriteFile: - filename := e.GetParamAsString(kparams.FileName) + filename := e.GetParamAsString(kparams.FilePath) size, _ := e.Kparams.GetUint32(kparams.FileIoSize) return printSummary(e, fmt.Sprintf("wrote %d bytes to %s file", size, filename)) case ktypes.SetFileInformation: - filename := e.GetParamAsString(kparams.FileName) + filename := e.GetParamAsString(kparams.FilePath) class := e.GetParamAsString(kparams.FileInfoClass) return printSummary(e, fmt.Sprintf("set %s information class on %s file", class, filename)) case ktypes.DeleteFile: - filename := e.GetParamAsString(kparams.FileName) + filename := e.GetParamAsString(kparams.FilePath) return printSummary(e, fmt.Sprintf("deleted %s file", filename)) case ktypes.RenameFile: - filename := e.GetParamAsString(kparams.FileName) + filename := e.GetParamAsString(kparams.FilePath) return printSummary(e, fmt.Sprintf("renamed %s file", filename)) case ktypes.CloseFile: - filename := e.GetParamAsString(kparams.FileName) + filename := e.GetParamAsString(kparams.FilePath) return printSummary(e, fmt.Sprintf("closed %s file", filename)) case ktypes.EnumDirectory: - filename := e.GetParamAsString(kparams.FileName) + filename := e.GetParamAsString(kparams.FilePath) return printSummary(e, fmt.Sprintf("enumerated %s directory", filename)) case ktypes.RegCreateKey: - key := e.GetParamAsString(kparams.RegKeyName) + key := e.GetParamAsString(kparams.RegPath) return printSummary(e, fmt.Sprintf("created %s key", key)) case ktypes.RegOpenKey: - key := e.GetParamAsString(kparams.RegKeyName) + key := e.GetParamAsString(kparams.RegPath) return printSummary(e, fmt.Sprintf("opened %s key", key)) case ktypes.RegDeleteKey: - key := e.GetParamAsString(kparams.RegKeyName) + key := e.GetParamAsString(kparams.RegPath) return printSummary(e, fmt.Sprintf("deleted %s key", key)) case ktypes.RegQueryKey: - key := e.GetParamAsString(kparams.RegKeyName) + key := e.GetParamAsString(kparams.RegPath) return printSummary(e, fmt.Sprintf("queried %s key", key)) case ktypes.RegSetValue: - key := e.GetParamAsString(kparams.RegKeyName) + key := e.GetParamAsString(kparams.RegPath) val, err := e.Kparams.GetString(kparams.RegValue) if err != nil { return printSummary(e, fmt.Sprintf("set %s value", key)) } return printSummary(e, fmt.Sprintf("set %s payload in %s value", val, key)) case ktypes.RegDeleteValue: - key := e.GetParamAsString(kparams.RegKeyName) + key := e.GetParamAsString(kparams.RegPath) return printSummary(e, fmt.Sprintf("deleted %s value", key)) case ktypes.RegQueryValue: - key := e.GetParamAsString(kparams.RegKeyName) + key := e.GetParamAsString(kparams.RegPath) return printSummary(e, fmt.Sprintf("queried %s value", key)) case ktypes.AcceptTCPv4, ktypes.AcceptTCPv6: ip, _ := e.Kparams.GetIP(kparams.NetSIP) diff --git a/pkg/kevent/kevent_windows_test.go b/pkg/kevent/kevent_windows_test.go index f47cb0175..4347b3649 100644 --- a/pkg/kevent/kevent_windows_test.go +++ b/pkg/kevent/kevent_windows_test.go @@ -57,7 +57,7 @@ func TestKeventSummary(t *testing.T) { Description: "Creates or opens a new file, directory, I/O device, pipe, console", Kparams: Kparams{ kparams.FileObject: {Name: kparams.FileObject, Type: kparams.Uint64, Value: uint64(12456738026482168384)}, - kparams.FileName: {Name: kparams.FileName, Type: kparams.UnicodeString, Value: "C:\\Windows\\system32\\user32.dll"}, + kparams.FilePath: {Name: kparams.FilePath, Type: kparams.UnicodeString, Value: "C:\\Windows\\system32\\user32.dll"}, kparams.FileType: {Name: kparams.FileType, Type: kparams.AnsiString, Value: "file"}, kparams.FileOperation: {Name: kparams.FileOperation, Type: kparams.Enum, Value: uint32(1), Enum: fs.FileCreateDispositions}, }, @@ -104,11 +104,11 @@ func TestPartialKey(t *testing.T) { 0x4cf5, }, { - &Kevent{Type: ktypes.CreateFile, PID: 4321, Kparams: Kparams{kparams.FileName: {Name: kparams.FileName, Type: kparams.FileDosPath, Value: "C:\\Windows\\System32\\kernelbase.dll"}}}, + &Kevent{Type: ktypes.CreateFile, PID: 4321, Kparams: Kparams{kparams.FilePath: {Name: kparams.FilePath, Type: kparams.DOSPath, Value: "C:\\Windows\\System32\\kernelbase.dll"}}}, 0x7ec254f31df879ec, }, { - &Kevent{Type: ktypes.CreateFile, PID: 4321, Kparams: Kparams{kparams.FileName: {Name: kparams.FileName, Type: kparams.FileDosPath, Value: "C:\\Windows\\System32\\kernel32.dll"}}}, + &Kevent{Type: ktypes.CreateFile, PID: 4321, Kparams: Kparams{kparams.FilePath: {Name: kparams.FilePath, Type: kparams.DOSPath, Value: "C:\\Windows\\System32\\kernel32.dll"}}}, 0xb6380d9159ccd174, }, } diff --git a/pkg/kevent/kparam.go b/pkg/kevent/kparam.go index 0178af6ca..1fab73fd9 100644 --- a/pkg/kevent/kparam.go +++ b/pkg/kevent/kparam.go @@ -107,7 +107,7 @@ type Kparam struct { // on the target where the capture is being taken. func (k Kparam) KcapType() kparams.Type { switch k.Type { - case kparams.HandleType, kparams.FileDosPath, kparams.Key: + case kparams.HandleType, kparams.DOSPath, kparams.Key: return kparams.UnicodeString default: return k.Type diff --git a/pkg/kevent/kparam_test.go b/pkg/kevent/kparam_test.go index 71c7fefca..b7b168f7b 100644 --- a/pkg/kevent/kparam_test.go +++ b/pkg/kevent/kparam_test.go @@ -30,14 +30,14 @@ func TestKparams(t *testing.T) { kparams.FileObject: {Name: kparams.FileObject, Type: kparams.Uint64, Value: uint64(18446738026482168384)}, kparams.ThreadID: {Name: kparams.ThreadID, Type: kparams.Uint32, Value: uint32(1484)}, kparams.FileCreateOptions: {Name: kparams.FileCreateOptions, Type: kparams.Uint32, Value: uint32(1223456)}, - kparams.FileName: {Name: kparams.FileName, Type: kparams.UnicodeString, Value: "\\Device\\HarddiskVolume2\\Windows\\system32\\kernel32.dll"}, + kparams.FilePath: {Name: kparams.FilePath, Type: kparams.UnicodeString, Value: "\\Device\\HarddiskVolume2\\Windows\\system32\\kernel32.dll"}, kparams.FileShareMask: {Name: kparams.FileShareMask, Type: kparams.Uint32, Value: uint32(5)}, } assert.True(t, kpars.Contains(kparams.FileObject)) assert.False(t, kpars.Contains(kparams.FileOffset)) - filename, err := kpars.GetString(kparams.FileName) + filename, err := kpars.GetString(kparams.FilePath) require.NoError(t, err) assert.Equal(t, "\\Device\\HarddiskVolume2\\Windows\\system32\\kernel32.dll", filename) @@ -53,8 +53,8 @@ func TestKparams(t *testing.T) { require.NoError(t, kpars.Set(kparams.FileShareMask, uint32(5), kparams.Enum)) - require.NoError(t, kpars.SetValue(kparams.FileName, "\\Device\\HarddiskVolume2\\Windows\\system32\\KERNEL32.dll")) - filename1, err := kpars.GetString(kparams.FileName) + require.NoError(t, kpars.SetValue(kparams.FilePath, "\\Device\\HarddiskVolume2\\Windows\\system32\\KERNEL32.dll")) + filename1, err := kpars.GetString(kparams.FilePath) require.NoError(t, err) assert.Equal(t, "\\Device\\HarddiskVolume2\\Windows\\system32\\KERNEL32.dll", filename1) } diff --git a/pkg/kevent/kparam_windows.go b/pkg/kevent/kparam_windows.go index a4ff13310..a91a31fdb 100644 --- a/pkg/kevent/kparam_windows.go +++ b/pkg/kevent/kparam_windows.go @@ -71,7 +71,7 @@ func (k Kparam) String() string { return "" } switch k.Type { - case kparams.UnicodeString, kparams.AnsiString, kparams.FilePath: + case kparams.UnicodeString, kparams.AnsiString, kparams.Path: return k.Value.(string) case kparams.SID, kparams.WbemSID: sid, err := getSID(&k) @@ -79,7 +79,7 @@ func (k Kparam) String() string { return "" } return sid.String() - case kparams.FileDosPath: + case kparams.DOSPath: return devMapper.Convert(k.Value.(string)) case kparams.Key: rootKey, keyName := key.Format(k.Value.(string)) @@ -395,7 +395,7 @@ func (e *Kevent) produceParams(evt *etw.EventRecord) { e.AppendParam(kparams.ImageDefaultBase, kparams.Address, defaultBase) e.AppendParam(kparams.ImageBase, kparams.Address, imageBase) e.AppendParam(kparams.ImageSize, kparams.Uint64, imageSize) - e.AppendParam(kparams.ImageFilename, kparams.FileDosPath, filename) + e.AppendParam(kparams.ImagePath, kparams.DOSPath, filename) e.AppendParam(kparams.ImageSignatureLevel, kparams.Enum, uint32(sigLevel), WithEnum(signature.Levels)) e.AppendParam(kparams.ImageSignatureType, kparams.Enum, uint32(sigType), WithEnum(signature.Types)) case ktypes.RegOpenKey, ktypes.RegCloseKey, @@ -422,7 +422,7 @@ func (e *Kevent) produceParams(evt *etw.EventRecord) { keyName = evt.ConsumeUTF16String(20) } e.AppendParam(kparams.RegKeyHandle, kparams.Address, keyHandle) - e.AppendParam(kparams.RegKeyName, kparams.Key, keyName) + e.AppendParam(kparams.RegPath, kparams.Key, keyName) e.AppendParam(kparams.NTStatus, kparams.Status, status) case ktypes.CreateFile: var ( @@ -452,7 +452,7 @@ func (e *Kevent) produceParams(evt *etw.EventRecord) { e.AppendParam(kparams.FileShareMask, kparams.Flags, shareAccess, WithFlags(FileShareModeFlags)) e.AppendParam(kparams.FileAttributes, kparams.Flags, fileAttributes, WithFlags(FileAttributeFlags)) e.AppendParam(kparams.FileCreateOptions, kparams.Flags, createOptions, WithFlags(FileCreateOptionsFlags)) - e.AppendParam(kparams.FileName, kparams.FileDosPath, filename) + e.AppendParam(kparams.FilePath, kparams.DOSPath, filename) case ktypes.FileOpEnd: var ( irp uint64 @@ -477,7 +477,7 @@ func (e *Kevent) produceParams(evt *etw.EventRecord) { filename = evt.ConsumeUTF16String(8) } e.AppendParam(kparams.FileObject, kparams.Address, fileObject) - e.AppendParam(kparams.FileName, kparams.FileDosPath, filename) + e.AppendParam(kparams.FilePath, kparams.DOSPath, filename) case ktypes.ReleaseFile, ktypes.CloseFile: var ( irp uint64 @@ -585,7 +585,7 @@ func (e *Kevent) produceParams(evt *etw.EventRecord) { e.AppendParam(kparams.FileObject, kparams.Address, fileObject) e.AppendParam(kparams.ThreadID, kparams.TID, tid) e.AppendParam(kparams.FileKey, kparams.Address, fileKey) - e.AppendParam(kparams.FileName, kparams.UnicodeString, filename) + e.AppendParam(kparams.FilePath, kparams.UnicodeString, filename) e.AppendParam(kparams.FileInfoClass, kparams.Enum, infoClass, WithEnum(fs.FileInfoClasses)) case ktypes.MapViewFile, ktypes.UnmapViewFile, ktypes.MapFileRundown: var ( diff --git a/pkg/kevent/kparams/fields_windows.go b/pkg/kevent/kparams/fields_windows.go index bdce9185a..9dcee0afa 100644 --- a/pkg/kevent/kparams/fields_windows.go +++ b/pkg/kevent/kparams/fields_windows.go @@ -87,8 +87,8 @@ const ( // FileObject determines the field name for the file object pointer. FileObject = "file_object" - // FileName represents the field that designates the absolute path of the file. - FileName = "file_name" + // FilePath represents the field that designates the absolute path of the file. + FilePath = "file_path" // FileCreateOptions is the field that represents the values passed in the CreateDispositions parameter to the NtCreateFile function. FileCreateOptions = "create_options" // FileOperation is the field that represents the values passed in the CreateOptions parameter to the NtCreateFile function. @@ -135,8 +135,8 @@ const ( // RegKeyHandle identifies the parameter name for the registry key handle. RegKeyHandle = "key_handle" - // RegKeyName represents the parameter name for the fully qualified key name. - RegKeyName = "key_name" + // RegPath represents the parameter name for the fully qualified key path. + RegPath = "key_path" // RegValue identifies the parameter name that contains the value RegValue = "value" // RegValueType identifies the parameter that represents registry value type e.g (DWORD, BINARY) @@ -150,8 +150,8 @@ const ( ImageCheckSum = "checksum" // ImageDefaultBase is the parameter name that represents image's base address. ImageDefaultBase = "default_address" - // ImageFilename is the parameter name that denotes file name and extension of the DLL/executable image. - ImageFilename = "file_name" + // ImagePath is the parameter name that denotes the file path and extension of the DLL/executable image. + ImagePath = "file_path" // ImageSignatureLevel is the parameter denoting the loaded module signature level. ImageSignatureLevel = "signature_level" // ImageSignatureType is the parameter denoting the loaded module signature type. diff --git a/pkg/kevent/kparams/types_windows.go b/pkg/kevent/kparams/types_windows.go index 0b69624f3..441cfa1f6 100644 --- a/pkg/kevent/kparams/types_windows.go +++ b/pkg/kevent/kparams/types_windows.go @@ -91,10 +91,10 @@ const ( Map // Object is the generic object type Object - // FileDosPath represents the file system path in DOS device notation - FileDosPath - // FilePath represents the file system path with normalized drive letter notation - FilePath + // DOSPath represents the file system path in DOS device notation + DOSPath + // Path represents the file system path with normalized drive letter notation + Path // Status represents the system error code message Status // Key represents the registry key diff --git a/pkg/kevent/marshaller_test.go b/pkg/kevent/marshaller_test.go index 33415bf9c..059266ebb 100644 --- a/pkg/kevent/marshaller_test.go +++ b/pkg/kevent/marshaller_test.go @@ -61,7 +61,7 @@ func TestMarshaller(t *testing.T) { Description: "Creates or opens a new file, directory, I/O device, pipe, console", Kparams: Kparams{ kparams.FileObject: {Name: kparams.FileObject, Type: kparams.Uint64, Value: uint64(12456738026482168384)}, - kparams.FileName: {Name: kparams.FileName, Type: kparams.UnicodeString, Value: "\\Device\\HarddiskVolume2\\Windows\\system32\\user32.dll"}, + kparams.FilePath: {Name: kparams.FilePath, Type: kparams.UnicodeString, Value: "\\Device\\HarddiskVolume2\\Windows\\system32\\user32.dll"}, kparams.FileType: {Name: kparams.FileType, Type: kparams.AnsiString, Value: "file"}, kparams.FileOperation: {Name: kparams.FileOperation, Type: kparams.AnsiString, Value: "open"}, kparams.BasePrio: {Name: kparams.BasePrio, Type: kparams.Int8, Value: int8(2)}, @@ -93,7 +93,7 @@ func TestMarshaller(t *testing.T) { assert.Len(t, clone.Kparams, 10) - filename, err := clone.Kparams.GetString(kparams.FileName) + filename, err := clone.Kparams.GetString(kparams.FilePath) require.NoError(t, err) assert.Equal(t, "\\Device\\HarddiskVolume2\\Windows\\system32\\user32.dll", filename) fileobject, err := clone.Kparams.GetUint64(kparams.FileObject) @@ -120,7 +120,7 @@ func TestKeventMarshalJSON(t *testing.T) { Description: "Creates or opens a new file, directory, I/O device, pipe, console", Kparams: Kparams{ kparams.FileObject: {Name: kparams.FileObject, Type: kparams.Uint64, Value: uint64(12456738026482168384)}, - kparams.FileName: {Name: kparams.FileName, Type: kparams.UnicodeString, Value: "\\Device\\HarddiskVolume2\\Windows\\system32\\user32.dll"}, + kparams.FilePath: {Name: kparams.FilePath, Type: kparams.UnicodeString, Value: "\\Device\\HarddiskVolume2\\Windows\\system32\\user32.dll"}, kparams.FileType: {Name: kparams.FileType, Type: kparams.AnsiString, Value: "file"}, kparams.FileOperation: {Name: kparams.FileOperation, Type: kparams.AnsiString, Value: "open"}, kparams.BasePrio: {Name: kparams.BasePrio, Type: kparams.Int8, Value: int8(2)}, @@ -236,7 +236,7 @@ func TestUnmarshalHugeHandles(t *testing.T) { Description: "Creates a new process", Kparams: Kparams{ kparams.FileObject: {Name: kparams.FileObject, Type: kparams.Uint64, Value: uint64(12456738026482168384)}, - kparams.FileName: {Name: kparams.FileName, Type: kparams.UnicodeString, Value: "\\Device\\HarddiskVolume2\\Windows\\system32\\user32.dll"}, + kparams.FilePath: {Name: kparams.FilePath, Type: kparams.UnicodeString, Value: "\\Device\\HarddiskVolume2\\Windows\\system32\\user32.dll"}, kparams.FileType: {Name: kparams.FileType, Type: kparams.AnsiString, Value: "file"}, kparams.FileOperation: {Name: kparams.FileOperation, Type: kparams.AnsiString, Value: "open"}, kparams.BasePrio: {Name: kparams.BasePrio, Type: kparams.Int8, Value: int8(2)}, @@ -298,7 +298,7 @@ func TestKeventMarshalJSONMultiple(t *testing.T) { Description: "Creates or opens a new file, directory, I/O device, pipe, console", Kparams: Kparams{ kparams.FileObject: {Name: kparams.FileObject, Type: kparams.Uint64, Value: uint64(12456738026482168384)}, - kparams.FileName: {Name: kparams.FileName, Type: kparams.UnicodeString, Value: "\\Device\\HarddiskVolume2\\Windows\\system32\\user32.dll"}, + kparams.FilePath: {Name: kparams.FilePath, Type: kparams.UnicodeString, Value: "\\Device\\HarddiskVolume2\\Windows\\system32\\user32.dll"}, kparams.FileType: {Name: kparams.FileType, Type: kparams.AnsiString, Value: "file"}, kparams.FileOperation: {Name: kparams.FileOperation, Type: kparams.AnsiString, Value: "open"}, kparams.BasePrio: {Name: kparams.BasePrio, Type: kparams.Int8, Value: int8(2)}, @@ -378,7 +378,7 @@ func BenchmarkKeventMarshalJSON(b *testing.B) { Description: "Creates or opens a new file, directory, I/O device, pipe, console", Kparams: Kparams{ kparams.FileObject: {Name: kparams.FileObject, Type: kparams.Uint64, Value: uint64(12456738026482168384)}, - kparams.FileName: {Name: kparams.FileName, Type: kparams.UnicodeString, Value: "\\Device\\HarddiskVolume2\\Windows\\system32\\user32.dll"}, + kparams.FilePath: {Name: kparams.FilePath, Type: kparams.UnicodeString, Value: "\\Device\\HarddiskVolume2\\Windows\\system32\\user32.dll"}, kparams.FileType: {Name: kparams.FileType, Type: kparams.AnsiString, Value: "file"}, kparams.FileOperation: {Name: kparams.FileOperation, Type: kparams.AnsiString, Value: "open"}, kparams.BasePrio: {Name: kparams.BasePrio, Type: kparams.Int8, Value: int8(2)}, @@ -462,7 +462,7 @@ func BenchmarkKeventMarshalJSONStdlib(b *testing.B) { Description: "Creates or opens a new file, directory, I/O device, pipe, console", Kparams: Kparams{ kparams.FileObject: {Name: kparams.FileObject, Type: kparams.Uint64, Value: uint64(12456738026482168384)}, - kparams.FileName: {Name: kparams.FileName, Type: kparams.UnicodeString, Value: "\\Device\\HarddiskVolume2\\Windows\\system32\\user32.dll"}, + kparams.FilePath: {Name: kparams.FilePath, Type: kparams.UnicodeString, Value: "\\Device\\HarddiskVolume2\\Windows\\system32\\user32.dll"}, kparams.FileType: {Name: kparams.FileType, Type: kparams.AnsiString, Value: "file"}, kparams.FileOperation: {Name: kparams.FileOperation, Type: kparams.AnsiString, Value: "open"}, kparams.BasePrio: {Name: kparams.BasePrio, Type: kparams.Int8, Value: int8(2)}, @@ -548,7 +548,7 @@ func BenchmarkMarshal(b *testing.B) { Description: "Creates or opens a new file, directory, I/O device, pipe, console", Kparams: Kparams{ kparams.FileObject: {Name: kparams.FileObject, Type: kparams.Uint64, Value: uint64(12456738026482168384)}, - kparams.FileName: {Name: kparams.FileName, Type: kparams.UnicodeString, Value: "\\Device\\HarddiskVolume2\\Windows\\system32\\user32.dll"}, + kparams.FilePath: {Name: kparams.FilePath, Type: kparams.UnicodeString, Value: "\\Device\\HarddiskVolume2\\Windows\\system32\\user32.dll"}, kparams.FileType: {Name: kparams.FileType, Type: kparams.AnsiString, Value: "file"}, kparams.FileOperation: {Name: kparams.FileOperation, Type: kparams.AnsiString, Value: "open"}, }, @@ -576,7 +576,7 @@ func BenchmarkUnmarshal(b *testing.B) { Description: "Creates or opens a new file, directory, I/O device, pipe, console", Kparams: Kparams{ kparams.FileObject: {Name: kparams.FileObject, Type: kparams.Uint64, Value: uint64(12456738026482168384)}, - kparams.FileName: {Name: kparams.FileName, Type: kparams.UnicodeString, Value: "\\Device\\HarddiskVolume2\\Windows\\system32\\user32.dll"}, + kparams.FilePath: {Name: kparams.FilePath, Type: kparams.UnicodeString, Value: "\\Device\\HarddiskVolume2\\Windows\\system32\\user32.dll"}, kparams.FileType: {Name: kparams.FileType, Type: kparams.AnsiString, Value: "file"}, kparams.FileOperation: {Name: kparams.FileOperation, Type: kparams.AnsiString, Value: "open"}, }, diff --git a/pkg/kevent/marshaller_windows.go b/pkg/kevent/marshaller_windows.go index 36c265370..378f9335d 100644 --- a/pkg/kevent/marshaller_windows.go +++ b/pkg/kevent/marshaller_windows.go @@ -100,7 +100,7 @@ func (e *Kevent) MarshalRaw() []byte { case kparams.AnsiString, kparams.UnicodeString: b = append(b, bytes.WriteUint16(uint16(len(kpar.Value.(string))))...) b = append(b, kpar.Value.(string)...) - case kparams.Key, kparams.FilePath, kparams.FileDosPath, kparams.HandleType: + case kparams.Key, kparams.Path, kparams.DOSPath, kparams.HandleType: v := e.GetParamAsString(kpar.Name) b = append(b, bytes.WriteUint16(uint16(len(v)))...) b = append(b, v...) @@ -272,7 +272,7 @@ func (e *Kevent) UnmarshalRaw(b []byte, ver kcapver.Version) error { var kval kparams.Value switch kparams.Type(typ) { - case kparams.AnsiString, kparams.UnicodeString, kparams.FilePath: + case kparams.AnsiString, kparams.UnicodeString, kparams.Path: // read string parameter l := bytes.ReadUint16(b[pi+offset+kparamNameLength+poffset:]) buf = b[inc(idx, 18)+offset+kparamNameLength+poffset:] diff --git a/pkg/outputs/amqp/amqp_test.go b/pkg/outputs/amqp/amqp_test.go index fbbc9edf7..db44d1ccc 100644 --- a/pkg/outputs/amqp/amqp_test.go +++ b/pkg/outputs/amqp/amqp_test.go @@ -207,7 +207,7 @@ func getBatch() *kevent.Batch { Description: "Creates or opens a new file, directory, I/O device, pipe, console", Kparams: kevent.Kparams{ kparams.FileObject: {Name: kparams.FileObject, Type: kparams.Uint64, Value: uint64(12456738026482168384)}, - kparams.FileName: {Name: kparams.FileName, Type: kparams.UnicodeString, Value: "\\Device\\HarddiskVolume2\\Windows\\system32\\user32.dll"}, + kparams.FilePath: {Name: kparams.FilePath, Type: kparams.UnicodeString, Value: "\\Device\\HarddiskVolume2\\Windows\\system32\\user32.dll"}, kparams.FileType: {Name: kparams.FileType, Type: kparams.AnsiString, Value: "file"}, kparams.FileOperation: {Name: kparams.FileOperation, Type: kparams.AnsiString, Value: "open"}, kparams.BasePrio: {Name: kparams.BasePrio, Type: kparams.Int8, Value: int8(2)}, @@ -275,7 +275,7 @@ func getBatch() *kevent.Batch { Description: "Creates or opens a new file, directory, I/O device, pipe, console", Kparams: kevent.Kparams{ kparams.FileObject: {Name: kparams.FileObject, Type: kparams.Uint64, Value: uint64(12456738026482168384)}, - kparams.FileName: {Name: kparams.FileName, Type: kparams.UnicodeString, Value: "\\Device\\HarddiskVolume2\\Windows\\system32\\user32.dll"}, + kparams.FilePath: {Name: kparams.FilePath, Type: kparams.UnicodeString, Value: "\\Device\\HarddiskVolume2\\Windows\\system32\\user32.dll"}, kparams.FileType: {Name: kparams.FileType, Type: kparams.AnsiString, Value: "file"}, kparams.FileOperation: {Name: kparams.FileOperation, Type: kparams.AnsiString, Value: "open"}, kparams.BasePrio: {Name: kparams.BasePrio, Type: kparams.Int8, Value: int8(2)}, @@ -343,7 +343,7 @@ func getBatch() *kevent.Batch { Description: "Creates or opens a new file, directory, I/O device, pipe, console", Kparams: kevent.Kparams{ kparams.FileObject: {Name: kparams.FileObject, Type: kparams.Uint64, Value: uint64(12456738026482168384)}, - kparams.FileName: {Name: kparams.FileName, Type: kparams.UnicodeString, Value: "\\Device\\HarddiskVolume2\\Windows\\system32\\user32.dll"}, + kparams.FilePath: {Name: kparams.FilePath, Type: kparams.UnicodeString, Value: "\\Device\\HarddiskVolume2\\Windows\\system32\\user32.dll"}, kparams.FileType: {Name: kparams.FileType, Type: kparams.AnsiString, Value: "file"}, kparams.FileOperation: {Name: kparams.FileOperation, Type: kparams.AnsiString, Value: "open"}, kparams.BasePrio: {Name: kparams.BasePrio, Type: kparams.Int8, Value: int8(2)}, diff --git a/pkg/outputs/elasticsearch/elasticsearch_test.go b/pkg/outputs/elasticsearch/elasticsearch_test.go index 6d1402479..635ad24e1 100644 --- a/pkg/outputs/elasticsearch/elasticsearch_test.go +++ b/pkg/outputs/elasticsearch/elasticsearch_test.go @@ -174,7 +174,7 @@ func getBatch() *kevent.Batch { Description: "Creates or opens a new file, directory, I/O device, pipe, console", Kparams: kevent.Kparams{ kparams.FileObject: {Name: kparams.FileObject, Type: kparams.Uint64, Value: uint64(12456738026482168384)}, - kparams.FileName: {Name: kparams.FileName, Type: kparams.UnicodeString, Value: "\\Device\\HarddiskVolume2\\Windows\\system32\\user32.dll"}, + kparams.FilePath: {Name: kparams.FilePath, Type: kparams.UnicodeString, Value: "\\Device\\HarddiskVolume2\\Windows\\system32\\user32.dll"}, kparams.FileType: {Name: kparams.FileType, Type: kparams.AnsiString, Value: "file"}, kparams.FileOperation: {Name: kparams.FileOperation, Type: kparams.AnsiString, Value: "open"}, kparams.BasePrio: {Name: kparams.BasePrio, Type: kparams.Int8, Value: int8(2)}, @@ -242,7 +242,7 @@ func getBatch() *kevent.Batch { Description: "Creates or opens a new file, directory, I/O device, pipe, console", Kparams: kevent.Kparams{ kparams.FileObject: {Name: kparams.FileObject, Type: kparams.Uint64, Value: uint64(12456738026482168384)}, - kparams.FileName: {Name: kparams.FileName, Type: kparams.UnicodeString, Value: "\\Device\\HarddiskVolume2\\Windows\\system32\\user32.dll"}, + kparams.FilePath: {Name: kparams.FilePath, Type: kparams.UnicodeString, Value: "\\Device\\HarddiskVolume2\\Windows\\system32\\user32.dll"}, kparams.FileType: {Name: kparams.FileType, Type: kparams.AnsiString, Value: "file"}, kparams.FileOperation: {Name: kparams.FileOperation, Type: kparams.AnsiString, Value: "open"}, kparams.BasePrio: {Name: kparams.BasePrio, Type: kparams.Int8, Value: int8(2)}, @@ -310,7 +310,7 @@ func getBatch() *kevent.Batch { Description: "Creates or opens a new file, directory, I/O device, pipe, console", Kparams: kevent.Kparams{ kparams.FileObject: {Name: kparams.FileObject, Type: kparams.Uint64, Value: uint64(12456738026482168384)}, - kparams.FileName: {Name: kparams.FileName, Type: kparams.UnicodeString, Value: "\\Device\\HarddiskVolume2\\Windows\\system32\\user32.dll"}, + kparams.FilePath: {Name: kparams.FilePath, Type: kparams.UnicodeString, Value: "\\Device\\HarddiskVolume2\\Windows\\system32\\user32.dll"}, kparams.FileType: {Name: kparams.FileType, Type: kparams.AnsiString, Value: "file"}, kparams.FileOperation: {Name: kparams.FileOperation, Type: kparams.AnsiString, Value: "open"}, kparams.BasePrio: {Name: kparams.BasePrio, Type: kparams.Int8, Value: int8(2)}, diff --git a/pkg/outputs/eventlog/eventlog_test.go b/pkg/outputs/eventlog/eventlog_test.go index 879ef8922..c8a8ccbe0 100644 --- a/pkg/outputs/eventlog/eventlog_test.go +++ b/pkg/outputs/eventlog/eventlog_test.go @@ -69,7 +69,7 @@ func getBatch() *kevent.Batch { Description: "Creates or opens a new file, directory, I/O device, pipe, console", Kparams: kevent.Kparams{ kparams.FileObject: {Name: kparams.FileObject, Type: kparams.Uint64, Value: uint64(12456738026482168384)}, - kparams.FileName: {Name: kparams.FileName, Type: kparams.UnicodeString, Value: "\\Device\\HarddiskVolume2\\Windows\\system32\\user32.dll"}, + kparams.FilePath: {Name: kparams.FilePath, Type: kparams.UnicodeString, Value: "\\Device\\HarddiskVolume2\\Windows\\system32\\user32.dll"}, kparams.FileType: {Name: kparams.FileType, Type: kparams.AnsiString, Value: "file"}, kparams.FileOperation: {Name: kparams.FileOperation, Type: kparams.AnsiString, Value: "open"}, kparams.BasePrio: {Name: kparams.BasePrio, Type: kparams.Int8, Value: int8(2)}, diff --git a/pkg/outputs/http/http_test.go b/pkg/outputs/http/http_test.go index 28a379bc6..875b904fd 100644 --- a/pkg/outputs/http/http_test.go +++ b/pkg/outputs/http/http_test.go @@ -161,7 +161,7 @@ func getBatch() *kevent.Batch { Description: "Creates or opens a new file, directory, I/O device, pipe, console", Kparams: kevent.Kparams{ kparams.FileObject: {Name: kparams.FileObject, Type: kparams.Uint64, Value: uint64(12456738026482168384)}, - kparams.FileName: {Name: kparams.FileName, Type: kparams.UnicodeString, Value: "\\Device\\HarddiskVolume2\\Windows\\system32\\user32.dll"}, + kparams.FilePath: {Name: kparams.FilePath, Type: kparams.UnicodeString, Value: "\\Device\\HarddiskVolume2\\Windows\\system32\\user32.dll"}, kparams.FileType: {Name: kparams.FileType, Type: kparams.AnsiString, Value: "file"}, kparams.FileOperation: {Name: kparams.FileOperation, Type: kparams.AnsiString, Value: "open"}, kparams.BasePrio: {Name: kparams.BasePrio, Type: kparams.Int8, Value: int8(2)}, @@ -229,7 +229,7 @@ func getBatch() *kevent.Batch { Description: "Creates or opens a new file, directory, I/O device, pipe, console", Kparams: kevent.Kparams{ kparams.FileObject: {Name: kparams.FileObject, Type: kparams.Uint64, Value: uint64(12456738026482168384)}, - kparams.FileName: {Name: kparams.FileName, Type: kparams.UnicodeString, Value: "\\Device\\HarddiskVolume2\\Windows\\system32\\user32.dll"}, + kparams.FilePath: {Name: kparams.FilePath, Type: kparams.UnicodeString, Value: "\\Device\\HarddiskVolume2\\Windows\\system32\\user32.dll"}, kparams.FileType: {Name: kparams.FileType, Type: kparams.AnsiString, Value: "file"}, kparams.FileOperation: {Name: kparams.FileOperation, Type: kparams.AnsiString, Value: "open"}, kparams.BasePrio: {Name: kparams.BasePrio, Type: kparams.Int8, Value: int8(2)}, @@ -297,7 +297,7 @@ func getBatch() *kevent.Batch { Description: "Creates or opens a new file, directory, I/O device, pipe, console", Kparams: kevent.Kparams{ kparams.FileObject: {Name: kparams.FileObject, Type: kparams.Uint64, Value: uint64(12456738026482168384)}, - kparams.FileName: {Name: kparams.FileName, Type: kparams.UnicodeString, Value: "\\Device\\HarddiskVolume2\\Windows\\system32\\user32.dll"}, + kparams.FilePath: {Name: kparams.FilePath, Type: kparams.UnicodeString, Value: "\\Device\\HarddiskVolume2\\Windows\\system32\\user32.dll"}, kparams.FileType: {Name: kparams.FileType, Type: kparams.AnsiString, Value: "file"}, kparams.FileOperation: {Name: kparams.FileOperation, Type: kparams.AnsiString, Value: "open"}, kparams.BasePrio: {Name: kparams.BasePrio, Type: kparams.Int8, Value: int8(2)}, diff --git a/pkg/ps/snapshotter_windows.go b/pkg/ps/snapshotter_windows.go index 058af534a..b6edf62f9 100644 --- a/pkg/ps/snapshotter_windows.go +++ b/pkg/ps/snapshotter_windows.go @@ -217,7 +217,7 @@ func (s *snapshotter) AddModule(e *kevent.Kevent) error { module := pstypes.Module{} module.Size, _ = e.Kparams.GetUint64(kparams.ImageSize) module.Checksum, _ = e.Kparams.GetUint32(kparams.ImageCheckSum) - module.Name = e.GetParamAsString(kparams.ImageFilename) + module.Name = e.GetParamAsString(kparams.ImagePath) module.BaseAddress = e.Kparams.TryGetAddress(kparams.ImageBase) module.DefaultBaseAddress = e.Kparams.TryGetAddress(kparams.ImageDefaultBase) module.SignatureLevel, _ = e.Kparams.GetUint32(kparams.ImageSignatureLevel) @@ -274,7 +274,7 @@ func (s *snapshotter) AddFileMapping(e *kevent.Kevent) error { return nil } - filename := e.GetParamAsString(kparams.FileName) + filename := e.GetParamAsString(kparams.FilePath) ext := strings.ToLower(filepath.Ext(filename)) // skip redundant or unneeded memory-mapped files if ext == ".dll" || ext == ".exe" || ext == ".mui" { diff --git a/pkg/ps/snapshotter_windows_test.go b/pkg/ps/snapshotter_windows_test.go index 8a24c97e6..f6127e1b7 100644 --- a/pkg/ps/snapshotter_windows_test.go +++ b/pkg/ps/snapshotter_windows_test.go @@ -392,8 +392,8 @@ func TestAddModule(t *testing.T) { &kevent.Kevent{ Type: ktypes.LoadImage, Kparams: kevent.Kparams{ - kparams.ProcessID: {Name: kparams.ProcessID, Type: kparams.PID, Value: uint32(os.Getpid())}, - kparams.ImageFilename: {Name: kparams.ImageFilename, Type: kparams.UnicodeString, Value: "C:\\Users\\admin\\AppData\\Roaming\\Spotify\\Spotify.exe"}, + kparams.ProcessID: {Name: kparams.ProcessID, Type: kparams.PID, Value: uint32(os.Getpid())}, + kparams.ImagePath: {Name: kparams.ImagePath, Type: kparams.UnicodeString, Value: "C:\\Users\\admin\\AppData\\Roaming\\Spotify\\Spotify.exe"}, }, }, true, @@ -402,8 +402,8 @@ func TestAddModule(t *testing.T) { &kevent.Kevent{ Type: ktypes.LoadImage, Kparams: kevent.Kparams{ - kparams.ProcessID: {Name: kparams.ProcessID, Type: kparams.PID, Value: uint32(os.Getpid() + 1)}, - kparams.ImageFilename: {Name: kparams.ImageFilename, Type: kparams.UnicodeString, Value: "C:\\Windows\\System32\\notepad.exe"}, + kparams.ProcessID: {Name: kparams.ProcessID, Type: kparams.PID, Value: uint32(os.Getpid() + 1)}, + kparams.ImagePath: {Name: kparams.ImagePath, Type: kparams.UnicodeString, Value: "C:\\Windows\\System32\\notepad.exe"}, }, }, false, @@ -419,7 +419,7 @@ func TestAddModule(t *testing.T) { ok, proc := psnap.Find(evt.Kparams.MustGetPid()) require.Equal(t, exists, ok) if ok { - require.NotNil(t, proc.FindModule(evt.GetParamAsString(kparams.ImageFilename))) + require.NotNil(t, proc.FindModule(evt.GetParamAsString(kparams.ImagePath))) assert.Equal(t, "C:\\Users\\admin\\AppData\\Roaming\\Spotify\\Spotify.exe", proc.Exe) } }) @@ -451,8 +451,8 @@ func TestRemoveModule(t *testing.T) { mevt := &kevent.Kevent{ Type: ktypes.LoadImage, Kparams: kevent.Kparams{ - kparams.ProcessID: {Name: kparams.ProcessID, Type: kparams.PID, Value: uint32(os.Getpid())}, - kparams.ImageFilename: {Name: kparams.ImageFilename, Type: kparams.UnicodeString, Value: "C:\\Windows\\System32\\notepad.exe"}, + kparams.ProcessID: {Name: kparams.ProcessID, Type: kparams.PID, Value: uint32(os.Getpid())}, + kparams.ImagePath: {Name: kparams.ImagePath, Type: kparams.UnicodeString, Value: "C:\\Windows\\System32\\notepad.exe"}, }, } diff --git a/pkg/symbolize/symbolizer.go b/pkg/symbolize/symbolizer.go index e499ba338..c0bdf0c95 100644 --- a/pkg/symbolize/symbolizer.go +++ b/pkg/symbolize/symbolizer.go @@ -205,7 +205,7 @@ func (s *Symbolizer) ProcessEvent(e *kevent.Kevent) (bool, error) { return true, nil } if e.IsLoadImage() || e.IsUnloadImage() { - filename := e.GetParamAsString(kparams.FileName) + filename := e.GetParamAsString(kparams.ImagePath) addr := e.Kparams.TryGetAddress(kparams.ImageBase) // if the kernel driver is loaded or unloaded, // load/unload symbol handlers respectively @@ -247,10 +247,11 @@ func (s *Symbolizer) ProcessEvent(e *kevent.Kevent) (bool, error) { // the map, we parse its export directory and insert // into the map. func (s *Symbolizer) syncModules(e *kevent.Kevent) error { - filename := e.GetParamAsString(kparams.FileName) + filename := e.GetParamAsString(kparams.ImagePath) addr := e.Kparams.TryGetAddress(kparams.ImageBase) s.mu.Lock() defer s.mu.Unlock() + if e.IsUnloadImage() { ok, _ := s.psnap.FindModule(addr) if !ok { @@ -263,6 +264,7 @@ func (s *Symbolizer) syncModules(e *kevent.Kevent) error { } return nil } + if s.mods[addr] != nil { return nil } @@ -270,7 +272,9 @@ func (s *Symbolizer) syncModules(e *kevent.Kevent) error { if err != nil { return fmt.Errorf("unable to parse PE exports for module [%s]: %v", filename, err) } + symModulesCount.Add(1) + m := &module{exports: px.Exports, accessed: time.Now(), hasExports: true} exportRVAs := convert.MapKeysToSlice(m.exports) if len(exportRVAs) > 0 { @@ -279,6 +283,7 @@ func (s *Symbolizer) syncModules(e *kevent.Kevent) error { m.hasExports = false } s.mods[addr] = m + return nil } diff --git a/pkg/symbolize/symbolizer_test.go b/pkg/symbolize/symbolizer_test.go index 7e52de3c7..f10066600 100644 --- a/pkg/symbolize/symbolizer_test.go +++ b/pkg/symbolize/symbolizer_test.go @@ -144,7 +144,7 @@ func TestProcessCallstackFastMode(t *testing.T) { Description: "Creates or opens a new file, directory, I/O device, pipe, console", Kparams: kevent.Kparams{ kparams.FileObject: {Name: kparams.FileObject, Type: kparams.Uint64, Value: uint64(12456738026482168384)}, - kparams.FileName: {Name: kparams.FileName, Type: kparams.UnicodeString, Value: "C:\\Windows\\system32\\user32.dll"}, + kparams.FilePath: {Name: kparams.FilePath, Type: kparams.UnicodeString, Value: "C:\\Windows\\system32\\user32.dll"}, kparams.FileType: {Name: kparams.FileType, Type: kparams.AnsiString, Value: "file"}, kparams.FileOperation: {Name: kparams.FileOperation, Type: kparams.Enum, Value: uint32(1), Enum: fs.FileCreateDispositions}, kparams.Callstack: {Name: kparams.Callstack, Type: kparams.Slice, Value: []va.Address{0x7ffb5c1d0396, 0x7ffb5d8e61f4, 0x7ffb3138592e, 0x7ffb313853b2, 0x2638e59e0a5}}, @@ -217,7 +217,7 @@ func TestProcessCallstackPeExports(t *testing.T) { Description: "Creates or opens a new file, directory, I/O device, pipe, console", Kparams: kevent.Kparams{ kparams.FileObject: {Name: kparams.FileObject, Type: kparams.Uint64, Value: uint64(12456738026482168384)}, - kparams.FileName: {Name: kparams.FileName, Type: kparams.UnicodeString, Value: "C:\\Windows\\system32\\mimi.dll"}, + kparams.FilePath: {Name: kparams.FilePath, Type: kparams.UnicodeString, Value: "C:\\Windows\\system32\\mimi.dll"}, kparams.FileType: {Name: kparams.FileType, Type: kparams.AnsiString, Value: "file"}, kparams.FileOperation: {Name: kparams.FileOperation, Type: kparams.Enum, Value: uint32(2), Enum: fs.FileCreateDispositions}, kparams.Callstack: {Name: kparams.Callstack, Type: kparams.Slice, Value: []va.Address{0x7ffb5c1d0396, 0x7ffb5d8e61f4, 0x7ffb3138592e, 0x7ffb313853b2, 0x2638e59e0a5}}, @@ -275,7 +275,7 @@ func TestProcessCallstackPeExports(t *testing.T) { Category: ktypes.Image, Kparams: kevent.Kparams{ kparams.ImageBase: {Name: kparams.ImageBase, Type: kparams.Address, Value: uint64(0x12345f)}, - kparams.FileName: {Name: kparams.FileName, Type: kparams.UnicodeString, Value: "C:\\Windows\\System32\\bcrypt32.dll"}, + kparams.FilePath: {Name: kparams.FilePath, Type: kparams.UnicodeString, Value: "C:\\Windows\\System32\\bcrypt32.dll"}, }, PS: proc, } @@ -294,7 +294,7 @@ func TestProcessCallstackPeExports(t *testing.T) { Category: ktypes.Image, Kparams: kevent.Kparams{ kparams.ImageBase: {Name: kparams.ImageBase, Type: kparams.Address, Value: uint64(0x12345f)}, - kparams.FileName: {Name: kparams.FileName, Type: kparams.UnicodeString, Value: filepath.Join(os.Getenv("SystemRoot"), "System32", "bcrypt32.dll")}, + kparams.FilePath: {Name: kparams.FilePath, Type: kparams.UnicodeString, Value: filepath.Join(os.Getenv("SystemRoot"), "System32", "bcrypt32.dll")}, }, PS: proc, } diff --git a/pkg/yara/config/config.go b/pkg/yara/config/config.go index d1cb408df..9d29ce4ae 100644 --- a/pkg/yara/config/config.go +++ b/pkg/yara/config/config.go @@ -165,7 +165,7 @@ func (c Config) ShouldSkipFile(file string) bool { // whether the process scan took place or a file/registry // key was scanned. func (c Config) AlertTitle(e *kevent.Kevent) string { - if (e.Category == ktypes.File && e.GetParamAsString(kparams.FileName) != "") || e.Category == ktypes.Registry { + if (e.Category == ktypes.File && e.GetParamAsString(kparams.FilePath) != "") || e.Category == ktypes.Registry { return FileThreatAlertTitle } return MemoryThreatAlertTitle diff --git a/pkg/yara/scanner.go b/pkg/yara/scanner.go index 5f1fcb618..cd0202809 100644 --- a/pkg/yara/scanner.go +++ b/pkg/yara/scanner.go @@ -199,7 +199,7 @@ func (s scanner) Scan(e *kevent.Kevent) (bool, error) { if typ != signature.None { return false, nil } - filename := e.GetParamAsString(kparams.ImageFilename) + filename := e.GetParamAsString(kparams.ImagePath) if s.config.ShouldSkipFile(filename) { return false, nil } @@ -228,7 +228,7 @@ func (s scanner) Scan(e *kevent.Kevent) (bool, error) { return false, nil } - filename := e.GetParamAsString(kparams.FileName) + filename := e.GetParamAsString(kparams.FilePath) if s.config.ShouldSkipFile(filename) || (e.PS != nil && s.config.ShouldSkipProcess(e.PS.Exe)) { return false, nil } @@ -292,7 +292,7 @@ func (s scanner) Scan(e *kevent.Kevent) (bool, error) { prot := e.Kparams.MustGetUint32(kparams.MemProtect) size := e.Kparams.MustGetUint64(kparams.FileViewSize) if e.PID != 4 && size >= 4096 && ((prot&kevent.SectionRX) != 0 && (prot&kevent.SectionRWX) != 0) { - filename := e.GetParamAsString(kparams.FileName) + filename := e.GetParamAsString(kparams.FilePath) // skip mappings of signed images addr := e.Kparams.MustGetUint64(kparams.FileViewBase) sign := signature.GetSignatures().GetSignature(addr) @@ -333,7 +333,7 @@ func (s scanner) Scan(e *kevent.Kevent) (bool, error) { return false, nil } if b, ok := v.Value.([]byte); ok && len(b) > 0 { - log.Debugf("scanning registry binary value %s. pid: %d", e.GetParamAsString(kparams.RegKeyName), e.PID) + log.Debugf("scanning registry binary value %s. pid: %d", e.GetParamAsString(kparams.RegPath), e.PID) matches, err = s.scan(b) registryScans.Add(1) isScanned = true diff --git a/pkg/yara/scanner_test.go b/pkg/yara/scanner_test.go index f548a09c9..9c1a7b843 100644 --- a/pkg/yara/scanner_test.go +++ b/pkg/yara/scanner_test.go @@ -287,7 +287,7 @@ func TestScan(t *testing.T) { Tid: 2484, PID: pid, Kparams: kevent.Kparams{ - kparams.FileName: {Name: kparams.FileName, Type: kparams.UnicodeString, Value: "tests.exe"}, + kparams.FilePath: {Name: kparams.FilePath, Type: kparams.UnicodeString, Value: "tests.exe"}, kparams.ImageBase: {Name: kparams.ImageBase, Type: kparams.Uint64, Value: uint64(0x74888fd99)}, kparams.ImageSignatureType: {Name: kparams.ImageSignatureType, Type: kparams.Uint32, Value: signature.None}, kparams.ProcessID: {Name: kparams.ProcessID, Type: kparams.PID, Value: pid}, @@ -342,7 +342,7 @@ func TestScan(t *testing.T) { Tid: 2484, PID: 565, Kparams: kevent.Kparams{ - kparams.FileName: {Name: kparams.FileName, Type: kparams.UnicodeString, Value: filepath.Join(os.Getenv("windir"), "notepad.exe")}, + kparams.FilePath: {Name: kparams.FilePath, Type: kparams.UnicodeString, Value: filepath.Join(os.Getenv("windir"), "notepad.exe")}, kparams.FileOperation: {Name: kparams.FileOperation, Type: kparams.Uint32, Value: uint32(windows.FILE_CREATE)}, }, Metadata: make(map[kevent.MetadataKey]any), @@ -395,7 +395,7 @@ func TestScan(t *testing.T) { Tid: 2484, PID: 565, Kparams: kevent.Kparams{ - kparams.FileName: {Name: kparams.FileName, Type: kparams.UnicodeString, Value: filepath.Join(os.Getenv("windir"), "System32", "cmd.exe")}, + kparams.FilePath: {Name: kparams.FilePath, Type: kparams.UnicodeString, Value: filepath.Join(os.Getenv("windir"), "System32", "cmd.exe")}, kparams.FileOperation: {Name: kparams.FileOperation, Type: kparams.Uint32, Value: uint32(windows.FILE_CREATE)}, }, Metadata: make(map[kevent.MetadataKey]any), @@ -446,7 +446,7 @@ func TestScan(t *testing.T) { Tid: 2484, PID: 565, Kparams: kevent.Kparams{ - kparams.FileName: {Name: kparams.FileName, Type: kparams.UnicodeString, Value: filepath.Join(os.Getenv("windir"), "splwow64.xml")}, + kparams.FilePath: {Name: kparams.FilePath, Type: kparams.UnicodeString, Value: filepath.Join(os.Getenv("windir"), "splwow64.xml")}, kparams.FileOperation: {Name: kparams.FileOperation, Type: kparams.Uint32, Value: uint32(windows.FILE_CREATE)}, }, Metadata: make(map[kevent.MetadataKey]any), @@ -494,7 +494,7 @@ func TestScan(t *testing.T) { Tid: 2484, PID: 565, Kparams: kevent.Kparams{ - kparams.FileName: {Name: kparams.FileName, Type: kparams.UnicodeString, Value: filepath.Join(os.Getenv("windir"), "System32", "cmd.exe")}, + kparams.FilePath: {Name: kparams.FilePath, Type: kparams.UnicodeString, Value: filepath.Join(os.Getenv("windir"), "System32", "cmd.exe")}, kparams.FileOperation: {Name: kparams.FileOperation, Type: kparams.Uint32, Value: uint32(windows.FILE_CREATE)}, }, Metadata: make(map[kevent.MetadataKey]any), @@ -556,7 +556,7 @@ func TestScan(t *testing.T) { Tid: 2484, PID: 565, Kparams: kevent.Kparams{ - kparams.FileName: {Name: kparams.FileName, Type: kparams.UnicodeString, Value: ads}, + kparams.FilePath: {Name: kparams.FilePath, Type: kparams.UnicodeString, Value: ads}, kparams.FileOperation: {Name: kparams.FileOperation, Type: kparams.Uint32, Value: uint32(windows.FILE_CREATE)}, }, Metadata: make(map[kevent.MetadataKey]any), @@ -878,7 +878,7 @@ func TestScan(t *testing.T) { PID: 565, Kparams: kevent.Kparams{ kparams.ProcessID: {Name: kparams.ProcessID, Type: kparams.PID, Value: uint32(1123)}, - kparams.FileName: {Name: kparams.FileName, Type: kparams.UnicodeString, Value: filepath.Join(os.Getenv("windir"), "regedit.exe")}, + kparams.FilePath: {Name: kparams.FilePath, Type: kparams.UnicodeString, Value: filepath.Join(os.Getenv("windir"), "regedit.exe")}, kparams.FileViewBase: {Name: kparams.FileViewBase, Type: kparams.Address, Value: uint64(0x7ffe0000)}, kparams.FileViewSize: {Name: kparams.FileViewSize, Type: kparams.Uint64, Value: uint64(12333)}, kparams.MemProtect: {Name: kparams.MemProtect, Type: kparams.Flags, Value: uint32(kevent.SectionRWX), Flags: kevent.ViewProtectionFlags}, @@ -935,7 +935,7 @@ func TestScan(t *testing.T) { Kparams: kevent.Kparams{ kparams.RegValueType: {Name: kparams.RegValueType, Type: kparams.Uint32, Value: uint32(registry.BINARY)}, kparams.RegValue: {Name: kparams.RegValue, Type: kparams.Binary, Value: data}, - kparams.RegKeyName: {Name: kparams.RegKeyName, Type: kparams.UnicodeString, Value: `HKEY_LOCAL_MACHINE\CurrentControlSet\Control\DeviceGuard\Mal`}, + kparams.RegPath: {Name: kparams.RegPath, Type: kparams.UnicodeString, Value: `HKEY_LOCAL_MACHINE\CurrentControlSet\Control\DeviceGuard\Mal`}, }, Metadata: make(map[kevent.MetadataKey]any), PS: proc, From 1540efe8929e66e867201615af522fc02ffd8ff1 Mon Sep 17 00:00:00 2001 From: rabbitstack Date: Fri, 20 Dec 2024 16:31:41 +0100 Subject: [PATCH 2/3] refactor(filter): Introduce *.path filter fields Historically, the file.name/image.name/registry.key.name filter fields were used to yield the full file path, image path, or registry key respectively. However, a better way to convey the referenced field is actually returning a fully-qualified path is to introduce a new set of fields. As a side effect, the previous fields return the base file/image/key names. --- pkg/aggregator/transformers/replace/replace_test.go | 6 +++--- pkg/aggregator/transformers/trim/trim_test.go | 6 +++--- pkg/kevent/queue_test.go | 8 ++++---- pkg/yara/config/config_test.go | 2 +- 4 files changed, 11 insertions(+), 11 deletions(-) diff --git a/pkg/aggregator/transformers/replace/replace_test.go b/pkg/aggregator/transformers/replace/replace_test.go index 472768a7e..d2ed0dc45 100644 --- a/pkg/aggregator/transformers/replace/replace_test.go +++ b/pkg/aggregator/transformers/replace/replace_test.go @@ -34,17 +34,17 @@ func TestTransform(t *testing.T) { Tid: 2484, PID: 859, Kparams: kevent.Kparams{ - kparams.RegKeyName: {Name: kparams.RegKeyName, Type: kparams.UnicodeString, Value: `HKEY_LOCAL_MACHINE\SYSTEM\Setup\Pid`}, + kparams.RegPath: {Name: kparams.RegPath, Type: kparams.UnicodeString, Value: `HKEY_LOCAL_MACHINE\SYSTEM\Setup\Pid`}, kparams.RegKeyHandle: {Name: kparams.RegKeyHandle, Type: kparams.Address, Value: uint64(18446666033449935464)}, }, } - transf, err := transformers.Load(transformers.Config{Type: transformers.Replace, Transformer: Config{Replacements: []Replacement{{Kpar: "key_name", Old: "HKEY_LOCAL_MACHINE", New: "HKLM"}}}}) + transf, err := transformers.Load(transformers.Config{Type: transformers.Replace, Transformer: Config{Replacements: []Replacement{{Kpar: "key_path", Old: "HKEY_LOCAL_MACHINE", New: "HKLM"}}}}) require.NoError(t, err) require.NoError(t, transf.Transform(kevt)) - keyName, _ := kevt.Kparams.GetString(kparams.RegKeyName) + keyName, _ := kevt.Kparams.GetString(kparams.RegPath) assert.Equal(t, `HKLM\SYSTEM\Setup\Pid`, keyName) } diff --git a/pkg/aggregator/transformers/trim/trim_test.go b/pkg/aggregator/transformers/trim/trim_test.go index f86526644..dc8e78b00 100644 --- a/pkg/aggregator/transformers/trim/trim_test.go +++ b/pkg/aggregator/transformers/trim/trim_test.go @@ -42,7 +42,7 @@ func TestTransform(t *testing.T) { Description: "Creates or opens a new file, directory, I/O device, pipe, console", Kparams: kevent.Kparams{ kparams.FileObject: {Name: kparams.FileObject, Type: kparams.Uint64, Value: uint64(12456738026482168384)}, - kparams.FileName: {Name: kparams.FileName, Type: kparams.UnicodeString, Value: "\\Device\\HarddiskVolume2\\Windows\\system32\\user32.dll"}, + kparams.FilePath: {Name: kparams.FilePath, Type: kparams.UnicodeString, Value: "\\Device\\HarddiskVolume2\\Windows\\system32\\user32.dll"}, kparams.FileType: {Name: kparams.FileType, Type: kparams.AnsiString, Value: "file"}, kparams.FileOperation: {Name: kparams.FileOperation, Type: kparams.AnsiString, Value: "overwriteif"}, kparams.BasePrio: {Name: kparams.BasePrio, Type: kparams.Int8, Value: int8(2)}, @@ -54,11 +54,11 @@ func TestTransform(t *testing.T) { Metadata: map[kevent.MetadataKey]any{"foo": "bar", "fooz": "barz"}, } - transf, err := transformers.Load(transformers.Config{Type: transformers.Trim, Transformer: Config{Prefixes: []Trim{{Name: "file_name", Trim: "\\Device"}}, Suffixes: []Trim{{Name: "create_disposition", Trim: "if"}}}}) + transf, err := transformers.Load(transformers.Config{Type: transformers.Trim, Transformer: Config{Prefixes: []Trim{{Name: "file_path", Trim: "\\Device"}}, Suffixes: []Trim{{Name: "create_disposition", Trim: "if"}}}}) require.NoError(t, err) require.NoError(t, transf.Transform(kevt)) - filename, _ := kevt.Kparams.GetString(kparams.FileName) + filename, _ := kevt.Kparams.GetString(kparams.FilePath) dispo, _ := kevt.Kparams.GetString(kparams.FileOperation) assert.Equal(t, "\\HarddiskVolume2\\Windows\\system32\\user32.dll", filename) diff --git a/pkg/kevent/queue_test.go b/pkg/kevent/queue_test.go index bf92d8aff..bc4ebf310 100644 --- a/pkg/kevent/queue_test.go +++ b/pkg/kevent/queue_test.go @@ -77,7 +77,7 @@ func TestQueuePush(t *testing.T) { Category: ktypes.File, Kparams: Kparams{ kparams.FileObject: {Name: kparams.FileObject, Type: kparams.Uint64, Value: uint64(12456738026482168384)}, - kparams.FileName: {Name: kparams.FileName, Type: kparams.UnicodeString, Value: "C:\\Windows\\system32\\user32.dll"}, + kparams.FilePath: {Name: kparams.FilePath, Type: kparams.UnicodeString, Value: "C:\\Windows\\system32\\user32.dll"}, kparams.FileType: {Name: kparams.FileType, Type: kparams.AnsiString, Value: "file"}, kparams.FileOperation: {Name: kparams.FileOperation, Type: kparams.Enum, Value: uint32(1), Enum: fs.FileCreateDispositions}, }, @@ -104,7 +104,7 @@ func TestQueuePush(t *testing.T) { Category: ktypes.File, Kparams: Kparams{ kparams.FileObject: {Name: kparams.FileObject, Type: kparams.Uint64, Value: uint64(12456738026482168384)}, - kparams.FileName: {Name: kparams.FileName, Type: kparams.UnicodeString, Value: "C:\\Windows\\system32\\user32.dll"}, + kparams.FilePath: {Name: kparams.FilePath, Type: kparams.UnicodeString, Value: "C:\\Windows\\system32\\user32.dll"}, kparams.FileType: {Name: kparams.FileType, Type: kparams.AnsiString, Value: "file"}, kparams.FileOperation: {Name: kparams.FileOperation, Type: kparams.Enum, Value: uint32(1), Enum: fs.FileCreateDispositions}, }, @@ -131,7 +131,7 @@ func TestQueuePush(t *testing.T) { Category: ktypes.File, Kparams: Kparams{ kparams.FileObject: {Name: kparams.FileObject, Type: kparams.Uint64, Value: uint64(12456738026482168384)}, - kparams.FileName: {Name: kparams.FileName, Type: kparams.UnicodeString, Value: "C:\\Windows\\system32\\user32.dll"}, + kparams.FilePath: {Name: kparams.FilePath, Type: kparams.UnicodeString, Value: "C:\\Windows\\system32\\user32.dll"}, kparams.FileType: {Name: kparams.FileType, Type: kparams.AnsiString, Value: "file"}, kparams.FileOperation: {Name: kparams.FileOperation, Type: kparams.Enum, Value: uint32(1), Enum: fs.FileCreateDispositions}, }, @@ -159,7 +159,7 @@ func TestQueuePush(t *testing.T) { Category: ktypes.File, Kparams: Kparams{ kparams.FileObject: {Name: kparams.FileObject, Type: kparams.Uint64, Value: uint64(12456738026482168384)}, - kparams.FileName: {Name: kparams.FileName, Type: kparams.UnicodeString, Value: "C:\\Windows\\system32\\user32.dll"}, + kparams.FilePath: {Name: kparams.FilePath, Type: kparams.UnicodeString, Value: "C:\\Windows\\system32\\user32.dll"}, kparams.FileType: {Name: kparams.FileType, Type: kparams.AnsiString, Value: "file"}, kparams.FileOperation: {Name: kparams.FileOperation, Type: kparams.Enum, Value: uint32(1), Enum: fs.FileCreateDispositions}, }, diff --git a/pkg/yara/config/config_test.go b/pkg/yara/config/config_test.go index 8e8cf6faa..c5d55d70b 100644 --- a/pkg/yara/config/config_test.go +++ b/pkg/yara/config/config_test.go @@ -115,7 +115,7 @@ func TestAlertTitle(t *testing.T) { }, { &kevent.Kevent{Type: ktypes.MapViewFile, Category: ktypes.File, - Kparams: kevent.Kparams{kparams.FileName: {Name: kparams.FileName, Type: kparams.UnicodeString, Value: "C:\\Windows\\System32\\wusa.exe"}}, + Kparams: kevent.Kparams{kparams.FilePath: {Name: kparams.FilePath, Type: kparams.UnicodeString, Value: "C:\\Windows\\System32\\wusa.exe"}}, }, FileThreatAlertTitle, }, From 335a1a4f6056eff4f2437695843395384d63a80c Mon Sep 17 00:00:00 2001 From: rabbitstack Date: Thu, 19 Dec 2024 19:45:26 +0100 Subject: [PATCH 3/3] refactor(rules): Adapt rules to *.path filter fields All rules referencing file.name/image.name/registry.key.name are adapted to use the new *.path fields. This effectively leads to a breaking change, that's why all affected rules minimum engine version is bumped. --- .../credentail_access_file_access_to_sam_database.yml | 6 +++--- ...memory_dump_preparation_via_silent_process_exit.yml | 6 +++--- rules/credential_access_lsass_memory_dump_via_wer.yml | 6 +++--- rules/credential_access_lsass_memory_dumping.yml | 6 +++--- rules/credential_access_potential_sam_hive_dumping.yml | 8 ++++---- ...ious_access_to_active_directory_domain_database.yml | 6 +++--- ...s_suspicious_access_to_unattended_panther_files.yml | 6 +++--- ..._suspicious_access_to_windows_dpapi_master_keys.yml | 6 +++--- ...cess_suspicious_access_to_windows_manager_files.yml | 6 +++--- ...access_suspicious_access_to_windows_vault_files.yml | 6 +++--- rules/credential_access_unusual_access_to_ssh_keys.yml | 6 +++--- ...unusual_access_to_web_browser_credential_stores.yml | 6 +++--- ...ss_unusual_access_to_windows_credential_history.yml | 6 +++--- ...anager_injection_via_clr_search_order_hijacking.yml | 8 ++++---- rules/defense_evasion_clear_eventlog.yml | 8 ++++---- rules/defense_evasion_dll_loaded_via_apc_queue.yml | 6 +++--- ...efense_evasion_dll_loaded_via_callback_function.yml | 8 ++++---- ...fense_evasion_dll_sideloading_via_copied_binary.yml | 8 ++++---- ...ion_dotnet_assembly_loaded_by_unmanaged_process.yml | 8 ++++---- rules/defense_evasion_hidden_registry_key_creation.yml | 8 ++++---- ...ion_process_execution_from_self_deleting_binary.yml | 6 +++--- ...l_access_execution_via_microsoft_office_process.yml | 6 +++--- rules/macros/macros.yml | 2 +- rules/persistence_hidden_local_account_creation.yml | 6 +++--- ...nection_via_startup_folder_executable_or_script.yml | 6 +++--- rules/persistence_rid_hijacking.yml | 6 +++--- ...pt_interpreter_or_untrusted_process_persistence.yml | 8 ++++---- ...ersistence_suspicious_microsoft_office_template.yml | 8 ++++---- ...uspicious_persistence_via_registry_modification.yml | 6 +++--- ...ce_suspicious_startup_shell_folder_modification.yml | 6 +++--- ...sistence_unusual_file_written_in_startup_folder.yml | 6 +++--- ...tence_unusual_process_modified_registry_run_key.yml | 6 +++--- ..._privilege_escalation_via_phantom_dll_hijacking.yml | 10 +++++----- ...calation_vulnerable_or_malicious_driver_dropped.yml | 6 +++--- ...scalation_vulnerable_or_malicious_driver_loaded.yml | 6 +++--- 35 files changed, 114 insertions(+), 114 deletions(-) diff --git a/rules/credentail_access_file_access_to_sam_database.yml b/rules/credentail_access_file_access_to_sam_database.yml index 3400ae5db..e8433c1ba 100644 --- a/rules/credentail_access_file_access_to_sam_database.yml +++ b/rules/credentail_access_file_access_to_sam_database.yml @@ -1,6 +1,6 @@ name: File access to SAM database id: e3dace20-4962-4381-884e-40dcdde66626 -version: 1.0.0 +version: 1.0.1 description: | Identifies access to the Security Account Manager on-disk database. labels: @@ -17,7 +17,7 @@ labels: condition: > open_file and - file.name imatches + file.path imatches ( '?:\\WINDOWS\\SYSTEM32\\CONFIG\\SAM', '\\Device\\HarddiskVolumeShadowCopy*\\WINDOWS\\SYSTEM32\\CONFIG\\SAM', @@ -32,4 +32,4 @@ condition: > '?:\\Windows\\System32\\lsass.exe' ) -min-engine-version: 2.0.0 +min-engine-version: 2.4.0 diff --git a/rules/credential_access_lsass_memory_dump_preparation_via_silent_process_exit.yml b/rules/credential_access_lsass_memory_dump_preparation_via_silent_process_exit.yml index 1cd80fa79..2ad2fa726 100644 --- a/rules/credential_access_lsass_memory_dump_preparation_via_silent_process_exit.yml +++ b/rules/credential_access_lsass_memory_dump_preparation_via_silent_process_exit.yml @@ -1,6 +1,6 @@ name: LSASS memory dump preparation via SilentProcessExit id: d325e426-f89a-4f7c-b655-3874dad07986 -version: 1.0.0 +version: 1.0.1 description: | Adversaries may exploit the SilentProcessExit debugging technique to conduct LSASS memory dump via WerFault.exe (Windows Error Reporting) binary by creating @@ -27,8 +27,8 @@ references: condition: > modify_registry and - registry.key.name + registry.path imatches 'HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\SilentProcessExit\\lsass*' -min-engine-version: 2.0.0 +min-engine-version: 2.4.0 diff --git a/rules/credential_access_lsass_memory_dump_via_wer.yml b/rules/credential_access_lsass_memory_dump_via_wer.yml index c9f19ab3f..999ede205 100644 --- a/rules/credential_access_lsass_memory_dump_via_wer.yml +++ b/rules/credential_access_lsass_memory_dump_via_wer.yml @@ -1,6 +1,6 @@ name: LSASS memory dump via Windows Error Reporting id: 7b4a74e2-c7a7-4c1f-b2ce-0e0273c3add7 -version: 1.0.0 +version: 1.0.1 description: | Adversaries may abuse Windows Error Reporting service to dump LSASS memory. The ALPC protocol can send a message to report an exception on LSASS and @@ -22,6 +22,6 @@ condition: > sequence maxspan 2m |spawn_process and ps.child.name in ('WerFault.exe', 'WerFaultSecure.exe')| by ps.child.uuid - |write_minidump_file and file.name icontains 'lsass'| by ps.uuid + |write_minidump_file and file.path icontains 'lsass'| by ps.uuid -min-engine-version: 2.0.0 +min-engine-version: 2.4.0 diff --git a/rules/credential_access_lsass_memory_dumping.yml b/rules/credential_access_lsass_memory_dumping.yml index e811dd2a2..659941689 100644 --- a/rules/credential_access_lsass_memory_dumping.yml +++ b/rules/credential_access_lsass_memory_dumping.yml @@ -1,6 +1,6 @@ name: LSASS memory dumping via legitimate or offensive tools id: 335795af-246b-483e-8657-09a30c102e63 -version: 1.0.0 +version: 1.0.1 description: | Detects an attempt to dump the LSAAS memory to the disk by employing legitimate tools such as procdump, Task Manager, Process Explorer or built-in Windows tools @@ -39,7 +39,7 @@ condition: > output: > Detected an attempt by `%1.ps.name` process to access and read the memory of the **Local Security And Authority Subsystem Service** - and subsequently write the `%2.file.name` dump file to the disk device + and subsequently write the `%2.file.path` dump file to the disk device severity: critical -min-engine-version: 2.0.0 +min-engine-version: 2.4.0 diff --git a/rules/credential_access_potential_sam_hive_dumping.yml b/rules/credential_access_potential_sam_hive_dumping.yml index d4653288a..82c81e218 100644 --- a/rules/credential_access_potential_sam_hive_dumping.yml +++ b/rules/credential_access_potential_sam_hive_dumping.yml @@ -1,6 +1,6 @@ name: Potential SAM hive dumping id: 2f326557-0291-4eb1-a87a-7a17b7d941cb -version: 1.0.0 +version: 1.0.1 description: Identifies access to the Security Account Manager registry hives. labels: @@ -30,10 +30,10 @@ condition: > | by ps.child.uuid |open_registry and - registry.key.name imatches 'HKEY_LOCAL_MACHINE\\SAM\\SAM\\Domains\\Account\\*' + registry.path imatches 'HKEY_LOCAL_MACHINE\\SAM\\SAM\\Domains\\Account\\*' and not - registry.key.name imatches + registry.path imatches ( 'HKEY_LOCAL_MACHINE\\SAM\\SAM\\Domains\\Account\\Users', 'HKEY_LOCAL_MACHINE\\SAM\\SAM\\Domains\\Account\\Users\\Names', @@ -68,4 +68,4 @@ condition: > ) | by ps.uuid -min-engine-version: 2.0.0 +min-engine-version: 2.4.0 diff --git a/rules/credential_access_suspicious_access_to_active_directory_domain_database.yml b/rules/credential_access_suspicious_access_to_active_directory_domain_database.yml index 2eafbeb5c..ceb485e9b 100644 --- a/rules/credential_access_suspicious_access_to_active_directory_domain_database.yml +++ b/rules/credential_access_suspicious_access_to_active_directory_domain_database.yml @@ -1,6 +1,6 @@ name: Suspicious access to Active Directory domain database id: a30c100e-28d0-4aa0-b98d-0d38025c2c29 -version: 1.0.0 +version: 1.0.1 description: | Detects suspicious access to the Active Directory domain database. Adversaries may attempt to access or create a copy of the Active Directory @@ -19,7 +19,7 @@ labels: condition: > open_file and - file.name imatches + file.path imatches ( '\\Device\\HarddiskVolumeShadowCopy*\\WINDOWS\\NTDS\\ntds.dit', '?:\\WINDOWS\\NTDS\\ntds.dit' @@ -32,4 +32,4 @@ condition: > '?:\\ProgramData\\Microsoft\\Windows Defender\\*\\MsMpEng.exe' ) -min-engine-version: 2.0.0 +min-engine-version: 2.4.0 diff --git a/rules/credential_access_suspicious_access_to_unattended_panther_files.yml b/rules/credential_access_suspicious_access_to_unattended_panther_files.yml index 46161beb4..ede8c4b9c 100644 --- a/rules/credential_access_suspicious_access_to_unattended_panther_files.yml +++ b/rules/credential_access_suspicious_access_to_unattended_panther_files.yml @@ -1,6 +1,6 @@ name: Suspicious access to Unattended Panther files id: d305fb15-6ad1-4d61-a84b-ada462f23a55 -version: 1.0.0 +version: 1.0.1 description: | Identifies suspicious to access to unattend.xml files where credentials are commonly stored within the Panther directory. Adversaries may search local @@ -19,7 +19,7 @@ labels: condition: > open_file and - file.name imatches + file.path imatches ( '?:\\Windows\\Panther\\Unattend\\Unattended.xml', '?:\\Windows\\Panther\\Unattend\\Unattend.xml', @@ -35,4 +35,4 @@ condition: > '?:\\ProgramData\\Microsoft\\Windows Defender\\*\\MsMpEng.exe' ) -min-engine-version: 2.0.0 +min-engine-version: 2.4.0 diff --git a/rules/credential_access_suspicious_access_to_windows_dpapi_master_keys.yml b/rules/credential_access_suspicious_access_to_windows_dpapi_master_keys.yml index 68548317f..6c66d9fa1 100644 --- a/rules/credential_access_suspicious_access_to_windows_dpapi_master_keys.yml +++ b/rules/credential_access_suspicious_access_to_windows_dpapi_master_keys.yml @@ -1,6 +1,6 @@ name: Suspicious access to Windows DPAPI Master Keys id: b1d5732a-5ad4-4cdd-8791-c22e34c591e5 -version: 1.0.0 +version: 1.0.1 description: | Detects suspicious processes accessing the Windows Data Protection API Master keys which is a sign of potential credential stealing. @@ -26,7 +26,7 @@ references: condition: > open_file and - file.name imatches + file.path imatches ( '?:\\Windows\\System32\\Microsoft\\Protect\\S-1-5-18\\Users\\*', '?:\\Users\\*\\AppData\\*\\Microsoft\\Protect\\S-1-5-21*\\*', @@ -42,4 +42,4 @@ condition: > '?:\\Windows\\SysWOW64\\*' ) -min-engine-version: 2.0.0 +min-engine-version: 2.4.0 diff --git a/rules/credential_access_suspicious_access_to_windows_manager_files.yml b/rules/credential_access_suspicious_access_to_windows_manager_files.yml index 2740de80d..fbb042c4b 100644 --- a/rules/credential_access_suspicious_access_to_windows_manager_files.yml +++ b/rules/credential_access_suspicious_access_to_windows_manager_files.yml @@ -1,6 +1,6 @@ name: Suspicious access to Windows Credential Manager files id: 4ab688f7-94e2-481b-9c7f-c49f3a79a379 -version: 1.0.0 +version: 1.0.1 description: | Identifies suspicious processes trying to acquire credentials from the Windows Credential Manager. labels: @@ -17,7 +17,7 @@ labels: condition: > open_file and - file.name imatches + file.path imatches ( '?:\\Users\\*\\AppData\\*\\Microsoft\\Credentials\\*', '?:\\Windows\\System32\\config\\systemprofile\\AppData\\*\\Microsoft\\Credentials\\*' @@ -31,4 +31,4 @@ condition: > '?:\\Windows\\System32\\lsass.exe' ) -min-engine-version: 2.0.0 +min-engine-version: 2.4.0 diff --git a/rules/credential_access_suspicious_access_to_windows_vault_files.yml b/rules/credential_access_suspicious_access_to_windows_vault_files.yml index 7004a7f5d..1c0dffb93 100644 --- a/rules/credential_access_suspicious_access_to_windows_vault_files.yml +++ b/rules/credential_access_suspicious_access_to_windows_vault_files.yml @@ -1,6 +1,6 @@ name: Suspicious access to Windows Vault files id: 44400221-f98d-424a-9388-497c75b18924 -version: 1.0.0 +version: 1.0.1 description: | Identifies attempts from adversaries to acquire credentials from Vault files. labels: @@ -17,7 +17,7 @@ labels: condition: > open_file and - file.name imatches + file.path imatches ( '?:\\Users\\*\\AppData\\*\\Microsoft\\Vault\\*\\*', '?:\\ProgramData\\Microsoft\\Vault\\*' @@ -34,4 +34,4 @@ condition: > '?:\\Windows\\System32\\svchost.exe' ) -min-engine-version: 2.0.0 +min-engine-version: 2.4.0 diff --git a/rules/credential_access_unusual_access_to_ssh_keys.yml b/rules/credential_access_unusual_access_to_ssh_keys.yml index 26022293f..dc680d3ba 100644 --- a/rules/credential_access_unusual_access_to_ssh_keys.yml +++ b/rules/credential_access_unusual_access_to_ssh_keys.yml @@ -1,6 +1,6 @@ name: Unusual access to SSH keys id: 90f5c1bd-abd6-4d1b-94e0-229f04473d60 -version: 1.0.0 +version: 1.0.1 description: | Identifies access by unusual process to saved SSH keys. labels: @@ -17,7 +17,7 @@ labels: condition: > open_file and - file.name imatches '?:\\Users\\*\\.ssh\\known_hosts' + file.path imatches '?:\\Users\\*\\.ssh\\known_hosts' and not ps.exe imatches @@ -37,4 +37,4 @@ condition: > 'WinSCP.exe' ) -min-engine-version: 2.0.0 +min-engine-version: 2.4.0 diff --git a/rules/credential_access_unusual_access_to_web_browser_credential_stores.yml b/rules/credential_access_unusual_access_to_web_browser_credential_stores.yml index 6351f3d0b..2cafbbbd1 100644 --- a/rules/credential_access_unusual_access_to_web_browser_credential_stores.yml +++ b/rules/credential_access_unusual_access_to_web_browser_credential_stores.yml @@ -1,6 +1,6 @@ name: Unusual access to Web Browser Credential stores id: 9d889b2b-ca13-4a04-8919-ff1151f23a71 -version: 1.0.0 +version: 1.0.1 description: | Identifies access to Web Browser Credential stores by unusual processes. labels: @@ -17,7 +17,7 @@ labels: condition: > open_file and - file.name imatches web_browser_cred_stores + file.path imatches web_browser_cred_stores and ps.name not iin web_browser_binaries and @@ -31,4 +31,4 @@ condition: > '?:\\ProgramData\\Microsoft\\Windows Defender\\*\\MpCopyAccelerator.exe' ) -min-engine-version: 2.0.0 +min-engine-version: 2.4.0 diff --git a/rules/credential_access_unusual_access_to_windows_credential_history.yml b/rules/credential_access_unusual_access_to_windows_credential_history.yml index df7b5e91f..f24a4ded0 100644 --- a/rules/credential_access_unusual_access_to_windows_credential_history.yml +++ b/rules/credential_access_unusual_access_to_windows_credential_history.yml @@ -1,6 +1,6 @@ name: Unusual access to Windows Credential history files id: 9d94062f-2cf3-407c-bd65-4072fe4b167f -version: 1.0.0 +version: 1.0.1 description: | Detects unusual accesses to the Windows Credential history file. The CREDHIST file contains all previous password-linked master key hashes used by @@ -20,7 +20,7 @@ labels: condition: > open_file and - file.name imatches '?:\\Users\\*\\AppData\\*\\Microsoft\\Protect\\CREDHIST' + file.path imatches '?:\\Users\\*\\AppData\\*\\Microsoft\\Protect\\CREDHIST' and not ps.exe imatches @@ -31,4 +31,4 @@ condition: > '?:\\Windows\\ccmcache\\*.exe' ) -min-engine-version: 2.0.0 +min-engine-version: 2.4.0 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 7dbbfdda4..b91287c3d 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.0 +version: 1.0.1 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 ((base(dir(image.name)) ~= base(image.name, false)) or (ps.envs[APPDOMAIN_MANAGER_ASM] istartswith base(image.name, false))) + (load_unsigned_or_untrusted_module) and ((base(dir(image.path)) ~= base(image.path, false)) or (ps.envs[APPDOMAIN_MANAGER_ASM] istartswith image.name)) and pe.is_dotnet and (image.is_dotnet or thread.callstack.symbols imatches ('clr.dll!ParseManifest*')) output: > - Process %ps.exe loaded untrusted .NET assembly %image.name from suspicious location + Process %ps.exe loaded untrusted .NET assembly %image.path from suspicious location severity: high -min-engine-version: 2.3.0 +min-engine-version: 2.4.0 diff --git a/rules/defense_evasion_clear_eventlog.yml b/rules/defense_evasion_clear_eventlog.yml index 4681bf654..7adfe1725 100644 --- a/rules/defense_evasion_clear_eventlog.yml +++ b/rules/defense_evasion_clear_eventlog.yml @@ -1,6 +1,6 @@ name: Clear Eventlog id: 692d3143-e1fb-4dab-8c9c-3109ff80ec85 -version: 1.0.1 +version: 1.0.2 description: | Identifies attempts to clear Windows event log stores. Adversaries attempt to evade detection or destroy forensic evidence on a system to cover their trails and slow down incident response. @@ -19,11 +19,11 @@ condition: > sequence maxspan 1m by file.object - |set_file_information and kevt.pid != 4 and file.info_class = 'EOF' and file.info.eof_size > 50000 and file.name imatches '?:\\Windows\\System32\\winevt\\Logs\\*.evtx'| + |set_file_information and kevt.pid != 4 and file.info_class = 'EOF' and file.info.eof_size > 50000 and file.path imatches '?:\\Windows\\System32\\winevt\\Logs\\*.evtx'| |set_file_information and file.info_class = 'Allocation' and file.info.allocation_size > 50000| output: > - Windows Eventlog store %1.file.name was cleared + Windows Eventlog store %1.file.path was cleared severity: medium -min-engine-version: 2.3.0 +min-engine-version: 2.4.0 diff --git a/rules/defense_evasion_dll_loaded_via_apc_queue.yml b/rules/defense_evasion_dll_loaded_via_apc_queue.yml index 07bab8437..80b0cfdf4 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.0 +version: 1.0.1 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 base(image.name) iin + load_dll and image.name iin ( 'winhttp.dll', 'clr.dll', 'bcrypt.dll', 'bcryptprimitives.dll', 'wininet.dll', 'taskschd.dll', 'dnsapi.dll', 'coreclr.dll', 'ws2_32.dll', @@ -30,4 +30,4 @@ condition: > and thread.callstack.symbols imatches ('KernelBase.dll!Sleep*') -min-engine-version: 2.0.0 +min-engine-version: 2.4.0 diff --git a/rules/defense_evasion_dll_loaded_via_callback_function.yml b/rules/defense_evasion_dll_loaded_via_callback_function.yml index 3f538919a..ff5aaf820 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.0 +version: 1.0.1 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 @@ -20,7 +20,7 @@ condition: > sequence maxspan 2m |spawn_process| by ps.child.uuid - |load_dll and base(image.name) iin + |load_dll and image.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: > | by ps.uuid output: > - %2.image.name loaded from callback function by process %ps.exe + %2.image.path loaded from callback function by process %ps.exe severity: high -min-engine-version: 2.0.0 +min-engine-version: 2.4.0 diff --git a/rules/defense_evasion_dll_sideloading_via_copied_binary.yml b/rules/defense_evasion_dll_sideloading_via_copied_binary.yml index 03c0cfe6b..6b02811cf 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.0 +version: 1.0.1 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 @@ -23,12 +23,12 @@ condition: > |create_file and file.is_exec and ps.sid not in ('S-1-5-18', 'S-1-5-19', 'S-1-5-20') and thread.callstack.symbols imatches ('*CopyFile*', '*MoveFile*') - | by file.name - |(load_dll) and dir(image.name) ~= dir(ps.exe) + | by file.path + |(load_dll) and dir(image.path) ~= dir(ps.exe) and pe.cert.subject icontains 'Microsoft' and pe.is_trusted and (image.signature.type = 'NONE' or image.signature.level = 'UNCHECKED' or image.signature.level = 'UNSIGNED') | by ps.exe -min-engine-version: 2.2.0 +min-engine-version: 2.4.0 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 3c1f987ba..430f03fa2 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.1 +version: 1.0.2 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. @@ -21,7 +21,7 @@ condition: > (image.is_dotnet or thread.callstack.modules imatches ('*clr.dll')) and not - image.name imatches + image.path imatches ( '?:\\Windows\\assembly\\*\\*.ni.dll', '?:\\Program Files\\WindowsPowerShell\\Modules\\*\\*.dll', @@ -35,7 +35,7 @@ condition: > ) output: > - .NET assembly %image.name loaded by unmanaged process %ps.exe + .NET assembly %image.path loaded by unmanaged process %ps.exe severity: high -min-engine-version: 2.3.0 +min-engine-version: 2.4.0 diff --git a/rules/defense_evasion_hidden_registry_key_creation.yml b/rules/defense_evasion_hidden_registry_key_creation.yml index e05933155..95b7daf18 100644 --- a/rules/defense_evasion_hidden_registry_key_creation.yml +++ b/rules/defense_evasion_hidden_registry_key_creation.yml @@ -1,6 +1,6 @@ name: Hidden registry key creation id: 65deda38-9b1d-42a0-9f40-a68903e81b49 -version: 1.1.0 +version: 1.1.1 description: | Identifies the creation of a hidden registry key. Adversaries can utilize the native NtSetValueKey API to create a hidden registry key and conceal payloads @@ -16,7 +16,7 @@ references: - https://github.com/outflanknl/SharpHide condition: > - set_value and kevt.pid != 4 and registry.key.name endswith '\\' + set_value and kevt.pid != 4 and registry.path endswith '\\' and thread.callstack.symbols imatches ('ntdll.dll!NtSetValueKey', 'ntdll.dll!ZwSetValueKey') and @@ -33,7 +33,7 @@ condition: > ) output: > - Hidden registry key %registry.key.name created by process %ps.exe + Hidden registry key %registry.path created by process %ps.exe severity: high -min-engine-version: 2.2.0 +min-engine-version: 2.4.0 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 d238a037f..ea5765955 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.0 +version: 1.0.1 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 @@ -24,7 +24,7 @@ condition: > |load_module| by image.name output: > - Process %2.image.name spawned from self-deleting binary + Process %2.image.path spawned from self-deleting binary severity: high -min-engine-version: 2.3.0 +min-engine-version: 2.4.0 diff --git a/rules/initial_access_execution_via_microsoft_office_process.yml b/rules/initial_access_execution_via_microsoft_office_process.yml index b5500e753..d5b166c1d 100644 --- a/rules/initial_access_execution_via_microsoft_office_process.yml +++ b/rules/initial_access_execution_via_microsoft_office_process.yml @@ -1,6 +1,6 @@ name: Execution via Microsoft Office process id: a10ebe66-1b55-4005-a374-840f1e2933a3 -version: 1.0.0 +version: 1.0.1 description: Identifies the execution of the file dropped by Microsoft Office process. labels: @@ -17,7 +17,7 @@ labels: condition: > sequence maxspan 1h - |create_file and (file.extension iin executable_extensions or file.is_exec) and ps.name iin msoffice_binaries| by file.name + |create_file and (file.extension iin executable_extensions or file.is_exec) and ps.name iin msoffice_binaries| by file.path |spawn_process and ps.name iin msoffice_binaries| by ps.child.exe -min-engine-version: 2.0.0 +min-engine-version: 2.4.0 diff --git a/rules/macros/macros.yml b/rules/macros/macros.yml index 018737b1a..f08852f4b 100644 --- a/rules/macros/macros.yml +++ b/rules/macros/macros.yml @@ -207,7 +207,7 @@ '.dump' ) or - is_minidump(file.name) + is_minidump(file.path) ) description: | Detects a process writing the minidump file. Minidump files are used for crash diff --git a/rules/persistence_hidden_local_account_creation.yml b/rules/persistence_hidden_local_account_creation.yml index 7b7747bec..8afb80b87 100644 --- a/rules/persistence_hidden_local_account_creation.yml +++ b/rules/persistence_hidden_local_account_creation.yml @@ -1,6 +1,6 @@ name: Hidden local account creation id: bfa83754-3730-4c46-a0fd-cc71365f64df -version: 1.0.0 +version: 1.0.1 description: | Identifies the creation of a hidden local account. Adversaries can create hidden accounts by appending the dollar sign to the account name. This technique renders the account name hidden @@ -17,7 +17,7 @@ labels: subtechnique.ref: https://attack.mitre.org/techniques/T1136/001/ condition: > - set_value and registry.key.name imatches + set_value and registry.path imatches ( 'HKEY_LOCAL_MACHINE\\SAM\\SAM\\Domains\\Account\\Users\\Names\\*$\\', 'HKEY_LOCAL_MACHINE\\SAM\\SAM\\Domains\\Account\\Users\\*$\\' @@ -25,4 +25,4 @@ condition: > severity: high -min-engine-version: 2.0.0 +min-engine-version: 2.4.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 f7efde2f4..ec3f5ae93 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.0 +version: 1.0.1 description: | Identifies the execution of unsigned binary or script from the Startup folder followed by network inbound or outbound connection. @@ -23,7 +23,7 @@ condition: > ( load_untrusted_executable and - image.name imatches startup_locations + image.path imatches startup_locations ) or ( @@ -36,4 +36,4 @@ condition: > | |((inbound_network) or (outbound_network)) and ps.cmdline imatches startup_locations| -min-engine-version: 2.0.0 +min-engine-version: 2.4.0 diff --git a/rules/persistence_rid_hijacking.yml b/rules/persistence_rid_hijacking.yml index 095620fc3..a4bb503b2 100644 --- a/rules/persistence_rid_hijacking.yml +++ b/rules/persistence_rid_hijacking.yml @@ -1,6 +1,6 @@ name: RID Hijacking id: 5c25666a-4a9f-4b7c-b02f-db0b5cdbde83 -version: 1.0.0 +version: 1.0.1 description: | RID (Relative ID part of security identifier) hijacking allows an attacker with SYSTEM level privileges to covertly replace the RID of a low privileged account effectively making @@ -17,11 +17,11 @@ references: - https://www.ired.team/offensive-security/persistence/rid-hijacking condition: > - set_value and registry.key.name imatches 'HKEY_LOCAL_MACHINE\\SAM\\SAM\\Domains\\Account\\Users\\*\\F' + set_value and registry.path imatches 'HKEY_LOCAL_MACHINE\\SAM\\SAM\\Domains\\Account\\Users\\*\\F' and ps.sid in ('S-1-5-18', 'S-1-5-19', 'S-1-5-20') and not ps.exe imatches '?:\\Windows\\System32\\lsass.exe' -min-engine-version: 2.0.0 +min-engine-version: 2.4.0 diff --git a/rules/persistence_script_interpreter_or_untrusted_process_persistence.yml b/rules/persistence_script_interpreter_or_untrusted_process_persistence.yml index 496e808d0..ffa34b867 100644 --- a/rules/persistence_script_interpreter_or_untrusted_process_persistence.yml +++ b/rules/persistence_script_interpreter_or_untrusted_process_persistence.yml @@ -1,6 +1,6 @@ name: Script interpreter host or untrusted process persistence id: cc41ee3a-6e44-4903-85a4-0147ec6a7eea -version: 1.0.2 +version: 1.0.3 description: | Identifies the script interpreter or untrusted process writing to commonly abused run keys or the Startup folder locations. @@ -27,9 +27,9 @@ condition: > ) and ( - registry.key.name imatches registry_run_keys + registry.path imatches registry_run_keys or - file.name imatches startup_locations + file.path imatches startup_locations ) and not @@ -42,4 +42,4 @@ condition: > action: - name: kill -min-engine-version: 2.0.0 +min-engine-version: 2.4.0 diff --git a/rules/persistence_suspicious_microsoft_office_template.yml b/rules/persistence_suspicious_microsoft_office_template.yml index 2d44adcff..74d11a80a 100644 --- a/rules/persistence_suspicious_microsoft_office_template.yml +++ b/rules/persistence_suspicious_microsoft_office_template.yml @@ -1,6 +1,6 @@ name: Suspicious Microsoft Office template id: c4be3b30-9d23-4a33-b974-fb12e17487a2 -version: 1.0.0 +version: 1.0.1 description: | Detects when attackers drop macro-enabled files in specific folders to trigger their execution every time the victim user @@ -21,7 +21,7 @@ references: condition: > create_file and - file.name imatches + file.path imatches ( '?:\\Users\\*\\AppData\\Roaming\\Microsoft\\Word\\Startup\\*', '?:\\Users\\*\\AppData\\Roaming\\Microsoft\\Templates\\*.dotm', @@ -41,6 +41,6 @@ condition: > ) output: > - Office template %file.name created by suspicious process %ps.exe + Office template %file.path created by suspicious process %ps.exe -min-engine-version: 2.0.0 +min-engine-version: 2.4.0 diff --git a/rules/persistence_suspicious_persistence_via_registry_modification.yml b/rules/persistence_suspicious_persistence_via_registry_modification.yml index 2bffeb6ef..8a2e3f692 100644 --- a/rules/persistence_suspicious_persistence_via_registry_modification.yml +++ b/rules/persistence_suspicious_persistence_via_registry_modification.yml @@ -1,6 +1,6 @@ name: Suspicious persistence via registry modification id: 1f496a17-4f0c-491a-823b-7a70adb9919c -version: 1.0.1 +version: 1.0.2 description: | Adversaries may abuse the registry to achieve persistence by modifying the keys that are unlikely modified by legitimate @@ -27,6 +27,6 @@ condition: > pe.is_signed = false or pe.is_trusted = false ) and - registry.key.name imatches registry_persistence_keys + registry.path imatches registry_persistence_keys -min-engine-version: 2.0.0 +min-engine-version: 2.4.0 diff --git a/rules/persistence_suspicious_startup_shell_folder_modification.yml b/rules/persistence_suspicious_startup_shell_folder_modification.yml index f6871d0fb..86c8b30f1 100644 --- a/rules/persistence_suspicious_startup_shell_folder_modification.yml +++ b/rules/persistence_suspicious_startup_shell_folder_modification.yml @@ -1,6 +1,6 @@ name: Suspicious Startup shell folder modification id: 7a4082f6-f7e3-49bd-9514-dbc8dd4e68ad -version: 1.0.0 +version: 1.0.1 description: | Detects when adversaries attempt to modify the default Startup folder path to to circumvent runtime rules that hunt for file @@ -19,7 +19,7 @@ labels: condition: > modify_registry and - registry.key.name imatches startup_shell_folder_registry_keys + registry.path imatches startup_shell_folder_registry_keys and not ( @@ -28,4 +28,4 @@ condition: > registry.value imatches ('%ProgramData%\\Microsoft\\Windows\\Start Menu\\Programs\\Startup') ) -min-engine-version: 2.0.0 +min-engine-version: 2.4.0 diff --git a/rules/persistence_unusual_file_written_in_startup_folder.yml b/rules/persistence_unusual_file_written_in_startup_folder.yml index ef5c7f06a..8212203d9 100644 --- a/rules/persistence_unusual_file_written_in_startup_folder.yml +++ b/rules/persistence_unusual_file_written_in_startup_folder.yml @@ -1,6 +1,6 @@ name: Unusual file written in Startup folder id: c5ffe15c-d94f-416b-bec7-c47f89843267 -version: 1.0.0 +version: 1.0.1 description: | Identifies suspicious files written to the startup folder that would allow adversaries to maintain persistence on the endpoint. @@ -24,7 +24,7 @@ condition: > (file.is_exec or file.is_dll) ) and - file.name imatches startup_locations + file.path imatches startup_locations and not ps.exe imatches @@ -36,4 +36,4 @@ condition: > '?:\\ProgramData\\Microsoft\\Windows Defender\\Platform\\*.exe' ) -min-engine-version: 2.0.0 +min-engine-version: 2.4.0 diff --git a/rules/persistence_unusual_process_modified_registry_run_key.yml b/rules/persistence_unusual_process_modified_registry_run_key.yml index d7ff66961..055e8dee8 100644 --- a/rules/persistence_unusual_process_modified_registry_run_key.yml +++ b/rules/persistence_unusual_process_modified_registry_run_key.yml @@ -1,6 +1,6 @@ name: Unusual process modified registry run key id: 921508a5-b627-4c02-a295-6c6863c0897b -version: 1.0.0 +version: 1.0.1 description: | Identifies an attempt by unusual Windows native processes to modify the run key and gain persistence on users logons or machine reboots. @@ -20,7 +20,7 @@ condition: > and ps.exe imatches '?:\\Windows\\*' and - registry.key.name imatches registry_run_keys + registry.path imatches registry_run_keys and not ps.exe imatches @@ -46,4 +46,4 @@ condition: > '?:\\Windows\\System32\\backgroundTaskHost.exe' ) -min-engine-version: 2.0.0 +min-engine-version: 2.4.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 c10d5148c..678885474 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.0 +version: 1.0.1 description: | Identifies the loading of the phantom DLL that was previously dropped to the System directory. Adversaries may exploit this flow to escalate @@ -27,7 +27,7 @@ references: condition: > sequence maxspan 10m - |create_file and file.name imatches + |create_file and file.path imatches ( '?:\\Windows\\System32\\wow64log.dll', '?:\\Windows\\wbemcomn.dll', @@ -44,7 +44,7 @@ condition: > '?:\\Windows\\System32\\Speech\\Engines\\TTS\\MSTTSLocEnUS.dll', '?:\\Windows\\System32\\DXGIDebug.dll' ) - | by file.name - |load_dll| by image.name + | by file.path + |load_dll| by image.path -min-engine-version: 2.0.0 +min-engine-version: 2.4.0 diff --git a/rules/privilege_escalation_vulnerable_or_malicious_driver_dropped.yml b/rules/privilege_escalation_vulnerable_or_malicious_driver_dropped.yml index bf202168b..c7198e1a4 100644 --- a/rules/privilege_escalation_vulnerable_or_malicious_driver_dropped.yml +++ b/rules/privilege_escalation_vulnerable_or_malicious_driver_dropped.yml @@ -1,6 +1,6 @@ name: Vulnerable or malicious driver dropped id: d4742163-cf68-4ebd-b9a2-3ad17bbf63d5 -version: 1.0.0 +version: 1.0.1 description: | Detects when adversaries drop a vulnerable/malicious driver onto a compromised system as a preparation for vulnerability @@ -21,6 +21,6 @@ condition: > (file.is_driver_vulnerable or file.is_driver_malicious) output: > - Vulnerable or malicious %file.name driver dropped + Vulnerable or malicious %file.path driver dropped -min-engine-version: 2.0.0 +min-engine-version: 2.4.0 diff --git a/rules/privilege_escalation_vulnerable_or_malicious_driver_loaded.yml b/rules/privilege_escalation_vulnerable_or_malicious_driver_loaded.yml index edfe6712a..c5db94e30 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.0 +version: 1.0.1 description: | Detects when adversaries load a vulnerable/malicious driver into the compromised system to exploit the vulnerability and @@ -21,6 +21,6 @@ condition: > (image.is_driver_vulnerable or image.is_driver_malicious) output: > - Vulnerable or malicious %image.name driver loaded + Vulnerable or malicious %image.path driver loaded -min-engine-version: 2.0.0 +min-engine-version: 2.4.0