原文地址:https://hausec.com/2019/08/12/offensive-lateral-movement/

所谓横向渗透,实际上就是通过一台已被攻陷的主机渗透其他主机的过程。为了完成这项任务,渗透测试人员和红队队员的通常做法是,利用powershell.exe在远程主机上运行base64编码的命令,以返回相应的beacon。这种方法的问题在于,攻击性的PowerShell早就被人们司空见惯了,因此,这些代码很容易被检测到并被阻止。横向渗透的难点在于,要求实施过程安全可靠(OpSec),这意味着产生的日志要尽可能少,或者生成的日志看起来是正常的,即隐藏在显眼的地方以避免被发现。本文的目的不仅是展示某些横向渗透技术,而且说明其幕后发生了什么,以及与之相关的检测指标。在这篇文章中,我们将用到许多Cobalt Strike语法,因为本文中主要利用它来实现C2,但是Cobalt Strike内置的横向渗透技术的动静大,因而无法支持OpSec特性。此外,并非所有人都拥有Cobalt Strike,所以,Meterpreter也会出现在大多数的例子中,因为技术是通用的。

在本文中,我们将为读者详细介绍多种横向渗透技巧。对于这些技术,我们首先会进行概要的介绍,然后介绍其工作原理。为了便于读者理解下文,让我们先来厘清几个术语。

  • 命名管道进程之间通过SMB(TCP 445端口)进行通信的一种方式( TCP 445)。命名管道运行于OSI模型的第5层,它也可以通过类似端口侦听连接的方式来侦听请求。
  • 访问令牌根据微软相关文档的描述:访问令牌是描述进程或线程的安全上下文的对象。令牌中的信息包括与进程或线程关联的用户帐户的标识和权限。用户登录时,系统通过将用户密码与存储在安全数据库中的信息进行比较来验证用户密码的正确性。当用户的凭证顺利通过验证后,系统就会为该用户生成一个访问令牌。所有以该用户的身份执行的进程都具有该访问令牌的副本。

换句话说,访问令牌提供了用户的身份信息,可以用来判断该用户是否有权访问系统上的特定内容。如果您对Windows身份验证机制并不是非常了解的话,可以简单的把访问令牌看作是用户登录Windows时创建的一个登录会话。

  • 网络登录(Type 3):当帐户在远程系统/服务上进行身份验证时,就会使用网络登录。在进行网络身份验证期间,可重用凭证不会发送到远程系统。因此,当用户通过网络登录方式登录到远程系统时,用户的凭证将不会出现在远程系统上以执行进一步的身份验证。这会带来所谓的双跃点问题,也就是说,即使我们通过one-liner以网络登录方式连接上了目标系统,也可以通过SMB抵达该系统,但由于没有SMB登录凭证,因此,登录就会失败。下面,让我们通过具体的例子对此加以说明。

PsExec

PsExec是微软的Sysinternals套件提供的一款工具,允许用户通过端口445(SMB)使用命名管道在远程主机上执行PowerShell。首先,它会通过SMB连接到目标系统上的ADMIN$共享,上传PSEXESVC.exe,并使用服务控制管理器启动这个.exe程序,后者会在远程系统上创建一个命名管道,并最终将该管道用于I/O。

下面,我们举例说明PsExec的语法:

psexec \test.domain -u Domain\User -p Password ipconfig

如果使用Cobalt Strike(CS)来完成这项任务的话,过程会略有不同。它首先创建一个Powershell脚本,该脚本将对从内存运行的嵌入式payload进行base64编码,并将其压缩成一个one-liner,然后连接到ADMIN$或C$共享并运行Powershell命令,具体如下所示:

演示视频

问题在于,这个脚本创建了一个服务并运行了base64编码命令,这些举动是很不正常的,将引发各种警报并生成相应的日志。此外,这里的命令是通过命名管道进行发送的,而命名管道在CS中都具有默认的名称(不过,这些默认的名称是允许进行修改的)。关于如何检测这些活动,请参阅Red Canary撰写的相关文章

Cobalt Strike提供了两个PsExec内置函数,一个名为PsExec,另一个名为PsExec(psh)。两者之间的区别在于,PsExec(psh)会调用Powershell.exe,因此,我们的beacon将作为Powershell.exe进程运行;而不带(psh)的PsExec将作为rundll32.exe运行。

通过Cobalt Strike查看进程ID

默认情况下,PsExec将生成rundll32.exe进程以在其中运行。并且,它不会将DLL存放到磁盘中,所以从蓝队的角度来看,如果rundll32.exe不带参数运行的话,那就非常可疑了。

SC

服务控制器的用途就不用多讲了吧——控制服务。它对于攻击者来说是特别有用的,因为调度任务可以通过SMB完成,所以启动远程服务的语法为:

sc \host.domain create ExampleService binpath= "c:\windows\system32**calc.exe"
sc \
host.domain** start ExampleService

唯一需要注意的是,这里的可执行文件必须是特定服务对应的二进制文件。服务的二进制文件与普通的二进制文件有所不同——它们必须“签入”到服务控制管理器(SCM)中,如果没有签入的话,则退出执行。因此,如果这里使用服务之外的二进制文件的话,那么返回的代理/beacon马上就会挂掉。

使用CS时,我们可以专门为服务创建相应的可执行文件:

通过CoBalt Strike为服务生成的可执行文件

上面的攻击过程,也可以借助Metasploit完成,具体如下所示:

演示视频

WMI

Windows Management Instrumentation(WMI)是Windows系统内置的一项服务,用户可以通过该服务远程访问各种Windows组件。由于可以通过端口135使用远程过程调用(RPC)进行远程访问(并借助于稍后介绍的临时端口),这样一来,管理员就能够远程执行自动管理任务了,例如,远程启动服务或远程执行命令等。当然,我们也可以直接通过wmic.exe进行交互。下面给出一个WMI查询示例:

wmic /node:target.domain /user:domain\user /password:password process call create "C:\Windows\System32\calc.exe"

演示视频

Cobalt Strike在目标系统上利用WMI服务执行Powershell payload时,PowerShell.exe程序会在启动内置的WMI服务时打开,这就会导致OpSec问题,因为执行的是经过base64编码的payload。

我们可以看到,借助于WMI服务的情况下,仍然会创建一个命名管道——尽管wmic.exe能够通过PowerShell在目标系统上运行命令,那么,为什么要首先创建一个命名管道呢?命名管道虽然并非执行payload所必需的,但是使用CS创建payload时,必须使用命名管道进行通信(通过SMB)。

对于WMI服务,这里只是介绍了一些皮毛。对于这方面感兴趣的读者,建议参阅我的同事@mattifestation在Blackhat 2015大会上的精彩演讲

WinRM

Windows远程管理服务通常用于管理服务器硬件,其通信方式为WMI over HTTP(S)。跟传统的Web流量不同,它并没有使用80/443端口,而是使用5985(HTTP)和5986(HTTPS)端口。通常情况下,WinRM虽然是Windows系统默认安装的组件,但用户必须手动开启;不过,服务器操作系统则是一个例外,因为从2012R2版本开始,该服务就是默认开启的。即使启动了WinRM服务,也必须在客户端上使用侦听器(听起来是不是很耳熟?),否则就无法处理相应的请求。这些工作,我们既可以在Powershell中执行命令完成,也可以通过WMI和Powershell远程完成:

Enable-PSRemoting -Force

如果不使用CS的话,可以执行下列命令(大家可以利用自己的二进制文件替换掉calc.exe):

winrs -r:EXAMPLE.lab.local -u:DOMAIN\user -p:password calc.exe

演示视频

如果借助于CobaltStrike,则可以:

当然,这里的问题在于必须使用PowerShell启动它。如果要想远程操作的话,那么还要借助于DCOM或WMI。虽然打开PowerShell通常不会引起人们的怀疑,启动WinRM侦听器也问题不大,但是在执行payload时就会闹出动静了,因为如果运行Cobalt Strike内置的WinRM模块的话,通常就会引起防御系统的警报了。

这里的警示指标为:

"c:\windows\syswow64\windowspowershell\v1.0\powershell.exe" -Version 5.1 -s -NoLogo -NoProfile

SchTasks

SchTasks是Scheduled Tasks的缩写,最初在端口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

演示视频

(未完待续)

点击收藏 | 2 关注 | 2
  • 动动手指,沙发就是你的了!
登录 后跟帖