Skip to content

Commit

Permalink
Enrich events with binary and ancestors
Browse files Browse the repository at this point in the history
Enrich Tracee's events with information about current process executed
binary and ancestors information.
This is done using the process tree.
  • Loading branch information
AlonZivony committed May 7, 2023
1 parent 121d408 commit e4dae80
Show file tree
Hide file tree
Showing 4 changed files with 71 additions and 4 deletions.
2 changes: 1 addition & 1 deletion cmd/tracee-rules/output_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -255,7 +255,7 @@ func TestOutputTemplates(t *testing.T) {
"a":123,"b":"c","d":true,"f":{"123":"456","foo":"bar"}
},
"Context":{
"timestamp":1321321,"processorId":0,"processId":21312,"threadId":0,"threadStartTime":0,"parentProcessId":0,"hostProcessId":0,"hostThreadId":0,"hostParentProcessId":0,"userId":0,"mountNamespace":0,"pidNamespace":0,"processName":"","hostName":"","cgroupId":0,"container":{"id":"abbc123"},"kubernetes":{},"eventId":"0","eventName":"execve","argsNum":0,"returnValue":0,"syscall":"execve","stackAddresses":null,"args":null,"contextFlags":{"containerStarted":true,"isCompat":false}
"timestamp":1321321,"processorId":0,"processId":21312,"threadId":0,"threadStartTime":0,"parentProcessId":0,"hostProcessId":0,"hostThreadId":0,"hostParentProcessId":0,"userId":0,"mountNamespace":0,"pidNamespace":0,"processName":"","hostName":"","cgroupId":0,"container":{"id":"abbc123"},"kubernetes":{},"eventId":"0","eventName":"execve","argsNum":0,"returnValue":0,"syscall":"execve","stackAddresses":null,"args":null,"contextFlags":{"containerStarted":true,"isCompat":false},"ancestors":null,"executedBinary":{"ctime":0,"device":0,"inode":0, "path":""}
},
"SigMetadata":{
"ID":"TRC-1","EventName": "stdio","Version":"0.1.0","Name":"Standard Input/Output Over Socket","Description":"Redirection of process's standard input/output to socket","Tags":["linux","container"],"Properties":{"MITRE ATT\u0026CK":"Persistence: Server Software Component","Severity":3}
Expand Down
52 changes: 52 additions & 0 deletions pkg/ebpf/events_pipeline.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,9 @@ func (t *Tracee) handleEvents(ctx context.Context) {
eventsChan, errc = t.processTree.StartProcessingPipeline(ctx, eventsChan)
errcList = append(errcList, errc)

eventsChan, errc = t.enrichProcess(ctx, eventsChan)
errcList = append(errcList, errc)

// Enrichment stage
// In this stage container events are enriched with additional runtime data
// Events may be enriched in the initial decode state if the enrichment data has been stored in the Containers structure
Expand Down Expand Up @@ -558,6 +561,55 @@ func (t *Tracee) getStackAddresses(stackID uint32) ([]uint64, error) {
return stackAddresses[0:stackCounter], nil
}

func (t *Tracee) enrichProcess(ctx context.Context, in <-chan *trace.Event) (<-chan *trace.Event, <-chan error) {
out := make(chan *trace.Event)
errc := make(chan error, 1)

go func() {
defer close(out)
defer close(errc)

for {
select {
case event := <-in:
currentProcess, err := t.processTree.GetProcessInfo(event.HostProcessID, event.Timestamp)
if err != nil {
logger.Errorw("error enriching event with process info", "error", err)
} else {
event.ExecutedBinary = trace.BinaryInfo{
Inode: currentProcess.ExecutionBinary.Inode,
Device: currentProcess.ExecutionBinary.Device,
Ctime: int(currentProcess.ExecutionBinary.Ctime),
Path: currentProcess.ExecutionBinary.Path,
}

// Currently we only add parent information, as each new field we add increase the load significantly.
// We don't necessary have information on the parent process, so we do best effort.
parentProcess, err := t.processTree.GetProcessInfo(event.HostParentProcessID, event.Timestamp)
if err == nil {
parent := trace.Process{
ID: parentProcess.InHostIDs.Pid,
Name: parentProcess.ProcessName,
Binary: trace.BinaryInfo{
Inode: parentProcess.ExecutionBinary.Inode,
Device: parentProcess.ExecutionBinary.Device,
Ctime: int(parentProcess.ExecutionBinary.Ctime),
Path: parentProcess.ExecutionBinary.Path,
},
}
event.Ancestors = append(event.Ancestors, parent)
}
}
out <- event
case <-ctx.Done():
return
}
}
}()

return out, errc
}

// WaitForPipeline waits for results from all error channels.
func (t *Tracee) WaitForPipeline(errs ...<-chan error) error {
errc := MergeErrors(errs...)
Expand Down
6 changes: 3 additions & 3 deletions pkg/ebpf/tracee.go
Original file line number Diff line number Diff line change
Expand Up @@ -222,9 +222,9 @@ func (t *Tracee) Stats() *metrics.Stats {
func GetEssentialEventsList() map[events.ID]eventConfig {
// Set essential events
return map[events.ID]eventConfig{
events.SchedProcessExec: {},
events.SchedProcessExit: {},
events.SchedProcessFork: {},
events.SchedProcessExec: {submit: 0xFFFFFFFFFFFFFFFF},
events.SchedProcessExit: {submit: 0xFFFFFFFFFFFFFFFF},
events.SchedProcessFork: {submit: 0xFFFFFFFFFFFFFFFF},
events.CgroupMkdir: {submit: 0xFFFFFFFFFFFFFFFF},
events.CgroupRmdir: {submit: 0xFFFFFFFFFFFFFFFF},
}
Expand Down
15 changes: 15 additions & 0 deletions types/trace/trace.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ type Event struct {
MountNS int `json:"mountNamespace"`
PIDNS int `json:"pidNamespace"`
ProcessName string `json:"processName"`
ExecutedBinary BinaryInfo `json:"executedBinary"`
HostName string `json:"hostName"`
Container Container `json:"container,omitempty"`
Kubernetes Kubernetes `json:"kubernetes,omitempty"`
Expand All @@ -40,6 +41,7 @@ type Event struct {
Syscall string `json:"syscall"`
StackAddresses []uint64 `json:"stackAddresses"`
ContextFlags ContextFlags `json:"contextFlags"`
Ancestors []Process `json:"ancestors"`
Args []Argument `json:"args"` // Arguments are ordered according their appearance in the original event
Metadata *Metadata `json:"metadata,omitempty"`
}
Expand Down Expand Up @@ -72,6 +74,19 @@ type ContextFlags struct {
IsCompat bool `json:"isCompat"`
}

type BinaryInfo struct {
Inode uint `json:"inode"`
Device uint `json:"device"`
Ctime int `json:"ctime"`
Path string `json:"path"`
}

type Process struct {
ID int `json:"id"`
Name string `json:"name"`
Binary BinaryInfo `json:"binary"`
}

// EventOrigin is where a trace.Event occured, it can either be from the host machine or from a container
type EventOrigin string

Expand Down

0 comments on commit e4dae80

Please sign in to comment.