1 /***************************************************************************
2 * ncrack_vnc.cc -- ncrack module for the vnc protocol *
3 * Coded by rhh *
4 * http://rycon.hu/ *
5 * *
6 ***********************IMPORTANT NMAP LICENSE TERMS************************
7 * *
8 * The Nmap Security Scanner is (C) 1996-2019 Insecure.Com LLC ("The Nmap *
9 * Project"). Nmap is also a registered trademark of the Nmap Project. *
10 * This program is free software; you may redistribute and/or modify it *
11 * under the terms of the GNU General Public License as published by the *
12 * Free Software Foundation; Version 2 ("GPL"), BUT ONLY WITH ALL OF THE *
13 * CLARIFICATIONS AND EXCEPTIONS DESCRIBED HEREIN. This guarantees your *
14 * right to use, modify, and redistribute this software under certain *
15 * conditions. If you wish to embed Nmap technology into proprietary *
16 * software, we sell alternative licenses (contact sales@nmap.com). *
17 * Dozens of software vendors already license Nmap technology such as *
18 * host discovery, port scanning, OS detection, version detection, and *
19 * the Nmap Scripting Engine. *
20 * *
21 * Note that the GPL places important restrictions on "derivative works", *
22 * yet it does not provide a detailed definition of that term. To avoid *
23 * misunderstandings, we interpret that term as broadly as copyright law *
24 * allows. For example, we consider an application to constitute a *
25 * derivative work for the purpose of this license if it does any of the *
26 * following with any software or content covered by this license *
27 * ("Covered Software"): *
28 * *
29 * o Integrates source code from Covered Software. *
30 * *
31 * o Reads or includes copyrighted data files, such as Nmap's nmap-os-db *
32 * or nmap-service-probes. *
33 * *
34 * o Is designed specifically to execute Covered Software and parse the *
35 * results (as opposed to typical shell or execution-menu apps, which will *
36 * execute anything you tell them to). *
37 * *
38 * o Includes Covered Software in a proprietary executable installer. The *
39 * installers produced by InstallShield are an example of this. Including *
40 * Nmap with other software in compressed or archival form does not *
41 * trigger this provision, provided appropriate open source decompression *
42 * or de-archiving software is widely available for no charge. For the *
43 * purposes of this license, an installer is considered to include Covered *
44 * Software even if it actually retrieves a copy of Covered Software from *
45 * another source during runtime (such as by downloading it from the *
46 * Internet). *
47 * *
48 * o Links (statically or dynamically) to a library which does any of the *
49 * above. *
50 * *
51 * o Executes a helper program, module, or script to do any of the above. *
52 * *
53 * This list is not exclusive, but is meant to clarify our interpretation *
54 * of derived works with some common examples. Other people may interpret *
55 * the plain GPL differently, so we consider this a special exception to *
56 * the GPL that we apply to Covered Software. Works which meet any of *
57 * these conditions must conform to all of the terms of this license, *
58 * particularly including the GPL Section 3 requirements of providing *
59 * source code and allowing free redistribution of the work as a whole. *
60 * *
61 * As another special exception to the GPL terms, the Nmap Project grants *
62 * permission to link the code of this program with any version of the *
63 * OpenSSL library which is distributed under a license identical to that *
64 * listed in the included docs/licenses/OpenSSL.txt file, and distribute *
65 * linked combinations including the two. *
66 * *
67 * The Nmap Project has permission to redistribute Npcap, a packet *
68 * capturing driver and library for the Microsoft Windows platform. *
69 * Npcap is a separate work with it's own license rather than this Nmap *
70 * license. Since the Npcap license does not permit redistribution *
71 * without special permission, our Nmap Windows binary packages which *
72 * contain Npcap may not be redistributed without special permission. *
73 * *
74 * Any redistribution of Covered Software, including any derived works, *
75 * must obey and carry forward all of the terms of this license, including *
76 * obeying all GPL rules and restrictions. For example, source code of *
77 * the whole work must be provided and free redistribution must be *
78 * allowed. All GPL references to "this License", are to be treated as *
79 * including the terms and conditions of this license text as well. *
80 * *
81 * Because this license imposes special exceptions to the GPL, Covered *
82 * Work may not be combined (even as part of a larger work) with plain GPL *
83 * software. The terms, conditions, and exceptions of this license must *
84 * be included as well. This license is incompatible with some other open *
85 * source licenses as well. In some cases we can relicense portions of *
86 * Nmap or grant special permissions to use it in other open source *
87 * software. Please contact fyodor@nmap.org with any such requests. *
88 * Similarly, we don't incorporate incompatible open source software into *
89 * Covered Software without special permission from the copyright holders. *
90 * *
91 * If you have any questions about the licensing restrictions on using *
92 * Nmap in other works, we are happy to help. As mentioned above, we also *
93 * offer an alternative license to integrate Nmap into proprietary *
94 * applications and appliances. These contracts have been sold to dozens *
95 * of software vendors, and generally include a perpetual license as well *
96 * as providing support and updates. They also fund the continued *
97 * development of Nmap. Please email sales@nmap.com for further *
98 * information. *
99 * *
100 * If you have received a written license agreement or contract for *
101 * Covered Software stating terms other than these, you may choose to use *
102 * and redistribute Covered Software under those terms instead of these. *
103 * *
104 * Source is provided to this software because we believe users have a *
105 * right to know exactly what a program is going to do before they run it. *
106 * This also allows you to audit the software for security holes. *
107 * *
108 * Source code also allows you to port Nmap to new platforms, fix bugs, *
109 * and add new features. You are highly encouraged to send your changes *
110 * to the dev@nmap.org mailing list for possible incorporation into the *
111 * main distribution. By sending these changes to Fyodor or one of the *
112 * Insecure.Org development mailing lists, or checking them into the Nmap *
113 * source code repository, it is understood (unless you specify *
114 * otherwise) that you are offering the Nmap Project the unlimited, *
115 * non-exclusive right to reuse, modify, and relicense the code. Nmap *
116 * will always be available Open Source, but this is important because *
117 * the inability to relicense code has caused devastating problems for *
118 * other Free Software projects (such as KDE and NASM). We also *
119 * occasionally relicense the code to third parties as discussed above. *
120 * If you wish to specify special license conditions of your *
121 * contributions, just say so when you send them. *
122 * *
123 * This program is distributed in the hope that it will be useful, but *
124 * WITHOUT ANY WARRANTY; without even the implied warranty of *
125 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the Nmap *
126 * license file for more details (it's in a COPYING file included with *
127 * Nmap, and also available from https://svn.nmap.org/nmap/COPYING) *
128 * *
129 ***************************************************************************/
130
131
132 #include "ncrack.h"
133 #include "nsock.h"
134 #include "NcrackOps.h"
135 #include "Service.h"
136 #include "modules.h"
137 #include <list>
138 #include <crypto.h>
139
140 #define TIMEOUT 20000
141 #define MAXPWLEN 8
142 #define CHALLENGESIZE 16
143
144 #define MAXMSPWLEN 32
145 #define CHALLENGESIZEMS 64
146
147 #define BYTES_TO_READ 1024
148
149 extern NcrackOps o;
150
151 extern void ncrack_read_handler(nsock_pool nsp, nsock_event nse, void *mydata);
152 extern void ncrack_write_handler(nsock_pool nsp, nsock_event nse, void *mydata);
153 extern void ncrack_connect_handler(nsock_pool nsp, nsock_event nse,
154 void *mydata);
155 extern void ncrack_module_end(nsock_pool nsp, void *mydata);
156
157 enum states { VNC_INIT, VNC_HANDSHAKE, VNC_SECURITY_TYPE, VNC_AUTH, VNC_SECURITY_RESULT };
158
159 /*
160 * Encrypt CHALLENGESIZE bytes in memory using a password.
161 */
162 static void
vncEncryptBytes(unsigned char * bytes,char * passwd)163 vncEncryptBytes(unsigned char *bytes, char *passwd)
164 {
165 unsigned char key[8];
166 size_t i;
167
168 /* key is simply password padded with nulls */
169
170 for (i = 0; i < 8; i++) {
171 if (i < strlen(passwd)) {
172 key[i] = passwd[i];
173 } else {
174 key[i] = 0;
175 }
176 }
177
178 deskey(key, EN0);
179
180 for (i = 0; i < CHALLENGESIZE; i += 8) {
181 des(bytes+i, bytes+i);
182 }
183 }
184
185
186 static int
buf_check(int n,char * p)187 buf_check(int n, char* p) {
188 int i;
189 for(i=0; i<n; i++)
190 if(p[i] != 0 )
191 return p[i];
192 return 0;
193 }
194
195 static uint8_t*
str2uint8(char * p,int str_length,int uint_length)196 str2uint8(char* p, int str_length, int uint_length)
197 {
198 uint8_t* retme;
199 retme = new uint8_t[str_length];
200
201 for(int i=0; i < str_length; i++)
202 retme[i] = (uint8_t)p[i];
203
204 if(uint_length>str_length)
205 for(int i=str_length; i < uint_length; i++)
206 retme[i] = (uint8_t)0;
207
208 return retme;
209 }
210
211 void
ncrack_vnc(nsock_pool nsp,Connection * con)212 ncrack_vnc(nsock_pool nsp, Connection *con)
213 {
214 nsock_iod nsi = con->niod;
215 Service *serv = con->service;
216 char version_test[] = {2,0};
217
218 switch (con->state)
219 {
220 case VNC_INIT:
221 con->state = VNC_HANDSHAKE;
222
223 break;
224
225 case VNC_HANDSHAKE:
226
227 /* Wait till we receive the server's input */
228 if(con->inbuf == NULL)
229 break;
230
231 //buf_print(con->inbuf->get_len(), (char*)con->inbuf->get_dataptr());
232
233 /* We may have hit our limit, so we need to check */
234 if (memsearch((const char *)con->inbuf->get_dataptr(), "Too many authentication failures", con->inbuf->get_len())||
235 memsearch((const char *)con->inbuf->get_dataptr(), "Too many security failures", con->inbuf->get_len())) {
236 if (o.debugging > 5)
237 error("%s Too many authentication failures (a)", serv->HostInfo());
238
239 con->close_reason = MODULE_ERR;
240 con->force_close = true;
241 return ncrack_module_end(nsp, con);
242 }
243
244 /* vnc begins with the server sending a version like "RFB 003.008\n" or "RFB 003.003\n"
245 * determine which one to use, and then continue
246 */
247 if (memsearch((const char *)con->inbuf->get_dataptr(), "RFB 003.008", con->inbuf->get_len())) {
248 con->outbuf = new Buf();
249 con->outbuf->snprintf(12 , "RFB 003.008\n");
250 nsock_write(nsp, nsi, ncrack_write_handler, TIMEOUT, con, (const char *)con->outbuf->get_dataptr(), con->outbuf->get_len());
251 con->state = VNC_SECURITY_TYPE;
252 }
253 else {
254 con->outbuf = new Buf();
255 con->outbuf->snprintf(12 , "RFB 003.003\n");
256 nsock_write(nsp, nsi, ncrack_write_handler, TIMEOUT, con, (const char *)con->outbuf->get_dataptr(), con->outbuf->get_len());
257 con->state = VNC_AUTH;
258 }
259 /* We are now waiting for a SECURITY_TYPE response back, which could be several bytes */
260
261 break;
262
263 case VNC_SECURITY_TYPE:
264 if(con->inbuf == NULL)
265 break;
266
267 if (memsearch((const char *)con->inbuf->get_dataptr(), "Too many authentication failures", con->inbuf->get_len())||
268 memsearch((const char *)con->inbuf->get_dataptr(), "Too many security failures", con->inbuf->get_len())) {
269 if (o.debugging > 5)
270 error("%s Too many authentication failures (b)", serv->HostInfo());
271
272 con->close_reason = MODULE_ERR;
273 con->force_close = true;
274 return ncrack_module_end(nsp, con);
275 }
276
277 /* At this point in the game, we should have gotten the number of security protocols,
278 * and a list of those protocols (like 0x02, 0x0210)
279 * handling VNC Authentication, which is 0x02, so let's ship that back and be on our way.
280 */
281 if (memsearch((const char *)con->inbuf->get_dataptr(), version_test, con->inbuf->get_len())) {
282 uint8_t sec_version; sec_version = 0x02;
283 con->outbuf = new Buf();
284 con->outbuf->append(&sec_version, sizeof(uint8_t));
285 nsock_write(nsp, nsi, ncrack_write_handler, TIMEOUT, con, (const char *)con->outbuf->get_dataptr(), con->outbuf->get_len());
286 con->state = VNC_AUTH;
287 }
288 /*
289 else {
290 error("%s This VNC server doesn't support VNC Auth.\n", serv->HostInfo());
291 con->service->end.orly = true;
292 //con->service->end.reason = Strndup("This VNC server doesn't support VNC Auth.", 23);
293
294 con->close_reason = MODULE_ERR;
295 con->force_close = true;
296 return ncrack_module_end(nsp, con);
297 }
298 */
299
300 /* Now we're waiting to hear back from the server whether we are good to go or not. 0 is go, 1 is fail */
301
302 break;
303
304 case VNC_AUTH:
305 /* At this point, we should have gotten a 16-unsigned byte challenege */
306
307 if(con->inbuf == NULL)
308 break;
309
310 /* des_data will hold the challenge before vncEncryptBytes() and the response after */
311 uint8_t* des_data;
312
313 /* if length is 20, we are in protocol version 003.003, which means we've gotten
314 * back a 4-byte security version number, as well as the challenge.
315 */
316 if(con->inbuf->get_len() == 20) {
317 des_data = str2uint8((char*)con->inbuf->get_dataptr()+4, 16, 16);
318 vncEncryptBytes(des_data, con->pass);
319 }
320 /* if it's exactly 16, we're in 003.007 or 003.008, so we can encrypt the challenge
321 * and continue
322 */
323 else if(con->inbuf->get_len() == 16) {
324 /* des_data will hold the challenge before vncEncryptBytes() and the response after */
325 des_data = str2uint8((char*)con->inbuf->get_dataptr(), 16, 16);
326 vncEncryptBytes(des_data, con->pass);
327 }
328 /* If we have a 4 byte response, we've received only the version, but not the request yet. So
329 * just break, and get the response next go round.
330 */
331 else if(con->inbuf->get_len() == 4) {
332 if (memsearch((const char *)con->inbuf->get_dataptr(), version_test, con->inbuf->get_len()))
333 break;
334 else {
335 if (o.debugging > 5)
336 error("%s The server claims not to support VNC Auth. (Can be an auth limit problem)\n", serv->HostInfo());
337 return ncrack_module_end(nsp, con);
338 }
339 }
340 /* if we don't get 20, 16 or 4, then I'm confused as to what has happened. I suppose
341 * we should probably terminate this connection. Hasn't really come up in my tests.
342 */
343 else {
344 if (o.debugging)
345 error("%s Challenge not the right length (%d, when 16 expected)!\n", serv->HostInfo(), con->inbuf->get_len());
346 return ncrack_module_end(nsp, con);
347 }
348
349 /* Ship our encrypted challenge back to the server, and await a result */
350 con->outbuf = new Buf();
351 con->outbuf->append(des_data, 16*sizeof(uint8_t));
352 nsock_write(nsp, nsi, ncrack_write_handler, TIMEOUT, con, (const char *)con->outbuf->get_dataptr(), con->outbuf->get_len());
353
354 con->state = VNC_SECURITY_RESULT;
355
356 break;
357
358 case VNC_SECURITY_RESULT:
359
360 if(con->inbuf == NULL)
361 break;
362
363 /* okay, at this point, we expect to have at least 4 bytes in response. If more, then we have a failure message
364 * However, we'll still check to make sure all bytes are 0 (the OK message) before we set auth_success to true
365 */
366 if(con->inbuf->get_len() >= 4 && buf_check(con->inbuf->get_len(), (char*)con->inbuf->get_dataptr()) == 0)
367 con->auth_success = true;
368
369 return ncrack_module_end(nsp, con);
370
371 con->state = VNC_INIT;
372
373 break;
374
375 }
376 /* Clean up when we are done with our buffers. */
377 if(con->inbuf)
378 delete con->inbuf;
379 con->inbuf = NULL;
380 if(con->outbuf)
381 delete con->outbuf;
382 con->outbuf = NULL;
383
384 /* Read the next thrilling chapter from the server */
385 nsock_read(nsp, nsi, ncrack_read_handler, BYTES_TO_READ, con);
386 }
387