aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/elevate
diff options
context:
space:
mode:
authorJason A. Donenfeld <Jason@zx2c4.com>2019-08-28 22:30:35 -0600
committerJason A. Donenfeld <Jason@zx2c4.com>2019-08-30 08:47:21 -0600
commit2bbd162221e56e0312593cb05956c100f253ff98 (patch)
tree2dab80c185282b6cb9270836cef88f852afe5a40 /elevate
parentelevate: use more strict check for admin group (diff)
downloadwireguard-windows-2bbd162221e56e0312593cb05956c100f253ff98.tar.xz
wireguard-windows-2bbd162221e56e0312593cb05956c100f253ff98.zip
elevate: check for desktop admin ownership
Diffstat (limited to 'elevate')
-rw-r--r--elevate/membership.go24
-rw-r--r--elevate/syscall_windows.go3
-rw-r--r--elevate/zsyscall_windows.go38
3 files changed, 57 insertions, 8 deletions
diff --git a/elevate/membership.go b/elevate/membership.go
index ccd0b60e..131c6d97 100644
--- a/elevate/membership.go
+++ b/elevate/membership.go
@@ -35,3 +35,27 @@ func TokenIsElevatedOrElevatable(token windows.Token) bool {
defer linked.Close()
return linked.IsElevated() && isAdmin(linked)
}
+
+func IsAdminDesktop() (bool, error) {
+ hwnd := getShellWindow()
+ if hwnd == 0 {
+ return false, windows.ERROR_INVALID_WINDOW_HANDLE
+ }
+ var pid uint32
+ _, err := getWindowThreadProcessId(hwnd, &pid)
+ if err != nil {
+ return false, err
+ }
+ process, err := windows.OpenProcess(windows.PROCESS_QUERY_INFORMATION, false, pid)
+ if err != nil {
+ return false, err
+ }
+ defer windows.CloseHandle(process)
+ var token windows.Token
+ err = windows.OpenProcessToken(process, windows.TOKEN_QUERY | windows.TOKEN_IMPERSONATE, &token)
+ if err != nil {
+ return false, err
+ }
+ defer token.Close()
+ return TokenIsElevatedOrElevatable(token), nil
+} \ No newline at end of file
diff --git a/elevate/syscall_windows.go b/elevate/syscall_windows.go
index dba56375..1957dea2 100644
--- a/elevate/syscall_windows.go
+++ b/elevate/syscall_windows.go
@@ -84,3 +84,6 @@ const (
//sys coInitializeEx(reserved uintptr, coInit uint32) (ret error) = ole32.CoInitializeEx
//sys coUninitialize() = ole32.CoUninitialize
//sys coGetObject(name *uint16, bindOpts *cBIND_OPTS3, guid *windows.GUID, functionTable ***[0xffff]uintptr) (ret error) = ole32.CoGetObject
+
+//sys getWindowThreadProcessId(hwnd uintptr, pid *uint32) (tid uint32, err error) = user32.GetWindowThreadProcessId
+//sys getShellWindow() (hwnd uintptr) = user32.GetShellWindow
diff --git a/elevate/zsyscall_windows.go b/elevate/zsyscall_windows.go
index 0ed13233..afff428f 100644
--- a/elevate/zsyscall_windows.go
+++ b/elevate/zsyscall_windows.go
@@ -37,14 +37,17 @@ func errnoErr(e syscall.Errno) error {
}
var (
- modntdll = windows.NewLazySystemDLL("ntdll.dll")
- modole32 = windows.NewLazySystemDLL("ole32.dll")
-
- procRtlInitUnicodeString = modntdll.NewProc("RtlInitUnicodeString")
- procRtlGetCurrentPeb = modntdll.NewProc("RtlGetCurrentPeb")
- procCoInitializeEx = modole32.NewProc("CoInitializeEx")
- procCoUninitialize = modole32.NewProc("CoUninitialize")
- procCoGetObject = modole32.NewProc("CoGetObject")
+ modntdll = windows.NewLazySystemDLL("ntdll.dll")
+ modole32 = windows.NewLazySystemDLL("ole32.dll")
+ moduser32 = windows.NewLazySystemDLL("user32.dll")
+
+ procRtlInitUnicodeString = modntdll.NewProc("RtlInitUnicodeString")
+ procRtlGetCurrentPeb = modntdll.NewProc("RtlGetCurrentPeb")
+ procCoInitializeEx = modole32.NewProc("CoInitializeEx")
+ procCoUninitialize = modole32.NewProc("CoUninitialize")
+ procCoGetObject = modole32.NewProc("CoGetObject")
+ procGetWindowThreadProcessId = moduser32.NewProc("GetWindowThreadProcessId")
+ procGetShellWindow = moduser32.NewProc("GetShellWindow")
)
func rtlInitUnicodeString(destinationString *cUNICODE_STRING, sourceString *uint16) {
@@ -78,3 +81,22 @@ func coGetObject(name *uint16, bindOpts *cBIND_OPTS3, guid *windows.GUID, functi
}
return
}
+
+func getWindowThreadProcessId(hwnd uintptr, pid *uint32) (tid uint32, err error) {
+ r0, _, e1 := syscall.Syscall(procGetWindowThreadProcessId.Addr(), 2, uintptr(hwnd), uintptr(unsafe.Pointer(pid)), 0)
+ tid = uint32(r0)
+ if tid == 0 {
+ if e1 != 0 {
+ err = errnoErr(e1)
+ } else {
+ err = syscall.EINVAL
+ }
+ }
+ return
+}
+
+func getShellWindow() (hwnd uintptr) {
+ r0, _, _ := syscall.Syscall(procGetShellWindow.Addr(), 0, 0, 0, 0)
+ hwnd = uintptr(r0)
+ return
+}