Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion pkg/config/schema_windows.go
Original file line number Diff line number Diff line change
Expand Up @@ -197,7 +197,7 @@ var schema = `
"blacklist": {
"type": "object",
"properties": {
"events": {"type": "array", "items": {"type": "string", "enum": ["CreateThread", "TerminateThread", "OpenProcess", "OpenThread", "SetThreadContext", "LoadImage", "UnloadImage", "CreateFile", "CloseFile", "ReadFile", "WriteFile", "DeleteFile", "RenameFile", "SetFileInformation", "EnumDirectory", "MapViewFile", "UnmapViewFile", "RegCreateKey", "RegOpenKey", "RegSetValue", "RegQueryValue", "RegQueryKey", "RegDeleteKey", "RegDeleteValue", "RegCloseKey", "Accept", "Send", "Recv", "Connect", "Disconnect", "Reconnect", "Retransmit", "CreateHandle", "CloseHandle", "DuplicateHandle", "QueryDns", "ReplyDns", "VirtualAlloc", "VirtualFree"]}},
"events": {"type": "array", "items": {"type": "string", "enum": ["CreateThread", "TerminateThread", "OpenProcess", "OpenThread", "SetThreadContext", "LoadImage", "UnloadImage", "CreateFile", "CloseFile", "ReadFile", "WriteFile", "DeleteFile", "RenameFile", "SetFileInformation", "EnumDirectory", "MapViewFile", "UnmapViewFile", "RegCreateKey", "RegOpenKey", "RegSetValue", "RegQueryValue", "RegQueryKey", "RegDeleteKey", "RegDeleteValue", "RegCloseKey", "Accept", "Send", "Recv", "Connect", "Disconnect", "Reconnect", "Retransmit", "CreateHandle", "CloseHandle", "DuplicateHandle", "QueryDns", "ReplyDns", "VirtualAlloc", "VirtualFree", "CreateSymbolicLinkObject"]}},
"images": {"type": "array", "items": {"type": "string", "minLength": 1}}
},
"additionalProperties": false
Expand Down
3 changes: 2 additions & 1 deletion pkg/filter/rules.go
Original file line number Diff line number Diff line change
Expand Up @@ -651,7 +651,8 @@ func (r *Rules) buildCompileResult() *config.RulesCompileResult {
if typ == ktypes.MapViewFile || typ == ktypes.UnmapViewFile {
rs.HasVAMapEvents = true
}
if typ == ktypes.OpenProcess || typ == ktypes.OpenThread || typ == ktypes.SetThreadContext {
if typ == ktypes.OpenProcess || typ == ktypes.OpenThread || typ == ktypes.SetThreadContext ||
typ == ktypes.CreateSymbolicLinkObject {
rs.HasAuditAPIEvents = true
}
if typ.Subcategory() == ktypes.DNS {
Expand Down
17 changes: 17 additions & 0 deletions pkg/kevent/flags.go
Original file line number Diff line number Diff line change
Expand Up @@ -256,3 +256,20 @@ var DNSOptsFlags = []ParamFlag{
{"DISABLE_IDN_ENCODING", 0x00200000},
{"APPEND_MULTILABEL", 0x00800000},
}

// AccessMaskFlags describes the generic and specific access rights
var AccessMaskFlags = []ParamFlag{
{"DELETE", windows.DELETE},
{"READ_CONTROL", windows.READ_CONTROL},
{"WRITE_DAC", windows.WRITE_DAC},
{"WRITE_OWNER", windows.WRITE_OWNER},
{"SYNCHRONIZE", windows.SYNCHRONIZE},
{"STANDARD_RIGHTS_REQUIRED", windows.STANDARD_RIGHTS_REQUIRED},
{"STANDARD_RIGHTS_ALL", windows.STANDARD_RIGHTS_ALL},
{"ACCESS_SYSTEM_SECURITY", windows.ACCESS_SYSTEM_SECURITY},
{"MAXIMUM_ALLOWED", windows.MAXIMUM_ALLOWED},
{"GENERIC_READ", windows.GENERIC_READ},
{"GENERIC_WRITE", windows.GENERIC_WRITE},
{"GENERIC_EXECUTE", windows.GENERIC_EXECUTE},
{"GENERIC_ALL", windows.GENERIC_ALL},
}
12 changes: 12 additions & 0 deletions pkg/kevent/kparam_windows.go
Original file line number Diff line number Diff line change
Expand Up @@ -735,6 +735,18 @@ func (e *Kevent) produceParams(evt *etw.EventRecord) {
n++
}
e.AppendParam(kparams.Callstack, kparams.Slice, callstack)
case ktypes.CreateSymbolicLinkObject:
source, offset := evt.ReadUTF16String(0)
target, offset := evt.ReadUTF16String(offset)
desiredAccess := evt.ReadUint32(offset)
status := evt.ReadUint32(offset + 4)
e.AppendParam(kparams.LinkSource, kparams.UnicodeString, source)
e.AppendParam(kparams.LinkTarget, kparams.UnicodeString, target)
e.AppendParam(kparams.DesiredAccess, kparams.Flags, desiredAccess, WithFlags(AccessMaskFlags))
e.AppendParam(kparams.NTStatus, kparams.Status, status)
if evt.HasStackTrace() {
e.AppendParam(kparams.Callstack, kparams.Slice, evt.Callstack())
}
}
}

Expand Down
5 changes: 5 additions & 0 deletions pkg/kevent/kparams/fields_windows.go
Original file line number Diff line number Diff line change
Expand Up @@ -241,4 +241,9 @@ const (
MemProtectMask = "protection_mask"
// MemPageType identifies the parameter that represents the allocated region type.
MemPageType = "page_type"

// LinkSource identifies the parameter that represents the source symbolic link object or other kernel object
LinkSource = "source"
// LinkTarget identifies the parameter that represents the target symbolic link object or other kernel object
LinkTarget = "target"
)
3 changes: 3 additions & 0 deletions pkg/kevent/ktypes/category.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,8 @@ const (
Driver Category = "driver"
// Mem is the category for memory events
Mem Category = "mem"
// Object the category for object manager events
Object Category = "object"
// Other is the category for uncategorized events
Other Category = "other"
// Unknown is the category for events that couldn't match any of the previous categories
Expand Down Expand Up @@ -79,5 +81,6 @@ func Categories() []string {
string(Driver),
string(Other),
string(Unknown),
string(Object),
}
}
13 changes: 11 additions & 2 deletions pkg/kevent/ktypes/ktypes_windows.go
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,9 @@ var (
// StackWalk represents stack walk event with the collection of return addresses
StackWalk = pack(windows.GUID{Data1: 0xdef2fe46, Data2: 0x7bd6, Data3: 0x4b80, Data4: [8]byte{0xbd, 0x94, 0xf5, 0x7f, 0xe2, 0x0d, 0x0c, 0xe3}}, 32)

// CreateSymbolicLinkObject represents the event emitted by the object manager when the new symbolic link is created within the object manager directory
CreateSymbolicLinkObject = pack(AuditAPIEventGUID, 3)

// UnknownKtype designates unknown kernel event type
UnknownKtype = pack(windows.GUID{}, 0)
)
Expand Down Expand Up @@ -322,6 +325,8 @@ func (k Ktype) String() string {
return "ReplyDns"
case StackWalk:
return "StackWalk"
case CreateSymbolicLinkObject:
return "CreateSymbolicLinkObject"
default:
return ""
}
Expand Down Expand Up @@ -355,6 +360,8 @@ func (k Ktype) Category() Category {
return Handle
case VirtualAlloc, VirtualFree:
return Mem
case CreateSymbolicLinkObject:
return Object
default:
return Unknown
}
Expand Down Expand Up @@ -455,6 +462,8 @@ func (k Ktype) Description() string {
return "Sends a DNS query to the name server"
case ReplyDNS:
return "Receives the response from the DNS server"
case CreateSymbolicLinkObject:
return "Creates the symbolic link within the object manager directory"
default:
return ""
}
Expand Down Expand Up @@ -540,7 +549,7 @@ func (k *Ktype) HookID() uint16 {
// Source designates the provenance of this event type.
func (k Ktype) Source() EventSource {
switch k {
case OpenProcess, OpenThread, SetThreadContext:
case OpenProcess, OpenThread, SetThreadContext, CreateSymbolicLinkObject:
return AuditAPICallsLogger
case QueryDNS, ReplyDNS:
return DNSLogger
Expand All @@ -555,7 +564,7 @@ func (k Ktype) Source() EventSource {
// events, but it appears first on the consumer callback
// before other events published before it.
func (k Ktype) CanArriveOutOfOrder() bool {
return k.Category() == Registry || k.Subcategory() == DNS || k == OpenProcess || k == OpenThread || k == SetThreadContext
return k.Category() == Registry || k.Subcategory() == DNS || k == OpenProcess || k == OpenThread || k == SetThreadContext || k == CreateSymbolicLinkObject
}

// FromParts builds ktype from provider GUID and hook ID.
Expand Down
Loading
Loading