导语:Invoke-Pbind是一个用PowerShell编写的迷你post开发框架,它使用push机制而不是pull机制在命名管道的SMB上构建C2通信。Pbind最初是为了克服横向渗透问题而创建的,特别是在受限的环境中,服务器VLAN不能直接与用户VLAN通信(在每个环境中
Invoke-Pbind是一个用PowerShell编写的迷你post开发框架,它使用push机制而不是pull机制在命名管道的SMB上构建C2通信。Pbind最初是为了克服横向渗透问题而创建的,特别是在受限的环境中,服务器VLAN不能直接与用户VLAN通信(在每个环境中都应该如此)。该工具被设计成可以与任何C2框架结合,或者作为独立的PowerShell脚本运行。
存在的问题:隔离和严格的防火墙
如果组织暴露在威胁中,并且通过HTTPS 进行C2通信,那么从用户的工作站中遍历网络外的公司代理服务器是有一定防护作用的,但想获得的目标数据集,位于服务器VLAN,该服务器的防火墙限制入站和出站流量。在这种情况下,防火墙规则总是允许特定的流量遍历预先批准的服务。下图说明了这样一种情况:环境允许从用户VLAN到服务器VLAN的有限服务,但不允许反向的端口之间的服务。
C2通信有哪些现存选项
以下是C2通信的一些选项及其缓解方法,它们会导致失败。
方法 |
缓解措施 |
结果
|
直接Internet访问 |
防火墙出站阻止
|
失败 |
遍历HTTP代理 |
防火墙出站阻止 |
失败 |
TCP反向外壳 |
阻塞或可能检测打开端口的扫描 |
失败 |
TCP绑定外壳 |
防火墙入站或运行在开放端口服务阻塞,未检测到关闭端口 |
失败 |
ICMP |
防火墙出站阻止 |
失败 |
用户VLAN中SMB上的Daisy |
TCP端口445阻塞从服务器到工作站 |
失败 |
用户VLAN中HTTP上的Daisy |
与标准反向所有阻塞端口相同 |
失败 |
DNS |
只有代理服务器才允许授权DNS,因此无法从服务器VLAN访问C2通信 |
失败 |
需要明确的是,在这一点上问题不在于执行,而在于拥有可靠的C2通信,为所有执行命令提供用户输出,并将植入物用作立足点或中转站,以进一步攻击受限环境中的服务器。
解决方案
命名管道是一种逻辑连接,与CIFS/SMB连接中涉及的客户机和服务器之间的传输控制协议(TCP)会话类似。管道的名称用作通信端点,就像端口号用作TCP会话端点一样。这称为命名管道端点。”——https://msdn.microsoft.com/en-us/library/cc239733.aspx。
.NET有一个用于创建并且与命名管道交互的类:
https://msdn.microsoft.com/en-us/library/system.io.pipes.namedpipeserverstream(v=vs.110).aspx?cs-save-lang=1&cs-lang=vb#code-snippet-1
当TCP端口445打开到服务器环境中时,我们可以覆盖SMB协议并使用命名管道在工作站和服务器之间共享数据,从而提供交换数据(通信)的方法。以下命令构成了使用允许“所有人”访问的访问规则创建命名管道的基础:
1 add-Type -assembly 'System.Core‘ 2 3 $PipeSecurity = New-Object System.IO.Pipes.PipeSecurity 4 $AccessRule = New-Object System.IO.Pipes.PipeAccessRule( 'Everyone', 'ReadWrite', 'Allow' ) 5 $PipeSecurity.AddAccessRule($AccessRule) 6 $Pipe = New-Object System.IO.Pipes.NamedPipeServerStream($pname,InOut,100, ‘Byte', 'None', 4096, 4096, $PipeSecurity)
自从使用匿名访问(CVE-199-0519)滥用IPC$的日子以来,大家都得到了好处,微软已经声明过“不——尽管不应该通过”——非微软的直接引用。在域环境中,任何用户都可以为$IPC共享创建一个域身份验证会话,然后可以对其进行piggy back,以获得对指定管道的访问权。下面是PowerShell中的一个简单脚本,用于创建经过身份验证的会话。要克服的一个快速问题是:虽然应用于管道的‘AccessRule’看起来似乎允许“每个人”访问指定的管道,但实际上并非如此。
1 $net = new-object -ComObject WScript.Network 2 $net.MapNetworkDrive("", "\\target\ipc$", $false, “domain\user", “password")
只要知道正在读取的数据类型,与命名管道的交互也是相当直接的;创建服务器时,我们知道如何处理管道,通过使用一个简单的StreamReader:
1 $pipeReader = new-object System.IO.StreamReader($pipe) 2 $PRead = $pipeReader.ReadLine() 3 $pipeWriter = new-object System.IO.StreamWriter($pipe) 4 5 pipeWriter.WriteLine($encCommand)
设计
当我们提出Invoke-Pbind时,实现了以下原则。
客户机/服务器模型
为了允许在C2框架中包含,创建了两个脚本块:客户机和服务器。服务器在远程目标(服务器)上启动并设置命名管道。然后客户机连接到指定的管道并通过TCP端口445 (SMB)交换消息。客户端通过现有的C2植入程序运行,并通过使用脚本块和运行空间,可以非交互地使用客户端,以更好地与大多数C2框架交互。
令牌传递
当共享一个公共空间(如命名管道)时,在客户端和服务器之间交换的消息在被对应的服务器接收之前不被覆盖是非常必要的。控制消息与TRY和IF语句一起使用,用于为客户机或服务器何时从指定管道读取或写入创建规则。
安全
在生成脚本块期间,运行时,会生成一个惟一的密钥,用于在客户机和服务器之间加密消息。Pbind支持AES 256加密。要从客户端发起到命名管道的连接,还要支持共享密钥以停止对命名管道的篡改。如果客户端没有提供正确的密钥,命名管道将关闭。
注入/执行
将种植体注入目标宿主的方法主要有两种。这些是Invoke-WMIExec和Invoke-SMBExec的修改版本(这些脚本归功于Kevin Robertson);这两个脚本都经过了更新,以支持传递密码,以前它们只接受哈希进行身份验证。植入物是自执行脚本块,并且是作为有效负载传递的。该脚本默认运行WMIExec,但包含开关参数来调用SMBExec:
为了提供额外的部署灵活性,脚本还包括exe方法。该方法使用CSC Windows .Net 自动化DLL将植入物编译成可执行文件,然后可以通过任何方式部署和执行。
注意:创建命名管道不需要管理员凭证,因此可执行文件可以作为非特权用户运行。另一方面,WMIExec和SMBExec需要管理员权限。
exe选项继续生成硬编码到可执行文件中的惟一变量,以便在密码学等领域中使用。exe选项可以离线使用以创建可执行的植入程序,并且不通过C2绑定到交互式会话。为了与种植体对话,脚本支持一个CLIENT选项,该选项用于与部署的种植体交互,在种植体编译时提供这些选项:
这种灵活性允许通过任何方式进行部署:
DCOM
RDP
共享文件夹
WinRM
SCCM
任何东西……
有许多选项是可配置的。如果没有选择选项,脚本将恢复到预先设置或随机生成的值。以下选项是可配置的:
KEY——默认为随机生成的AES 256键-允许指定一个键,通常在客户模式中使用。
SECRET——默认为随机的5个字符值——允许使用特定的密钥。
PNAME——默认为随机8个字符值–允许选择特定管道名称。
TIMEOUT——默认为60秒–用来改变客户端连接到植入物的等待时间,用于慢速网络。
EXE——生成一个独立的可执行文件;
CLIENT——在客户机模式下运行脚本,以连接到部署的可执行文件;
TARGET——用于指定一个远程IP地址。
Domain2/User2/Password2 /User2/Password2——当使用散列作为主要身份验证机制时,用于将驱动器映射到目标系统。
Dir——在EXE模式中用于输出生成的可执行文件。
Automation——用于EXE模式中,目录位置的自动化DLL。
交互
已经创建了3个主要的功能来与客户端植入物交互。第一个功能,可能也是最有用的一个功能,特别是在我们介绍模板的时候,即Pbind-Command。这只是在一个变量中注册一个命令,该变量由客户机读取,并在执行之前传递给植入器(服务器)。下面是一个简单的例子:
1 Pbind-Command “net user doug password /add”
Pbind-module c:\folder\powerup.ps1第二种功能是Pbind-Module,它允许您读取任何其他ps1文件,并将其注入到植入主机的内存中。然后可以使用Pbind-Command执行ps1脚本中的任何函数。但是因为所有脚本都必须是客户端的本地脚本,所以这里有一个限制,并且在C2设置中不能很好地起作用。在大多数情况下,客户机已经在目标工作站上运行,并且需要在将所有脚本发送到植入程序之前将其上传到客户机。
1 Pbind- Command “Invoke-AllCheck”
为了解决Pbind-Module 的局限性,设计了Pbind-Squirt。这个函数的思想是将一些脚本作为base64对象嵌入到之后可以被调用的脚本中,并且自动被执行到客户机上的内存中。唯一被嵌入的是PowerUp,以帮助对新植入的主机进行资产评估。
1 Pbind-Squirt powerup
然而,在实践中,Pbind-module和Pbind-squirt都不是最优的,因此构建了一个新的解决方案,称为“Templates”。实际上,该方案只是与Pbind-Command函数交互的一种更好的方法。因此我们决定,通过创建一些可以自动化任务的小脚本,可以实现类似于Pbind-module和Pbind-squirt的思想。像上传mimikatz和提取密码、上传PowerView和运行查询,或者上传invoke-SMBExec和攻击其他机器这样的任务都可以使用以下类似的模板来编写脚本
了解脚本如何运行的最好方法是下载脚本并尝试一下。下面的截图显示了在另一个用户的上下文中本地运行脚本,同时执行命令的简单示例。
视频教程
我们创建了一个视频教程来帮助说明Invoke-Pbind的使用,见原文。