Skip to content
Open
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
24 changes: 22 additions & 2 deletions pkg/edrRecon/drivers_windows.go
Original file line number Diff line number Diff line change
Expand Up @@ -169,11 +169,25 @@ func GetDriverBaseName(driverAddrs uintptr) (string, error) {

func IterateOverDrivers(numberOfDrivers uint, driverAddrs []uintptr) ([]resources.DriverMetaData, error) {
var (
multiErr error
summary []resources.DriverMetaData = make([]resources.DriverMetaData, 0)
multiErr error
summary []resources.DriverMetaData = make([]resources.DriverMetaData, 0)
total = len(driverAddrs)
nilCount int
processedCount int
)

if total == 0 && numberOfDrivers > 0 {
total = int(numberOfDrivers)
}

for _, addr := range driverAddrs {
if addr == 0 {
nilCount++
continue
}

processedCount++

driverFileName, err := GetDriverFileName(addr)
if err != nil {
multiErr = multierror.Append(multiErr, err)
Expand All @@ -200,6 +214,10 @@ func IterateOverDrivers(numberOfDrivers uint, driverAddrs []uintptr) ([]resource
}
}

if total > 0 && processedCount == 0 && nilCount == total {
return summary, errors.New("EnumDeviceDrivers returned only NULL addresses; SeDebugPrivilege likely not enabled")
}

return summary, multiErr
}

Expand Down Expand Up @@ -246,6 +264,8 @@ func CheckDrivers() ([]resources.DriverMetaData, error) {
numberOfDrivers = uint(sizeOfDriverArrayInBytes) / sizeOfOneDriverAddress
driverAddrs = make([]uintptr, numberOfDrivers)

_ = enableSeDebugPrivilegeIfRequired()

success := EnumDeviceDrivers(driverAddrs, DWORD(sizeOfDriverArrayInBytes), &sizeOfDriverArrayInBytes)
if !success {
return drivers, fmt.Errorf("failed to enumerate device drivers, error code: %w", syscall.GetLastError())
Expand Down
85 changes: 85 additions & 0 deletions pkg/edrRecon/privilege_windows.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
package edrRecon

import (
"fmt"
"unsafe"

"golang.org/x/sys/windows"
)

const windowsBuildRequireSeDebugForDriverAddresses = 26100

type osVersionInfoExW struct {
dwOSVersionInfoSize uint32
dwMajorVersion uint32
dwMinorVersion uint32
dwBuildNumber uint32
dwPlatformId uint32
szCSDVersion [128]uint16
wServicePackMajor uint16
wServicePackMinor uint16
wSuiteMask uint16
wProductType byte
wReserved byte
}

func getWindowsBuildNumber() (uint32, error) {
ntdll := windows.NewLazySystemDLL("ntdll.dll")
rtlGetVersion := ntdll.NewProc("RtlGetVersion")

versionInfo := osVersionInfoExW{dwOSVersionInfoSize: uint32(unsafe.Sizeof(osVersionInfoExW{}))}
r1, _, callErr := rtlGetVersion.Call(uintptr(unsafe.Pointer(&versionInfo)))
if r1 != 0 {
if callErr != nil && callErr != windows.ERROR_SUCCESS {
return 0, fmt.Errorf("RtlGetVersion failed: %w", callErr)
}
return 0, fmt.Errorf("RtlGetVersion returned NTSTATUS 0x%x", uint32(r1))
}

return versionInfo.dwBuildNumber, nil
}

func enableSeDebugPrivilegeIfRequired() error {
buildNumber, err := getWindowsBuildNumber()
if err != nil {
return nil
}

if buildNumber < windowsBuildRequireSeDebugForDriverAddresses {
return nil
}

var token windows.Token
err = windows.OpenProcessToken(windows.CurrentProcess(), windows.TOKEN_QUERY|windows.TOKEN_ADJUST_PRIVILEGES, &token)
if err != nil {
return fmt.Errorf("failed to open process token: %w", err)
}
defer token.Close()

var luid windows.LUID
err = windows.LookupPrivilegeValue(nil, windows.StringToUTF16Ptr("SeDebugPrivilege"), &luid)
if err != nil {
return fmt.Errorf("failed to lookup SeDebugPrivilege LUID: %w", err)
}

tokenPrivileges := windows.Tokenprivileges{
PrivilegeCount: 1,
Privileges: [1]windows.LUIDAndAttributes{
{
Luid: luid,
Attributes: windows.SE_PRIVILEGE_ENABLED,
},
},
}

err = windows.AdjustTokenPrivileges(token, false, &tokenPrivileges, 0, nil, nil)
if err != nil {
return fmt.Errorf("failed to adjust token privileges: %w", err)
}

if windows.GetLastError() == windows.ERROR_NOT_ALL_ASSIGNED {
return fmt.Errorf("failed to enable SeDebugPrivilege: %w", windows.ERROR_NOT_ALL_ASSIGNED)
}

return nil
}