一次内网横向移动实战:从一个 5900 端口到穿越防火墙
〇、引言
在一次授权的内网安全评估中,我们发现了一台开放了 5900 端口的主机。这个端口本身并不稀奇------在中小型网络中,远程桌面管理是刚需,运维人员为了方便,常常随手开一个服务就丢在那里了。
但正是这个"随手一开",串联出了一个完整的横向移动路径:暴露的管理端口 → 白名单信任缺陷 → 内部网络的纵深突破。
整个过程没有用到 0day,也没有高明到需要什么 APT 工具。但它触及了一个很多网络管理者容易忽略的问题------暴露一个端口,带来的不仅仅是协议层面的攻击面,它还可能是一张通往更深层网络的入场券。
这篇文章记录了这个过程中的思路与方法,全部在授权范围内完成。
一、信息收集:端口的价值不止于"开了什么服务"
常规的网段扫描中,我们首先注意到一台主机开放了 5900 端口:
bash
nmap -sT -Pn -p 5900 --open 192.168.1.0/24
输出:
Nmap scan report for 192.168.1.47
PORT STATE SERVICE
5900/tcp open vnc
确认服务版本:
bash
nmap -sV --script vnc-info -p 5900 192.168.1.47
服务正常响应,版本信息可识别。
为什么 5900 本身就值得关注
很多人看到 5900,第一反应是"一个远程桌面端口而已"。但在内网评估中,5900 的意义远不止于此:
第一,它的暴露本身就说明了一些管理习惯。 内网中开放 5900 通常意味着有人觉得"内网是安全的",所以随手开了个远程管理服务。这种"内部信任"心态,往往也蔓延到其他配置中------比如弱密码、比如过宽的访问控制。
第二,远程桌面服务的认证机制相对简单。 与 SSH 的公钥认证、RDP 的网络层认证(NLA)不同,5900 对应的远程帧缓冲协议(RFB)默认仅依赖于一个密码字段。协议本身不提供账户体系、不强制加密、不记录审计日志。即使密码够强,开放的 5900 端口仍然意味着:
- 可以被任何人尝试连接和爆破------没有账户锁定策略
- 认证失败不会触发系统级安全事件日志------Windows Event Log 中不会默认记录 RFB 认证失败
- 密码的哈希以可逆方式存储------一旦机器被拿下,密码文件可被离线恢复
- 协议早期版本明文传输------中间人可直接捕获密码
第三,它往往对应一个完整的桌面会话。 这和其他远程管理协议有本质区别:SSH 给的是一个 Shell,RDP 给的是一个终端会话,而 5900 给你的是坐在那台机器面前的体验。图形界面、已登录的应用程序、保存的密码、打开的文件------全都直接可见。
换言之,5900 端口的暴露本身就是风险。密码强弱只是决定"多快能进去"的因素,而不是"能不能构成威胁"的决定因素。
二、突破:获取访问权限
在授权范围内,我们对这台机器进行了轻量化的凭据测试。
由于 5900 协议没有账户锁定机制,也并不记录认证失败的审计日志,在爆破过程中不会触发任何告警或账户锁定。使用标准工具配合常用字典进行了尝试:
bash
hydra -P password_list.txt vnc://192.168.1.47
很快匹配成功。
这里需要强调一个认知:很多人觉得"我的密码不弱,所以不用管"。但实际上:
- 5900 端口本身就可以被爆破,没有锁定策略
- 即使密码够强,工具和服务本身可能存在已知漏洞(特定版本的认证绕过、内存泄露等)
- 就算密码真的很强、服务也没有漏洞,暴露 5900 依然等于把你的桌面直接挂在网络上了------你确定这个场景本身是安全的吗?
安全从来不能只靠一层密码撑着。
三、连接与权限确认
使用远程桌面客户端连接:
vncviewer 192.168.1.47:5900
输入密码,认证通过。此时打开了这台机器的完整桌面会话。
在会话中打开终端(CMD 或 PowerShell),确认当前身份:
cmd
whoami
whoami /groups
输出显示当前用户位于本地管理员组。这意味着在这台机器上,可以:
- 查看和修改所有文件
- 查看网络连接状态和路由表
- 读取系统配置、安全策略
- 安装或执行任意程序
- 导出本地存储的凭据
- 修改本地防火墙规则
- 创建计划任务和服务
- 将这台机器作为跳板,访问同一网络中的其他主机
四、关键转折:这台机器是防火墙白名单
获得权限只是入口。真正的价值在于------搞清楚这台机器在整个网络拓扑中的位置。
4.1 网络定位
在终端中执行:
cmd
ipconfig /all
netstat -ano
route print
arp -a
几个关键发现:
- 这台机器跨网段,同时存在于办公网和另一个业务网段中
- 路由表显示它能到达我们在外部扫描中完全看不到的网段
- ARP 表中存在若干同网段主机,其中一台(后称目标机 B)与它有大量已建立的连接
4.2 "白名单"的致命缺陷
进一步确认发现,这台机器在边界防火墙上被配置为白名单节点。防火墙的策略大致是:
- 默认:阻断外部办公网对内部业务网的全部入站流量
- 例外:允许这台 5900 机器自由访问内部业务网的所有主机
这是一个典型的"按主机做信任"而非"按流量做信任"的策略:
攻击者 ──(防火墙阻断)──→ 目标机 B
攻击者 ──(5900入口)──→ 跳板机 A ──(白名单全通)──→ 目标机 B
防火墙保护了所有入口,唯独没有审视这条"已被信任的通道"。
只要进入了 A,防火墙对 B 的保护就等于不存在了。更危险的是------因为白名单策略放行的是"所有流量",从 A 发起的任何连接(SSH、RDP、SMB、数据库客户端、自定义工具)都可以直达 B,没有任何端口级限制。
这就是零信任体系反复提醒的事情:**信任一条主机,不等于信任它的所有流量。**但现实中,大量中小型网络的防火墙规则就是"某几台机器可以全通",因为这样配置最简单。
五、横向移动:利用已有的信任关系
确认 A 可以直接访问 B 之后,横向移动变成了一个相对直接的过程。
5.1 在 A 上定位 B
通过 netstat 确定 B 的 IP 地址:
cmd
netstat -ano | findstr ESTABLISHED
A 与 B 之间存在若干已建立的 TCP 连接。通过 PID 关联到进程:
cmd
tasklist | findstr <PID>
这些连接对应的常见服务包括:SMB(445)、数据库(1433/3306/5432)、文件传输服务等。说明 A 和 B 之间有正常的业务数据通信------这也是 A 被放进白名单的业务理由。
5.2 在 A 上扫描 B
既然 A 可以访问 B 的任意端口,从 A 上做一次 B 的端口扫描是自然的下一步。Windows 原生就能完成,不需要上传额外工具:
powershell
$target = "10.10.10.88"
22,80,135,139,445,1433,3306,3389,5432,5985,8080 | ForEach-Object {
$tcp = New-Object Net.Sockets.TcpClient
$result = $tcp.BeginConnect($target, $_, $null, $null)
if ($result.AsyncWaitHandle.WaitOne(1000)) {
Write-Host "[OPEN] $_" -ForegroundColor Green
}
$tcp.Close()
}
5.3 利用已有信任关系访问 B
A 和 B 既然有业务通信,A 上很可能保存了访问 B 的凭据。依次检查:
保存的凭据:
cmd
cmdkey /list
已建立的共享映射:
cmd
net use
计划任务(可能包含定时数据同步的脚本和凭据):
cmd
schtasks /query /fo LIST /v
如果计划任务中发现了定时从 B 拉取数据或向 B 推送数据的脚本,这些脚本内部往往直接携带 B 的登录凭据。
拿到凭据或发现已有会话后,可以尝试直接访问 B:
cmd
net view \\10.10.10.88
dir \\10.10.10.88\C$
mstsc /v:10.10.10.88
如果在 A 上找到了凭据管理器中的条目但密码不可直接查看,可以用凭证提取工具进一步处理:
powershell
# 仅用于授权安全测试
mimikatz "privilege::debug" "sekurlsa::logonpasswords" exit
⚠️ 重申:以上所有操作均在书面授权范围内进行。本文不构成任何形式的攻击教学,仅用于安全评估参考。
六、复盘:攻击链为什么能成立
回头看,这条攻击链不是靠某个单一漏洞完成的,而是一连串配置上的"小问题"叠加的结果:
| 环节 | 实际操作 | 应有的做法 |
|---|---|---|
| 5900 端口暴露 | 直接监听 0.0.0.0,全网可达 | 绑定 127.0.0.1,通过 SSH 隧道转发 |
| 协议自身缺陷 | 无账户锁定、无审计日志、密码可逆存储 | 用自带审计和账户锁定机制的协议替代 |
| 认证强度不足 | 凭据可被字典匹配 | 强凭据 + 如协议支持则启用多因素认证 |
| 日常以管理员身份登录 | 远程桌面会话就是管理员 | 普通用户登录 + UAC,需要时再提权 |
| 防火墙白名单过宽 | 对跳板机全协议全端口放行 | 按源 IP + 目的 IP + 目的端口 + 协议逐条细化 |
| 跨主机凭据残留 | 跳板机上保存了目标机的访问凭据 | 凭据不落地,临时授权,定期轮换 |
| 横向移动无感知 | A → B 的所有连接均无异常检测 | 部署 EDR / NDR,对横向行为建基线并告警 |
核心问题:信任模型太粗
整个防御体系建立在一条单一的假设上:"A 是安全的"。但 A 的安全怎么保证?靠一个密码。这个密码一旦被突破,防火墙的存在感就消失了。
**白名单不等于"完全信任"。**它应该被理解为"在特定条件下,允许特定类型的流量通过"。把白名单从主机级细化到端口级,是低成本但高回报的加固手段。
七、防御建议
7.1 收敛 5900 的攻击面
最优方案:不暴露。
# 远程桌面服务只监听本地回环地址
# 管理员通过 SSH 隧道转发后从 localhost 连接:
# Step 1: 建立 SSH 隧道
ssh -L 5900:localhost:5900 user@server
# Step 2: 通过隧道连接
vncviewer localhost:5900
次优方案:即使暴露了,也做好以下措施。
- 强密码(≥ 16 位,大小写字母 + 数字 + 特殊字符)
- 来源 IP 限制(防火墙规则只允许特定管理终端 IP 访问 5900)
- 启用连接审计(确认服务端是否支持日志记录)
- 考虑使用支持 NLA 或多因素认证的替代协议
7.2 防火墙白名单策略细化
从"信任主机"变成"信任特定流量":
修正前:
源: 192.168.1.47 → 目标: 10.10.10.0/24 → 动作: 全部放行 ❌
修正后:
源: 192.168.1.47 → 目标: 10.10.10.88 → 目的端口: 3306 → 动作: 放行 ✅
源: 192.168.1.47 → 目标: 10.10.10.88 → 目的端口: 445 → 动作: 阻断 ✅
按照业务实际需求,把每条规则细化到源 IP + 目的 IP + 目的端口 + 协议(TCP/UDP),不用的端口一律不放。
7.3 凭据管理
- 定期检查并清理保存的凭据(
cmdkey /list→cmdkey /delete) - 服务账户与日常登录账户物理隔离
- Windows 环境启用 Credential Guard
- 部署 LAPS(Local Administrator Password Solution),确保每台机器本地管理员密码不同且定期轮换
- 对 SMB、RDP、WinRM 等可横向移动的协议启用网络层认证
7.4 检测与监控
| 检测点 | 可疑特征 | 推荐方案 |
|---|---|---|
| 5900 爆破 | 短时间内大量认证失败 | 网络流量分析 + SIEM 告警 |
| 5900 异常登录 | 非工作时间、异常来源 IP | 主机日志 + 服务端审计 |
| 异常进程行为 | 跳板机上出现扫描/凭据提取工具 | EDR 进程行为监控 |
| 异常横向流量 | A → B 出现非业务端口的连接 | NDR / 网络流量基线分析 |
| 凭据访问 | lsass.exe 被非系统进程访问 | Sysmon Event ID 10 |
| 计划任务变更 | 非授权的计划任务创建/修改 | Windows Event ID 4698 |
八、总结
这次授权评估的收获,浓缩为几点:
-
**5900 端口的暴露本身就是风险,不是因为密码弱才危险。**开放的远程桌面端口意味着:爆破面、协议漏洞面、会话窃取面。暴露它就是给别人递了一把钥匙坯------剩下只是什么时候配出来。
-
**防火墙白名单是双刃剑。**它解决了业务连通性问题,但也可能把整个内部网络的安全锚定在一台机器的"安全假设"上。一旦这台机器失守,防火墙的保护作用归零。
-
**攻击链的威力从来不在于单点的技术含量。**一个暴露的端口、一个过宽的信任策略、一个残留的凭据------三条普通的毛线,编在一起就是一根能拉开大门的绳子。
-
**横向移动的成功往往取决于信任模型的粒度。**从"信任主机"变为"信任特定流量",从"密码就是防线"变为"纵深防御",这些不是成本很高的改造,但能把攻击者的跳板路径堵掉大半。
-
**作为安全从业者,知道怎么走进去很重要,但知道怎么堵上更有价值。**如果你的网络中也有开放着 5900 端口的主机,在别人注意到它们之前,你应该先去看看。不仅仅是改个密码,而是问问自己:这台机器,值得被信任吗?
声明:本文所有技术描述均基于授权安全测试场景。文中所有 IP 地址、主机名、端口及网络拓扑均为虚构示例,不指代任何真实系统或网络。安全测试必须在获得书面授权的前提下进行,任何未经授权的网络入侵行为均属违法。