Skip to content

Commit

Permalink
Fix #90 v1.8.0 beta5 bug
Browse files Browse the repository at this point in the history
Fix #91 Correlate and enrich Microsoft-Windows-Kernel-File ETW logs
  • Loading branch information
qjerome committed Dec 10, 2021
1 parent de162e5 commit b90752b
Show file tree
Hide file tree
Showing 8 changed files with 237 additions and 19 deletions.
25 changes: 25 additions & 0 deletions event/event.go
Original file line number Diff line number Diff line change
Expand Up @@ -81,10 +81,35 @@ func (e *EdrEvent) GetInt(p engine.XPath) (i int64, ok bool) {
return
}
}
return
}

func (e *EdrEvent) GetIntOr(p engine.XPath, or int64) (i int64, ok bool) {
if i, ok = e.GetInt(p); ok {
return
}
return or, ok
}

func (e *EdrEvent) GetUint(p engine.XPath) (i uint64, ok bool) {
var s string
var err error

if s, ok = e.GetString(p); ok {
if i, err = strconv.ParseUint(s, 0, 64); err == nil {
return
}
}
return
}

func (e *EdrEvent) GetUintOr(p engine.XPath, or uint64) (i uint64, ok bool) {
if i, ok = e.GetUint(p); ok {
return
}
return or, ok
}

func (e *EdrEvent) GetBool(p engine.XPath) (b bool, ok bool) {
var s string
var err error
Expand Down
57 changes: 57 additions & 0 deletions hids/eventids.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,3 +35,60 @@ const (
// https://docs.microsoft.com/en-us/windows/security/threat-protection/auditing/event-4663
SecurityAccessObject = 4663
)

// Microsoft-Windows-Kernel-File/Analytic
const (
KernelFileNameCreate int64 = iota + 10
KernelFileNameDelete
KernelFileCreate
KernelFileCleanup
KernelFileClose
KernelFileRead
KernelFileWrite
KernelFileSetInformation
KernelFileSetDelete
KernelFileRename
KernelFileDirEnum
KernelFileFlush
KernelFileQueryInformation
KernelFileFSCTL
KernelFileOperationEnd
KernelFileDirNotify
KernelFileDeletePath
KernelFileRenamePath
KernelFileSetLinkPath
KernelFileCreateNewFile
KernelFileSetSecurity
KernelFileQuerySecurity
KernelFileSetEA
KernelFileQueryEA
)

var (
KernelFileOperations = map[int64]string{
KernelFileNameCreate: "NameCreate",
KernelFileNameDelete: "NameDelete",
KernelFileCreate: "Create",
KernelFileCleanup: "Cleanup",
KernelFileClose: "Close",
KernelFileRead: "Read",
KernelFileWrite: "Write",
KernelFileSetInformation: "SetInformation",
KernelFileSetDelete: "SetDelete",
KernelFileRename: "Rename",
KernelFileDirEnum: "DirEnum",
KernelFileFlush: "Flush",
KernelFileQueryInformation: "QueryInformation",
KernelFileFSCTL: "FSCTL",
KernelFileOperationEnd: "OperationEnd",
KernelFileDirNotify: "DirNotify",
KernelFileDeletePath: "DeletePath",
KernelFileRenamePath: "RenamePath",
KernelFileSetLinkPath: "SetLinkPath",
KernelFileCreateNewFile: "CreateNewFile",
KernelFileSetSecurity: "SetSecurity",
KernelFileQuerySecurity: "QuerySecurity",
KernelFileSetEA: "SetEA",
KernelFileQueryEA: "QueryEA",
}
)
22 changes: 20 additions & 2 deletions hids/filters.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,10 @@ import (
"github.com/0xrawsec/whids/event"
)

//Sysmon related
var (
// sysmonChannel Sysmon windows event log channel
sysmonChannel = "Microsoft-Windows-Sysmon/Operational"
// securityChannel Security windows event log channel
securityChannel = "Security"

// Filters definitions
fltAnyEvent = NewFilter([]int64{}, "")
Expand Down Expand Up @@ -40,11 +39,30 @@ var (
SysmonFileDelete,
SysmonFileDeleteDetected},
sysmonChannel)
)

// Security channel related
var (
// securityChannel Security windows event log channel
securityChannel = "Security"
// Security filters
fltFSObjectAccess = NewFilter([]int64{SecurityAccessObject}, securityChannel)
)

// ETW Kernel File related
var (
kernelFileChannel = "Microsoft-Windows-Kernel-File/Analytic"
/*fltKernelFile = NewFilter([]int64{
KernelFileCreate,
KernelFileClose,
KernelFileRead,
KernelFileWrite},
kernelFileChannel)
*/
fltKernelFile = NewFilter([]int64{},
kernelFileChannel)
)

// Filter structure
type Filter struct {
EventIDs *datastructs.SyncedSet
Expand Down
29 changes: 16 additions & 13 deletions hids/hids.go
Original file line number Diff line number Diff line change
Expand Up @@ -159,10 +159,11 @@ func NewHIDS(c *Config) (h *HIDS, err error) {
// fixing local audit policies if necessary
h.config.AuditConfig.Configure()

// tries to update the engine
// update and load engine
if err := h.update(true); err != nil {
return h, err
}

return h, nil
}

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

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

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

reloadRules := h.needsRulesUpdate()
reloadContainers := h.needsIoCsUpdate()
// check that we are connected to any manager
if h.config.IsForwardingEnabled() {
reloadRules = h.needsRulesUpdate()
reloadContainers = h.needsIoCsUpdate()
}

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

if h.forwarder.Local {
// Don't need update if not connected to a manager
if h.config.IsForwardingEnabled() {
return false
}

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

// Don't need update if not connected to a manager
if h.config.IsForwardingEnabled() {
return false
}

container := api.IoCContainerName
_, locContSha256Path := h.containerPaths(container)

Expand Down
47 changes: 46 additions & 1 deletion hids/hookdefs.go
Original file line number Diff line number Diff line change
Expand Up @@ -294,7 +294,7 @@ func hookUpdateGeneScore(h *HIDS, e *event.EdrEvent) {
return
}

if t := processTrackFromEvent(h, e); t != nil {
if t := processTrackFromEvent(h, e); !t.IsZero() {
if d := e.GetDetection(); d != nil {
t.ThreatScore.Update(d)
}
Expand Down Expand Up @@ -684,3 +684,48 @@ func hookClipboardEvents(h *HIDS, e *event.EdrEvent) {
}
}
}

var (
pathKernelFileFileObject = engine.Path("/Event/EventData/FileObject")
pathKernelFileFileName = engine.Path("/Event/EventData/FileName")
)

func hookKernelFiles(h *HIDS, e *event.EdrEvent) {

// Enrich all events with Sysmon Info
pt := h.processTracker.GetByPID(int64(e.Event.System.Execution.ProcessID))

// We enrich event with other data
e.SetIfOr(pathSysmonProcessGUID, pt.ProcessGUID, !pt.IsZero(), "?")
e.SetIfOr(pathSysmonImage, pt.Image, !pt.IsZero(), "?")
e.SetIfOr(pathSysmonCommandLine, pt.CommandLine, !pt.IsZero(), "?")
// put hashes in ImageHashes field to avoid confusion in analyst's mind
// not to think it is file content hashes
e.SetIfOr(pathImageHashes, pt.hashes, !pt.IsZero(), "?")
e.SetIfOr(pathSysmonProcessId, toString(pt.PID), !pt.IsZero(), toString(-1))
e.SetIfOr(pathSysmonIntegrityLevel, pt.IntegrityLevel, !pt.IsZero(), "?")
e.SetIfOr(pathSysmonUser, pt.User, !pt.IsZero(), "?")
e.SetIfOr(pathServices, pt.Services, !pt.IsZero(), "?")
e.Set(pathSysmonEventType, KernelFileOperations[e.EventID()])

if e.EventID() == KernelFileCreate {
// We track file
h.processTracker.AddKernelFile(KernelFileFromEvent(e))
} else {
var fo uint64
var ok bool

// We correlate with the filename
if fo, ok = e.GetUint(pathKernelFileFileObject); ok {
fileName := "?"
if kf, ok := h.processTracker.GetKernelFile(fo); ok {
fileName = kf.FileName
}
e.Set(pathKernelFileFileName, fileName)
}
// We delete entry in tracking structure
if e.EventID() == KernelFileClose {
h.processTracker.DelKernelFile(fo)
}
}
}
1 change: 1 addition & 0 deletions hids/paths.go
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ var (
pathSysmonTargetImage = engine.Path("/Event/EventData/TargetImage")

// EventID 12,13,14: Registry
pathSysmonEventType = engine.Path("/Event/EventData/EventType")
pathSysmonTargetObject = engine.Path("/Event/EventData/TargetObject")
pathSysmonDetails = engine.Path("/Event/EventData/Details")

Expand Down
Loading

0 comments on commit b90752b

Please sign in to comment.