0x00 VNC是什么

VNC(Virtual Network Computing),是一种使用RFB协议的屏幕画面分享及远程操作软件。此软件借由网络,可发送键盘与鼠标的动作及即时的屏幕画面。

VNC与操作系统无关,因此可跨平台使用,例如可用Windows连线到某Linux的电脑,反之亦同。甚至在没有安装客户端程序的电脑中,只要有支持JAVA的浏览器,也可使用。

VNC的龙头老大是RealVNC,RFB的协议规范(rfc 6143)也是RealVNC起草发布的。所以LZ就用了RealVNC做实验环境。

0x01 RFB协议

RFB(Remote Framebuffer)-用于远程访问图形台式计算机的客户端-服务器网络协议。RFB是VNC中使用的协议。由于它在帧缓冲区级别工作,因此可以用于图形窗口系统,例如X Window System,Windows,Quartz Compositor。

android NDEF协议wifi novif协议_客户端

默认端口

默认情况下,RFB使用5900到5906之间的TCP端口范围。每个端口代表相应的X服务器屏幕(端口5900到5906与屏幕之间的关联从0到6)。

对于Windows系统,默认screen是:0,它对应于端口5900。

反向连接

VNC支持反向建立连接,vncviewer监听5500端口,等待服务端主动连接。对于内网穿透的情况,反向连接很有用处。

网络层协议

支持TCP/UDP协议。最新版本Real VNC默认使用5900/UDP进行通信。

协议版本

版本

发行者

日期

规格

RFB 3.3

Orl

January 1998

The Remote Framebuffer Protocol 3.3

RFB 3.7

RealVNC Ltd

August 2003

The Remote Framebuffer Protocol 3.7

RFB 3.8 (current)

RealVNC Ltd

June 2007

The Remote Framebuffer Protocol 3.8

RFC 6143 - The Remote Framebuffer Protocol (2011) 是针对RFB 3.x版本综合整理的正式协议规范。Real VNC之后每年都会更新RFB版本,现在已经出到RFB 6.0了,但是因为加入加密,高画质传输,聊天等功能,Real VNC对这些在市面上没有公开的协议说明。wireshark也主要是对未加密的RFB 3.x版本的通信数据做解析。

0x02 VNC协商过程

时序图

android NDEF协议wifi novif协议_服务器_02


UML源码

title: RFB协议协商过程

_: **1. 握手过程**
客户端 <- 服务器: Server protocol version: 003.008

客户端-> 服务器 : Client Protocol version: 003.008
_: **2. 认证过程**
客户端 <- 服务器: Security types supported
客户端 -> 服务器: Authentication type selected by client
客户端 <- 服务器: Authentication challenge from server
客户端 --> 服务器: ACK
客户端 -> 服务器: Authentication response from client
客户端 <- 服务器: Authentication result
_: **2. 初始化桌面**
客户端 -> 服务器: Share desktop flag

note: 服务器图像颜色等配置,鼠标,键盘事件等交互

协商过程

VNC连接可以分为4个阶段:握手过程,认证过程,桌面交互和挥手过程。

这里只说前两个阶段。对VNC的图像传输,事件交互处理感兴趣的童鞋可以参考VNCDoTool编写的RFB协议文档。【传送门

握手过程

服务器先发送一个ProtocolVersion给客户端,让客户端知道服务器能支持的最高版本号。

客户端回复一个相同格式的ProtocolVerion给服务器,握手结束。

字节数

文本

12

“RFB 003.008\n” (hex 52 46 42 20 30 30 33 2e 30 30 33 0a)

wireshark抓包

android NDEF协议wifi novif协议_客户端_03

认证过程

服务器向客户端发送一个安全类型(Security Type),通知客户端用什么方式认证。这里以VNC认证(2)为例。

android NDEF协议wifi novif协议_服务器_04


安全类型

常用值如下


名称

0

Invalid

1

None

2

VNC Authentication

一些其他的值,来自官方定义【传送门


名称

3-4

RealVNC

5

RA2

6

RA2ne

7-15

RealVNC

17

Ultra

18

TLS

19

VeNCrypt

20

SASL

21

MD5 hash authentication

30-35

Apple Inc.

128-255

RealVNC

客户端回复相同的安全类型,表示确认。

android NDEF协议wifi novif协议_客户端_05


VNC认证中加密用的参数并没有想TLS协议一样被加密,所以安全性不高,服务器发送一个16字节随机数作为challenge。

android NDEF协议wifi novif协议_客户端_06


客户端通过challenge对自己的密码进行DES加密,然后把算出来的16字节结果作为response发送给服务器。

android NDEF协议wifi novif协议_Real_07


DES加密算法

  • 输入16字节的challenge
  • 8字节密码作为key
  • mode为ECB
  • IV为00000000(8个字节全为0)

android NDEF协议wifi novif协议_服务器_08


使用openssl加密的方法

$ echo 612522e570df96c66abf7a915c9c8f12 |xxd -r -p |openssl des-ecb -nopad -K 61646D696E313233|xxd -p
fbad0f1e3263a809fea34aedcbdde38a

当然,你可能在想为啥这个response(fb ad 0f 1e 32 63 a8 09 fe a3 4a ed cb dd e3 8a
)跟上面wireshark的response(a1 e0 31 7b ec be df e8 15 74 fe ab 9a 3b 20 46)不同。

这是一个好问题,因为VNC对密码做了简单处理,单字节位反转,演示如下

Password : 12345678
Ascii values (HEX) : 31 32 33 34 35 36 37 38
Binary values:      00110001 00110010 00110011 ....
Binary reversed:  10001100 01001100 11001100 ....
Reversed (HEX): 8c 4c cc 2c ac 6c ec 1c

实际用于加密的key为: 8c4ccc2cac6cec1c (12345678 in ASCII)。所以response不同。

至于如何从流量中破解VNC认证方式的密码,有两个思路

  1. 已知DES加密算法只能接受56位的密钥,加上8位奇偶校验位凑成8个字节密钥对64位数据块加密,所以密钥最长8个字节。逐个字节爆破速度也不会太慢,据称使用2个NVIDIA Quadro P4000 8GB显卡3天就能爆破出最难的密码。
  2. 或者内置一部分密码做碰撞。

服务器判断response是否正确,返回授权结果。0表示授权成功。

android NDEF协议wifi novif协议_VNC_09


授权结果类型

字节数

类型

描述

4

0

OK

4

1

failed

4

2

failed, too many attempts

在3.8以上版本,如果失败,服务器会发送失败原因的字符串,然后断开连接。

字节数

描述

4

reason-length

reason-length

reason-string

1a表示后面有26个字节

android NDEF协议wifi novif协议_客户端_10


在RFB3.3和3.7版本,如果失败,服务器断开连接。

0x03 总结

  1. VNC传统加密密码最长8个字节,使用DES加密方法。可以被爆破。
  2. RealVNC密码已经可以支持256个字节,并且支持TLS,SASL等加密方法做认证,这种目前很难爆破,如果有量子计算机的话。

0x04 扩展问题

  1. DES是56位密码,应该是7个字节,为什么VNC是8个字节密码?
  2. 通过des对challenge做了加密,key也做了位反转,为什么还是跟流量中的response不同?(有些VNC协议是魔改的,比如华为云V100R005C50 虚拟机VNC,使用SHA256替代了DES算法)
  3. 本机的VNC密钥存在哪里?能破解吗?
  4. VNC的防爆破机制是什么?

0x05 参考文献

https://vncdotool.readthedocs.io/en/0.8.0/rfbproto.html
https://miloserdov.org/?p=4854 https://jamesdotcom.com/vnc-authentication-checking-with-python/ https://ics-cert.kaspersky.com/reports/2019/11/22/vnc-vulnerability-research/ https://news.ycombinator.com/item?id=11130699 https://support.huawei.com/enterprise/zh/doc/EDOC1000091631
https://hashcat.net/forum/thread-8833-post-46908.html#pid46908
https://github.com/x0rz4/vncpwd

P.S. 这篇博文写了大约2个星期终于完成了。开始想写点协议细节的,发现还要看Remote FrameBuffer的图形交互接口,太繁琐了,定的目标太大,容易进坑。所以再三cut之后,总结了一些有用的知识点与同学们分享。