Hello,
We are seeing false positive alerts claiming VNC Brute Force Login (NVT OID: 1.3.6.1.4.1.25623.1.0.106056) on a couple of MacOS devices. The underlying reason seems to be that the built-in VNC server in MacOS violates the RFB protocol and sends the authentication result field using the wrong endianness, which is interpreted by standards-compliant clients (like Greenbone) as always succeeding. However, the server also claims to use an unknown version of the protocol, which means this condition should be possible to handle in gb_vnc_brute_force.nasl
.
Tcpdump reports the server’s handshake packet as (with IP addresses censored):
0x0000: 0800 0000 0000 0010 0001 0006 0009 0f09 ................
0x0010: 0a1c 0000 4500 0040 0000 4000 3c06 b8f1 ....E..@..@.<...
0x0020: 2020 2020 2020 2020 170c 81c6 b193 a47f ........
0x0030: 2bde 97ba 8018 0804 f136 0000 0101 080a +........6......
0x0040: 1b7f ede7 5a8c 782e 5246 4220 3030 332e ....Z.x.RFB.003.
0x0050: 3838 390a 889.
That’s RFB 3.889, which is not a standard - RFC 6143 describes 3.3, 3.7, and 3.8.
The client selects 3.8 instead:
0x0000: 0800 0000 0000 0010 0001 0406 f4a8 0d4c ...............L
0x0010: 0745 0000 4500 0040 5b01 4000 4006 59f0 .E..E..@[.@.@.Y.
0x0020: 2020 2020 2020 2020 81c6 170c 2bde 97ba ....+...
0x0030: b193 a48b 8018 01f6 85f9 0000 0101 080a ................
0x0040: 5a8c 788e 1b7f ede7 5246 4220 3030 332e Z.x.....RFB.003.
0x0050: 3030 380a 008.
and authentication continues according to the 3.8 standard with method selection and challenge-response until the server replies with:
0x0000: 0800 0000 0000 0010 0001 0006 0009 0f09 ................
0x0010: 0a1c 0000 4500 0064 0000 4000 3c06 b8cd ....E..d..@.<...
0x0020: 2020 2020 2020 2020 170c 81c6 b193 a4a0 ........
0x0030: 2bde 97d7 8018 0803 42d0 0000 0101 080a +.......B.......
0x0040: 1b7f fbe8 5a8c 8485 0100 0000 0000 0027 ....Z..........'
0x0050: 4175 7468 656e 7469 6361 7469 6f6e 206f Authentication.o
0x0060: 7220 6175 7468 6f72 697a 6174 696f 6e20 r.authorization.
0x0070: 6661 696c 7572 6500 failure.
Note this line in the authentication response:
0x0040: 1b7f fbe8 5a8c 8485 0100 0000 0000 0027 ....Z..........'
^result^^ ^length^^
gb_vnc_brute_force.nasl
looks at the fourth byte of result
, sees that it’s 0
, and reports a successful authentication:
auth_res = ord( res[3] );
if( auth_res == 0 ) {
report = "It was possible to connect to the VNC server with the password: " + password;
So does tshark -T json
:
"tcp.payload": "01:00:00:00:00:00:00:27:41:75:74:68:65:6e:74:69:63:61:74:69:6f:6e:20:6f:72:20:61:75:74:68:6f:72:69:7a:61:74:69:6f:6e:20:66:61:69:6c:75:72:65:00"
},
"vnc": {
"vnc.auth_result": "0"
}
This is what RFC 6143, section 7.1.3 says you should do:
The server sends a word to inform the client whether the security
handshaking was successful.+--------------+--------------+-------------+ | No. of bytes | Type [Value] | Description | +--------------+--------------+-------------+ | 4 | U32 | status: | | | 0 | OK | | | 1 | failed | +--------------+--------------+-------------+
If successful, the protocol passes to the initialization phase
(Section 7.3).If unsuccessful, the server sends a string describing the reason for
the failure, and then closes the connection:+---------------+--------------+---------------+ | No. of bytes | Type [Value] | Description | +---------------+--------------+---------------+ | 4 | U32 | reason-length | | reason-length | U8 array | reason-string | +---------------+--------------+---------------+
And the protocol is explicitly big-endian (section 7):
All multiple-byte integers (other than pixel values themselves) are in big endian order (most significant byte first).
But is obviously not what MacOS does. Interestingly, this only applies to the result code - the error message string is correctly encoded according to the RFC:
Some messages use arrays of the basic types, with the number of entries in the array determined from fields preceding the array.
The length
field is 00 00 00 27
, indicating a 39-byte string in big-endian form.
Would it be possible for gb_vnc_brute_force.nasl
to check for protocol minor version 889 and, if so, byte-swap the authentication result field?
Also, someone with more direct access to a Mac than me should probably check what happens if you do manage to authenticate successfully. Or I’ll see if I can get one of my users to cooperate.
I have no idea how long MacOS has behaved this way, but I found this bug from 2011 about it claiming to be version 3.889.