-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcheck_token_privileges.py
185 lines (146 loc) · 6.19 KB
/
check_token_privileges.py
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
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
"""
Filename: open_process_token.py
Description: Given a window title, it gets the process token for that process
and checks if it has SEDebugPrivilege enabled. Could be modified to check for
other privileges as well.
Modified from Brandon Dennis' "Hacking Windows API With Python" course on
Udemy.
Created by: Benjamin M. Singleton
Created: 03-12-2020
"""
# Import the required module to handle Windows API Calls
import ctypes
# Import Python -> Windows Types from ctypes
from ctypes.wintypes import DWORD
# Grab a handle to kernel32.dll & USer32.dll & Advapi32.dll
k_handle = ctypes.WinDLL("Kernel32.dll")
u_handle = ctypes.WinDLL("User32.dll")
a_handle = ctypes.WinDLL("Advapi32.dll")
# Access Rights
PROCESS_ALL_ACCESS = (0x000F0000 | 0x00100000 | 0xFFF)
# Token Access Rights
STANDARD_RIGHTS_REQUIRED = 0x000F0000
STANDARD_RIGHTS_READ = 0x00020000
TOKEN_ASSIGN_PRIMARY = 0x0001
TOKEN_DUPLICATE = 0x0002
TOKEN_IMPERSONATION = 0x0004
TOKEN_QUERY = 0x0008
TOKEN_QUERY_SOURCE = 0x0010
TOKEN_ADJUST_PRIVILEGES = 0x0020
TOKEN_ADJUST_GROUPS = 0x0040
TOKEN_ADJUST_DEFAULT = 0x0080
TOKEN_ADJUST_SESSIONID = 0x0100
TOKEN_READ = (STANDARD_RIGHTS_READ | TOKEN_QUERY)
TOKEN_ALL_ACCESS = (STANDARD_RIGHTS_REQUIRED |
TOKEN_ASSIGN_PRIMARY |
TOKEN_DUPLICATE |
TOKEN_IMPERSONATION |
TOKEN_QUERY |
TOKEN_QUERY_SOURCE |
TOKEN_ADJUST_PRIVILEGES |
TOKEN_ADJUST_GROUPS |
TOKEN_ADJUST_DEFAULT |
TOKEN_ADJUST_SESSIONID)
# Privilege Enabled/Disabled Mask
SE_PRIVILEGE_ENABLED = 0x00000002
SE_PRIVILEGE_DISABLED = 0x00000000
# Needed Structures for used API Calls
class LUID(ctypes.Structure):
_fields_ = [
("LowPart", DWORD),
("HighPart", DWORD),
]
class LUID_AND_ATTRIBUTES(ctypes.Structure):
_fields_ = [
("Luid", LUID),
("Attributes", DWORD),
]
class PRIVILEGE_SET(ctypes.Structure):
_fields_ = [
("PrivilegeCount", DWORD),
("Control", DWORD),
("Privileges", LUID_AND_ATTRIBUTES),
]
# Grab The Windows Name from User32
lpWindowName = ctypes.c_char_p(input("Enter Window Name To Hook Into: ").encode('utf-8'))
# Grab a Handle to the Process
hWnd = u_handle.FindWindowA(None, lpWindowName)
# Check to see if we have the Handle
if hWnd == 0:
print("[ERROR] Could Not Grab Handle! Error Code: {0}".format(k_handle.GetLastError()))
exit(1)
else:
print("[INFO] Grabbed Handle...")
# Get the PID of the process at the handle
lpdwProcessId = ctypes.c_ulong()
# We use byref to pass a pointer to the value as needed by the API Call
response = u_handle.GetWindowThreadProcessId(hWnd, ctypes.byref(lpdwProcessId))
# Check to see if the call Completed
if response == 0:
print("[ERROR] Could Not Get PID from Handle! Error Code: {0}".format(k_handle.GetLastError()))
else:
print("[INFO] Found PID...")
# Opening the Process by PID with Specific Access
dwDesiredAccess = PROCESS_ALL_ACCESS
bInheritHandle = False
dwProcessId = lpdwProcessId
# Calling the Windows API Call to Open the Process
hProcess = k_handle.OpenProcess(dwDesiredAccess, bInheritHandle, dwProcessId)
# Check to see if we have a valid Handle to the process
if hProcess <= 0:
print("[ERROR] Could Not Grab Privileged Handle! Error Code: {0}".format(k_handle.GetLastError()))
else:
print("[INFO] Privileged Handle Opened...")
# Open a Handle to the Process's Token Directly
ProcessHandle = hProcess
DesiredAccess = TOKEN_ALL_ACCESS
TokenHandle = ctypes.c_void_p()
# Issue the API Call
response = k_handle.OpenProcessToken(ProcessHandle, DesiredAccess, ctypes.byref(TokenHandle))
# Handle an Error
if response > 0:
print("[INFO] Handle to Process Token Created! Token: {0}".format(TokenHandle))
else:
print("[ERROR] Could Not Grab Privileged Handle to Token! Error Code: {0}".format(k_handle.GetLastError()))
# Check to see if we have SEDebugPrivilege
# First use the LookupPrivilegeValue API Call to get the LUID based on the String Privilege name
# Setup a PRIVILEGE_SET for the PrivilegeCheck Call to be used later - We need the LUID to be used
# We will reference it later as well
requiredPrivileges = PRIVILEGE_SET()
requiredPrivileges.PrivilegeCount = 1 # We are only looking at 1 Privilege at a time here
requiredPrivileges.Privileges = LUID_AND_ATTRIBUTES() # Setup a new LUID_AND_ATTRIBUTES
requiredPrivileges.Privileges.Luid = LUID() # Setup a New LUID inside of the LUID_AND_ATTRIBUTES structure
requiredPrivileges.Privileges.Attributes = SE_PRIVILEGE_ENABLED # We want to enable if possible
# Params for Lookup API Call
lpSystemName = None
lpName = "SEDebugPrivilege"
"""
We need to look up the LUID for the privilege we're interested in. There isn't
a universal number you can use to check if a token has a certain privilege.
Instead, each Windows machine has a unique number for each of is privileges.
"""
# We now issue the Call to configure the LUID with the Systems Value of that Privilege
response = a_handle.LookupPrivilegeValueW(lpSystemName, lpName, ctypes.byref(requiredPrivileges.Privileges.Luid))
# Handle an Error
if response > 0:
print("[INFO] Lookup For SEDebugPrivilege Worked...")
else:
print("[ERROR] Lookup for SEDebugPrivilege Failed! Error Code: {0}".format(k_handle.GetLastError()))
# if the privilege doesn't exist on the machine the call will succeed but the
# LUID will be all zeroes
if requiredPrivileges.Privileges.Luid.HighPart == 0 and requiredPrivileges.Privileges.Luid.LowPart == 0:
print('LookupPrivilegeValue() call succeeded, but privilege was not found.')
exit(1)
# Now that our LUID is setup and pointing to the correct Privilege we can check to see if its enabled
pfResult = ctypes.c_long()
response = a_handle.PrivilegeCheck(TokenHandle, ctypes.byref(requiredPrivileges), ctypes.byref(pfResult))
# Handle an Error
if response > 0:
print("[INFO] PrivilegeCheck Worked...")
else:
print("[ERROR] PrivilegeCheck Failed! Error Code: {0}".format(k_handle.GetLastError()))
# We can check pfResult to see if our Privilege is enabled or not
if pfResult:
print("[INFO] Privilege SEDebugPrivilege is Enabled...")
else:
print("[INFO] Privilege SEDebugPrivilege is NOT Enabled...")