# 端口转发

端口转发是计算机网络中使用的一种技术，允许外部设备连接到专用网络内的特定设备，这是通过将通信请求从一个 IP 地址和端口号转发到另一个 IP 地址和端口号来实现的。而在跳板 (Pivoting) 的上下文中，攻击者可以通过正向端口转发技术来绕过网络限制访问其他的主机，或者通过逆向端口转发让无法访问外部网络的主机与攻击者的主机得以通信。

一个实际的例子，攻击者攻陷了边界主机 B，并且实现了对内部网络其他主机的代码执行能力。当攻击者试图让内部主机 C 运行 Beacon 并获得会话的时候发现主机 C 不能与互联网通信，即无法连接到我们的转发器 A 上。因为 B 与 C 有着共同的网卡接口，因此内部网络的访问控制相对宽松，B 与 C 之间有着能互相通信的端口，而 B 能与转发器 A 直接通信，因此攻击者可以将 B 作为 A 与 C 之间的中继主机。

[![image.png](https://raven-medicine.com/uploads/images/gallery/2023-05/scaled-1680-/oLnnY3N8eSOnSLM5-image.png)](https://raven-medicine.com/uploads/images/gallery/2023-05/oLnnY3N8eSOnSLM5-image.png)

在我们的靶场中，为了降低复杂度，并没有设置诸多基于网络的访问控制，即一切都是最理想的情况。例如 white-bird 域中，Web02 是边界主机，如果 Dc05 不能连接互联网，那么我们可以将 VPS 的一端口逆向转发到 Web02 上。这样，当 Dc05 访问 Web02 的该端口时，就像在直接访问 VPS 的该端口。

在 CobaltStrike 中，rportfwd 命令可以用于创建逆向端口转发隧道。在 Web02 上，我们执行命令 **rportfwd 8180 127.0.0.1 8180**，这样，我们将团队服务器的 8180 端口转发到了 Web02 的 8180 端口。

[![image.png](https://raven-medicine.com/uploads/images/gallery/2023-05/scaled-1680-/Vdyt8Z0JUxt8hF99-image.png)](https://raven-medicine.com/uploads/images/gallery/2023-05/Vdyt8Z0JUxt8hF99-image.png)

当 Dc05 访问 Web02 的 8180 端口时，团队服务器的 8180 端口会有访问记录。

[![image.png](https://raven-medicine.com/uploads/images/gallery/2023-05/scaled-1680-/EDlvLPAZh7kdjQ2M-image.png)](https://raven-medicine.com/uploads/images/gallery/2023-05/EDlvLPAZh7kdjQ2M-image.png)

[![image.png](https://raven-medicine.com/uploads/images/gallery/2023-05/scaled-1680-/VXkLUkfKgfhzX6ZA-image.png)](https://raven-medicine.com/uploads/images/gallery/2023-05/VXkLUkfKgfhzX6ZA-image.png)

对于 rportfwd 命令，我们需要注意该命令先隧道了传向团队服务器的流量，然后团队服务器再将流量传递给目标，因此该命令不用于在**内部主机之间**中继流量。并且，这些流量是包含在 **C2 流量**中的，而不是作为单独的套接字。如果我们**没有管理员权限**，只能使用**高端口号**。

CS 还有这 **rportfwd\_local** 命令，与 rportfwd 有所不同的是，前者将流量隧道至 CS 客户端而非团队服务器，其余用法则相同。因为也有很多时候我们在运行 CS 客户端的主机上使用其他工具，这会很有用。

[![image.png](https://raven-medicine.com/uploads/images/gallery/2023-05/scaled-1680-/rHsfk2INULHVyhc2-image.png)](https://raven-medicine.com/uploads/images/gallery/2023-05/rHsfk2INULHVyhc2-image.png)

[![image.png](https://raven-medicine.com/uploads/images/gallery/2023-05/scaled-1680-/pC3g5NWLgFjMI0q9-image.png)](https://raven-medicine.com/uploads/images/gallery/2023-05/pC3g5NWLgFjMI0q9-image.png)

此外，我们还可以通过 **netsh** 来实现端口转发，这在内部主机直接中继流量会尤其方便，因为即便是内网，也会存在着网络隔离，域与域之间也默认开启着防火墙 (尽管我手动关闭了)。假设这么一种情况，white-bird 域中的 Dc05 可以与 raven-med 域中的 Dc02 互相连通，Dc02 与 med-factory 域中的 Dc03 互相连通，但 Dc05 与 Dc03 互相不连通。考虑到域信任的关系，这在实际中是可能存在的情况。那么，我们可以让与 Dc05 以及 Dc03 都连通的 Dc02 作为中继。

我们在 Dc03 上运行该脚本：

```powershell
$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()
}
```

这个脚本绑定了 4444 端口，如果有任何外来通信连接到该端口，那么会输出消息。接着，在 Dc02 上使用 netsh 添加一个 v4tov4 代理：

```powershell
netsh interface portproxy add v4tov4 listenaddress=0.0.0.0 listenport=4444 connectaddress=172.16.1.31 connectport=4444 protocol=tcp
```

该命令指定了 Dc02 上绑定的网卡接口以及端口，转发至的目标主机的地址以及端口，协议为 TCP。添加完成后，使用命令 **netsh interface portproxy show v4tov4** 来罗列刚才添加的规则：

[![image.png](https://raven-medicine.com/uploads/images/gallery/2023-05/scaled-1680-/PrmRieoGOOjIYnS0-image.png)](https://raven-medicine.com/uploads/images/gallery/2023-05/PrmRieoGOOjIYnS0-image.png)

在 Dc05 上，使用 Test-NetConnection 来连接 Dc02 的 4444 端口，我们会发现 Dc03 上持续运行的脚本显示有客户端连接了，说明 Dc05 对于 Dc03 的访问通过 Dc02 的中继达成了。

[![image.png](https://raven-medicine.com/uploads/images/gallery/2023-05/scaled-1680-/AYLqOrZI0EHpmRWx-image.png)](https://raven-medicine.com/uploads/images/gallery/2023-05/AYLqOrZI0EHpmRWx-image.png)  
最后，我们可以使用如下命令移除添加的 v4tov4 代理。

```powershell
netsh interface portproxy delete v4tov4 listenaddress=0.0.0.0 listenport=4444
```

使用 netsh 添加端口转发规则，我们需要成为管理员，无论端口号高低。