1 /*
2 ** VNC Password Checking Medusa Module
3 **
4 ** ------------------------------------------------------------------------
5 ** Copyright (C) 2011 Joe Mondloch
6 ** JoMo-Kun / jmk@foofus.net
7 **
8 ** This program is free software; you can redistribute it and/or modify
9 ** it under the terms of the GNU General Public License version 2,
10 ** as published by the Free Software Foundation
11 **
12 ** This program is distributed in the hope that it will be useful,
13 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
14 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 ** GNU General Public License for more details.
16 **
17 ** http://www.gnu.org/licenses/gpl.txt
18 **
19 ** This program is released under the GPL with the additional exemption
20 ** that compiling, linking, and/or using OpenSSL is allowed.
21 **
22 ** ------------------------------------------------------------------------
23 **
24 ** Based on code from:
25 ** VNCrack [FX/Phenolite]
26 ** RealVNC (VNC Server 4 -- FREE)
27 ** UltraVNC 1.0.9.6.1
28 **
29 ** Supports: password-less VNC, password-only VNC and UltraVNC MS-Logon
30 */
31
32 #include <sys/types.h>
33 #include <libgen.h>
34 #include <stdio.h>
35 #include <string.h>
36 #include <stdlib.h>
37 #include "module.h"
38 #include "d3des.h"
39
40 #define MODULE_NAME "vnc.mod"
41 #define MODULE_AUTHOR "JoMo-Kun <jmk@foofus.net>"
42 #define MODULE_SUMMARY_USAGE "Brute force module for VNC sessions"
43 #define MODULE_VERSION "2.1"
44 #define MODULE_VERSION_SVN "$Id: vnc.c 9217 2015-05-07 18:07:03Z jmk $"
45 #define MODULE_SUMMARY_FORMAT "%s : version %s"
46 #define MODULE_SUMMARY_FORMAT_WARN "%s : version %s (%s)"
47 #define OPENSSL_WARNING "No usable OPENSSL. Module disabled."
48
49 #ifdef HAVE_LIBSSL
50
51 #include <openssl/dh.h>
52
53 #define PORT_VNC 5900
54 #define CHALLENGE_SIZE 16
55
56 #define SESSION_SUCCESS 1
57 #define SESSION_FAILURE 2
58 #define SESSION_SUCCESS_NO_AUTH 3
59 #define SESSION_MAX_AUTH_REALVNC 4
60 #define SESSION_MAX_AUTH_ULTRAVNC 5
61
62 #define AUTH_VNC 1
63 #define AUTH_UVNC_MSLOGIN 2
64
65 typedef struct __VNC_DATA {
66 int nMaxAuthSleep;
67 int nAuthType;
68 unsigned char* szChallenge;
69 char* szDomain;
70 } _VNC_DATA;
71
72 // Tells us whether we are to continue processing or not
73 enum MODULE_STATE
74 {
75 MSTATE_NEW,
76 MSTATE_RUNNING,
77 MSTATE_EXITING,
78 MSTATE_COMPLETE
79 };
80
81 // Forward declarations
82 int tryLogin(int hSocket, sLogin** login, _VNC_DATA* _psSessionData, char* szLogin, char* szPassword);
83 int initModule(sLogin* login, _VNC_DATA *_psSessionData);
84 int vncSessionSetup(int hSocket, _VNC_DATA *_psSessionData);
85
86 // Tell medusa how many parameters this module allows
getParamNumber()87 int getParamNumber()
88 {
89 return 0; // we don't need no stinking parameters
90 }
91
92 // Displays information about the module and how it must be used
summaryUsage(char ** ppszSummary)93 void summaryUsage(char **ppszSummary)
94 {
95 // Memory for ppszSummary will be allocated here - caller is responsible for freeing it
96 int iLength = 0;
97
98 if (*ppszSummary == NULL)
99 {
100 iLength = strlen(MODULE_SUMMARY_USAGE) + strlen(MODULE_VERSION) + strlen(MODULE_SUMMARY_FORMAT) + 1;
101 *ppszSummary = (char*)malloc(iLength);
102 memset(*ppszSummary, 0, iLength);
103 snprintf(*ppszSummary, iLength, MODULE_SUMMARY_FORMAT, MODULE_SUMMARY_USAGE, MODULE_VERSION);
104 }
105 else
106 {
107 writeError(ERR_ERROR, "%s reports an error in summaryUsage() : ppszSummary must be NULL when called", MODULE_NAME);
108 }
109 }
110
111 /* Display module usage information */
showUsage()112 void showUsage()
113 {
114 writeVerbose(VB_NONE, "%s (%s) %s :: %s\n", MODULE_NAME, MODULE_VERSION, MODULE_AUTHOR, MODULE_SUMMARY_USAGE);
115 writeVerbose(VB_NONE, "Available module options:");
116 writeVerbose(VB_NONE, " MAXSLEEP:?");
117 writeVerbose(VB_NONE, " Sets the maximum allowed sleep time when the VNC RealVNC anti-brute force delay");
118 writeVerbose(VB_NONE, " is encountered. This value is in seconds and, if left unset, defaults to 60.");
119 writeVerbose(VB_NONE, " DOMAIN:?");
120 writeVerbose(VB_NONE, " Sets the domain value when authenticating against UltraVNC's MS-Logon feature.");
121 writeVerbose(VB_NONE, "");
122 writeVerbose(VB_NONE, "Some versions of VNC have built-in anti-brute force functionality. RealVNC, for example,");
123 writeVerbose(VB_NONE, "allows 5 failed attempts and then enforces a 10 second delay. For each subsequent");
124 writeVerbose(VB_NONE, "attempt that delay is doubled. UltraVNC appears to allow 6 invalid attempts and then forces");
125 writeVerbose(VB_NONE, "a 10 second delay between each following attempt. This module attempts to identify these");
126 writeVerbose(VB_NONE, "situations and react appropriately by invoking sleep(). The user can set a sleep limit when");
127 writeVerbose(VB_NONE, "brute forcing RealVNC using the MAXSLEEP parameter. Once this value has been reached, the");
128 writeVerbose(VB_NONE, "module will exit.");
129 writeVerbose(VB_NONE, "");
130 writeVerbose(VB_NONE, "It should be noted that this module currently supports password-less and password-only VNC");
131 writeVerbose(VB_NONE, "servers. In addition, it supports UltraVNC's MS-Logon feature that can be used to provide");
132 writeVerbose(VB_NONE, "pass-through authentication against local and domain Windows accounts. In the case of basic");
133 writeVerbose(VB_NONE, "password-only VNC, provide any arbitrary username value.");
134 writeVerbose(VB_NONE, "");
135 writeVerbose(VB_NONE, "Usage example: \"-M vnc -m MAXSLEEP:120 -m DOMAIN:FOOFUSDOM\"");
136 }
137
138 // The "main" of the medusa module world - this is what gets called to actually do the work
go(sLogin * logins,int argc,char * argv[])139 int go(sLogin* logins, int argc, char *argv[])
140 {
141 int i;
142 char *strtok_ptr, *pOpt, *pOptTmp;
143 _VNC_DATA *psSessionData;
144 psSessionData = malloc(sizeof(_VNC_DATA));
145 memset(psSessionData, 0, sizeof(_VNC_DATA));
146 psSessionData->nMaxAuthSleep = 60;
147
148 if ((argc < 0) || (argc > 2))
149 {
150 writeError(ERR_ERROR, "%s: Incorrect number of parameters passed to module (%d). Use \"-q\" option to display module usage.", MODULE_NAME, argc);
151 return FAILURE;
152 }
153 else
154 {
155 writeError(ERR_DEBUG_MODULE, "OMG teh %s module has been called!!", MODULE_NAME);
156
157 for (i=0; i<argc; i++) {
158 pOptTmp = malloc( strlen(argv[i]) + 1);
159 memset(pOptTmp, 0, strlen(argv[i]) + 1);
160 strncpy(pOptTmp, argv[i], strlen(argv[i]));
161 writeError(ERR_DEBUG_MODULE, "Processing complete option: %s", pOptTmp);
162 pOpt = strtok_r(pOptTmp, ":", &strtok_ptr);
163 writeError(ERR_DEBUG_MODULE, "Processing option: %s", pOpt);
164
165 if (strcmp(pOpt, "MAXSLEEP") == 0)
166 {
167 pOpt = strtok_r(NULL, "\0", &strtok_ptr);
168 writeError(ERR_DEBUG_MODULE, "Processing option parameter: %s", pOpt);
169
170 if ( pOpt )
171 psSessionData->nMaxAuthSleep = atoi(pOpt);
172 else
173 writeError(ERR_WARNING, "Method MAXSLEEP requires value to be set.");
174 }
175 else if (strcmp(pOpt, "DOMAIN") == 0)
176 {
177 pOpt = strtok_r(NULL, "\0", &strtok_ptr);
178 writeError(ERR_DEBUG_MODULE, "Processing option parameter: %s", pOpt);
179
180 if ( pOpt )
181 {
182 psSessionData->szDomain = malloc(strlen(pOpt) + 1);
183 memset(psSessionData->szDomain, 0, strlen(pOpt) + 1);
184 strncpy((char *) psSessionData->szDomain, pOpt, strlen(pOpt));
185 }
186 else
187 writeError(ERR_WARNING, "Method DOMAIN requires value to be set.");
188 }
189 else
190 writeError(ERR_WARNING, "Invalid method: %s.", pOpt);
191
192 free(pOptTmp);
193 }
194
195 initModule(logins, psSessionData);
196 }
197
198 FREE(psSessionData);
199 return SUCCESS;
200 }
201
initModule(sLogin * psLogin,_VNC_DATA * _psSessionData)202 int initModule(sLogin* psLogin, _VNC_DATA *_psSessionData)
203 {
204 int hSocket = -1;
205 enum MODULE_STATE nState = MSTATE_NEW;
206 int iRet;
207 sConnectParams params;
208 int nAngrySleep = 10;
209 int bAuthAllowed = FALSE;
210 sCredentialSet *psCredSet = NULL;
211
212 psCredSet = malloc( sizeof(sCredentialSet) );
213 memset(psCredSet, 0, sizeof(sCredentialSet));
214
215 if (getNextCredSet(psLogin, psCredSet) == FAILURE)
216 {
217 writeError(ERR_ERROR, "[%s] Error retrieving next credential set to test.", MODULE_NAME);
218 nState = MSTATE_COMPLETE;
219 }
220 else if (psCredSet->psUser)
221 {
222 writeError(ERR_DEBUG_MODULE, "[%s] module started for host: %s user: %s", MODULE_NAME, psLogin->psServer->pHostIP, psCredSet->psUser->pUser);
223 }
224 else
225 {
226 writeError(ERR_DEBUG_MODULE, "[%s] module started for host: %s - no more available users to test.", MODULE_NAME);
227 nState = MSTATE_COMPLETE;
228 }
229
230 memset(¶ms, 0, sizeof(sConnectParams));
231 if (psLogin->psServer->psAudit->iPortOverride > 0)
232 params.nPort = psLogin->psServer->psAudit->iPortOverride;
233 else
234 params.nPort = PORT_VNC;
235 initConnectionParams(psLogin, ¶ms);
236
237 while (nState != MSTATE_COMPLETE)
238 {
239 switch (nState)
240 {
241 case MSTATE_NEW:
242 while (!bAuthAllowed)
243 {
244 if (hSocket > 0)
245 medusaDisconnect(hSocket);
246
247 hSocket = medusaConnect(¶ms);
248
249 if (hSocket < 0)
250 {
251 writeError(ERR_NOTICE, "%s: failed to connect, port %d was not open on %s", MODULE_NAME, params.nPort, psLogin->psServer->pHostIP);
252 psLogin->iResult = LOGIN_RESULT_UNKNOWN;
253 return FAILURE;
254 }
255
256 writeError(ERR_DEBUG_MODULE, "Connected");
257
258 iRet = vncSessionSetup(hSocket, _psSessionData);
259 switch( iRet )
260 {
261 case SESSION_SUCCESS:
262 writeError(ERR_DEBUG_MODULE, "VNC Session Initialized.");
263 bAuthAllowed = TRUE;
264 nState = MSTATE_RUNNING;
265 break;
266 case SESSION_SUCCESS_NO_AUTH:
267 writeError(ERR_DEBUG_MODULE, "VNC Server Does Not Require Authentication.");
268 psLogin->iResult = LOGIN_RESULT_SUCCESS;
269 setPassResult(psLogin, "[NO AUTH REQUIRED]");
270 bAuthAllowed = TRUE;
271 nState = MSTATE_EXITING;
272 break;
273 case SESSION_MAX_AUTH_REALVNC:
274 writeError(ERR_ALERT, "[%s] Host %s reported too many security failures. Sleeping %d seconds before next attempt.", MODULE_NAME, psLogin->psServer->pHostIP, nAngrySleep);
275 if (nAngrySleep > _psSessionData->nMaxAuthSleep)
276 {
277 writeError(ERR_ERROR, "[%s] Host %s exceeded maximum allowed sleep. Terminating connection.", MODULE_NAME, psLogin->psServer->pHostIP);
278 psLogin->iResult = LOGIN_RESULT_UNKNOWN;
279 bAuthAllowed = TRUE;
280 nState = MSTATE_EXITING;
281 }
282 else
283 {
284 sleep(nAngrySleep + 1);
285 nAngrySleep = 2 * nAngrySleep;
286 }
287 break;
288 case SESSION_MAX_AUTH_ULTRAVNC:
289 writeError(ERR_ALERT, "[%s] Host %s has rejected the connection. Sleeping 10 seconds before next attempt.", MODULE_NAME, psLogin->psServer->pHostIP);
290 if (nAngrySleep > _psSessionData->nMaxAuthSleep)
291 {
292 writeError(ERR_ERROR, "[%s] Host %s exceeded maximum allowed sleep. Terminating connection.", MODULE_NAME, psLogin->psServer->pHostIP);
293 psLogin->iResult = LOGIN_RESULT_UNKNOWN;
294 bAuthAllowed = TRUE;
295 nState = MSTATE_EXITING;
296 }
297 else
298 {
299 sleep(10 + 1);
300 nAngrySleep = nAngrySleep + 10;
301 }
302 break;
303 default:
304 writeError(ERR_DEBUG_MODULE, "VNC Session Setup Failed.");
305 psLogin->iResult = LOGIN_RESULT_UNKNOWN;
306 bAuthAllowed = TRUE;
307 nState = MSTATE_EXITING;
308 break;
309 }
310 }
311
312 bAuthAllowed = FALSE;
313 break;
314 case MSTATE_RUNNING:
315 nState = tryLogin(hSocket, &psLogin, _psSessionData, psCredSet->psUser->pUser, psCredSet->pPass);
316
317 if (psLogin->iResult != LOGIN_RESULT_UNKNOWN)
318 {
319 if (getNextCredSet(psLogin, psCredSet) == FAILURE)
320 {
321 writeError(ERR_ERROR, "[%s] Error retrieving next credential set to test.", MODULE_NAME);
322 nState = MSTATE_EXITING;
323 }
324 else
325 {
326 if (psCredSet->iStatus == CREDENTIAL_DONE)
327 {
328 writeError(ERR_DEBUG_MODULE, "[%s] No more available credential sets to test.", MODULE_NAME);
329 nState = MSTATE_EXITING;
330 }
331 else if (psCredSet->iStatus == CREDENTIAL_NEW_USER)
332 {
333 writeError(ERR_DEBUG_MODULE, "[%s] Starting testing for new user: %s.", MODULE_NAME, psCredSet->psUser->pUser);
334 nState = MSTATE_NEW;
335 }
336 else
337 writeError(ERR_DEBUG_MODULE, "[%s] Next credential set - user: %s password: %s", MODULE_NAME, psCredSet->psUser->pUser, psCredSet->pPass);
338 }
339 }
340 break;
341 case MSTATE_EXITING:
342 if (hSocket > 0)
343 medusaDisconnect(hSocket);
344 hSocket = -1;
345 nState = MSTATE_COMPLETE;
346 break;
347 default:
348 writeError(ERR_CRITICAL, "Unknown %s module state %d", MODULE_NAME, nState);
349 if (hSocket > 0)
350 medusaDisconnect(hSocket);
351 hSocket = -1;
352 psLogin->iResult = LOGIN_RESULT_UNKNOWN;
353 return FAILURE;
354 }
355 }
356
357 FREE(psCredSet);
358 return SUCCESS;
359 }
360
361 /* VNC Specific Functions */
362
363 /*
364 ** Encrypt CHALLENGE_SIZE bytes in memory using a password.
365 ** Ripped from vncauth.c
366 */
vncEncryptBytes(unsigned char * bytes,char * passwd)367 void vncEncryptBytes(unsigned char *bytes, char *passwd)
368 {
369 unsigned char key[8];
370 unsigned int i;
371
372 /* key is simply password padded with nulls */
373 for (i = 0; i < 8; i++) {
374 if (i < strlen(passwd)) {
375 key[i] = passwd[i];
376 } else {
377 key[i] = 0;
378 }
379 }
380 deskey(key, EN0);
381 for (i = 0; i < CHALLENGE_SIZE; i += 8) {
382 des(bytes + i, bytes + i);
383 }
384 }
385
vncEncryptPasswdMs(unsigned char * encryptedPasswd,char * passwd)386 void vncEncryptPasswdMs( unsigned char *encryptedPasswd, char *passwd )
387 {
388 unsigned char key[8];
389 unsigned int i;
390
391 /* pad password with nulls */
392 for (i = 0; i < 32; i++) {
393 if (i < strlen(passwd)) {
394 encryptedPasswd[i] = passwd[i];
395 } else {
396 encryptedPasswd[i] = 0;
397 }
398 }
399
400 /* Do encryption in-place - this way we overwrite our copy of the plaintext
401 password */
402 deskey(key, EN0);
403 des(encryptedPasswd, encryptedPasswd);
404 }
405
406 /* [UltraVNC/rfb/dh.cpp] */
bytesToInt64(const unsigned char * const bytes)407 uint64_t bytesToInt64(const unsigned char* const bytes) {
408 uint64_t result = 0;
409 int i;
410
411 for (i = 0; i < 8; i++) {
412 result <<= 8;
413 result += bytes[i];
414 }
415 return result;
416 }
417
int64ToBytes(const uint64_t integer,char * const bytes)418 int int64ToBytes(const uint64_t integer, char* const bytes) {
419 int i;
420 for (i = 0; i < 8; i++) {
421 bytes[i] = (unsigned char) (integer >> (8 * (7 - i)));
422 }
423 return SUCCESS;
424 }
425
426 /* [UltraVNC/vncviewer/vncauth.c] */
vncEncryptBytes2(unsigned char * where,const int length,unsigned char * key)427 void vncEncryptBytes2(unsigned char *where, const int length, unsigned char *key) {
428 int i, j;
429 deskey(key, EN0);
430 for (i = 0; i< 8; i++)
431 where[i] ^= key[i];
432 des(where, where);
433 for (i = 8; i < length; i += 8) {
434 for (j = 0; j < 8; j++)
435 where[i + j] ^= where[i + j - 8];
436 des(where + i, where + i);
437 }
438 }
439
440
vncSessionSetup(int hSocket,_VNC_DATA * _psSessionData)441 int vncSessionSetup(int hSocket, _VNC_DATA* _psSessionData)
442 {
443 unsigned char ProtocolVersion[13];
444 int iServerProtocolVersion;
445 unsigned char* bufReceive;
446 int nReceiveBufferSize = 0;
447 int i = 0;
448 int nSecurityTypes = 0;
449 unsigned char* szSecurityTypes = NULL;
450
451 memset(ProtocolVersion, 0, 13);
452
453 /* --- VNC Protocol Handshake --- */
454
455 /* Retrieve server VNC protocol version */
456 nReceiveBufferSize = 0;
457 bufReceive = medusaReceiveRaw(hSocket, &nReceiveBufferSize);
458 if (bufReceive == NULL)
459 return SESSION_FAILURE;
460
461 writeError(ERR_DEBUG_MODULE, "VNC Server Protocol Version: %s", bufReceive);
462
463 /* The following message is triggered by 5 failed authentication attempts, at which
464 ** point a 10 second lockout is applied before the next attempt is permitted. Each
465 ** subsequent failed attempt causes the timeout to be doubled.
466 **
467 ** RealVNC: Too many security failures
468 ** WinVNC (<=3.3.3r2): Too many authentication failures
469 */
470 if ((strncmp((char *)bufReceive + 20, "Too many security failures", 26) == 0) || (strncmp((char *)bufReceive + 20, "Too many authentication failures", 32) == 0))
471 {
472 writeError(ERR_DEBUG_MODULE, "[%s] Host reported too many security failures.", MODULE_NAME);
473 return SESSION_MAX_AUTH_REALVNC;
474 }
475 /* 3.3, 3.7 and 3.8 are the only published protocol versions (RFB Protocol v3.8 11/26/2010) */
476 else if (strncmp((char *)bufReceive, "RFB 003.003", 11) == 0)
477 {
478 memcpy(ProtocolVersion, "RFB 003.003\n", 12);
479 iServerProtocolVersion = 3;
480 }
481 else if (strncmp((char *)bufReceive, "RFB 003.007", 11) == 0)
482 {
483 memcpy(ProtocolVersion, "RFB 003.007\n", 12);
484 iServerProtocolVersion = 7;
485 }
486 else if (strncmp((char *)bufReceive, "RFB 003.008", 11) == 0)
487 {
488 memcpy(ProtocolVersion, "RFB 003.008\n", 12);
489 iServerProtocolVersion = 8;
490 }
491 /* RealVNC - VNC Server Enterprise Edition E4.6.3 (r66752) */
492 else if (strncmp((char *)bufReceive, "RFB 004.001", 11) == 0)
493 {
494 memcpy(ProtocolVersion, "RFB 004.001\n", 12);
495 iServerProtocolVersion = 8;
496 }
497 else
498 {
499 writeError(ERR_DEBUG_MODULE, "[%s] Unknown session setup response: %s. Setting client response to version 3.3.", MODULE_NAME, bufReceive);
500 memcpy(ProtocolVersion, "RFB 003.003\n", 12);
501 iServerProtocolVersion = 3;
502 }
503
504 /* Send client VNC protocol version */
505 writeError(ERR_DEBUG_MODULE, "VNC Client Protocol Version: %s", ProtocolVersion);
506 if (medusaSend(hSocket, ProtocolVersion, 12, 0) < 0)
507 {
508 writeError(ERR_ERROR, "%s failed: medusaSend was not successful", MODULE_NAME);
509 }
510
511 /* Some VNC servers seem to get upset if we go too fast. Sleeping 1/2 second seems to help. */
512 usleep(0.5 * 1000000);
513
514 /* --- VNC Security Type Handshake --- */
515
516 /* Retrieve VNC protocol authentication scheme response */
517 nReceiveBufferSize = 0;
518 bufReceive = medusaReceiveRaw(hSocket, &nReceiveBufferSize);
519
520 if ((bufReceive == NULL) || (nReceiveBufferSize == 0))
521 {
522 writeError(ERR_ERROR, "No security type response received from server.");
523 return SESSION_FAILURE;
524 }
525 /* RFB Protocol 3.3 - Security Type
526 **
527 ** Server: U32 [security type]
528 **
529 ** if the security types is 0, response is followed by:
530 ** Server: U32 [reason-length]
531 ** U8 array [reason for connection failure]
532 */
533 else if (iServerProtocolVersion == 3)
534 {
535 writeErrorBin(ERR_DEBUG_MODULE, "Supported Security Types (version 3.3): ", bufReceive, nReceiveBufferSize);
536 switch (bufReceive[3])
537 {
538 case 0x00: /* connection failure */
539 writeError(ERR_DEBUG_MODULE, "VNC Session Setup - Failed.");
540
541 if (nReceiveBufferSize > 16)
542 writeError(ERR_DEBUG_MODULE, "VNC Session Setup Failure Message: %s", bufReceive + 8);
543
544 /* Server is probably in anti-brute force mode (UltraVNC) */
545 if ((nReceiveBufferSize == 42) && (strncmp((char *)bufReceive + 8, "Your connection has been rejected.", 34) == 0))
546 return SESSION_MAX_AUTH_ULTRAVNC;
547 else
548 return SESSION_FAILURE;
549 break;
550
551 case 0x01: /* no authentication required */
552 writeError(ERR_DEBUG_MODULE, "VNC Session Setup - Successful - No Authentication Required.");
553 return SESSION_SUCCESS_NO_AUTH;
554 break;
555
556 case 0x02: /* authentication required -- set authentication challenge */
557 writeError(ERR_DEBUG_MODULE, "VNC Session Setup - Successful.");
558 if (nReceiveBufferSize == 20)
559 {
560 _psSessionData->szChallenge = malloc(17);
561 memset(_psSessionData->szChallenge, 0, 17);
562 memcpy(_psSessionData->szChallenge, bufReceive + 4, 16);
563 writeError(ERR_DEBUG_MODULE, "VNC authentication challenge: %s", _psSessionData->szChallenge);
564 _psSessionData->nAuthType = AUTH_VNC;
565 return SESSION_SUCCESS;
566 }
567 else
568 {
569 writeError(ERR_ERROR, "[%s] Unknown session challenge. Possible unsupported authentication type.", MODULE_NAME);
570 return SESSION_FAILURE;
571 }
572 break;
573
574 case 0xFA: /* UltaVNC MS-Logon */
575 writeError(ERR_DEBUG_MODULE, "VNC Session Setup - UltraVNC MS-Logon.");
576
577 if (nReceiveBufferSize == 28)
578 {
579 _psSessionData->szChallenge = malloc(25);
580 memset(_psSessionData->szChallenge, 0, 25);
581 memcpy(_psSessionData->szChallenge, bufReceive + 4, 24);
582 writeErrorBin(ERR_DEBUG_MODULE, "VNC authentication challenge: ", bufReceive + 4, 24);
583 _psSessionData->nAuthType = AUTH_UVNC_MSLOGIN;
584 return SESSION_SUCCESS;
585 }
586 else
587 {
588 writeError(ERR_ERROR, "[%s] Unknown session challenge. Possible unsupported authentication type.", MODULE_NAME);
589 return SESSION_FAILURE;
590 }
591
592 break;
593
594 default: /* unknown response */
595 writeError(ERR_ERROR, "[%s] VNC Session Setup - Unknown Response (3.3): %d", MODULE_NAME, bufReceive[3]);
596 return SESSION_FAILURE;
597 break;
598 }
599 }
600 /* RFB Protocol 3.7, 3.8 - Security Type
601 **
602 ** Server: U8 [number of security types]
603 ** U8 array [security type]
604 **
605 ** If the number of security types is 0, response is followed by:
606 ** Server: U32 [reason-length]
607 ** U8 array [reason for connection failure]
608 */
609 else if ((iServerProtocolVersion == 7) || (iServerProtocolVersion == 8))
610 {
611 writeErrorBin(ERR_DEBUG_MODULE, "Supported Security Types (> version 3.7): ", bufReceive, nReceiveBufferSize);
612
613 /* connection failure */
614 if (bufReceive[0] == 0)
615 {
616 writeError(ERR_DEBUG_MODULE, "VNC Session Setup - Failed.");
617
618 //memcpy(nReasonLength + sizeof(int), bufReceive + 1, 4);
619
620 if (nReceiveBufferSize > 8)
621 writeError(ERR_DEBUG_MODULE, "VNC Session Setup Failure Message: %s", bufReceive + 5);
622
623 /* Server is probably in anti-brute force mode (UltraVNC) */
624 if (strncmp((char *)bufReceive + 5, "Your connection has been rejected.", 34) == 0)
625 return SESSION_MAX_AUTH_ULTRAVNC;
626 else
627 return SESSION_FAILURE;
628 }
629 /* verify response length */
630 else if (nReceiveBufferSize == 1 + (int)bufReceive[0])
631 {
632 nSecurityTypes = (int)bufReceive[0];
633 szSecurityTypes = malloc(nSecurityTypes + 1);
634 memset(szSecurityTypes, 0, nSecurityTypes + 1);
635 memcpy(szSecurityTypes, bufReceive + 1, nSecurityTypes);
636
637 for (i = 0; i <= nSecurityTypes; i++)
638 {
639 writeError(ERR_DEBUG_MODULE, "Processing server security type: %d (%d/%d). We will select the first supported type encountered.", szSecurityTypes[i], i + 1, nSecurityTypes);
640 switch (szSecurityTypes[i])
641 {
642 case 0x01: /* no authentication required */
643 writeError(ERR_DEBUG_MODULE, "VNC Session Setup - Password-only VNC - No Authentication Required");
644
645 if (medusaSend(hSocket, &szSecurityTypes[i], 1, 0) < 0)
646 {
647 writeError(ERR_ERROR, "[%s] failed: medusaSend was not successful", MODULE_NAME);
648 return FAILURE;
649 }
650
651 nReceiveBufferSize = 0;
652 bufReceive = medusaReceiveRaw(hSocket, &nReceiveBufferSize);
653 if (bufReceive == NULL)
654 return FAILURE;
655 else if (bufReceive[3] == 0)
656 return SESSION_SUCCESS_NO_AUTH;
657 else
658 return FAILURE;
659
660 break;
661 case 0x02: /* authentication required -- set authentication challenge */
662 writeError(ERR_DEBUG_MODULE, "VNC Session Setup - Password-only VNC");
663
664 if (medusaSend(hSocket, &szSecurityTypes[i], 1, 0) < 0)
665 {
666 writeError(ERR_ERROR, "[%s] failed: medusaSend was not successful", MODULE_NAME);
667 return FAILURE;
668 }
669
670 nReceiveBufferSize = 0;
671 bufReceive = medusaReceiveRaw(hSocket, &nReceiveBufferSize);
672
673 if (nReceiveBufferSize == 16)
674 {
675 _psSessionData->szChallenge = malloc(17);
676 memset(_psSessionData->szChallenge, 0, 17);
677 memcpy(_psSessionData->szChallenge, bufReceive, 16);
678 writeError(ERR_DEBUG_MODULE, "VNC authentication challenge: %s", _psSessionData->szChallenge);
679 _psSessionData->nAuthType = AUTH_VNC;
680 return SESSION_SUCCESS;
681 }
682 else
683 {
684 writeError(ERR_ERROR, "[%s] Unknown session challenge. Possible unsupported authentication type.", MODULE_NAME);
685 return SESSION_FAILURE;
686 }
687 break;
688
689 case 0x05: /* 5: RealVNC RA2 */
690 case 0x06: /* 6: RealVNC RA2ne */
691 case 0x81: /* 129: UNIX Logon Authentication */
692 case 0x82: /* 130: External Authentication */
693 writeError(ERR_ERROR, "[%s] VNC Session Setup - RealVNC (Type %d). RealVNC native authentication mode is NOT currently supported.", MODULE_NAME, szSecurityTypes[i]);
694 break;
695
696 case 0x11: /* 17: UltraVNC */
697 /* http://www.uvnc.com/features/authentication.html */
698 /*
699 [rfb/rfbproto.h]
700 rfbUltraVNC 0x17 - after rfbUltraVNC, auth repeats via rfbVncAuthContinue
701
702 rfbUltraVNC_SCPrompt 0x68
703 rfbUltraVNC_SessionSelect 0x69
704 rfbUltraVNC_MsLogonIAuth 0x70
705 rfbUltraVNC_MsLogonIIAuth 0x71
706 rfbUltraVNC_SecureVNCPluginAuth 0x72
707 */
708
709 writeError(ERR_DEBUG_MODULE, "VNC Session Setup - UltraVNC");
710
711 /*
712 0x11 UltraVNC contains multiple sub-types. If we respond with 0x11, the server
713 should send us a list. For example, 0xffffffff 0x0171 (UltraVNC MS-Logon II).
714 This appears to be sent sometimes as a single packet, sometimes as two. It seems
715 that any sub-types we would enumerate here, however, were also listed in the initial
716 supported security type response. As such, let's just skip this type and move on
717 to the next in the list. If this assumption turns out to be incorrect, we should
718 continue the security type negotiation here.
719 */
720
721 break;
722
723 case 0x70: /* 17: UltraVNC MS-Logon I */
724 case 0x71: /* 17: UltraVNC MS-Logon II */
725 writeError(ERR_DEBUG_MODULE, "VNC Session Setup - UltraVNC (Type %d)", szSecurityTypes[i]);
726
727 if (medusaSend(hSocket, &szSecurityTypes[i], 1, 0) < 0)
728 {
729 writeError(ERR_ERROR, "[%s] failed: medusaSend was not successful", MODULE_NAME);
730 return FAILURE;
731 }
732
733 nReceiveBufferSize = 0;
734 bufReceive = medusaReceiveRaw(hSocket, &nReceiveBufferSize);
735
736 if (nReceiveBufferSize == 24)
737 {
738 writeError(ERR_DEBUG_MODULE, "VNC Session Setup - UltraVNC MS-Logon II - Process authentication challenge");
739 _psSessionData->szChallenge = malloc(25);
740 memset(_psSessionData->szChallenge, 0, 25);
741 memcpy(_psSessionData->szChallenge, bufReceive, 24);
742 writeErrorBin(ERR_DEBUG_MODULE, "VNC authentication challenge: ", _psSessionData->szChallenge, 24);
743 _psSessionData->nAuthType = AUTH_UVNC_MSLOGIN;
744 return SESSION_SUCCESS;
745 }
746
747 break;
748
749 default: /* unknown response - skip and see if we find a supported type */
750 writeError(ERR_ERROR, "[%s] VNC Session Setup - Unknown Response (3.7/3.8): %d", MODULE_NAME, szSecurityTypes[i]);
751 break;
752 }
753 }
754 }
755 else
756 {
757 writeError(ERR_ERROR, "[%s] VNC Session Setup - Unknown Response", MODULE_NAME);
758 return SESSION_FAILURE;
759 }
760 }
761
762 FREE(szSecurityTypes);
763 return SESSION_FAILURE;
764 }
765
sendAuthVNC(int hSocket,_VNC_DATA * _psSessionData,char * szPassword)766 int sendAuthVNC(int hSocket, _VNC_DATA* _psSessionData, char* szPassword)
767 {
768 writeError(ERR_DEBUG_MODULE, "[%s] VNC authentication challenge: %s", MODULE_NAME, _psSessionData->szChallenge);
769 vncEncryptBytes(_psSessionData->szChallenge, szPassword);
770 writeError(ERR_DEBUG_MODULE, "[%s] VNC authentication response: %s", MODULE_NAME, _psSessionData->szChallenge);
771
772 if (medusaSend(hSocket, _psSessionData->szChallenge, 16, 0) < 0)
773 {
774 writeError(ERR_ERROR, "[%s] failed: medusaSend was not successful", MODULE_NAME);
775 return FAILURE;
776 }
777
778 return SUCCESS;
779 }
780
781 /*
782 Based on ClientConnection::AuthMsLogonII() [UltraVNC/vncviewer/ClientConnection.cpp]
783
784 MS Logon authentication supports "domain\user", "user" and "user@domain" logins
785 */
sendAuthMSLogin(int hSocket,_VNC_DATA * _psSessionData,char * szLogin,char * szPassword)786 int sendAuthMSLogin(int hSocket, _VNC_DATA* _psSessionData, char* szLogin, char* szPassword)
787 {
788 unsigned char ms_user[256], ms_passwd[64];
789 unsigned char key[8];
790 int i = 0;
791
792 int client_priv = 31337; /* arbitrary value -- client would typically randomly generate */
793 uint64_t g, p, resp;
794 char client_pub[8];
795 BIGNUM* server_pub;
796
797 DH *dh_struct;
798 int dh_error;
799 unsigned char *dh_secret;
800
801 unsigned char *bufSend = NULL;
802
803 writeError(ERR_DEBUG_MODULE, "[%s] VNC Authentication - UltraVNC Microsoft Logon", MODULE_NAME);
804
805 /* parse server challenge -- g, p (mod) and server public key */
806 g = bytesToInt64(_psSessionData->szChallenge);
807 p = bytesToInt64(_psSessionData->szChallenge + 8);
808 resp = bytesToInt64(_psSessionData->szChallenge + 16);
809
810 writeError(ERR_DEBUG_MODULE, "[%s] Server DH values: g: %d p/mod: %d public key: %d", MODULE_NAME, g, p, resp);
811
812 /* create and populate DH structure */
813 dh_struct = DH_new();
814
815 #if OPENSSL_VERSION_NUMBER >= 0x10100005L
816 DH_set0_pqg(dh_struct, (BIGNUM*) &p, (BIGNUM*) &client_priv, (BIGNUM*) &g);
817 #else
818 dh_struct->g = BN_new();
819 BN_set_word(dh_struct->g, g);
820
821 dh_struct->p = BN_new();
822 BN_set_word(dh_struct->p, p);
823
824 dh_struct->priv_key = BN_new();
825 BN_set_word(dh_struct->priv_key, client_priv);
826 #endif
827
828 if (DH_generate_key(dh_struct) == 0)
829 writeError(ERR_ERROR, "[%s] Failed to generate key", MODULE_NAME);
830
831 DH_check(dh_struct, &dh_error);
832 if (dh_error & DH_CHECK_P_NOT_SAFE_PRIME)
833 writeError(ERR_DEBUG_MODULE, "[%s] Failed to create DH structure: DH_CHECK_P_NOT_SAFE_PRIME", MODULE_NAME);
834 if (dh_error & DH_NOT_SUITABLE_GENERATOR)
835 writeError(ERR_DEBUG_MODULE, "[%s] Failed to create DH structure: DH_NOT_SUITABLE_GENERATOR", MODULE_NAME);
836 if (dh_error & DH_UNABLE_TO_CHECK_GENERATOR)
837 writeError(ERR_DEBUG_MODULE, "[%s] Failed to create DH structure: DH_UNABLE_TO_CHECK_GENERATOR", MODULE_NAME);
838
839 /* convert client public key into proper format for sending */
840 #if OPENSSL_VERSION_NUMBER >= 0x10100005L
841 DH_set0_key(dh_struct, (BIGNUM*) &client_pub, (BIGNUM*) &client_priv);
842 #else
843 int64ToBytes(BN_get_word(dh_struct->pub_key), client_pub);
844 #endif
845
846 /* generate shared secret using private DH key and server's public key */
847 server_pub = BN_new();
848 BN_set_word(server_pub, resp);
849
850 dh_secret = malloc( DH_size(dh_struct) );
851 DH_compute_key(dh_secret, server_pub, dh_struct);
852
853 /* OpenSSLs DH implementation is compliant with the SSL/TLS requirements that skip
854 leading zeroes on the output. We need our key to be exactly 8 bytes long, so
855 let's prepend it with the necessary number of zeros. */
856 memset(key, 0, 8);
857 if (DH_size(dh_struct) < 8)
858 for (i=0; i < DH_size(dh_struct); i++)
859 key[8 - DH_size(dh_struct) + i] = dh_secret[i];
860
861 DH_free(dh_struct);
862
863 writeErrorBin(ERR_DEBUG_MODULE, "Shared secret key: ", key, 8);
864
865 memset(ms_user, 0, 256);
866 memset(ms_passwd, 0, 64);
867
868 if ((_psSessionData->szDomain) && (strlen(_psSessionData->szDomain) + 1 + strlen(szLogin) < 256))
869 {
870 strncpy((char *)ms_user, _psSessionData->szDomain, strlen(_psSessionData->szDomain));
871 strncat((char *)ms_user, "\\", 1);
872 strncat((char *)ms_user, szLogin, strlen(szLogin));
873 }
874 else
875 strncpy((char *)ms_user, szLogin, 256);
876
877 strncpy((char *)ms_passwd, szPassword, 64);
878
879 writeError(ERR_DEBUG_MODULE, "Username: %s Password: %s", ms_user, ms_passwd);
880 writeErrorBin(ERR_DEBUG_MODULE, "Username: ", ms_user, 256);
881 writeErrorBin(ERR_DEBUG_MODULE, "Password: ", ms_passwd, 64);
882
883 vncEncryptBytes2((unsigned char*) &ms_user, sizeof(ms_user), key);
884 vncEncryptBytes2((unsigned char*) &ms_passwd, sizeof(ms_passwd), key);
885
886 writeErrorBin(ERR_DEBUG_MODULE, "Encrypted username: ", ms_user, 256);
887 writeErrorBin(ERR_DEBUG_MODULE, "Encrypted password: ", ms_passwd, 64);
888
889 /* send client public key, encrypted username, and encrypted password */
890 bufSend = malloc(8 + sizeof(ms_user) + sizeof(ms_passwd) + 1);
891 memset(bufSend, 0, 8 + sizeof(ms_user) + sizeof(ms_passwd) + 1);
892
893 /*
894 For extra fun, set client_pub to a value of 0x80000000 or greater. No more server...
895 memset(client_pub, 0x0000000080, 5);
896 */
897 memcpy(bufSend, client_pub, 8);
898 memcpy(bufSend + 8, ms_user, sizeof(ms_user));
899 memcpy(bufSend + 8 + sizeof(ms_user), ms_passwd, sizeof(ms_passwd));
900
901 if (medusaSend(hSocket, bufSend, 8 + sizeof(ms_user) + sizeof(ms_passwd), 0) < 0)
902 {
903 writeError(ERR_ERROR, "[%s] failed: medusaSend was not successful", MODULE_NAME);
904 return FAILURE;
905 }
906
907 return SUCCESS;
908 }
909
sendExit(int hSocket)910 int sendExit(int hSocket)
911 {
912 unsigned char szExit[] = { 0x00, 0x00, 0x00, 0x00, 0x05, 0x1D, 0x03, 0x20 };
913
914 writeError(ERR_DEBUG_MODULE, "[%s] Send VNC connection termination command.", MODULE_NAME);
915
916 if (medusaSend(hSocket, szExit, 8, 0) < 0)
917 {
918 writeError(ERR_ERROR, "[%s] failed: medusaSend was not successful", MODULE_NAME);
919 return FAILURE;
920 }
921
922 return SUCCESS;
923 }
924
tryLogin(int hSocket,sLogin ** psLogin,_VNC_DATA * _psSessionData,char * szLogin,char * szPassword)925 int tryLogin(int hSocket, sLogin** psLogin, _VNC_DATA* _psSessionData, char* szLogin, char* szPassword)
926 {
927 unsigned char* bufReceive;
928 int nReceiveBufferSize = 0;
929 int iRet;
930
931 /* perform authentication */
932 switch(_psSessionData->nAuthType)
933 {
934 case AUTH_VNC:
935 sendAuthVNC(hSocket, _psSessionData, szPassword);
936 break;
937 case AUTH_UVNC_MSLOGIN:
938 sendAuthMSLogin(hSocket, _psSessionData, szLogin, szPassword);
939 break;
940 default:
941 writeError(ERR_DEBUG_MODULE, "[%s] VNC Authentication - blah", MODULE_NAME);
942 break;
943 }
944
945 writeError(ERR_DEBUG_MODULE, "[%s] VNC Authentication - Waiting for authentication result", MODULE_NAME);
946 nReceiveBufferSize = 0;
947 bufReceive = medusaReceiveRaw(hSocket, &nReceiveBufferSize);
948 if (bufReceive == NULL)
949 return FAILURE;
950 else if (nReceiveBufferSize == 0)
951 {
952 /* Some VNC servers (e.g. TightVNC 2.0 Beta) simply drop the connection on a bad password */
953 writeError(ERR_DEBUG_MODULE, "[%s] VNC Authentication - Failed (no response from server)", MODULE_NAME);
954 (*psLogin)->iResult = LOGIN_RESULT_FAIL;
955 iRet = MSTATE_NEW;
956 }
957 else if (nReceiveBufferSize >= 4)
958 {
959 switch (bufReceive[3])
960 {
961 case 0x00:
962 writeError(ERR_DEBUG_MODULE, "[%s] VNC Authentication - Success", MODULE_NAME);
963 (*psLogin)->iResult = LOGIN_RESULT_SUCCESS;
964 iRet = MSTATE_EXITING;
965
966 // TODO: Is this only for UltraVNC?
967 sendExit(hSocket);
968 break;
969 case 0x01:
970 if ((nReceiveBufferSize > 8) && (strstr((char *)bufReceive + 8, "Connection rejected by user") != NULL))
971 {
972 writeError(ERR_DEBUG_MODULE, "[%s] VNC Authentication - Success (User rejected connection)", MODULE_NAME);
973 (*psLogin)->pErrorMsg = malloc( 40 + 1 );
974 memset((*psLogin)->pErrorMsg, 0, 40 + 1 );
975 sprintf((*psLogin)->pErrorMsg, "User rejected connection request.");
976 (*psLogin)->iResult = LOGIN_RESULT_SUCCESS;
977 iRet = MSTATE_EXITING;
978 }
979 else
980 {
981 writeError(ERR_DEBUG_MODULE, "[%s] VNC Authentication - Failed", MODULE_NAME);
982 (*psLogin)->iResult = LOGIN_RESULT_FAIL;
983 iRet = MSTATE_NEW;
984 }
985 break;
986 default:
987 writeError(ERR_ERROR, "[%s] VNC Authentication - Unknown Response: %d", MODULE_NAME, bufReceive[3]);
988 (*psLogin)->iResult = LOGIN_RESULT_ERROR;
989 iRet = MSTATE_EXITING;
990 break;
991 }
992 }
993 else
994 {
995 writeError(ERR_ERROR, "[%s] VNC Authentication - Unknown Response", MODULE_NAME);
996 (*psLogin)->iResult = LOGIN_RESULT_ERROR;
997 iRet = MSTATE_EXITING;
998 }
999
1000 setPassResult((*psLogin), szPassword);
1001
1002 return(iRet);
1003 }
1004
1005 #else
1006
summaryUsage(char ** ppszSummary)1007 void summaryUsage(char **ppszSummary)
1008 {
1009 // Memory for ppszSummary will be allocated here - caller is responsible for freeing it
1010 int iLength = 0;
1011
1012
1013 if (*ppszSummary == NULL)
1014 {
1015 iLength = strlen(MODULE_SUMMARY_USAGE) + strlen(MODULE_VERSION) + strlen(MODULE_SUMMARY_FORMAT) + strlen(OPENSSL_WARNING) + 1;
1016 *ppszSummary = (char*)malloc(iLength);
1017 memset(*ppszSummary, 0, iLength);
1018 snprintf(*ppszSummary, iLength, MODULE_SUMMARY_FORMAT_WARN, MODULE_SUMMARY_USAGE, MODULE_VERSION, OPENSSL_WARNING);
1019 }
1020 else
1021 {
1022 writeError(ERR_ERROR, "%s reports an error in summaryUsage() : ppszSummary must be NULL when called", MODULE_NAME);
1023 }
1024 }
1025
showUsage()1026 void showUsage()
1027 {
1028 writeVerbose(VB_NONE, "%s (%s) %s :: %s\n", MODULE_NAME, MODULE_VERSION, MODULE_AUTHOR, MODULE_SUMMARY_USAGE);
1029 writeVerbose(VB_NONE, "** Module was not properly built. Is OPENSSL installed correctly? **");
1030 writeVerbose(VB_NONE, "");
1031 }
1032
go(sLogin * logins,int argc,char * argv[])1033 int go(sLogin* logins, int argc, char *argv[])
1034 {
1035 writeVerbose(VB_NONE, "%s (%s) %s :: %s\n", MODULE_NAME, MODULE_VERSION, MODULE_AUTHOR, MODULE_SUMMARY_USAGE);
1036 writeVerbose(VB_NONE, "** Module was not properly built. Is OPENSSL installed correctly? **");
1037 writeVerbose(VB_NONE, "");
1038 return FAILURE;
1039 }
1040
1041 #endif
1042