Skip to content

Commit f8a2adc

Browse files
committed
fix(ps): Make executable path assignation more robust
Introduce a new metadata attribute in the process state to distinguish how the initial process state is created - either from internal event or system logger. This attribute is utilized in the state machine to set the correct executable path.
1 parent 3cdfd31 commit f8a2adc

File tree

3 files changed

+12
-4
lines changed

3 files changed

+12
-4
lines changed

pkg/ps/snapshotter_windows.go

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -162,25 +162,25 @@ func (s *snapshotter) Write(e *event.Event) error {
162162
if ps := s.procs[pid]; ps == nil && (e.IsCreateProcessInternal() || e.IsProcessRundownInternal()) {
163163
// only modify the state if there is no process derived from the NT kernel logger process events
164164
s.procs[pid] = proc
165-
} else if ps, ok := s.procs[pid]; ok && (e.IsCreateProcessInternal() || e.IsProcessRundownInternal()) {
165+
} else if ps, ok := s.procs[pid]; ok && (e.IsCreateProcessInternal() || e.IsProcessRundownInternal()) && ps.IsCreatedFromSystemLogger {
166166
// process state derived from the core kernel events exists - enrich it
167167
ps.TokenIntegrityLevel = proc.TokenIntegrityLevel
168168
ps.TokenElevationType = proc.TokenElevationType
169169
ps.IsTokenElevated = proc.IsTokenElevated
170-
if len(proc.Exe) > len(ps.Exe) {
170+
if strings.EqualFold(ps.Name, filepath.Base(proc.Exe)) && len(proc.Exe) > len(ps.Exe) {
171171
// prefer full executable path
172172
ps.Exe = proc.Exe
173173
}
174174
s.procs[pid] = ps
175-
} else if ps, ok := s.procs[pid]; ok && (e.IsCreateProcess() || e.IsProcessRundown()) && ps.TokenIntegrityLevel != "" {
175+
} else if ps, ok := s.procs[pid]; ok && (e.IsCreateProcess() || e.IsProcessRundown()) && !ps.IsCreatedFromSystemLogger {
176176
// enrich the existing process state with the newly arrived NT kernel logger process events
177177
// but obtain the integrity level and executable path from the previous proc state
178178
processEnrichments.Add(1)
179179
proc.TokenIntegrityLevel = ps.TokenIntegrityLevel
180180
proc.TokenElevationType = ps.TokenElevationType
181181
proc.IsTokenElevated = ps.IsTokenElevated
182182

183-
if len(ps.Exe) > len(proc.Exe) {
183+
if strings.EqualFold(proc.Name, filepath.Base(ps.Exe)) && len(ps.Exe) > len(proc.Exe) {
184184
// prefer full executable path
185185
proc.Exe = ps.Exe
186186
e.AppendParam(params.Exe, params.Path, ps.Exe)
@@ -393,6 +393,7 @@ func (s *snapshotter) newProcState(pid, ppid uint32, e *event.Event) (*pstypes.P
393393
proc.IsWOW64 = (e.Params.MustGetUint32(params.ProcessFlags) & event.PsWOW64) != 0
394394
proc.IsPackaged = (e.Params.MustGetUint32(params.ProcessFlags) & event.PsPackaged) != 0
395395
proc.IsProtected = (e.Params.MustGetUint32(params.ProcessFlags) & event.PsProtected) != 0
396+
proc.IsCreatedFromSystemLogger = true
396397

397398
if !s.capture {
398399
if proc.Username != "" {

pkg/ps/snapshotter_windows_test.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -224,6 +224,7 @@ func TestWriteInternalEventsEnrichment(t *testing.T) {
224224
params.ProcessID: {Name: params.ProcessID, Type: params.PID, Value: uint32(1024)},
225225
params.ProcessParentID: {Name: params.ProcessParentID, Type: params.PID, Value: uint32(444)},
226226
params.Exe: {Name: params.Exe, Type: params.UnicodeString, Value: `svchost.exe`},
227+
params.ProcessName: {Name: params.ProcessName, Type: params.UnicodeString, Value: `svchost.exe`},
227228
params.Cmdline: {Name: params.Cmdline, Type: params.UnicodeString, Value: `svchost.exe -k LocalSystemNetworkRestricted -p -s NcbService`},
228229
params.UserSID: {Name: params.UserSID, Type: params.WbemSID, Value: []byte{224, 8, 226, 31, 15, 167, 255, 255, 0, 0, 0, 0, 15, 167, 255, 255, 1, 1, 0, 0, 0, 0, 0, 5, 18, 0, 0, 0}},
229230
params.SessionID: {Name: params.SessionID, Type: params.Uint32, Value: uint32(1)},
@@ -262,6 +263,7 @@ func TestWriteInternalEventsEnrichment(t *testing.T) {
262263
params.ProcessID: {Name: params.ProcessID, Type: params.PID, Value: uint32(1024)},
263264
params.ProcessParentID: {Name: params.ProcessParentID, Type: params.PID, Value: uint32(444)},
264265
params.Exe: {Name: params.Exe, Type: params.UnicodeString, Value: `C:\Windows\System32\svchost.exe`},
266+
params.ProcessName: {Name: params.ProcessName, Type: params.UnicodeString, Value: `svchost.exe`},
265267
params.ProcessTokenIntegrityLevel: {Name: params.ProcessTokenIntegrityLevel, Type: params.AnsiString, Value: "HIGH"},
266268
params.ProcessTokenIsElevated: {Name: params.ProcessTokenIsElevated, Type: params.Bool, Value: true},
267269
params.ProcessTokenElevationType: {Name: params.ProcessTokenElevationType, Type: params.AnsiString, Value: "FULL"},
@@ -272,6 +274,7 @@ func TestWriteInternalEventsEnrichment(t *testing.T) {
272274
Params: event.Params{
273275
params.ProcessID: {Name: params.ProcessID, Type: params.PID, Value: uint32(1024)},
274276
params.ProcessParentID: {Name: params.ProcessParentID, Type: params.PID, Value: uint32(444)},
277+
params.ProcessName: {Name: params.ProcessName, Type: params.UnicodeString, Value: `svchost.exe`},
275278
params.Exe: {Name: params.Exe, Type: params.UnicodeString, Value: `svchost.exe`},
276279
params.Cmdline: {Name: params.Cmdline, Type: params.UnicodeString, Value: `svchost.exe -k LocalSystemNetworkRestricted -p -s NcbService`},
277280
params.UserSID: {Name: params.UserSID, Type: params.WbemSID, Value: []byte{224, 8, 226, 31, 15, 167, 255, 255, 0, 0, 0, 0, 15, 167, 255, 255, 1, 1, 0, 0, 0, 0, 0, 5, 18, 0, 0, 0}},
@@ -300,6 +303,7 @@ func TestWriteInternalEventsEnrichment(t *testing.T) {
300303
params.ProcessID: {Name: params.ProcessID, Type: params.PID, Value: uint32(os.Getpid())},
301304
params.ProcessParentID: {Name: params.ProcessParentID, Type: params.PID, Value: uint32(444)},
302305
params.Exe: {Name: params.Exe, Type: params.UnicodeString, Value: `svchost.exe`},
306+
params.ProcessName: {Name: params.ProcessName, Type: params.UnicodeString, Value: `svchost.exe`},
303307
params.Cmdline: {Name: params.Cmdline, Type: params.UnicodeString, Value: `svchost.exe -k LocalSystemNetworkRestricted -p -s NcbService`},
304308
params.UserSID: {Name: params.UserSID, Type: params.WbemSID, Value: []byte{224, 8, 226, 31, 15, 167, 255, 255, 0, 0, 0, 0, 15, 167, 255, 255, 1, 1, 0, 0, 0, 0, 0, 5, 18, 0, 0, 0}},
305309
params.SessionID: {Name: params.SessionID, Type: params.Uint32, Value: uint32(1)},

pkg/ps/types/types_windows.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,9 @@ type PS struct {
100100
TokenElevationType string `json:"token_elevation_type"`
101101
// IsTokenElevated indicates if the process token is elevated.
102102
IsTokenElevated bool `json:"is_token_elevated"`
103+
// IsCreatedFromSystemLogger is the metadata attribute that indicates if the
104+
// process state is created from the event published by the NT kernel logger.
105+
IsCreatedFromSystemLogger bool `json:"-"`
103106
}
104107

105108
// UUID is meant to offer a more robust version of process ID that

0 commit comments

Comments
 (0)