我记得第一次在 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 环境):

方案平均延迟帧率
原始(无优化)320ms8 FPS
优化后(压缩+分辨率)52ms24 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 标准的帧。这种“协议封装”是云原生安全的基石——它让封闭的协议在开放的互联网中安全通行。

延伸阅读