Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for UltraVNC MS-Logon II credentials #1197

Closed
rgl opened this issue Feb 3, 2019 · 9 comments · Fixed by #1731
Closed

Add support for UltraVNC MS-Logon II credentials #1197

rgl opened this issue Feb 3, 2019 · 9 comments · Fixed by #1731

Comments

@rgl
Copy link

rgl commented Feb 3, 2019

UltraVNC as an extended credentials/security type called MS-Logon II. It lets one use local or domain account credentials with an username and password instead of the tradicional VNC password.

This would be a nice addition to noVNC.

@CendioOssman
Copy link
Member

Agreed, that would be nice. Someone needs to figure out the protocol details first though and add them to @rfbproto. Hopefully it should be fairly simple to implement after that.

@CendioOssman
Copy link
Member

There is also the VeNCrypt "Plain" authentication method that also supports username and password, as well as the XVP auth (which noVNC already supports).

@rgl
Copy link
Author

rgl commented Feb 4, 2019

It seems there's no formal documentation about the format, only the vncviewer code. From reading it, it seems to work like this:

server sends DH parameters and its A public value:
    U64 g (aka generator)
    U64 p (aka modulus)
    U64 A

client sends its DH B public value and the user plain-text username/password encrypted with the shared key (from the DH exchange):
    U64 B
    byte[256] DES(username, s)
    byte[64] DES(password, s)

I'm not sure if the DH and DES implementations are standard... but the rabbit hole starts at:

void ClientConnection::AuthMsLogonII()
void vncEncryptBytes2(unsigned char *where, const int length, unsigned char *key)
void deskey(unsigned char *key, short edf)
void des(unsigned char *inblock, *outblock)

Can you guide me to where should I start implementing this on noVNC?

@CendioOssman
Copy link
Member

Start with _init_msg() and follow it to _negotiate_security() and _negotiate_authentication(). Look at the existing authentication methods for some clues how this is done.

I would very much like a patch to rfbproto once you've figured out the protocol though. That way we have some reference and don't have to dig around in code.

rgl added a commit to rgl/vnc2video that referenced this issue Feb 6, 2019
@rgl
Copy link
Author

rgl commented Feb 6, 2019

the MS-Logon II authentication is somewhat working at https://github.com/rgl/vnc2video but I had to take a detour and use the actual code from vnc to make it work... I'm scratching my head on why the normal DES implementation (from Go) does not work. Do you known why?

The code that should have worked is commented:

func encrypt(cipherTextLength int, plainText []byte, key []byte) ([]byte, error) {
	out, err := exec.Command(
		"./ultra-ms-logon-2-encrypt",
		hex.EncodeToString(key),
		strconv.Itoa(cipherTextLength),
		string(plainText)).Output()
	if err != nil {
		return nil, err
	}
	return hex.DecodeString(strings.TrimSpace(string(out)))

	// XXX so the following code should have worked... but the vnc des
	//     implementation does not seem to be standard... so I had to
	//	   create an external application that uses the same C code as
	//     TightVNC/UltraVNC and that works... any idea why?
	// // create zero-padded slice.
	// cipherText := make([]byte, cipherTextLength)
	// copy(cipherText, plainText)

	// block, err := des.NewCipher(key)
	// if err != nil {
	// 	return nil, err
	// }

	// mode := cipher.NewCBCEncrypter(block, key)
	// mode.CryptBlocks(cipherText, cipherText)

	// return cipherText, nil
}

once this is cleared up I think we have enough to write this down on @rfbproto and implement it in noVNC.

@rgl
Copy link
Author

rgl commented Feb 6, 2019

For reference, some discussion about this was also started at https://forum.ultravnc.net/viewtopic.php?f=4&t=34796

@CendioOssman
Copy link
Member

It might be that they are using the same DES implementation that is used for the classical VNC authentication. It uses a reverse bit order compared to most other DES implementations. There is a comment about it here:

https://github.com/rfbproto/rfbproto/blob/master/rfbproto.rst#vnc-authentication

You should be able to test that theory by shifting the bits around before you give the data to Go's DES functions.

@Neustradamus
Copy link

Any news on it?

@Neustradamus
Copy link

@pdlan: Thanks for your PR!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants