Skip to content

Commit b90752b

Browse files
committed
Fix #90 v1.8.0 beta5 bug
Fix #91 Correlate and enrich Microsoft-Windows-Kernel-File ETW logs
1 parent de162e5 commit b90752b

File tree

8 files changed

+237
-19
lines changed

8 files changed

+237
-19
lines changed

event/event.go

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,10 +81,35 @@ func (e *EdrEvent) GetInt(p engine.XPath) (i int64, ok bool) {
8181
return
8282
}
8383
}
84+
return
85+
}
86+
87+
func (e *EdrEvent) GetIntOr(p engine.XPath, or int64) (i int64, ok bool) {
88+
if i, ok = e.GetInt(p); ok {
89+
return
90+
}
91+
return or, ok
92+
}
93+
94+
func (e *EdrEvent) GetUint(p engine.XPath) (i uint64, ok bool) {
95+
var s string
96+
var err error
8497

98+
if s, ok = e.GetString(p); ok {
99+
if i, err = strconv.ParseUint(s, 0, 64); err == nil {
100+
return
101+
}
102+
}
85103
return
86104
}
87105

106+
func (e *EdrEvent) GetUintOr(p engine.XPath, or uint64) (i uint64, ok bool) {
107+
if i, ok = e.GetUint(p); ok {
108+
return
109+
}
110+
return or, ok
111+
}
112+
88113
func (e *EdrEvent) GetBool(p engine.XPath) (b bool, ok bool) {
89114
var s string
90115
var err error

hids/eventids.go

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,3 +35,60 @@ const (
3535
// https://docs.microsoft.com/en-us/windows/security/threat-protection/auditing/event-4663
3636
SecurityAccessObject = 4663
3737
)
38+
39+
// Microsoft-Windows-Kernel-File/Analytic
40+
const (
41+
KernelFileNameCreate int64 = iota + 10
42+
KernelFileNameDelete
43+
KernelFileCreate
44+
KernelFileCleanup
45+
KernelFileClose
46+
KernelFileRead
47+
KernelFileWrite
48+
KernelFileSetInformation
49+
KernelFileSetDelete
50+
KernelFileRename
51+
KernelFileDirEnum
52+
KernelFileFlush
53+
KernelFileQueryInformation
54+
KernelFileFSCTL
55+
KernelFileOperationEnd
56+
KernelFileDirNotify
57+
KernelFileDeletePath
58+
KernelFileRenamePath
59+
KernelFileSetLinkPath
60+
KernelFileCreateNewFile
61+
KernelFileSetSecurity
62+
KernelFileQuerySecurity
63+
KernelFileSetEA
64+
KernelFileQueryEA
65+
)
66+
67+
var (
68+
KernelFileOperations = map[int64]string{
69+
KernelFileNameCreate: "NameCreate",
70+
KernelFileNameDelete: "NameDelete",
71+
KernelFileCreate: "Create",
72+
KernelFileCleanup: "Cleanup",
73+
KernelFileClose: "Close",
74+
KernelFileRead: "Read",
75+
KernelFileWrite: "Write",
76+
KernelFileSetInformation: "SetInformation",
77+
KernelFileSetDelete: "SetDelete",
78+
KernelFileRename: "Rename",
79+
KernelFileDirEnum: "DirEnum",
80+
KernelFileFlush: "Flush",
81+
KernelFileQueryInformation: "QueryInformation",
82+
KernelFileFSCTL: "FSCTL",
83+
KernelFileOperationEnd: "OperationEnd",
84+
KernelFileDirNotify: "DirNotify",
85+
KernelFileDeletePath: "DeletePath",
86+
KernelFileRenamePath: "RenamePath",
87+
KernelFileSetLinkPath: "SetLinkPath",
88+
KernelFileCreateNewFile: "CreateNewFile",
89+
KernelFileSetSecurity: "SetSecurity",
90+
KernelFileQuerySecurity: "QuerySecurity",
91+
KernelFileSetEA: "SetEA",
92+
KernelFileQueryEA: "QueryEA",
93+
}
94+
)

hids/filters.go

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,10 @@ import (
55
"github.com/0xrawsec/whids/event"
66
)
77

8+
//Sysmon related
89
var (
910
// sysmonChannel Sysmon windows event log channel
1011
sysmonChannel = "Microsoft-Windows-Sysmon/Operational"
11-
// securityChannel Security windows event log channel
12-
securityChannel = "Security"
1312

1413
// Filters definitions
1514
fltAnyEvent = NewFilter([]int64{}, "")
@@ -40,11 +39,30 @@ var (
4039
SysmonFileDelete,
4140
SysmonFileDeleteDetected},
4241
sysmonChannel)
42+
)
4343

44+
// Security channel related
45+
var (
46+
// securityChannel Security windows event log channel
47+
securityChannel = "Security"
4448
// Security filters
4549
fltFSObjectAccess = NewFilter([]int64{SecurityAccessObject}, securityChannel)
4650
)
4751

52+
// ETW Kernel File related
53+
var (
54+
kernelFileChannel = "Microsoft-Windows-Kernel-File/Analytic"
55+
/*fltKernelFile = NewFilter([]int64{
56+
KernelFileCreate,
57+
KernelFileClose,
58+
KernelFileRead,
59+
KernelFileWrite},
60+
kernelFileChannel)
61+
*/
62+
fltKernelFile = NewFilter([]int64{},
63+
kernelFileChannel)
64+
)
65+
4866
// Filter structure
4967
type Filter struct {
5068
EventIDs *datastructs.SyncedSet

hids/hids.go

Lines changed: 16 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -159,10 +159,11 @@ func NewHIDS(c *Config) (h *HIDS, err error) {
159159
// fixing local audit policies if necessary
160160
h.config.AuditConfig.Configure()
161161

162-
// tries to update the engine
162+
// update and load engine
163163
if err := h.update(true); err != nil {
164164
return h, err
165165
}
166+
166167
return h, nil
167168
}
168169

@@ -194,26 +195,22 @@ func (h *HIDS) initHooks(advanced bool) {
194195
h.preHooks.Hook(hookFileSystemAudit, fltFSObjectAccess)
195196
// Must be run the last as it depends on other filters
196197
h.preHooks.Hook(hookEnrichAnySysmon, fltAnySysmon)
197-
// Not sastifying results with Sysmon 11.11 we should try enabling this on newer versions
198-
//h.preHooks.Hook(HookDNS, fltDNS)
199-
//h.preHooks.Hook(hookEnrichDNSSysmon, fltNetworkConnect)
200-
// Experimental
201-
//h.preHooks.Hook(hookSetValueSize, fltRegSetValue)
198+
h.preHooks.Hook(hookKernelFiles, fltKernelFile)
202199

203200
// This hook must run before action handling as we want
204201
// the gene score to be set before an eventual reporting
205202
h.postHooks.Hook(hookUpdateGeneScore, fltAnyEvent)
206-
// Handles actions defined in rules for any Sysmon event
207-
/*if h.config.Endpoint {
208-
h.postHooks.Hook(hookHandleActions, fltAnyEvent)
209-
}*/
210203
}
211204
}
212205

213206
func (h *HIDS) update(force bool) (last error) {
207+
var reloadRules, reloadContainers bool
214208

215-
reloadRules := h.needsRulesUpdate()
216-
reloadContainers := h.needsIoCsUpdate()
209+
// check that we are connected to any manager
210+
if h.config.IsForwardingEnabled() {
211+
reloadRules = h.needsRulesUpdate()
212+
reloadContainers = h.needsIoCsUpdate()
213+
}
217214

218215
// check if we need rule update
219216
if reloadRules {
@@ -309,7 +306,8 @@ func (h *HIDS) needsRulesUpdate() bool {
309306
var oldSha256, sha256 string
310307
_, rulesSha256Path := h.config.RulesConfig.RulesPaths()
311308

312-
if h.forwarder.Local {
309+
// Don't need update if not connected to a manager
310+
if h.config.IsForwardingEnabled() {
313311
return false
314312
}
315313

@@ -326,6 +324,11 @@ func (h *HIDS) needsRulesUpdate() bool {
326324
func (h *HIDS) needsIoCsUpdate() bool {
327325
var localSha256, remoteSha256 string
328326

327+
// Don't need update if not connected to a manager
328+
if h.config.IsForwardingEnabled() {
329+
return false
330+
}
331+
329332
container := api.IoCContainerName
330333
_, locContSha256Path := h.containerPaths(container)
331334

hids/hookdefs.go

Lines changed: 46 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -294,7 +294,7 @@ func hookUpdateGeneScore(h *HIDS, e *event.EdrEvent) {
294294
return
295295
}
296296

297-
if t := processTrackFromEvent(h, e); t != nil {
297+
if t := processTrackFromEvent(h, e); !t.IsZero() {
298298
if d := e.GetDetection(); d != nil {
299299
t.ThreatScore.Update(d)
300300
}
@@ -684,3 +684,48 @@ func hookClipboardEvents(h *HIDS, e *event.EdrEvent) {
684684
}
685685
}
686686
}
687+
688+
var (
689+
pathKernelFileFileObject = engine.Path("/Event/EventData/FileObject")
690+
pathKernelFileFileName = engine.Path("/Event/EventData/FileName")
691+
)
692+
693+
func hookKernelFiles(h *HIDS, e *event.EdrEvent) {
694+
695+
// Enrich all events with Sysmon Info
696+
pt := h.processTracker.GetByPID(int64(e.Event.System.Execution.ProcessID))
697+
698+
// We enrich event with other data
699+
e.SetIfOr(pathSysmonProcessGUID, pt.ProcessGUID, !pt.IsZero(), "?")
700+
e.SetIfOr(pathSysmonImage, pt.Image, !pt.IsZero(), "?")
701+
e.SetIfOr(pathSysmonCommandLine, pt.CommandLine, !pt.IsZero(), "?")
702+
// put hashes in ImageHashes field to avoid confusion in analyst's mind
703+
// not to think it is file content hashes
704+
e.SetIfOr(pathImageHashes, pt.hashes, !pt.IsZero(), "?")
705+
e.SetIfOr(pathSysmonProcessId, toString(pt.PID), !pt.IsZero(), toString(-1))
706+
e.SetIfOr(pathSysmonIntegrityLevel, pt.IntegrityLevel, !pt.IsZero(), "?")
707+
e.SetIfOr(pathSysmonUser, pt.User, !pt.IsZero(), "?")
708+
e.SetIfOr(pathServices, pt.Services, !pt.IsZero(), "?")
709+
e.Set(pathSysmonEventType, KernelFileOperations[e.EventID()])
710+
711+
if e.EventID() == KernelFileCreate {
712+
// We track file
713+
h.processTracker.AddKernelFile(KernelFileFromEvent(e))
714+
} else {
715+
var fo uint64
716+
var ok bool
717+
718+
// We correlate with the filename
719+
if fo, ok = e.GetUint(pathKernelFileFileObject); ok {
720+
fileName := "?"
721+
if kf, ok := h.processTracker.GetKernelFile(fo); ok {
722+
fileName = kf.FileName
723+
}
724+
e.Set(pathKernelFileFileName, fileName)
725+
}
726+
// We delete entry in tracking structure
727+
if e.EventID() == KernelFileClose {
728+
h.processTracker.DelKernelFile(fo)
729+
}
730+
}
731+
}

hids/paths.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ var (
7272
pathSysmonTargetImage = engine.Path("/Event/EventData/TargetImage")
7373

7474
// EventID 12,13,14: Registry
75+
pathSysmonEventType = engine.Path("/Event/EventData/EventType")
7576
pathSysmonTargetObject = engine.Path("/Event/EventData/TargetObject")
7677
pathSysmonDetails = engine.Path("/Event/EventData/Details")
7778

0 commit comments

Comments
 (0)