通过SSH实现流量转发:本地、远程、动态端口转发与VPN配置详解

本文详细介绍了使用SSH进行本地、远程和动态端口转发的技术方法,包括具体命令语法和实际应用场景。还探讨了通过SSH建立VPN连接以突破SOCKS代理限制的高级配置,涉及tun接口设置、路由配置和iptables规则等深层网络技术。

通过SSH转发流量

本文原本计划是一篇OpenSSH使用指南,但在阅读man页面(通过在Linux终端输入man ssh访问的手册页)时,我发现了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 user@testing_machine_ip

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是要执行的命令以将进程fork到后台(这可以是任何命令)。

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 设计