通过SSH实现流量转发:端口转发与VPN配置详解

本文详细介绍了如何使用SSH进行本地、远程和动态端口转发,以及如何配置SSH VPN来突破SOCKS代理的限制,实现更灵活的内网渗透和流量路由。

通过SSH转发流量

这篇博客原本打算写成OpenSSH的使用指南,但由于我有时间,决定阅读man页面(在Linux终端中输入man ssh可访问的手册页),并在过程中探索了各种可能性。在阅读man页面时,我了解到可以使用SSH设置VPN网络,并决定尝试一下。虽然我刚学会这个技巧,尚未在测试中使用,但我认为这是一个很好的资源,特别是在使用的工具不支持SOCKS代理或Proxychains不支持协议的情况下。

端口转发

使用SSH进行端口转发是一个有详细文档的主题,但如果你是新手的化,这里快速回顾一下。(你也可以在这里观看Ralph May的视频解释:https://www.youtube.com/watch?v=zG4jYmHoEr8&t=348s)

SSH可用于本地、远程和动态端口转发。本地端口转发基本上在你的本地机器(你SSH的来源)上打开一个端口,并将其流量转发到你连接的机器或网络上的远程端口。一旦你获得对系统的shell访问并发现服务在环回或内部接口上监听时,这会很有用。本地端口转发允许你将该服务转发到本地机器的一个端口。

命令语法如下:

1
ssh –N -L local_port:remote_service_ip:remote_service_port

可选地,你可以在端口前添加IP地址来指定监听哪个接口。

1
ssh –N -L local_ip:local_port:remote_service_ip:remote_service_port

例如,假设你访问了一个系统(192.168.136.120),运行netstat后,发现环回接口的8080端口上运行着一个服务。

为了演示,我们将使用Python的http.server模块在目标主机的环回接口上设置一个Web服务器,托管一个简单的文本文件。

在目标主机上,运行以下命令创建文件并启动服务器:

1
2
echo "This is a local service" > file.txt
python3 -m http.server --bind 127.0.0.1 8080

目标机器上服务器已启动

你可以使用以下命令将该端口转发到本地机器:

1
ssh -N -L 8081:127.0.0.1:8080 user@192.168.136.120

这将在本地机器上打开端口8081,并将其所有流量转发到远程机器192.168.136.120上的127.0.0.1:8080。

现在,如果我们在测试机器上请求http://127.0.0.1:8081/file.txt,我们应该能够访问目标机器上127.0.0.1:8080托管的文件。

使用本地端口转发访问文件

远程端口转发的行为相反。它在远程机器上打开一个端口,并将来自远程网络的所有流量转发到本地机器或网络上的本地端口。当你想将本地端口转发到远程机器上监听时,这很有用。

远程端口转发的语法类似;这次使用-R标志,并首先指定远程IP和端口。

1
ssh -N -R [remote_service_ip]:remote_port:local_ip:local_port

回到之前的例子,假设你处于相同的情况——访问系统(192.168.136.120)并发现服务在127.0.0.1:8080监听,但这次目标机器的端口22上入口流量被阻止,因此本地端口转发不可行。在这种情况下,你可以使用远程端口转发来实现相同的结果。你可以从目标计算机使用SSH连接到测试机器,并将目标上的本地端口8080转发到测试机器上的远程端口8081。

1
ssh -N -R 8081:127.0.0.1:8080 tester@192.168.136.130

SSH远程端口转发到测试机器

再次,你可以在测试机器上的127.0.0.1:8081与服务交互。

通过远程端口转发请求文件

动态端口转发在本地机器上启动一个SOCKS代理,并将所有前往该代理的流量转发到远程机器,在那里连接将基于应用协议路由。

当你在需要访问远程网络上多个端口的情况下,这很有用。动态端口转发通过使用-D标志以及本地系统上的监听端口来指定。

1
ssh -D local_port user@host

让我们回到之前的例子,但这次假设你不是发现服务在本地主机上监听,而是发现了到其他主机的连接,并想枚举内部网络。在这种情况下,你可以使用以下命令进行动态端口转发。以下命令将在本地机器的端口1080上启动一个SOCKS代理。

1
ssh -D 1080 user@192.168.136.120

这将创建一个本地SOCKS代理,它将任何传入连接转发到本地端口1080到远程系统。要与本地SOCKS代理交互,你可以使用诸如BurpSuite、Web浏览器、Proxychains或任何其他支持SOCKS代理的工具。

例如,我们可以使用Proxychains和Nmap在内部网络上运行连接扫描。Proxychains默认会尝试连接到端口9050上的socks4代理,如其配置文件/etc/proxychains4.conf所述。我们需要修改此配置以匹配我们的代理监听端口。以下命令可用于更改配置文件:

1
sed -i 's/^socks4.*/socks5 127.0.0.1 1080/' /etc/proxychains4.conf

你的配置文件现在应该看起来像这样。

Proxychains4配置文件

现在我们可以使用Proxychains在内部网络上运行Nmap,如下例所示,我们扫描主机10.10.10.128。

1
proxychains4 -q nmap -sT -Pn 10.10.10.128

运行连接扫描

SSH VPN

虽然端口转发是最直接的方法,并且不需要在目标上拥有高权限来设置,但我们可能会遇到工具不完全支持SOCKS代理的限制。例如,在撰写本文时,Proxychains仅支持TCP,这限制了我们在远程网络中可以进行的扫描和攻击类型。如果我们尝试通过Proxychains进行UDP扫描或SYN扫描,它会失败,因为不支持UDP,并且SYN扫描会破坏TCP握手。

使用Proxychains失败的SYN扫描

这就是我认为SSH VPN可能有用的地方,因为它在第3层设置点对点连接,从而克服这些限制。再次说明,我并不是说这是端口转发的替代品,但如果你在目标系统上拥有root访问权限,它可以是一个有用的资源。为了实现这一点,需要在测试机器和目标机器上进行一系列配置。

首先,我们需要通过以root身份运行以下命令在测试机器上添加和配置tun接口:

1
2
3
ip tuntap add mode tun tun0
ip link set dev tun0 up
ip addr add 10.1.1.10/24 dev tun0

在测试机器上运行命令ip addr show tun0应该显示一个带有IP地址10.1.1.10的新接口。

测试机器上的Tun0接口配置

然后我们需要通过新的tun0接口设置到目标内部网络的路由。

1
ip route add 10.10.10.0/24 via 10.1.1.10

在测试机器上运行命令ip route show应该显示包含新添加路由的路由信息。

测试机器上的路由配置

现在在目标机器上,我们需要通过将PermitTunnel选项设置为yes来启用SSH服务器上的隧道,然后重新加载服务。你可以使用文本编辑器将该选项添加到文件/etc/ssh/sshd_config中。

1
PermitTunnel yes

然后使用systemctl reload sshd重新加载配置。

既然SSH允许隧道,我们可以像在测试机器上一样在目标系统上设置tun接口。

1
2
3
ip tuntap add mode tun tun0
ip link set dev tun0 up
ip addr add 10.1.1.20/24 dev tun0

目标机器上的Tun0接口配置

并添加从内部网络到我们的SSH VPN的路由。

1
ip route add 10.1.1.0/24 via 10.1.1.20

现在,目标系统上还需要进行一些更多配置。首先,需要在新建的tun接口和可以从测试机器访问的外部接口上启用IP转发。感谢Tim Fowler帮助我进行IP转发和NAT设置。

1
2
sysctl -w net.ipv4.conf.tun0.forwarding=1
sysctl -w net.ipv4.conf.ens36.forwarding=1

还要在目标系统上启用NAT,以便传入目标系统的数据包知道去哪里。

1
iptables -t nat -A POSTROUTING -o <interface> -j MASQUERADE

其中<interface>是目标系统的内部接口,在我的情况下是ens36。

内部接口上的Iptables NAT规则

最后,我们可以使用SSH隧道两个接口并访问内部网络。-f标志用于将进程后台化,而-w标志带有参数0:0,表示命令将本地机器上的隧道设备0转发到远程机器上的隧道设备0,而true是要执行的命令以将进程分叉到后台(这可以是任何命令)。

1
ssh -f -w 0:0 user@192.168.136.120 true

我们现在应该与目标主机的端口22建立了连接,可以使用命令ss -at '( dport = :22 )'检查。

SSH隧道已建立

隧道建立后,我们可以直接与内部网络交互,无需使用Proxychains,进行SYN扫描,并与其他协议(如ICMP或UDP)交互。

通过SSH VPN进行Nmap SYN扫描

结束语

虽然VPN设置在某些条件下可以改进SOCKS代理,但它需要更多配置并且需要root访问权限。此外,在撰写此博客时,我只能使其在Linux到Linux的连接上工作。另外,如果你的工具完全支持SOCKS5,端口转发可能是更好的选择(如果你没有root访问权限,则是唯一选择)。

尽管如此,作为渗透测试人员,我们永远不知道会遇到什么样的情况,拥有额外的资源可以在测试中产生巨大的差异。

comments powered by Disqus
使用 Hugo 构建
主题 StackJimmy 设计