multivnc icon indicating copy to clipboard operation
multivnc copied to clipboard

Crashes UltraVNC server that has MSLogonII enabled

Open bk138 opened this issue 2 years ago • 2 comments

If you'd like to put out an incentive for fixing this bug, you can do so at https://issuehunt.io/r/bk138/multivnc?tab=idle

Is your bug report about the Desktop Multivnc or the Mobile MultiVNC?

  • Desktop (wxWidgets) or Mobile (Android): Android

Which MultiVNC version are you using?

2.0.9

Which server are you connecting to?

  • VNC server vendor: UltraVNC
  • VNC server version: 1.3.8.1
  • OS version: Windows 10
  • OS language: German

Describe the bug

Crashes UltraVNC server that has MSLogonII enabled

To Reproduce

  1. Enable MSLogon II in UltraVNC Server admin panel as per https://github.com/LibVNC/libvncserver/pull/480#issuecomment-912085852
  2. Connect with Android MultiVNC 2.0.9
  3. enter username and password
  4. server crashes

Expected Behavior

server does not crash ;-)

Screenshots

For the Desktop Version (please complete the following information):

  • OS and version:
  • Xorg version used:
  • Wayland version used:

For the Mobile Version (please complete the following information):

  • Android version: 12
  • Installed from Play Store, F-Droid, Amazon Appstore: any

Additional context

  • Probably needs a debug build of the server to see what's going on...
  • Another libvncclient-based client worked and still works: https://github.com/LibVNC/libvncserver/pull/480#issuecomment-925234917
  • Maybe wireshark on the server side might be useful to diff the communication flows.

bk138 avatar Aug 07 '22 20:08 bk138

MSLogon w/ MultiVNC 2.0.9

Screenshot 2022-08-08 205000

server terminates afterwards 💣 ...

but also, in another run:

Screenshot 2022-08-08 205442

MSLogon w/ SDLvncviewer built from MultiVNC's libvncserver submodule

Screenshot 2022-08-08 204843

works OK ✔️

bk138 avatar Aug 08 '22 18:08 bk138

https://github.com/LibVNC/libvncserver/issues/493 is related...

bk138 avatar Aug 11 '22 07:08 bk138

I also found this bug of UltraVNC when implementing MSLogonII for noVNC and TigerVNC. It seems if the username/password is long enough or is not null terminalted, the UltraVNC server will crash. If this happens, the encryption algorithm is likely to be incorrect so the server gets the wrong decrypteed plaintext (which may be long or not null terminated).

pdlan avatar Jan 17 '23 07:01 pdlan

@pdlan were you able to pinpoint the exact cause so we can find some kinda fix/workaround? Is it:

  • credentials length > x -> crash
  • username and or password not 0-terminated -> crash ?

bk138 avatar Jan 17 '23 09:01 bk138

I just tested it. When the username length is > 179 the server crashes. The password length doesn't matter.

pdlan avatar Jan 17 '23 10:01 pdlan

I had the problem with "usual" usernames as well. What about the 0-termination?

bk138 avatar Jan 17 '23 11:01 bk138

The case without null termination should be similar to long usernames because the length can be as long as 256 (if there isn't a zero by accident). If your username is very short (e.g. crashes even if the length is 8), I guess it's mostly likely to be because you don't handle DES-CBC correctly, i.e., all blocks but the first one are corrupted.

pdlan avatar Jan 17 '23 11:01 pdlan

The case without null termination should be similar to long usernames because the length can be as long as 256 (if there isn't a zero by accident). If your username is very short (e.g. crashes even if the length is 8), I guess it's mostly likely to be because you don't handle DES-CBC correctly, i.e., all blocks but the first one are corrupted.

Yeah true.

bk138 avatar Jan 17 '23 11:01 bk138

So, I ran UltraVNC under Visual Studio debugger and found that it is throwing an exception during DH key exchange. The exception is not handled, leading to this crash.

Exception source: https://github.com/ultravnc/UltraVNC/blob/1586ec05577d7b82eb19cac5746cf02d6823df5b/rfb/dh.cpp#L136 Called from: https://github.com/ultravnc/UltraVNC/blob/1586ec05577d7b82eb19cac5746cf02d6823df5b/winvnc/winvnc/vncclient.cpp#L1718

After looking around a bit, it seems that UltraVNC limits DH key to 31bits, and when LibVNCClient sends 64bit public key, it throws an exception.

BTW, AVNC with wolfSSL has same issue, so it doesn't seem to related to OpenSSL specifically.

I can't explain why it works in some cases for you guys. For me, It always crashes, even for 4-5 character username.

UltraVNC version: 1.4.0.6 from GitHub

gujjwal00 avatar Jan 19 '23 04:01 gujjwal00

Oh, it seems that you guys might find a different bug from what I found. The long username bug occurs even with UltraVNC client + server.

pdlan avatar Jan 19 '23 04:01 pdlan

BTW I don't think the length limit is a issue because the UltraVNC server always sends a prime < maxNum, so no matter how big the client's private key is, the public key sent by it should always be < prime < maxNum as long as the implementation is correct.

pdlan avatar Jan 19 '23 05:01 pdlan

The issue seems to be incorrect handling of buffers used for holding DH keys crypto_openssl.c.

dh_generate_keypair() & dh_compute_shared_key() are given 8-byte buffers to fill with DH keys. But if a key is smaller, e.g. here it is only 4-byte long, it will be stored in starting bytes of the buffer. Later, when that buffer is treated as full 8-byte key, it results in incorrect calculations.

Now, LibVNCClient already uses BN_bn2binpad which automatically pads the buffer with zeros, but it is not available in older OpenSSL/LibreSSL version. LibVNCClient will fall back to BN_bn2bin which doesn't add zeros. This is probably why SDLvncviewer is working, as it might have been compiled with OpenSSL 1.1.1.

If I manually pad the buffer with this quick patch, I can connect successfully.

gujjwal00 avatar Jan 20 '23 07:01 gujjwal00

If I manually pad the buffer with this quick patch, I can connect successfully.

Great work @gujjwal00! (as always) Can you whip up a PR for libvncclient?

bk138 avatar Jan 20 '23 08:01 bk138

Sure 👍

gujjwal00 avatar Jan 20 '23 08:01 gujjwal00