Skip to content

Commit f050bc2

Browse files
authored
feat: Driver loading events (#132)
* introduce Antimalware Engine provider and LoadDriver events * add LoadDriver event metainfo * fix tests and build errors
1 parent 380790a commit f050bc2

21 files changed

Lines changed: 453 additions & 177 deletions

configs/fibratus.yml

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -175,6 +175,13 @@ kstream:
175175
# collected by Kernel Logger provider
176176
#enable-handle: false
177177

178+
# Determines whether kernel Audit API calls events are collected
179+
#enable-audit-api: true
180+
181+
# Determines whether the Microsoft Antimalware Engine events are collected. For the
182+
# events to be collected it is necessary to enable Windows Defender realtime protection.
183+
#enable-antimalware-engine: true
184+
178185
# Determines if raw event buffer parsing is used instead of TDH (Trace Data Helper) API
179186
# raw-event-parsing: true
180187

@@ -184,7 +191,6 @@ kstream:
184191
# Contains a list of kernel event names that are dropped from the event stream
185192
events:
186193
- CloseFile
187-
- CloseHandle
188194
# Contains a list of case-sensitive process image names including the extension.
189195
# Any event originated by the image specified in this list is dropped from the event stream
190196
images:

pkg/config/config_windows.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -335,6 +335,8 @@ func (c *Config) addFlags() {
335335
c.flags.Bool(enableFileIOKevents, true, "Determines whether disk I/O kernel events are collected by Kernel Logger provider")
336336
c.flags.Bool(enableImageKevents, true, "Determines whether file I/O kernel events are collected by Kernel Logger provider")
337337
c.flags.Bool(enableHandleKevents, false, "Determines whether object manager kernel events (handle creation/destruction) are collected by Kernel Logger provider")
338+
c.flags.Bool(enableAuditAPIEvents, true, "Determines whether kernel audit API calls events are published")
339+
c.flags.Bool(enableAntimalwareEngineEvents, true, "Determines whether antimalware engine events are published")
338340
c.flags.Int(bufferSize, int(maxBufferSize), "Represents the amount of memory allocated for each event tracing session buffer, in kilobytes. The buffer size affects the rate at which buffers fill and must be flushed (small buffer size requires less memory but it increases the rate at which buffers must be flushed)")
339341
c.flags.Int(minBuffers, int(defaultMinBuffers), "Determines the minimum number of buffers allocated for the event tracing session's buffer pool")
340342
c.flags.Int(maxBuffers, int(defaultMaxBuffers), "Determines the maximum number of buffers allocated for the event tracing session's buffer pool")

pkg/config/kstream.go

Lines changed: 19 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -33,17 +33,19 @@ import (
3333
)
3434

3535
const (
36-
enableThreadKevents = "kstream.enable-thread"
37-
enableRegistryKevents = "kstream.enable-registry"
38-
enableNetKevents = "kstream.enable-net"
39-
enableFileIOKevents = "kstream.enable-fileio"
40-
enableImageKevents = "kstream.enable-image"
41-
enableHandleKevents = "kstream.enable-handle"
42-
bufferSize = "kstream.buffer-size"
43-
minBuffers = "kstream.min-buffers"
44-
maxBuffers = "kstream.max-buffers"
45-
flushInterval = "kstream.flush-interval"
46-
rawEventParsing = "kstream.raw-event-parsing"
36+
enableThreadKevents = "kstream.enable-thread"
37+
enableRegistryKevents = "kstream.enable-registry"
38+
enableNetKevents = "kstream.enable-net"
39+
enableFileIOKevents = "kstream.enable-fileio"
40+
enableImageKevents = "kstream.enable-image"
41+
enableHandleKevents = "kstream.enable-handle"
42+
enableAuditAPIEvents = "kstream.enable-audit-api"
43+
enableAntimalwareEngineEvents = "kstream.enable-antimalware-engine"
44+
bufferSize = "kstream.buffer-size"
45+
minBuffers = "kstream.min-buffers"
46+
maxBuffers = "kstream.max-buffers"
47+
flushInterval = "kstream.flush-interval"
48+
rawEventParsing = "kstream.raw-event-parsing"
4749

4850
excludedEvents = "kstream.blacklist.events"
4951
excludedImages = "kstream.blacklist.images"
@@ -71,6 +73,10 @@ type KstreamConfig struct {
7173
EnableImageKevents bool `json:"enable-image" yaml:"enable-image"`
7274
// EnableHandleKevents indicates whether handle creation/disposal events are enabled.
7375
EnableHandleKevents bool `json:"enable-handle" yaml:"enable-handle"`
76+
// EnableAuditAPIEvents indicates if kernel audit API calls events are enabled
77+
EnableAuditAPIEvents bool `json:"enable-audit-api" yaml:"enable-audit-api"`
78+
// EnableAntimalwareEngineEvents indicates if Antimalware Engine events are enabled
79+
EnableAntimalwareEngineEvents bool `json:"enable-antimalware-engine" yaml:"enable-antimalware-engine"`
7480
// BufferSize represents the amount of memory allocated for each event tracing session buffer, in kilobytes.
7581
// The buffer size affects the rate at which buffers fill and must be flushed (small buffer size requires
7682
// less memory but it increases the rate at which buffers must be flushed).
@@ -100,6 +106,8 @@ func (c *KstreamConfig) initFromViper(v *viper.Viper) {
100106
c.EnableFileIOKevents = v.GetBool(enableFileIOKevents)
101107
c.EnableImageKevents = v.GetBool(enableImageKevents)
102108
c.EnableHandleKevents = v.GetBool(enableHandleKevents)
109+
c.EnableAuditAPIEvents = v.GetBool(enableAuditAPIEvents)
110+
c.EnableAntimalwareEngineEvents = v.GetBool(enableAntimalwareEngineEvents)
103111
c.BufferSize = uint32(v.GetInt(bufferSize))
104112
c.MinBuffers = uint32(v.GetInt(minBuffers))
105113
c.MaxBuffers = uint32(v.GetInt(maxBuffers))

pkg/config/schema_windows.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,8 @@ var schema = `
153153
"enable-fileio": {"type": "boolean"},
154154
"enable-handle": {"type": "boolean"},
155155
"enable-net": {"type": "boolean"},
156+
"enable-audit-api": {"type": "boolean"},
157+
"enable-antimalware-engine": {"type": "boolean"},
156158
"raw-event-parsing":{"type": "boolean"},
157159
"min-buffers": {"type": "integer", "minimum": 1, "maximum": {{ .MinBuffers }}},
158160
"max-buffers": {"type": "integer", "minimum": 2, "maximum": {{ .MaxBuffers }}},

pkg/handle/types.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,8 @@ const (
6666
Process = "Process"
6767
// SymbolicLink represents the symbolic link object
6868
SymbolicLink = "SymbolicLink"
69+
// Driver represents the device driver object
70+
Driver = "Driver"
6971
// Unknown is the unknown handle object
7072
Unknown = "Unknown"
7173
)

pkg/kevent/kparam.go

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,17 @@ func NewKparamFromKcap(name string, typ kparams.Type, value kparams.Value) *Kpar
7878
return &Kparam{Name: name, Type: typ, Value: value}
7979
}
8080

81+
// NewKparamBuilder yields a new event parameter builder.
82+
func NewKparamBuilder(n int) Kparams {
83+
kpars := make(Kparams, n)
84+
return kpars
85+
}
86+
87+
// Build returns all appended parameters.
88+
func (kpars Kparams) Build() Kparams {
89+
return kpars
90+
}
91+
8192
// Append adds a new parameter with the specified name, type and value.
8293
func (kpars Kparams) Append(name string, typ kparams.Type, value kparams.Value) Kparams {
8394
kpars[name] = NewKparam(name, typ, value)

pkg/kevent/kparams/canonicalize.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@ const (
3030
dirTableBase = "DirectoryTableBase"
3131
userSID = "UserSID"
3232
imageFileName = "ImageFileName"
33+
imageName = "ImageName"
34+
imagePath = "ImagePath"
3335
commandLine = "CommandLine"
3436

3537
tthreadID = "TThreadId"
@@ -105,6 +107,8 @@ func Canonicalize(name string) string {
105107
return SessionID
106108
case imageFileName:
107109
return ProcessName
110+
case imageName, imagePath:
111+
return ImageFilename
108112
case commandLine:
109113
return Comm
110114
case userSID:

pkg/kevent/ktypes/category.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,8 @@ const (
3838
Image Category = "image"
3939
// Handle is the category for handle events
4040
Handle Category = "handle"
41+
// Driver is the category for driver events
42+
Driver Category = "driver"
4143
// Other is the category for uncategorized events
4244
Other Category = "other"
4345
// Unknown is the category for events that couldn't match any of the previous categories

pkg/kevent/ktypes/ktypes_windows.go

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,9 @@ var (
160160
// CloseHandle represents handle closure kernel event
161161
CloseHandle = Pack(syscall.GUID{Data1: 0x89497f50, Data2: 0xeffe, Data3: 0x4440, Data4: [8]byte{0x8c, 0xf2, 0xce, 0x6b, 0x1c, 0xdc, 0xac, 0xa7}}, 33)
162162

163+
// LoadDriver represents kernel driver loading event.
164+
LoadDriver = Pack(syscall.GUID{Data1: 0xa002690, Data2: 0x3839, Data3: 0x4e3a, Data4: [8]byte{0xb3, 0xb6, 0x96, 0xd8, 0xdf, 0x86, 0x8d, 0x99}}, 10)
165+
163166
// UnknownKtype designates unknown kernel event type
164167
UnknownKtype = Pack(syscall.GUID{}, 0)
165168
)
@@ -241,6 +244,8 @@ func (k Ktype) String() string {
241244
return "Disconnect"
242245
case Retransmit, RetransmitTCPv4, RetransmitTCPv6:
243246
return "Retransmit"
247+
case LoadDriver:
248+
return "LoadDriver"
244249
default:
245250
return string(k[:])
246251
}
@@ -269,6 +274,8 @@ func (k Ktype) Category() Category {
269274
return Net
270275
case CreateHandle, CloseHandle:
271276
return Handle
277+
case LoadDriver:
278+
return Driver
272279
default:
273280
return Unknown
274281
}
@@ -341,6 +348,8 @@ func (k Ktype) Description() string {
341348
return "Creates a new handle"
342349
case CloseHandle:
343350
return "Closes the handle"
351+
case LoadDriver:
352+
return "Loads the kernel driver"
344353
default:
345354
return ""
346355
}
@@ -403,7 +412,8 @@ func (k Ktype) Exists() bool {
403412
RetransmitTCPv4, RetransmitTCPv6,
404413
DisconnectTCPv4, DisconnectTCPv6,
405414
SendTCPv4, SendTCPv6, SendUDPv4, SendUDPv6,
406-
RecvTCPv4, RecvTCPv6, RecvUDPv4, RecvUDPv6:
415+
RecvTCPv4, RecvTCPv6, RecvUDPv4, RecvUDPv6,
416+
LoadDriver:
407417
return true
408418
default:
409419
return false

pkg/kevent/ktypes/metainfo_windows.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ var kevents = map[Ktype]KeventInfo{
6464
UnloadImage: {"UnloadImage", Image, "Unloads the module from the address space of the calling process"},
6565
CreateHandle: {"CreateHandle", Handle, "Creates a new handle"},
6666
CloseHandle: {"CloseHandle", Handle, "Closes the handle"},
67+
LoadDriver: {"LoadDriver", Driver, "Loads the kernel driver"},
6768
}
6869

6970
var ktypes = map[string]Ktype{
@@ -99,6 +100,7 @@ var ktypes = map[string]Ktype{
99100
"Retransmit": Retransmit,
100101
"CreateHandle": CreateHandle,
101102
"CloseHandle": CloseHandle,
103+
"LoadDriver": LoadDriver,
102104
}
103105

104106
// KtypeToKeventInfo maps the kernel event type to a structure that stores detailed information about the event.

0 commit comments

Comments
 (0)