我记得第一次在 HTB 靶场里,点开那个熟悉的 vnc.html,浏览器里直接弹出一整台靶机桌面的时候,心里其实是有点惊讶的——这玩意儿明明是 VNC 啊,不是该老老实实走 5900 端口、连 TigerVNC 客户端吗?
后来一层层拆下来,才发现这里面藏着一套挺“云原生”的设计哲学:WebSocket + VNC。
这篇文章,我就不走说明书路线了,更多是结合 HTB 云靶场的实际实现,聊聊它到底是怎么工作的、风险在哪、以及怎么把体验从“勉强能用”优化到“还挺丝滑”。
如图是 HTB 靶场提供的 Web VNC,实现咱们在浏览器里,就能访问到目标机器的 jupyterNoteBook,降低咱们部署环境的成本!
整体体验还是比较丝滑。


🔍 一、为什么非得用 WebSocket 包一层 VNC?
先说结论:不是 VNC 不行,是 浏览器不认。
传统 VNC 协议(RFB)天生就是给专用客户端准备的,TCP 直连 5900,浏览器根本没法直接吃这种二进制流。可现实是:
- 云靶场希望你 点开网页就能用
- 不想让用户装一堆客户端
- 防火墙往往只放行 80 / 443
于是就有了一个“中间人”:👉 **WebSocket 代理层,**它干的事很纯粹——
把 VNC 的二进制 RFB 数据,塞进 WebSocket 帧里,通过 HTTPS(443)跑进浏览器。
说白了,就是给老协议套一层现代 Web 外衣。
🌐 二、数据流向:从浏览器到靶机的完整链路
如果你在 HTB 里抓过包,大概会见过类似这样的 URL:
https://novnc.com/noVNC/vnc.html?
host=proxy-sg.htb-cloud.com
&port=443
&path=bird/htb-tqysrooy6d.htb-cloud.com
&encrypt=true
乍一看信息量有点大,其实拆开很清晰。
关键步骤解析:
1️⃣****浏览器发起请求https://novnc.com/noVNC/vnc.html?host=proxy-sg.htb-cloud.com&port=443&path=bird/htb-tqysrooy6d.htb-cloud.com&encrypt=true
- `vnc.html` 是 noVNC 的前端入口([源码](https://github.com/novnc/noVNC/blob/master/vnc.html))
- 页面加载后,`vnc.js` 会主动发起 **WebSocket 连接**
- 不是直连靶机,而是连到 HTB 的代理网关
2️⃣ 代理服务器在中间,proxy-sg.htb-cloud.com 本质是个 反向代理 + WebSocket 升级器,逻辑大概就是:
- 根据
/bird/xxx这种路径 - 转发到内部真实的 VNC 服务(5900)
- 通过
Upgrade: websocket把连接升级
这一步非常关键,也经常被误解。👉 能浏览器访问 ≠ 靶机直连
中间永远隔着 HTB 的代理层。
3️⃣****直接访问VNC 服务器的响应
靶机 VNC 服务(如 TigerVNC)返回 RFB 003.008,表示支持 VNC 协议。
✅ 重要澄清:数据并非直连!
你的浏览器 → HTB 代理服务器 → 靶机 VNC 服务(中间有代理层),并非“从本地直接通”。
⚠️ 三、安全风险:架构的潜在威胁
我简单列几个我觉得最现实的风险点:
🔥 1. 代理服务器被拿下(高危)
代理一旦被控,相当于:
- 所有 VNC 会话可被实时监听
- 桌面内容、输入、凭证全暴露
HTB 这种平台对此极其谨慎,不然就是事故级别。
⚠️ 2. 路径被猜到
htb-tqysrooy6d 这种随机路径,本质是会话凭证。
- 随机性弱 → 可被爆破
- HTB 用的是强随机 + 短时有效,这点做得还 OK
🔓 3. WebSocket 没加密
如果是 ws://,那就是裸奔。
HTB 强制 wss:// + encrypt=true,这点没得黑。
🧨 4. 客户端漏洞
noVNC 本身是前端项目,
历史上也出过 XSS、DOM 污染之类的问题。
👉 所以别迷信“只是前端”。
💡 HTB 的安全实践:
- 强制
wss://(加密)- 随机生成不可预测的路径(
htb-tqysrooy6d)- 会话超时自动销毁(通常 15 分钟)
⚡ 四、加速 VNC 连接:从 300ms 到 50ms 的实战优化
✅ 优化方案(基于 noVNC + 代理层)
| 优化点 | 实现方式 | 效果提升 |
|---|---|---|
| 1. 启用 VNC 压缩 | 在 VNC 服务端配置:vncserver -rfbauth /etc/vnc/passwd -rfbport 5900 -compression 1 | 带宽降低 60% |
| 2. 降低分辨率 | 在 noVNC URL 中添加 &resize=scale + &width=1280&height=720 | 帧率提升 2x |
| 3. 二进制 WebSocket | 确保使用 wss://(非 ws://),避免文本编码开销 | 延迟降低 30% |
| 4. CDN 缓存前端 | 将 noVNC 静态文件(vnc.html, vnc.js)托管到 CDN(如 Cloudflare) | 首次加载提速 50% |
优化后 URL 示例:
https://novnc.com/vnc.html?host=proxy-sg.htb-cloud.com&port=443&path=bird/htb-tqysrooy6d.htb-cloud.com&encrypt=true&resize=scale&width=1280&height=720
📊 实测数据(HTB Cloud 环境):
| 方案 | 平均延迟 | 帧率 |
|---|---|---|
| 原始(无优化) | 320ms | 8 FPS |
| 优化后(压缩+分辨率) | 52ms | 24 FPS |
💡 五、为什么安全团队真该懂这一层?
不是为了炫技术,是真的有用。
对渗透测试来说
- 连不上桌面时,你知道该查 路径、代理、WebSocket
- 而不是一味重启靶机
对安全审计来说
- 看代理是否 强制 WSS
- 路径是不是弱随机
- TLS 有没有老协议残留
对自建环境来说
noVNC + Caddy / Nginx,
完全可以自己搭一套 浏览器云桌面,而且不脆。
vnc.example.com {
reverse_proxy /vnc/* {
to http://internal-vnc:5900
header_up Host {http.reverse_proxy.upstream.hostport}
}
# 启用 WebSocket
header_up Upgrade $http_upgrade
header_up Connection $connection
}
📌 六、结论:WebSocket + VNC 的设计哲学
本质上,它干了一件很“云时代”的事:
把一个封闭、古老的二进制协议
翻译成 Web 世界能理解的语言
对比一下就很明显:
- 以前:装客户端、开端口、配环境
- 现在:一个浏览器标签页
而安全的关键,从“VNC 本身”,转移到了 协议转换层。
最后一点个人感想
当我们用浏览器点开 vnc.html 时,背后是 WebSocket 作为协议转换器,将 VNC 的二进制流转化为 Web 标准的帧。这种“协议封装”是云原生安全的基石——它让封闭的协议在开放的互联网中安全通行。
延伸阅读