1
2 /***************************************************************************
3 * ncrack.cc -- ncrack's core engine along with all nsock callback *
4 * handlers reside in here. Simple options' (not host or service-options *
5 * specification handling) parsing also happens in main() here. *
6 * *
7 ***********************IMPORTANT NMAP LICENSE TERMS************************
8 * *
9 * The Nmap Security Scanner is (C) 1996-2019 Insecure.Com LLC ("The Nmap *
10 * Project"). Nmap is also a registered trademark of the Nmap Project. *
11 * This program is free software; you may redistribute and/or modify it *
12 * under the terms of the GNU General Public License as published by the *
13 * Free Software Foundation; Version 2 ("GPL"), BUT ONLY WITH ALL OF THE *
14 * CLARIFICATIONS AND EXCEPTIONS DESCRIBED HEREIN. This guarantees your *
15 * right to use, modify, and redistribute this software under certain *
16 * conditions. If you wish to embed Nmap technology into proprietary *
17 * software, we sell alternative licenses (contact sales@nmap.com). *
18 * Dozens of software vendors already license Nmap technology such as *
19 * host discovery, port scanning, OS detection, version detection, and *
20 * the Nmap Scripting Engine. *
21 * *
22 * Note that the GPL places important restrictions on "derivative works", *
23 * yet it does not provide a detailed definition of that term. To avoid *
24 * misunderstandings, we interpret that term as broadly as copyright law *
25 * allows. For example, we consider an application to constitute a *
26 * derivative work for the purpose of this license if it does any of the *
27 * following with any software or content covered by this license *
28 * ("Covered Software"): *
29 * *
30 * o Integrates source code from Covered Software. *
31 * *
32 * o Reads or includes copyrighted data files, such as Nmap's nmap-os-db *
33 * or nmap-service-probes. *
34 * *
35 * o Is designed specifically to execute Covered Software and parse the *
36 * results (as opposed to typical shell or execution-menu apps, which will *
37 * execute anything you tell them to). *
38 * *
39 * o Includes Covered Software in a proprietary executable installer. The *
40 * installers produced by InstallShield are an example of this. Including *
41 * Nmap with other software in compressed or archival form does not *
42 * trigger this provision, provided appropriate open source decompression *
43 * or de-archiving software is widely available for no charge. For the *
44 * purposes of this license, an installer is considered to include Covered *
45 * Software even if it actually retrieves a copy of Covered Software from *
46 * another source during runtime (such as by downloading it from the *
47 * Internet). *
48 * *
49 * o Links (statically or dynamically) to a library which does any of the *
50 * above. *
51 * *
52 * o Executes a helper program, module, or script to do any of the above. *
53 * *
54 * This list is not exclusive, but is meant to clarify our interpretation *
55 * of derived works with some common examples. Other people may interpret *
56 * the plain GPL differently, so we consider this a special exception to *
57 * the GPL that we apply to Covered Software. Works which meet any of *
58 * these conditions must conform to all of the terms of this license, *
59 * particularly including the GPL Section 3 requirements of providing *
60 * source code and allowing free redistribution of the work as a whole. *
61 * *
62 * As another special exception to the GPL terms, the Nmap Project grants *
63 * permission to link the code of this program with any version of the *
64 * OpenSSL library which is distributed under a license identical to that *
65 * listed in the included docs/licenses/OpenSSL.txt file, and distribute *
66 * linked combinations including the two. *
67 * *
68 * The Nmap Project has permission to redistribute Npcap, a packet *
69 * capturing driver and library for the Microsoft Windows platform. *
70 * Npcap is a separate work with it's own license rather than this Nmap *
71 * license. Since the Npcap license does not permit redistribution *
72 * without special permission, our Nmap Windows binary packages which *
73 * contain Npcap may not be redistributed without special permission. *
74 * *
75 * Any redistribution of Covered Software, including any derived works, *
76 * must obey and carry forward all of the terms of this license, including *
77 * obeying all GPL rules and restrictions. For example, source code of *
78 * the whole work must be provided and free redistribution must be *
79 * allowed. All GPL references to "this License", are to be treated as *
80 * including the terms and conditions of this license text as well. *
81 * *
82 * Because this license imposes special exceptions to the GPL, Covered *
83 * Work may not be combined (even as part of a larger work) with plain GPL *
84 * software. The terms, conditions, and exceptions of this license must *
85 * be included as well. This license is incompatible with some other open *
86 * source licenses as well. In some cases we can relicense portions of *
87 * Nmap or grant special permissions to use it in other open source *
88 * software. Please contact fyodor@nmap.org with any such requests. *
89 * Similarly, we don't incorporate incompatible open source software into *
90 * Covered Software without special permission from the copyright holders. *
91 * *
92 * If you have any questions about the licensing restrictions on using *
93 * Nmap in other works, we are happy to help. As mentioned above, we also *
94 * offer an alternative license to integrate Nmap into proprietary *
95 * applications and appliances. These contracts have been sold to dozens *
96 * of software vendors, and generally include a perpetual license as well *
97 * as providing support and updates. They also fund the continued *
98 * development of Nmap. Please email sales@nmap.com for further *
99 * information. *
100 * *
101 * If you have received a written license agreement or contract for *
102 * Covered Software stating terms other than these, you may choose to use *
103 * and redistribute Covered Software under those terms instead of these. *
104 * *
105 * Source is provided to this software because we believe users have a *
106 * right to know exactly what a program is going to do before they run it. *
107 * This also allows you to audit the software for security holes. *
108 * *
109 * Source code also allows you to port Nmap to new platforms, fix bugs, *
110 * and add new features. You are highly encouraged to send your changes *
111 * to the dev@nmap.org mailing list for possible incorporation into the *
112 * main distribution. By sending these changes to Fyodor or one of the *
113 * Insecure.Org development mailing lists, or checking them into the Nmap *
114 * source code repository, it is understood (unless you specify *
115 * otherwise) that you are offering the Nmap Project the unlimited, *
116 * non-exclusive right to reuse, modify, and relicense the code. Nmap *
117 * will always be available Open Source, but this is important because *
118 * the inability to relicense code has caused devastating problems for *
119 * other Free Software projects (such as KDE and NASM). We also *
120 * occasionally relicense the code to third parties as discussed above. *
121 * If you wish to specify special license conditions of your *
122 * contributions, just say so when you send them. *
123 * *
124 * This program is distributed in the hope that it will be useful, but *
125 * WITHOUT ANY WARRANTY; without even the implied warranty of *
126 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the Nmap *
127 * license file for more details (it's in a COPYING file included with *
128 * Nmap, and also available from https://svn.nmap.org/nmap/COPYING) *
129 * *
130 ***************************************************************************/
131
132
133 #include "ncrack.h"
134 #include "NcrackOps.h"
135 #include "utils.h"
136 #include "services.h"
137 #include "targets.h"
138 #include "TargetGroup.h"
139 #include "ServiceGroup.h"
140 #include "nsock.h"
141 #include "global_structures.h"
142 #include "NcrackOutputTable.h"
143 #include "modules.h"
144 #include "ncrack_error.h"
145 #include "output.h"
146 #include "ncrack_tty.h"
147 #include "ncrack_input.h"
148 #include "ncrack_resume.h"
149 #include "xml.h"
150 #include <time.h>
151 #include <vector>
152
153 #if HAVE_SIGNAL
154 #include <signal.h>
155 #endif
156
157 #if HAVE_OPENSSL
158 #include <openssl/ssl.h>
159 #endif
160
161 #ifdef WIN32
162 #include "winfix.h"
163 #endif
164
165 #define DEFAULT_CONNECT_TIMEOUT 5000
166 /* includes connect() + ssl negotiation */
167 #define DEFAULT_CONNECT_SSL_TIMEOUT 8000
168 #define DEFAULT_USERNAME_FILE "default.usr"
169 #define DEFAULT_PASSWORD_FILE "default.pwd"
170
171 /* (in milliseconds) every such interval we poll for interactive user input */
172 #define KEYPRESSED_INTERVAL 500
173
174 /* (in milliseconds) every such interval check for pending signals */
175 #define SIGNAL_CHECK_INTERVAL 1000
176
177 #define SERVICE_TIMEDOUT "Service timed-out as specified by user option."
178
179 extern NcrackOps o;
180 using namespace std;
181
182 /* global lookup table for available services */
183 vector <global_service> ServicesTable;
184 /* global login and pass array */
185 vector <char *> UserArray;
186 vector <char *> PassArray;
187
188
189 /* schedule additional connections */
190 static void ncrack_probes(nsock_pool nsp, ServiceGroup *SG);
191 /* ncrack initialization */
192 static int ncrack(ServiceGroup *SG);
193 /* Poll for interactive user input every time this timer is called. */
194 static void status_timer_handler(nsock_pool nsp, nsock_event nse,
195 void *mydata);
196 static void signal_timer_handler(nsock_pool nsp, nsock_event nse,
197 void *mydata);
198
199 /* module name demultiplexor */
200 static void call_module(nsock_pool nsp, Connection* con);
201
202 static void parse_login_list(char *const arg, int mode);
203 static void load_login_file(const char *filename, int mode);
204 enum mode { USER, PASS };
205
206
207 static void print_usage(void);
208 static void lookup_init(const char *const filename);
209 static int file_readable(const char *pathname);
210 static int ncrack_fetchfile(char *filename_returned, int bufferlen,
211 const char *file, int useroption = 0);
212 static char *grab_next_host_spec(FILE *inputfd, int argc, char **argv);
213 static void startTimeOutClocks(ServiceGroup *SG);
214 static void sigcatch(int signo);
215 static void sigcheck(ServiceGroup *SG);
216 static int ncrack_main(int argc, char **argv);
217
218
219 static void
print_usage(void)220 print_usage(void)
221 {
222 log_write(LOG_STDOUT, "%s %s ( %s )\n"
223 "Usage: ncrack [Options] {target and service specification}\n"
224 "TARGET SPECIFICATION:\n"
225 " Can pass hostnames, IP addresses, networks, etc.\n"
226 " Ex: scanme.nmap.org, microsoft.com/24, 192.168.0.1; "
227 "10.0.0-255.1-254\n"
228 " -iX <inputfilename>: Input from Nmap's -oX XML output format\n"
229 " -iN <inputfilename>: Input from Nmap's -oN Normal output format\n"
230 " -iL <inputfilename>: Input from list of hosts/networks\n"
231 " --exclude <host1[,host2][,host3],...>: Exclude hosts/networks\n"
232 " --excludefile <exclude_file>: Exclude list from file\n"
233 "SERVICE SPECIFICATION:\n"
234 " Can pass target specific services in <service>://target (standard) "
235 "notation or\n"
236 " using -p which will be applied to all hosts in non-standard "
237 "notation.\n"
238 " Service arguments can be specified to be host-specific, type of "
239 "service-specific\n"
240 " (-m) or global (-g). Ex: ssh://10.0.0.10,at=10,cl=30 -m ssh:at=50 "
241 "-g cd=3000\n"
242 " Ex2: ncrack -p ssh,ftp:3500,25 10.0.0.10 scanme.nmap.org "
243 "google.com:80,ssl\n"
244 " -p <service-list>: services will be applied to all non-standard "
245 "notation hosts\n"
246 " -m <service>:<options>: options will be applied to all services "
247 "of this type\n"
248 " -g <options>: options will be applied to every service globally\n"
249 " Misc options:\n"
250 " ssl: enable SSL over this service\n"
251 " path <name>: used in modules like HTTP ('=' needs escaping if "
252 "used)\n"
253 " db <name>: used in modules like MongoDB to specify the database\n"
254 " domain <name>: used in modules like WinRM to specify the domain\n"
255 "TIMING AND PERFORMANCE:\n"
256 " Options which take <time> are in seconds, unless you append 'ms'\n"
257 " (miliseconds), 'm' (minutes), or 'h' (hours) to the value (e.g. 30m)."
258 "\n"
259 " Service-specific options:\n"
260 " cl (min connection limit): minimum number of concurrent parallel "
261 "connections\n"
262 " CL (max connection limit): maximum number of concurrent parallel "
263 "connections\n"
264 " at (authentication tries): authentication attempts per connection\n"
265 " cd (connection delay): delay <time> between each connection "
266 "initiation\n"
267 " cr (connection retries): caps number of service connection "
268 "attempts\n"
269 " to (time-out): maximum cracking <time> for service, regardless "
270 "of success so far\n"
271 " -T<0-5>: Set timing template (higher is faster)\n"
272 " --connection-limit <number>: threshold for total concurrent "
273 "connections\n"
274 " --stealthy-linear: try credentials using only one connection against "
275 "each specified host \n until you hit the same host again. "
276 "Overrides all other timing options.\n"
277 "AUTHENTICATION:\n"
278 " -U <filename>: username file\n"
279 " -P <filename>: password file\n"
280 " --user <username_list>: comma-separated username list\n"
281 " --pass <password_list>: comma-separated password list\n"
282 " --passwords-first: Iterate password list for each username. "
283 "Default is opposite.\n"
284 " --pairwise: Choose usernames and passwords in pairs.\n"
285 "OUTPUT:\n"
286 " -oN/-oX <file>: Output scan in normal and XML format, respectively, "
287 "to the given filename.\n"
288 " -oA <basename>: Output in the two major formats at once\n"
289 " -v: Increase verbosity level (use twice or more for greater effect)\n"
290 " -d[level]: Set or increase debugging level (Up to 10 is meaningful)\n"
291 " --nsock-trace <level>: Set nsock trace level (Valid range: 0 - 10)\n"
292 " --log-errors: Log errors/warnings to the normal-format output file\n"
293 " --append-output: Append to rather than clobber specified output "
294 "files\n"
295 "MISC:\n"
296 " --resume <file>: Continue previously saved session\n"
297 " --save <file>: Save restoration file with specific filename\n"
298 " -f: quit cracking service after one found credential\n"
299 " -6: Enable IPv6 cracking\n"
300 " -sL or --list: only list hosts and services\n"
301 " --datadir <dirname>: Specify custom Ncrack data file location\n"
302 " --proxy <type://proxy:port>: Make connections via socks4, 4a, http.\n"
303 " -V: Print version number\n"
304 " -h: Print this help summary page.\n"
305 "MODULES:\n"
306 " SSH, RDP, FTP, Telnet, HTTP(S), Wordpress, POP3(S), IMAP, CVS, SMB, VNC, SIP, Redis, "
307 "PostgreSQL, MQTT, MySQL, MSSQL, MongoDB, Cassandra, WinRM, OWA, DICOM\n"
308 "EXAMPLES:\n"
309 " ncrack -v --user root localhost:22\n"
310 " ncrack -v -T5 https://192.168.0.1\n"
311 " ncrack -v -iX ~/nmap.xml -g CL=5,to=1h\n"
312 "SEE THE MAN PAGE (http://nmap.org/ncrack/man.html) FOR MORE OPTIONS "
313 "AND EXAMPLES\n",
314 NCRACK_NAME, NCRACK_VERSION, NCRACK_URL);
315 exit(EXIT_FAILURE);
316 }
317
318
319 static void
lookup_init(const char * const filename)320 lookup_init(const char *const filename)
321 {
322 char line[1024];
323 char servicename[128], proto[16];
324 u16 portno;
325 FILE *fp;
326 vector <global_service>::iterator vi;
327 global_service temp;
328
329 memset(&temp, 0, sizeof(temp));
330 temp.timing.min_connection_limit = -1;
331 temp.timing.max_connection_limit = -1;
332 temp.timing.auth_tries = -1;
333 temp.timing.connection_delay = -1;
334 temp.timing.connection_retries = -1;
335 temp.timing.timeout = -1;
336
337 fp = fopen(filename, "r");
338 if (!fp)
339 fatal("%s: failed to open file %s for reading!", __func__, filename);
340
341 while (fgets(line, sizeof(line), fp)) {
342 if (*line == '\n' || *line == '#')
343 continue;
344
345 temp.misc.ssl = false;
346 temp.misc.db = NULL;
347 temp.misc.domain = NULL;
348
349 if (sscanf(line, "%127s %hu/%15s", servicename, &portno, proto) != 3)
350 fatal("invalid ncrack-services file: %s", filename);
351
352 temp.lookup.portno = portno;
353 temp.lookup.proto = str2proto(proto);
354 temp.lookup.name = strdup(servicename);
355 /*
356 * When more ssl-services are going to be added, this will probably
357 * need a more generic scheme
358 */
359 if (!strncmp(servicename, "https", sizeof("https"))
360 || !strncmp(servicename, "pop3s", sizeof("pop3s"))
361 || !strncmp(servicename, "owa", sizeof("owa"))
362 || !strncmp(servicename, "wordpress-tls", sizeof("wordpress-tls"))
363 || !strncmp(servicename, "wp-tls", sizeof("wp-tls")))
364 temp.misc.ssl = true;
365
366 if (!strncmp(servicename, "mongodb", sizeof("mongodb")))
367 temp.misc.db = Strndup("admin", sizeof("admin"));
368
369 if (!strncmp(servicename, "winrm", sizeof("winrm")))
370 temp.misc.domain = Strndup("Workstation", sizeof("Workstation"));
371
372 for (vi = ServicesTable.begin(); vi != ServicesTable.end(); vi++) {
373 if ((vi->lookup.portno == temp.lookup.portno)
374 && (vi->lookup.proto == temp.lookup.proto)
375 && !(strcmp(vi->lookup.name, temp.lookup.name))) {
376 if (o.debugging)
377 error("Port %d proto %s is duplicated in services file %s",
378 portno, proto, filename);
379 continue;
380 }
381 }
382
383 ServicesTable.push_back(temp);
384 }
385
386 fclose(fp);
387 }
388
389
390 /* Returns one if the file pathname given exists, is not a directory and
391 * is readable by the executing process. Returns two if it is readable
392 * and is a directory. Otherwise returns 0.
393 */
394 static int
file_readable(const char * pathname)395 file_readable(const char *pathname) {
396 char *pathname_buf = strdup(pathname);
397 int status = 0;
398
399 #ifdef WIN32
400 /* stat on windows only works for "dir_name" not for "dir_name/"
401 * or "dir_name\\"
402 */
403 int pathname_len = strlen(pathname_buf);
404 char last_char = pathname_buf[pathname_len - 1];
405
406 if( last_char == '/'
407 || last_char == '\\')
408 pathname_buf[pathname_len - 1] = '\0';
409
410 #endif
411
412 struct stat st;
413
414 if (stat(pathname_buf, &st) == -1)
415 status = 0;
416 else if (access(pathname_buf, R_OK) != -1)
417 status = S_ISDIR(st.st_mode) ? 2 : 1;
418
419 free(pathname_buf);
420 return status;
421 }
422
423 /*
424 * useroption should be 1 if either -U or -P has been specified.
425 * by default it is 0
426 */
427 int
ncrack_fetchfile(char * filename_returned,int bufferlen,const char * file,int useroption)428 ncrack_fetchfile(char *filename_returned, int bufferlen, const char *file,
429 int useroption) {
430 char *dirptr;
431 int res;
432 int foundsomething = 0;
433 struct passwd *pw;
434 static int warningcount = 0;
435 char dot_buffer[512];
436
437 /* -U or -P has been specified */
438 if (useroption) {
439 res = Snprintf(filename_returned, bufferlen, "%s", file);
440 if (res > 0 && res < bufferlen) {
441 foundsomething = file_readable(filename_returned);
442 }
443 }
444
445
446 /* First, check the map of requested data file names. If there's an entry for
447 file, use it and return.
448 Otherwise, we try [--datadir]/file, then $NCRACKDIR/file
449 next we try ~user/.ncrack/file
450 then we try NCRACKDATADIR/file <--NCRACKDATADIR
451 finally we try ./file
452
453 -- or on Windows --
454
455 --datadir -> $NCRACKDIR -> ncrack.exe directory -> NCRACKDATADIR -> .
456 */
457
458 if (o.datadir && !foundsomething) {
459 res = Snprintf(filename_returned, bufferlen, "%s/%s", o.datadir, file);
460 if (res > 0 && res < bufferlen) {
461 foundsomething = file_readable(filename_returned);
462 }
463 }
464
465 if (!foundsomething && (dirptr = getenv("NCRACKDIR"))) {
466 res = Snprintf(filename_returned, bufferlen, "%s/%s", dirptr, file);
467 if (res > 0 && res < bufferlen) {
468 foundsomething = file_readable(filename_returned);
469 }
470 }
471
472 #ifndef WIN32
473 if (!foundsomething) {
474 pw = getpwuid(getuid());
475 if (pw) {
476 res = Snprintf(filename_returned, bufferlen, "%s/.ncrack/%s",
477 pw->pw_dir, file);
478 if (res > 0 && res < bufferlen) {
479 foundsomething = file_readable(filename_returned);
480 }
481 }
482 if (!foundsomething && getuid() != geteuid()) {
483 pw = getpwuid(geteuid());
484 if (pw) {
485 res = Snprintf(filename_returned, bufferlen, "%s/.ncrack/%s",
486 pw->pw_dir, file);
487 if (res > 0 && res < bufferlen) {
488 foundsomething = file_readable(filename_returned);
489 }
490 }
491 }
492 }
493 #else
494 if (!foundsomething) { /* Try the Ncrack directory */
495 char fnbuf[MAX_PATH];
496 int i;
497 res = GetModuleFileName(GetModuleHandle(0), fnbuf, 1024);
498 if(!res) fatal("GetModuleFileName failed (!)\n");
499
500 /* Strip it */
501 for(i = res - 1; i >= 0 && fnbuf[i] != '/' && fnbuf[i] != '\\'; i--);
502 if(i >= 0) /* we found it */
503 fnbuf[i] = 0;
504 res = Snprintf(filename_returned, bufferlen, "%s\\%s", fnbuf, file);
505 if(res > 0 && res < bufferlen)
506 foundsomething = file_readable(filename_returned);
507
508 /* Now try under 'lists' for the installed directory */
509 if (!foundsomething) {
510 res = Snprintf(filename_returned, bufferlen, "%s\\lists\\%s", fnbuf, file);
511 if(res > 0 && res < bufferlen)
512 foundsomething = file_readable(filename_returned);
513 }
514 }
515 #endif
516
517 if (!foundsomething) {
518 res = Snprintf(filename_returned, bufferlen, "%s/%s", NCRACKDATADIR, file);
519 if (res > 0 && res < bufferlen) {
520 foundsomething = file_readable(filename_returned);
521 }
522 }
523
524 if (foundsomething && (*filename_returned != '.') && !useroption) {
525 res = Snprintf(dot_buffer, sizeof(dot_buffer), "./%s", file);
526 if (res > 0 && res < bufferlen) {
527 if (file_readable(dot_buffer)) {
528 #ifdef WIN32
529 if (warningcount++ < 1 && o.debugging)
530 #else
531 if(warningcount++ < 1)
532 #endif
533 error("Warning: File %s exists, but Ncrack is using %s for "
534 "security and consistency reasons. Set NCRACKDIR=. to give "
535 "priority to files in your local directory (may affect the "
536 "other data files too).", dot_buffer, filename_returned);
537 }
538 }
539 }
540
541 if (!foundsomething) {
542 res = Snprintf(filename_returned, bufferlen, "./%s", file);
543 if (res > 0 && res < bufferlen)
544 foundsomething = file_readable(filename_returned);
545 }
546
547 /* For username/password lists also search ./lists */
548 if (!foundsomething) {
549 res = Snprintf(filename_returned, bufferlen, "./lists/%s", file);
550 if (res > 0 && res < bufferlen)
551 foundsomething = file_readable(filename_returned);
552 }
553
554 if (!foundsomething) {
555 Snprintf(filename_returned, bufferlen, "%s", file);
556 }
557
558 if (foundsomething && o.debugging > 1)
559 log_write(LOG_PLAIN, "Fetchfile found %s\n", filename_returned);
560
561 return foundsomething;
562
563 }
564
565 /*
566 * The only thing that a safe and generic signal handler should do, is to set a
567 * flag that will be later checked by the main program. Ncrack will
568 * periodically check this variable, and take appropriate action to exit
569 * cleanly and also possibly save the current state into a file that can be
570 * used later with --resume.
571 */
572 static void
sigcatch(int signo)573 sigcatch(int signo)
574 {
575 o.saved_signal = signo;
576 return;
577 }
578
579 static void
sigcheck(ServiceGroup * SG)580 sigcheck(ServiceGroup *SG)
581 {
582 if (o.saved_signal == -1)
583 return;
584
585 fflush(stdout);
586 switch (o.saved_signal) {
587 case SIGINT:
588 error("caught SIGINT signal, cleaning up");
589 break;
590
591 #ifdef SIGTERM
592 case SIGTERM:
593 error("caught SIGTERM signal, cleaning up");
594 break;
595 #endif
596
597 #ifdef SIGHUP
598 case SIGHUP:
599 error("caught SIGHUP signal, cleaning up");
600 break;
601 #endif
602
603 #ifdef SIGBUS
604 case SIGBUS:
605 error("caught SIGBUS signal, cleaning up");
606 break;
607 #endif
608
609 default:
610 error("caught signal %d, cleaning up", o.saved_signal);
611 break;
612 }
613
614 log_close(LOG_NORMAL);
615 /* Now try and save available information into a file that might be later
616 * recalled with --resume.
617 */
618 ncrack_save(SG);
619
620 exit(1);
621 }
622
623
624 static char *
grab_next_host_spec(FILE * inputfd,int argc,char ** argv)625 grab_next_host_spec(FILE *inputfd, int argc, char **argv)
626 {
627 static char host_spec[1024];
628 unsigned int host_spec_index;
629 int ch;
630
631 if (!inputfd) {
632 return ((optind < argc) ? argv[optind++] : NULL);
633 } else {
634 if (o.nmap_input_xml) {
635 if (xml_input(inputfd, host_spec) < 0)
636 return NULL;
637 } else if (o.nmap_input_normal) {
638 if (normal_input(inputfd, host_spec) < 0)
639 return NULL;
640 } else {
641 host_spec_index = 0;
642 while((ch = getc(inputfd)) != EOF) {
643 if (ch == ' ' || ch == '\r' || ch == '\n' || ch == '\t' || ch == '\0') {
644 if (host_spec_index == 0)
645 continue;
646 host_spec[host_spec_index] = '\0';
647 return host_spec;
648 } else if (host_spec_index < sizeof(host_spec) / sizeof(char) -1) {
649 host_spec[host_spec_index++] = (char) ch;
650 } else fatal("One of the host_specifications from your input file "
651 "is too long (> %d chars)", (int) sizeof(host_spec));
652 }
653 host_spec[host_spec_index] = '\0';
654 }
655 }
656 if (!*host_spec)
657 return NULL;
658 return host_spec;
659 }
660
661
662 /*
663 * Parses the username and password list that has been specified from the
664 * command line through the --user and --pass options. The argument must be a
665 * comma separated list of words for each case.
666 */
667 static void
parse_login_list(char * const arg,int mode)668 parse_login_list(char *const arg, int mode)
669 {
670 vector <char *> *p = NULL;
671 size_t i, j, arg_len;
672 char *word;
673
674 if (mode == USER)
675 p = &UserArray;
676 else if (mode == PASS)
677 p = &PassArray;
678 else
679 fatal("%s invalid mode specified!", __func__);
680
681 arg_len = strlen(arg);
682 j = i = 0;
683 while (i < arg_len) {
684 if (arg[i] == ',') {
685 word = Strndup(&arg[j], i - j);
686 p->push_back(word);
687 j = i + 1;
688 }
689
690 i++;
691 }
692
693 /* In case, user just typed --user "," or --pass "," don't add two blank
694 * passwords as there is no point in that.
695 */
696 if (arg[0] == ',' && arg_len == 1)
697 return;
698
699 word = Strndup(&arg[j], i - j);
700 p->push_back(word);
701
702 }
703
704
705 static void
load_login_file(const char * filename,int mode)706 load_login_file(const char *filename, int mode)
707 {
708 char line[1024];
709 char *tmp;
710 FILE *fd;
711 vector <char *> *p = NULL;
712
713 if (!strcmp(filename, "-"))
714 fd = stdin;
715 else {
716 fd = fopen(filename, "r");
717 if (!fd)
718 fatal("Failed to open input file %s for reading!", filename);
719 }
720
721 if (mode == USER)
722 p = &UserArray;
723 else if (mode == PASS)
724 p = &PassArray;
725 else
726 fatal("%s invalid mode specified!", __func__);
727
728 while (fgets(line, sizeof(line), fd)) {
729 /* Note that supporting comment lines starting with '#' automatically
730 * entails not being able to get passwords that start with '#'.
731 */
732 if (*line == '#')
733 continue;
734
735 /* A blank line (just the '\n' char) in a wordlist file means that a
736 * blank entry will be tested. Strndup allocates an entry that is at least
737 * of 1 size ('\0'), so supplying it with the length of each line minus the
738 * '\n' character of the line will universally work in all cases.
739 * However, we need to take into account the possibility that the user
740 * supplies Windows-derived wordlists which use CRLF termination.
741 * In that case, just drop the 1 extra character.
742 */
743 if (strlen(line) == 2 && !strncmp(line, "\r\n", 2))
744 line[1] = '\0';
745
746 tmp = Strndup(line, strlen(line) - 1);
747 p->push_back(tmp);
748 }
749 }
750
751
752
753 static void
call_module(nsock_pool nsp,Connection * con)754 call_module(nsock_pool nsp, Connection *con)
755 {
756 char *name = con->service->name;
757
758 /* initialize connection state variables */
759 con->auth_success = false;
760 con->check_closed = false;
761 con->auth_complete = false;
762 con->peer_alive = false;
763 con->finished_normally = false;
764 con->close_reason = -1;
765 con->force_close = false;
766
767
768 if (!strcmp(name, "ftp"))
769 ncrack_ftp(nsp, con);
770 else if (!strcmp(name, "telnet"))
771 ncrack_telnet(nsp, con);
772 else if (!strcmp(name, "http"))
773 ncrack_http(nsp, con);
774 else if (!strcmp(name, "pop3"))
775 ncrack_pop3(nsp, con);
776 else if (!strcmp(name, "vnc"))
777 ncrack_vnc(nsp, con);
778 else if (!strcmp(name, "redis"))
779 ncrack_redis(nsp, con);
780 else if (!strcmp(name, "mqtt"))
781 ncrack_mqtt(nsp, con);
782 else if (!strcmp(name, "imap"))
783 ncrack_imap(nsp, con);
784 else if (!strcmp(name, "cassandra"))
785 ncrack_cassandra(nsp, con);
786 else if (!strcmp(name,"cvs"))
787 ncrack_cvs(nsp,con);
788 else if (!strcmp(name, "joomla"))
789 ncrack_joomla(nsp, con);
790 else if (!strcmp(name, "dicom"))
791 ncrack_dicom(nsp, con);
792 else if (!strcmp(name, "wordpress") || !strcmp(name, "wp"))
793 ncrack_wordpress(nsp, con);
794 #if HAVE_OPENSSL
795 else if (!strcmp(name, "wordpress-tls") || !strcmp(name, "wp-tls"))
796 ncrack_wordpress(nsp, con);
797 else if (!strcmp(name, "winrm"))
798 ncrack_winrm(nsp, con);
799 else if (!strcmp(name, "mongodb"))
800 ncrack_mongodb(nsp, con);
801 else if (!strcmp(name, "pop3s"))
802 ncrack_pop3(nsp, con);
803 else if (!strcmp(name, "mysql"))
804 ncrack_mysql(nsp, con);
805 else if (!strcmp(name, "psql"))
806 ncrack_psql(nsp, con);
807 else if (!strcmp(name, "mssql"))
808 ncrack_mssql(nsp, con);
809 else if (!strcmp(name, "ssh"))
810 ncrack_ssh(nsp, con);
811 else if (!strcmp(name, "owa"))
812 ncrack_owa(nsp, con);
813 else if (!strcmp(name, "https"))
814 ncrack_http(nsp, con);
815 else if (!strcmp(name, "sip"))
816 ncrack_sip(nsp, con);
817 else if (!strcmp(name, "rdp") || !strcmp(name, "ms-wbt-server"))
818 ncrack_rdp(nsp, con);
819 else if (!strcmp(name, "smb") || !strcmp(name, "netbios-ssn"))
820 ncrack_smb(nsp, con);
821 else if (!strcmp(name, "smb2"))
822 ncrack_smb2(nsp, con);
823
824 #endif
825 else
826 fatal("Invalid service module: %s", name);
827 }
828
829
830 int
main(int argc,char ** argv)831 main(int argc, char **argv)
832 {
833 char **myargv = NULL;
834 int myargc = 0;
835
836 if (argc == 3 && strcmp("--resume", argv[1]) == 0) {
837 if (ncrack_resume(argv[2], &myargc, &myargv) == -1) {
838 fatal("Cannot resume from (supposed) log file %s", argv[2]);
839 }
840 o.resume = true;
841 return ncrack_main(myargc, myargv);
842 }
843
844 return ncrack_main(argc, argv);
845 }
846
847
848
849
850 static int
ncrack_main(int argc,char ** argv)851 ncrack_main(int argc, char **argv)
852 {
853 ts_spec spec;
854
855 FILE *inputfd = NULL;
856 char *normalfilename = NULL;
857 char *xmlfilename = NULL;
858 time_t timep;
859 unsigned int i; /* iteration var */
860 char services_file[256]; /* path name for "ncrack-services" file */
861 char username_file[256];
862 char password_file[256];
863 /* strtok changes the first argument and we don't want to mess with
864 * the argv stuff, as they hold important info for later. For this reason,
865 * we copy optarg to tmp each time a function that calls strtok is going to
866 * be invoked.
867 */
868 char *tmp = NULL;
869
870 char *host_spec = NULL;
871 Target *currenths = NULL;
872 vector <Target *> Targets; /* targets to be ncracked */
873 vector <Target *>::iterator Tvi;
874
875 ServiceGroup *SG; /* all services to be ncracked */
876 list <Service *>::iterator li;
877
878 vector <Service *>Services; /* temporary services vector */
879 vector <Service *>::iterator Svi; /* iterator for services vector */
880 Service *service;
881
882 vector <service_lookup *> services_cmd;
883 vector <service_lookup *>::iterator SCvi;
884
885 char *glob_options = NULL; /* for -g option */
886 timing_options timing; /* for -T option */
887
888 /* time variables */
889 struct tm *tm;
890 time_t now;
891 char tbuf[128];
892 char mytime[128];
893
894 /* exclude-specific variables */
895 FILE *excludefd = NULL;
896 char *exclude_spec = NULL;
897 TargetGroup *exclude_group = NULL;
898
899
900 /* getopt-specific */
901 int arg;
902 int option_index;
903 extern char *optarg;
904 extern int optind;
905 struct option long_options[] =
906 {
907 {"resume", required_argument, 0, 0},
908 {"save", required_argument, 0, 0},
909 {"list", no_argument, 0, 0},
910 {"services", required_argument, 0, 'p'},
911 {"version", no_argument, 0, 'V'},
912 {"verbose", no_argument, 0, 'v'},
913 {"datadir", required_argument, 0, 0},
914 {"debug", optional_argument, 0, 'd'},
915 {"help", no_argument, 0, 'h'},
916 {"timing", required_argument, 0, 'T'},
917 {"excludefile", required_argument, 0, 0},
918 {"exclude", required_argument, 0, 0},
919 {"iL", required_argument, 0, 0},
920 {"iX", required_argument, 0, 0},
921 {"iN", required_argument, 0, 0},
922 {"oA", required_argument, 0, 0},
923 {"oN", required_argument, 0, 0},
924 {"oX", required_argument, 0, 0},
925 {"append_output", no_argument, 0, 0},
926 {"append-output", no_argument, 0, 0},
927 {"log_errors", no_argument, 0, 0},
928 {"log-errors", no_argument, 0, 0},
929 {"stealthy_linear", no_argument, 0, 0},
930 {"stealthy-linear", no_argument, 0, 0},
931 {"connection_limit", required_argument, 0, 0},
932 {"connection-limit", required_argument, 0, 0},
933 {"passwords_first", no_argument, 0, 0},
934 {"passwords-first", no_argument, 0, 0},
935 {"pairwise", no_argument, 0, 0},
936 {"user", required_argument, 0, 0},
937 {"pass", required_argument, 0, 0},
938 {"nsock-trace", required_argument, 0, 0},
939 {"nsock_trace", required_argument, 0, 0},
940 {"proxy", required_argument, 0, 0},
941 {"proxies", required_argument, 0, 0},
942 {0, 0, 0, 0}
943 };
944
945 if (argc < 2)
946 print_usage();
947
948 ncrack_fetchfile(services_file, sizeof(services_file), "ncrack-services");
949 /* Initialize available services' lookup table */
950 lookup_init(services_file);
951
952 #if WIN32
953 win_init();
954 #endif
955
956
957 now = time(NULL);
958 tm = localtime(&now);
959
960 /* Argument parsing */
961 optind = 1;
962 while((arg = getopt_long_only(argc, argv, "6d::f::g:hU:P:m:o:p:s:T:v::V",
963 long_options, &option_index)) != EOF) {
964 switch(arg) {
965 case 0:
966 if (!strcmp(long_options[option_index].name, "excludefile")) {
967 if (exclude_spec)
968 fatal("--excludefile and --exclude options are mutually "
969 "exclusive.");
970 excludefd = fopen(optarg, "r");
971 if (!excludefd)
972 fatal("Failed to open exclude file %s for reading", optarg);
973 } else if (!strcmp(long_options[option_index].name, "exclude")) {
974 if (excludefd)
975 fatal("--excludefile and --exclude options are mutually "
976 "exclusive.");
977 exclude_spec = strdup(optarg);
978
979 } else if (!strcmp(long_options[option_index].name, "services")) {
980 parse_services(optarg, services_cmd);
981 } else if (!strcmp(long_options[option_index].name, "list")) {
982 o.list_only = true;
983 } else if (!optcmp(long_options[option_index].name,
984 "connection-limit")) {
985 o.connection_limit = atoi(optarg);
986 } else if (!optcmp(long_options[option_index].name,
987 "passwords-first")) {
988 o.passwords_first = true;
989 } else if (!optcmp(long_options[option_index].name,
990 "pairwise")) {
991 o.pairwise = true;
992 } else if (!optcmp(long_options[option_index].name,
993 "nsock-trace")) {
994 int lvl;
995
996 lvl = atoi(optarg);
997
998 if (lvl >= 7)
999 o.nsock_loglevel = NSOCK_LOG_DBG_ALL;
1000 else if (lvl >= 4)
1001 o.nsock_loglevel = NSOCK_LOG_DBG;
1002 else if (lvl >= 2)
1003 o.nsock_loglevel = NSOCK_LOG_INFO;
1004 else
1005 o.nsock_loglevel = NSOCK_LOG_ERROR;
1006 } else if (!optcmp(long_options[option_index].name, "proxy") ||
1007 !optcmp(long_options[option_index].name, "proxies")) {
1008 if (nsock_proxychain_new(optarg, &o.proxychain, NULL) < 0)
1009 fatal("Invalid proxy chain specification.");
1010 if (strlen(optarg) >= 7 && !(strncmp(optarg, "socks4a", 7)))
1011 o.socks4a = true;
1012 } else if (!optcmp(long_options[option_index].name, "log-errors")) {
1013 o.log_errors = true;
1014 } else if (!optcmp(long_options[option_index].name, "stealthy-linear")) {
1015 o.stealthy_linear = true;
1016 } else if (!optcmp(long_options[option_index].name, "append-output")) {
1017 o.append_output = true;
1018 } else if (strcmp(long_options[option_index].name, "datadir") == 0) {
1019 o.datadir = strdup(optarg);
1020 } else if (strcmp(long_options[option_index].name, "iX") == 0) {
1021 if (inputfd)
1022 fatal("Only one input filename allowed");
1023 o.nmap_input_xml = true;
1024 inputfd = fopen(strdup(optarg), "r");
1025 if (!inputfd)
1026 fatal("Failed to open input file %s for reading", optarg);
1027 } else if (strcmp(long_options[option_index].name, "iN") == 0) {
1028 if (inputfd)
1029 fatal("Only one input filename allowed");
1030 o.nmap_input_normal = true;
1031 inputfd = fopen(strdup(optarg), "r");
1032 if (!inputfd)
1033 fatal("Failed to open input file %s for reading", optarg);
1034 } else if (strcmp(long_options[option_index].name, "iL") == 0) {
1035 if (inputfd)
1036 fatal("Only one input filename allowed");
1037 inputfd = fopen(strdup(optarg), "r");
1038 if (!inputfd)
1039 fatal("Failed to open input file %s for reading", optarg);
1040 } else if (strcmp(long_options[option_index].name, "oN") == 0) {
1041 normalfilename = logfilename(optarg, tm);
1042 } else if (strcmp(long_options[option_index].name, "oX") == 0) {
1043 xmlfilename = logfilename(optarg, tm);
1044 } else if (strcmp(long_options[option_index].name, "oA") == 0) {
1045 char buf[MAXPATHLEN];
1046 Snprintf(buf, sizeof(buf), "%s.ncrack", logfilename(optarg, tm));
1047 normalfilename = strdup(buf);
1048 Snprintf(buf, sizeof(buf), "%s.xml", logfilename(optarg, tm));
1049 xmlfilename = strdup(buf);
1050 } else if (strcmp(long_options[option_index].name, "user") == 0) {
1051 if (o.userlist_src)
1052 fatal("You have already specified the username list source!\n");
1053 o.userlist_src = 1;
1054
1055 tmp = Strndup(optarg, strlen(optarg));
1056 parse_login_list(tmp, USER);
1057 free(tmp);
1058 } else if (strcmp(long_options[option_index].name, "pass") == 0) {
1059 if (o.passlist_src)
1060 fatal("You have already specified the password list source!\n");
1061 o.passlist_src = 1;
1062 tmp = Strndup(optarg, strlen(optarg));
1063 parse_login_list(tmp, PASS);
1064 free(tmp);
1065 } else if (strcmp(long_options[option_index].name, "resume") == 0) {
1066 fatal("--resume <file> can only be used as sole command-line "
1067 "option to Ncrack! Invoke Ncrack without any other "
1068 "arguments.\n");
1069 } else if (strcmp(long_options[option_index].name, "vv") == 0) {
1070 /* Compatability hack ... ugly */
1071 o.verbose += 2;
1072 } else if (strcmp(long_options[option_index].name, "save") == 0) {
1073 o.save_file = logfilename(optarg, tm);
1074 }
1075 break;
1076 case '6':
1077 #if !HAVE_IPV6
1078 fatal("I am afraid IPv6 is not available because your host doesn't "
1079 "support it or you chose to compile Ncrack w/o IPv6 support.");
1080 #else
1081 o.setaf(AF_INET6);
1082 #endif /* !HAVE_IPV6 */
1083 break;
1084 case 'd':
1085 if (optarg && isdigit(optarg[0])) {
1086 o.debugging = o.verbose = atoi(optarg);
1087 } else {
1088 const char *p;
1089 o.debugging++;
1090 o.verbose++;
1091 for (p = optarg != NULL ? optarg : ""; *p == 'd'; p++) {
1092 o.debugging++;
1093 o.verbose++;
1094 }
1095 if (*p != '\0')
1096 fatal("Invalid argument to -d: \"%s\".", optarg);
1097 }
1098 break;
1099 case 'f':
1100 if (optarg && isdigit(optarg[0])) {
1101 o.finish = atoi(optarg);
1102 } else {
1103 const char *p;
1104 o.finish++;
1105 for (p = optarg != NULL ? optarg : ""; *p == 'd'; p++) {
1106 o.finish++;
1107 }
1108 if (*p != '\0')
1109 fatal("Invalid argument to -f: \"%s\".", optarg);
1110 }
1111 break;
1112 case 'g':
1113 glob_options = strdup(optarg);
1114 o.global_options = true;
1115 break;
1116 case 'h': /* help */
1117 print_usage();
1118 break;
1119 #if 0
1120 case 'i':
1121 if (inputfd)
1122 fatal("Only one input filename allowed");
1123 if (!strcmp(optarg, "-"))
1124 inputfd = stdin;
1125 else
1126 fatal("You have to specify a specific input format for -i option: "
1127 "-iL, -iN or -iX\n");
1128 break;
1129 #endif
1130 case 'U':
1131 if (o.userlist_src)
1132 fatal("You have already specified the username list source!\n");
1133 o.userlist_src = 2;
1134 ncrack_fetchfile(username_file, sizeof(username_file),
1135 optarg, 1);
1136 load_login_file(username_file, USER);
1137 break;
1138 case 'P':
1139 if (o.passlist_src)
1140 fatal("You have already specified the password list source!\n");
1141 o.passlist_src = 2;
1142 ncrack_fetchfile(password_file, sizeof(password_file),
1143 optarg, 1);
1144 load_login_file(password_file, PASS);
1145 break;
1146 case 'm':
1147 tmp = Strndup(optarg, strlen(optarg));
1148 parse_module_options(tmp);
1149 free(tmp);
1150 break;
1151 case 'o':
1152 normalfilename = logfilename(optarg, tm);
1153 break;
1154 case 'p': /* services */
1155 tmp = Strndup(optarg, strlen(optarg));
1156 parse_services(tmp, services_cmd);
1157 free(tmp);
1158 break;
1159 case 's': /* only list hosts */
1160 if (*optarg == 'L')
1161 o.list_only = true;
1162 else
1163 fatal("Illegal argument for option '-s' Did you mean -sL?");
1164 break;
1165 case 'T': /* timing template */
1166 if (*optarg == '0' || (strcasecmp(optarg, "Paranoid") == 0)) {
1167 o.timing_level = 0;
1168 } else if (*optarg == '1' || (strcasecmp(optarg, "Sneaky") == 0)) {
1169 o.timing_level = 1;
1170 } else if (*optarg == '2' || (strcasecmp(optarg, "Polite") == 0)) {
1171 o.timing_level = 2;
1172 } else if (*optarg == '3' || (strcasecmp(optarg, "Normal") == 0)) {
1173 o.timing_level = 3;
1174 } else if (*optarg == '4' || (strcasecmp(optarg, "Aggressive") == 0)) {
1175 o.timing_level = 4;
1176 } else if (*optarg == '5' || (strcasecmp(optarg, "Insane") == 0)) {
1177 o.timing_level = 5;
1178 } else {
1179 fatal("Unknown timing mode (-T argument). Use either \"Paranoid\", "
1180 "\"Sneaky\", \"Polite\", \"Normal\", \"Aggressive\", "
1181 "\"Insane\" or a number from 0 (Paranoid) to 5 (Insane)");
1182 }
1183 break;
1184 case 'V':
1185 log_write(LOG_STDOUT, "\n%s version %s ( %s )\n",
1186 NCRACK_NAME, NCRACK_VERSION, NCRACK_URL);
1187 log_write(LOG_STDOUT, "Modules: SSH, RDP, FTP, Telnet, HTTP(S), Wordpress, POP3(S), IMAP, CVS, "
1188 "SMB, VNC, SIP, Redis, PostgreSQL, MQTT, MySQL, MSSQL, MongoDB, Cassandra, WinRM, OWA, DICOM\n");
1189 exit(EXIT_SUCCESS);
1190 break;
1191 case 'v':
1192 if (optarg && isdigit(optarg[0])) {
1193 o.verbose = atoi(optarg);
1194 } else {
1195 const char *p;
1196 o.verbose++;
1197 for (p = optarg != NULL ? optarg : ""; *p == 'v'; p++)
1198 o.verbose++;
1199 if (*p != '\0')
1200 fatal("Invalid argument to -v: \"%s\".", optarg);
1201 }
1202 break;
1203 case '?': /* error */
1204 print_usage();
1205 }
1206 }
1207
1208 /* Initialize tty for interactive output */
1209 tty_init();
1210
1211 /* Open the log files, now that we know whether the user wants them appended
1212 or overwritten */
1213 if (normalfilename) {
1214 log_open(LOG_NORMAL, normalfilename);
1215 free(normalfilename);
1216 }
1217 if (xmlfilename) {
1218 log_open(LOG_XML, xmlfilename);
1219 free(xmlfilename);
1220 }
1221
1222 if (UserArray.empty()) {
1223 ncrack_fetchfile(username_file, sizeof(username_file),
1224 DEFAULT_USERNAME_FILE);
1225 load_login_file(username_file, USER);
1226 }
1227 if (PassArray.empty()) {
1228 ncrack_fetchfile(password_file, sizeof(password_file),
1229 DEFAULT_PASSWORD_FILE);
1230 load_login_file(password_file, PASS);
1231 }
1232
1233
1234 /* Now handle signals */
1235
1236 #if defined(HAVE_SIGNAL) && defined(SIGPIPE)
1237 signal(SIGPIPE, SIG_IGN);
1238 /* ignore SIGPIPE so our program doesn't crash because
1239 * of it, but we really shouldn't get an unsuspected SIGPIPE
1240 */
1241 #endif
1242
1243 /* The handler for the rest of the signals will be established after
1244 * ServiceGroup has been initialized, since the saved state that is going to
1245 * be written into the file used for --resume option, requires that
1246 * information. There is no point in catching the signals before, because
1247 * there is no benefit in doing anything special then (can't save the state
1248 * yet that is). The default actions are enough.
1249 */
1250
1251
1252 /* Prepare -T option (3 is default) */
1253 prepare_timing_template(&timing);
1254
1255 if (strftime(tbuf, sizeof(tbuf), "%Y-%m-%d %H:%M %Z", tm) <= 0)
1256 fatal("Unable to properly format time");
1257 log_write(LOG_STDOUT, "\nStarting %s %s ( %s ) at %s\n",
1258 NCRACK_NAME, NCRACK_VERSION, NCRACK_URL, tbuf);
1259
1260
1261 /* lets load our exclude list */
1262 if ((NULL != excludefd) || (NULL != exclude_spec)) {
1263 exclude_group = load_exclude(excludefd, exclude_spec);
1264
1265 if (o.debugging > 3)
1266 dumpExclude(exclude_group);
1267
1268 if ((FILE *)NULL != excludefd)
1269 fclose(excludefd);
1270 if ((char *)NULL != exclude_spec)
1271 free(exclude_spec);
1272 }
1273
1274 /* Brief info incase they forget what was scanned */
1275 timep = time(NULL);
1276 Strncpy(mytime, ctime(&now), sizeof(mytime));
1277 chomp(mytime);
1278
1279 //char *xslfname = o.XSLStyleSheet();
1280 char *xslfname = NULL; // no stylesheet for now
1281
1282 xml_start_document("ncrackrun");
1283 if (xslfname) {
1284 xml_open_pi("xml-stylesheet");
1285 xml_attribute("href", "%s", xslfname);
1286 xml_attribute("type", "text/xsl");
1287 xml_close_pi();
1288 xml_newline();
1289 }
1290
1291 xml_start_comment();
1292 xml_write_escaped(" %s %s scan initiated %s as: %s ", NCRACK_NAME, NCRACK_VERSION, mytime, join_quoted(argv, argc).c_str());
1293 xml_end_comment();
1294 xml_newline();
1295
1296 xml_open_start_tag("ncrackrun");
1297 xml_attribute("scanner", "ncrack");
1298 xml_attribute("args", "%s", join_quoted(argv, argc).c_str());
1299 xml_attribute("start", "%lu", (unsigned long) timep);
1300 xml_attribute("startstr", "%s", mytime);
1301 xml_attribute("version", "%s", NCRACK_VERSION);
1302 xml_attribute("xmloutputversion", NCRACK_XMLOUTPUTVERSION);
1303 xml_close_start_tag();
1304 xml_newline();
1305
1306 xml_open_start_tag("verbose");
1307 xml_attribute("level", "%d", o.verbose);
1308 xml_close_empty_tag();
1309 xml_newline();
1310 xml_open_start_tag("debugging");
1311 xml_attribute("level", "%d", o.debugging);
1312 xml_close_empty_tag();
1313 xml_newline();
1314
1315 std::string command;
1316 if (argc > 0)
1317 command += argv[0];
1318 for (i = 1; i < (unsigned int)argc; i++) {
1319 command += " ";
1320 command += argv[i];
1321 }
1322
1323 log_write(LOG_NORMAL, "# ");
1324 log_write(LOG_NORMAL, "%s %s scan initiated %s as: ", NCRACK_NAME, NCRACK_VERSION, mytime);
1325 log_write(LOG_NORMAL, "%s", command.c_str());
1326 log_write(LOG_NORMAL, "\n");
1327
1328 /*
1329 * These will later be used by ncrack_save() to write the way Ncrack was
1330 * called to the restore file.
1331 */
1332 o.saved_argv = argv;
1333 o.saved_argc = argc;
1334
1335
1336 SG = new ServiceGroup();
1337 SG->connection_limit = o.connection_limit;
1338
1339
1340 while ((host_spec = grab_next_host_spec(inputfd, argc, argv))) {
1341
1342 /* preparse and separate host - service */
1343 spec = parse_services_target(host_spec);
1344 if (spec.error)
1345 continue;
1346
1347 // log_write(LOG_STDOUT,"%s://%s:%s?%s\n",spec.service_name,
1348 // spec.host_expr, spec.portno, spec.service_options);
1349
1350 if (spec.service_name) {
1351 service = new Service();
1352 service->name = strdup(spec.service_name);
1353 service->UserArray = &UserArray;
1354 service->PassArray = &PassArray;
1355 Services.push_back(service);
1356 } else { /* -p option */
1357 for (SCvi = services_cmd.begin(); SCvi != services_cmd.end(); SCvi++) {
1358 service = new Service();
1359 service->name = (*SCvi)->name;
1360 service->portno = (*SCvi)->portno;
1361 service->proto = (*SCvi)->proto;
1362 service->UserArray = &UserArray;
1363 service->PassArray = &PassArray;
1364 Services.push_back(service);
1365 }
1366 }
1367
1368 Svi = Services.begin();
1369 while (Svi != Services.end()) {
1370 /* first apply timing template */
1371 apply_timing_template(*Svi, &timing);
1372 /* then apply global options -g if they exist */
1373 if (o.global_options)
1374 apply_host_options(*Svi, glob_options);
1375 /* then apply options from ServiceTable (-m option) */
1376 if (apply_service_options(*Svi) < 0) {
1377 /* If service is not supported, remove it from list */
1378 Svi = Services.erase(Svi);
1379 } else
1380 Svi++;
1381 }
1382
1383 /* finally, if they have been specified, apply options from host */
1384 if (spec.service_options)
1385 apply_host_options(Services[0], spec.service_options);
1386 if (spec.portno)
1387 Services[0]->portno = str2port(spec.portno);
1388
1389
1390 while ((currenths = nexthost(spec.host_expr, exclude_group))) {
1391 for (Tvi = Targets.begin(); Tvi != Targets.end(); Tvi++) {
1392 if (!(strcmp((*Tvi)->NameIP(), currenths->NameIP())))
1393 break;
1394 }
1395 if (Tvi == Targets.end())
1396 Targets.push_back(currenths);
1397 else
1398 currenths = *Tvi;
1399
1400 for (Svi = Services.begin(); Svi != Services.end(); Svi++) {
1401 service = new Service(**Svi);
1402
1403 service->target = currenths;
1404 /* check for duplicates */
1405 for (li = SG->services_all.begin(); li != SG->services_all.end();
1406 li++) {
1407 if (!strcmp((*li)->target->NameIP(), currenths->NameIP())
1408 && (!strcmp((*li)->name, service->name))
1409 && ((*li)->portno == service->portno))
1410 fatal("Duplicate service %s for target %s !",
1411 service->name, currenths->NameIP());
1412 }
1413
1414 /*
1415 * Push service to both 'services_all' (every service resides there)
1416 * and to 'services_active' list (every service starts with
1417 * 1 connection)
1418 */
1419 SG->services_all.push_back(service);
1420 SG->services_active.push_back(service);
1421 SG->total_services++;
1422 }
1423 }
1424 Services.clear();
1425 clean_spec(&spec);
1426 }
1427
1428 if (o.list_only) {
1429 if (o.debugging) {
1430 log_write(LOG_PLAIN, "----- [ Timing Template ] -----\n");
1431 log_write(LOG_PLAIN, "cl=%ld, CL=%ld, at=%ld, cd=%ld, cr=%ld, to=%lld\n",
1432 timing.min_connection_limit, timing.max_connection_limit,
1433 timing.auth_tries, timing.connection_delay,
1434 timing.connection_retries, timing.timeout);
1435
1436 log_write(LOG_PLAIN, "\n----- [ ServicesTable ] -----\n");
1437
1438 int colno = 0;
1439 int col_port = colno++;
1440 int col_cl = colno++;
1441 int col_CL = colno++;
1442 int col_at = colno++;
1443 int col_cd = colno++;
1444 int col_cr = colno++;
1445 int col_to = colno++;
1446 int col_ssl = colno++;
1447 int col_path = colno++;
1448 int col_db = colno++;
1449 int col_domain = colno++;
1450 int numrows = ServicesTable.size() + 1;
1451 NcrackOutputTable *Tbl = new NcrackOutputTable(numrows, colno);
1452
1453 Tbl->addItem(0, col_port, false, "SERVICE", sizeof("SERVICE") - 1);
1454 Tbl->addItem(0, col_cl, false, "cl", sizeof("cl") - 1);
1455 Tbl->addItem(0, col_CL, false, "CL", sizeof("CL") - 1);
1456 Tbl->addItem(0, col_at, false, "at", sizeof("at") - 1);
1457 Tbl->addItem(0, col_cd, false, "cd", sizeof("cd") - 1);
1458 Tbl->addItem(0, col_cr, false, "cr", sizeof("cr") - 1);
1459 Tbl->addItem(0, col_to, false, "to", sizeof("to") - 1);
1460 Tbl->addItem(0, col_ssl, false, "ssl", sizeof("ssl") - 1);
1461 Tbl->addItem(0, col_path, false, "path", sizeof("path") - 1);
1462 Tbl->addItem(0, col_db, false, "db", sizeof("db") - 1);
1463 Tbl->addItem(0, col_domain, false, "domain", sizeof("domain") - 1);
1464
1465 int rowno = 1;
1466
1467 for (i = 0; i < ServicesTable.size(); i++) {
1468
1469 Tbl->addItemFormatted(rowno, col_port, false, "%s:%hu",
1470 ServicesTable[i].lookup.name, ServicesTable[i].lookup.portno);
1471
1472 if (ServicesTable[i].timing.min_connection_limit != NOT_ASSIGNED)
1473 Tbl->addItemFormatted(rowno, col_cl, false, "%ld",
1474 ServicesTable[i].timing.min_connection_limit);
1475 else
1476 Tbl->addItem(rowno, col_cl, false, "N/A");
1477
1478 if (ServicesTable[i].timing.max_connection_limit != NOT_ASSIGNED)
1479 Tbl->addItemFormatted(rowno, col_CL, false, "%ld",
1480 ServicesTable[i].timing.max_connection_limit);
1481 else
1482 Tbl->addItem(rowno, col_CL, false, "N/A");
1483
1484 if (ServicesTable[i].timing.auth_tries != NOT_ASSIGNED)
1485 Tbl->addItemFormatted(rowno, col_at, false, "%ld",
1486 ServicesTable[i].timing.auth_tries);
1487 else
1488 Tbl->addItem(rowno, col_at, false, "N/A");
1489
1490 if (ServicesTable[i].timing.connection_delay != NOT_ASSIGNED)
1491 Tbl->addItemFormatted(rowno, col_cd, false, "%ld",
1492 ServicesTable[i].timing.connection_delay);
1493 else
1494 Tbl->addItem(rowno, col_cd, false, "N/A");
1495
1496 if (ServicesTable[i].timing.connection_retries != NOT_ASSIGNED)
1497 Tbl->addItemFormatted(rowno, col_cr, false, "%ld",
1498 ServicesTable[i].timing.connection_retries);
1499 else
1500 Tbl->addItem(rowno, col_cr, false, "N/A");
1501
1502 if (ServicesTable[i].timing.timeout != NOT_ASSIGNED)
1503 Tbl->addItemFormatted(rowno, col_to, false, "%ld",
1504 ServicesTable[i].timing.timeout);
1505 else
1506 Tbl->addItem(rowno, col_to, false, "N/A");
1507
1508 Tbl->addItem(rowno, col_ssl, false,
1509 ServicesTable[i].misc.ssl ? "yes" : "no");
1510
1511 Tbl->addItem(rowno, col_path, false, ServicesTable[i].misc.path ?
1512 ServicesTable[i].misc.path : "null");
1513
1514 Tbl->addItem(rowno, col_db, false, ServicesTable[i].misc.db ?
1515 ServicesTable[i].misc.db : "null");
1516
1517 Tbl->addItem(rowno, col_domain, false, ServicesTable[i].misc.domain ?
1518 ServicesTable[i].misc.domain : "null");
1519
1520 rowno++;
1521 }
1522 log_write(LOG_PLAIN, "%s", Tbl->printableTable(NULL));
1523 delete Tbl;
1524
1525 }
1526 log_write(LOG_PLAIN, "\n----- [ Targets ] -----\n");
1527 for (i = 0; i < Targets.size(); i++) {
1528 log_write(LOG_PLAIN, "Host: %s", Targets[i]->NameIP());
1529 if (Targets[i]->targetname)
1530 log_write(LOG_PLAIN, " ( %s ) ", Targets[i]->targetname);
1531 log_write(LOG_PLAIN, "\n");
1532 for (li = SG->services_all.begin(); li != SG->services_all.end(); li++) {
1533 if ((*li)->target == Targets[i])
1534 log_write(LOG_PLAIN, " %s:%hu cl=%ld, CL=%ld, at=%ld, cd=%ld, "
1535 "cr=%ld, to=%lldms, ssl=%s, path=%s, db=%s, domain=%s\n",
1536 (*li)->name, (*li)->portno, (*li)->min_connection_limit,
1537 (*li)->max_connection_limit, (*li)->auth_tries,
1538 (*li)->connection_delay, (*li)->connection_retries,
1539 (*li)->timeout, (*li)->ssl ? "yes" : "no", (*li)->path,
1540 (*li)->db, (*li)->domain);
1541 }
1542 }
1543 } else {
1544 if (!SG->total_services)
1545 fatal("No services specified!");
1546
1547 /* If --resume had been specified, it is time to copy the saved session
1548 * info into our ServiceGroup.
1549 */
1550 if (o.resume) {
1551
1552 map<uint32_t, struct saved_info>::iterator mi;
1553 list <Service *>::iterator li;
1554 vector <loginpair>::iterator vi;
1555
1556 for (mi = o.resume_map.begin(); mi != o.resume_map.end(); mi++) {
1557
1558 for (li = SG->services_all.begin(); li != SG->services_all.end();
1559 li++) {
1560 if ((*li)->uid == mi->first)
1561 break;
1562 }
1563
1564 (*li)->setUserlistIndex(mi->second.user_index);
1565 (*li)->setPasslistIndex(mi->second.pass_index);
1566
1567 for (vi = mi->second.credentials_found.begin();
1568 vi != mi->second.credentials_found.end(); vi++) {
1569 (*li)->addCredential(vi->user, vi->pass);
1570 }
1571
1572 }
1573 }
1574
1575 /* Now is the right time to establish the signal handlers, since
1576 * ServiceGroup has been initialized */
1577 #if HAVE_SIGNAL
1578 signal(SIGINT, sigcatch);
1579 signal(SIGTERM, sigcatch);
1580 #ifndef WIN32
1581 signal(SIGHUP, sigcatch);
1582 #endif
1583 #endif
1584
1585 if (o.stealthy_linear)
1586 SG->connection_limit = SG->services_all.size();
1587
1588
1589 SG->last_accessed = SG->services_active.end();
1590 SG->prev_modified = SG->services_active.end();
1591 /* Ncrack 'em all! */
1592 ncrack(SG);
1593 }
1594
1595
1596 log_write(LOG_STDOUT, "\n");
1597 /* Now print the final results for each service
1598 * In addition, check if any of the services timed out so that
1599 * we can save a .restore file in case the user needs to resume the session
1600 * another time.
1601 */
1602 bool save_state = false;
1603 for (li = SG->services_all.begin(); li != SG->services_all.end(); li++) {
1604
1605 xml_open_start_tag("service");
1606 xml_attribute("starttime", "%lu", (unsigned long) (*li)->StartTime());
1607 xml_attribute("endtime", "%lu", (unsigned long) (*li)->EndTime());
1608 xml_close_start_tag();
1609 xml_newline();
1610
1611 xml_open_start_tag("address");
1612 xml_attribute("addr", "%s", (*li)->target->NameIP());
1613 xml_attribute("addrtype", "%s", (o.af() == AF_INET) ? "ipv4" : "ipv6");
1614 xml_close_empty_tag();
1615 xml_newline();
1616
1617 xml_open_start_tag("port");
1618 xml_attribute("protocol", IPPROTO2STR((*li)->proto));
1619 xml_attribute("portid", "%d", (*li)->portno);
1620 xml_attribute("name", (*li)->name);
1621 xml_close_start_tag();
1622 xml_end_tag(); /* </port> */
1623 xml_newline();
1624
1625 if ((*li)->end.reason != NULL && !strncmp((*li)->end.reason, SERVICE_TIMEDOUT, sizeof(SERVICE_TIMEDOUT)))
1626 save_state = true;
1627
1628 if ((*li)->credentials_found.size() != 0)
1629 print_service_output(*li);
1630
1631 xml_end_tag(); /* </service> */
1632 xml_newline();
1633 }
1634
1635 /* Print final output information */
1636 print_final_output(SG);
1637 log_flush_all();
1638
1639 /* If any service timed out, then save a .restore file */
1640 if (save_state)
1641 ncrack_save(SG);
1642
1643 /* Free all of the Targets */
1644 while(!Targets.empty()) {
1645 currenths = Targets.back();
1646 delete currenths;
1647 Targets.pop_back();
1648 }
1649 delete SG;
1650
1651 log_write(LOG_STDOUT, "\nNcrack finished.\n");
1652 exit(EXIT_SUCCESS);
1653 }
1654
1655
1656 /* Start the timeout clocks of any targets that aren't already timedout */
1657 static void
startTimeOutClocks(ServiceGroup * SG)1658 startTimeOutClocks(ServiceGroup *SG)
1659 {
1660 struct timeval tv;
1661 list<Service *>::iterator li;
1662
1663 gettimeofday(&tv, NULL);
1664 for (li = SG->services_all.begin(); li != SG->services_all.end(); li++) {
1665 if (!(*li)->timedOut(NULL))
1666 (*li)->startTimeOutClock(&tv);
1667 }
1668 }
1669
1670
1671 /*
1672 * It handles module endings
1673 */
1674 void
ncrack_module_end(nsock_pool nsp,void * mydata)1675 ncrack_module_end(nsock_pool nsp, void *mydata)
1676 {
1677 Connection *con = (Connection *) mydata;
1678 ServiceGroup *SG = (ServiceGroup *) nsock_pool_get_udata(nsp);
1679 Service *serv = con->service;
1680 nsock_iod nsi = con->niod;
1681 struct timeval now;
1682 int pair_ret;
1683 const char *hostinfo = serv->HostInfo();
1684
1685 con->login_attempts++;
1686 con->auth_complete = true;
1687 serv->total_attempts++;
1688 serv->finished_attempts++;
1689
1690 /* First check if the module reported that it can no longer continue to
1691 * crack the assigned service, in which case we should place it in the
1692 * finished services.
1693 */
1694 if (serv->end.orly) {
1695 if (o.debugging) {
1696 if (serv->end.reason) {
1697 chomp(serv->end.reason);
1698 log_write(LOG_STDOUT, "%s will no longer be cracked because module "
1699 "reported that:\n %s\n", hostinfo, serv->end.reason);
1700 } else {
1701 log_write(LOG_STDOUT, "%s will no longer be cracked. No reason was "
1702 "reported from module.\n", hostinfo);
1703 }
1704 }
1705 SG->pushServiceToList(serv, &SG->services_finished);
1706 if (o.verbose)
1707 log_write(LOG_STDOUT, "%s finished.\n", hostinfo);
1708 return ncrack_connection_end(nsp, con);
1709 }
1710
1711 if (con->auth_success) {
1712 serv->addCredential(con->user, con->pass);
1713 SG->credentials_found++;
1714
1715 if (o.verbose)
1716 log_write(LOG_PLAIN, "Discovered credentials on %s '%s' '%s'\n",
1717 hostinfo, con->user, con->pass);
1718
1719 /* Quit cracking service if '-f' has been specified. */
1720 if (o.finish == 1) {
1721
1722 SG->pushServiceToList(serv, &SG->services_finished);
1723 if (o.verbose)
1724 log_write(LOG_STDOUT, "%s finished.\n", hostinfo);
1725 return ncrack_connection_end(nsp, con);
1726
1727 } else if (o.finish > 1) {
1728 /* Quit cracking every service if '-f -f' or greater has been
1729 * specified.
1730 */
1731 list <Service *>::iterator li;
1732 for (li = SG->services_all.begin(); li != SG->services_all.end(); li++) {
1733 SG->pushServiceToList(*li, &SG->services_finished);
1734 if (o.verbose)
1735 log_write(LOG_STDOUT, "%s finished.\n", hostinfo);
1736 }
1737 /* Now quit nsock_loop */
1738 nsock_loop_quit(nsp);
1739 return ncrack_connection_end(nsp, con);
1740 }
1741
1742 } else {
1743 if (!serv->more_rounds) {
1744 if (o.debugging > 6) {
1745 if (!strcmp(serv->name, "redis"))
1746 log_write(LOG_STDOUT, "%s (EID %li) Login failed: '%s'\n",
1747 hostinfo, nsock_iod_id(con->niod), con->pass);
1748 else
1749 log_write(LOG_STDOUT, "%s (EID %li) Login failed: '%s' '%s'\n",
1750 hostinfo, nsock_iod_id(con->niod), con->user, con->pass);
1751 }
1752 } else {
1753 serv->appendToPool(con->user, con->pass);
1754 }
1755 }
1756
1757 if (serv->just_started && !serv->more_rounds
1758 && con->close_reason != MODULE_ERR) {
1759 serv->supported_attempts++;
1760 serv->auth_rate_meter.update(1, NULL);
1761 }
1762
1763 gettimeofday(&now, NULL);
1764 if (!serv->just_started && !serv->more_rounds
1765 && timeval_msec_subtract(now, serv->last_auth_rate.time) >= 500) {
1766 double current_rate = serv->auth_rate_meter.getCurrentRate();
1767 if (o.debugging)
1768 log_write(LOG_STDOUT, "%s last: %.2f current %.2f parallelism %ld\n",
1769 hostinfo, serv->last_auth_rate.rate, current_rate,
1770 serv->ideal_parallelism);
1771 if (current_rate < serv->last_auth_rate.rate + 3) {
1772 if (serv->ideal_parallelism + 3 < serv->max_connection_limit)
1773 serv->ideal_parallelism += 3;
1774 else
1775 serv->ideal_parallelism = serv->max_connection_limit;
1776 if (o.debugging)
1777 log_write(LOG_STDOUT, "%s Increasing connection limit to: %ld\n",
1778 hostinfo, serv->ideal_parallelism);
1779 }
1780 serv->last_auth_rate.time = now;
1781 serv->last_auth_rate.rate = current_rate;
1782 }
1783
1784 /* If login pair was extracted from pool, permanently remove it from it. */
1785 if (con->from_pool && !serv->isMirrorPoolEmpty()) {
1786 serv->removeFromPool(con->user, con->pass);
1787 con->from_pool = false;
1788 }
1789
1790 if (serv->isMirrorPoolEmpty() && !serv->active_connections
1791 && serv->getListFinishing()) {
1792 SG->pushServiceToList(serv, &SG->services_finished);
1793 if (o.verbose)
1794 log_write(LOG_STDOUT, "%s finished.\n", hostinfo);
1795 return ncrack_connection_end(nsp, con);
1796 }
1797
1798 /*
1799 * Check if we had previously surpassed imposed connection limit so that
1800 * we remove service from 'services_full' list
1801 */
1802 if (serv->getListFull()
1803 && serv->active_connections < serv->ideal_parallelism)
1804 SG->popServiceFromList(serv, &SG->services_full);
1805
1806 /* Initiate new connections if service gets active again */
1807 if (serv->getListActive())
1808 ncrack_probes(nsp, SG);
1809
1810 /* If module itself reported an error in the connection, then mark the flag
1811 * auth_complete as false.
1812 */
1813 if (con->close_reason == MODULE_ERR)
1814 con->auth_complete = false;
1815
1816 /* If module instructed to close the connection by force, then do so
1817 * here.
1818 */
1819 if (con->force_close)
1820 return ncrack_connection_end(nsp, con);
1821
1822 /*
1823 * If we need to check whether peer is alive or not we do the following:
1824 * Since there is no portable way to check if the peer has closed the
1825 * connection or not (hence we are in CLOSE_WAIT state), issue a read call
1826 * with a very small timeout and check if nsock timed out (host hasn't closed
1827 * connection yet) or returned an EOF (host sent FIN making active close)
1828 * Note, however that the connection might have already indicated that the
1829 * peer is alive (for example telnetd sends the next login prompt along with
1830 * the authentication results, denoting that it immediately expects another
1831 * authentication attempt), so in that case we need to get the next login
1832 * pair only and make no additional check.
1833 */
1834 if (con->peer_alive) {
1835 if ((!serv->auth_tries
1836 || con->login_attempts < (unsigned long)serv->auth_tries)
1837 && (pair_ret = serv->getNextPair(&con->user, &con->pass)) != -1) {
1838 if (pair_ret == 1)
1839 con->from_pool = true;
1840 nsock_timer_create(nsp, ncrack_timer_handler, 0, con);
1841 } else
1842 return ncrack_connection_end(nsp, con);
1843 } else {
1844 /*
1845 * We need to check if host is alive only on first timing
1846 * probe. Thereafter we can use the 'supported_attempts'.
1847 */
1848 if (serv->just_started && serv->more_rounds) {
1849 ncrack_connection_end(nsp, con);
1850 } else if (serv->just_started) {
1851 con->check_closed = true;
1852 nsock_read(nsp, nsi, ncrack_read_handler, 10, con);
1853 } else if ((!serv->auth_tries
1854 || con->login_attempts < (unsigned long)serv->auth_tries)
1855 && con->login_attempts < serv->supported_attempts
1856 && (pair_ret = serv->getNextPair(&con->user, &con->pass)) != -1) {
1857 if (pair_ret == 1)
1858 con->from_pool = true;
1859
1860
1861 call_module(nsp, con);
1862 } else {
1863 /* We end the connection if:
1864 * (we are not the first timing probe) AND
1865 * (we are either at the server's imposed authentication limit OR
1866 * we are at the user's imposed authentication limit)
1867 */
1868 ncrack_connection_end(nsp, con);
1869 }
1870 }
1871 return;
1872 }
1873
1874
1875 void
ncrack_connection_end(nsock_pool nsp,void * mydata)1876 ncrack_connection_end(nsock_pool nsp, void *mydata)
1877 {
1878 Connection *con = (Connection *) mydata;
1879 Service *serv = con->service;
1880 nsock_iod nsi = con->niod;
1881 ServiceGroup *SG = (ServiceGroup *) nsock_pool_get_udata(nsp);
1882 list <Connection *>::iterator li;
1883 const char *hostinfo = serv->HostInfo();
1884 unsigned long eid = nsock_iod_id(con->niod);
1885
1886
1887 if (con->close_reason == CON_ERR)
1888 SG->connections_timedout++;
1889
1890 if (con->close_reason == READ_TIMEOUT) {
1891
1892 if (!con->auth_complete) {
1893 serv->appendToPool(con->user, con->pass);
1894 }
1895
1896 if (serv->getListPairfini())
1897 SG->popServiceFromList(serv, &SG->services_pairfini);
1898 if (o.debugging)
1899 error("%s (EID %li) nsock READ timeout!", hostinfo, eid);
1900
1901 } else if (con->close_reason == READ_EOF || con->close_reason == MODULE_ERR) {
1902 /*
1903 * Check if we are on the point where peer might close at any moment
1904 * (usually we set 'peer_might_close' after writing the password on the
1905 * network and before issuing the next read call), so that this connection
1906 * ending was actually expected.
1907 */
1908 if (con->peer_might_close) {
1909 /* If we are the first special timing probe, then increment the number of
1910 * server-allowed authentication attempts per connection.
1911 */
1912 if (serv->just_started)
1913 serv->supported_attempts++;
1914
1915 serv->total_attempts++;
1916 serv->finished_attempts++;
1917
1918 if (o.debugging > 6)
1919 log_write(LOG_STDOUT, "%s (EID %li) Failed '%s' '%s'\n", hostinfo, eid,
1920 con->user, con->pass);
1921
1922 } else if (serv->more_rounds) {
1923 /* We are still checking timing of the host, so don't do anything yet. */
1924
1925 } else if (!con->auth_complete) {
1926 serv->appendToPool(con->user, con->pass);
1927 if (serv->getListPairfini())
1928 SG->popServiceFromList(serv, &SG->services_pairfini);
1929
1930 /* Now this is strange: peer closed on us in the middle of
1931 * authentication. This shouldn't happen, unless extreme network
1932 * conditions are happening!
1933 */
1934 if (!serv->just_started
1935 && con->login_attempts < serv->supported_attempts) {
1936 if (o.debugging > 3)
1937 error("%s (EID %li) closed on us in the middle of authentication!", hostinfo, eid);
1938 SG->connections_closed++;
1939 }
1940 }
1941 if (o.debugging > 5)
1942 error("%s (EID %li) Connection closed by peer", hostinfo, eid);
1943 }
1944 con->close_reason = -1;
1945
1946
1947 /*
1948 * If we are not the first timing probe and the authentication wasn't
1949 * completed (we double check that by seeing if we are inside the supported
1950 * -by the server- threshold of authentication attempts per connection), then
1951 * we take drastic action and drop the connection limit.
1952 */
1953 if (!serv->just_started && !serv->more_rounds && !con->auth_complete
1954 && !con->peer_might_close
1955 && con->login_attempts < serv->supported_attempts) {
1956 serv->total_attempts++;
1957 // TODO:perhaps here we might want to differentiate between the two errors:
1958 // timeout and premature close, giving a unique drop value to each
1959 if (serv->ideal_parallelism - 5 >= serv->min_connection_limit)
1960 serv->ideal_parallelism -= 5;
1961 else
1962 serv->ideal_parallelism = serv->min_connection_limit;
1963
1964 if (o.debugging)
1965 log_write(LOG_STDOUT, "%s (EID %li) Dropping connection limit due to connection "
1966 "error to: %ld\n", hostinfo, eid, serv->ideal_parallelism);
1967 }
1968
1969
1970 /*
1971 * If that was our first connection, then calculate initial ideal_parallelism
1972 * (which was 1 previously) based on the box of min_connection_limit,
1973 * max_connection_limit and a default desired parallelism for each timing
1974 * template.
1975 */
1976 if (serv->just_started == true && !serv->more_rounds) {
1977 serv->just_started = false;
1978 long desired_par = 1;
1979 if (o.timing_level == 0)
1980 desired_par = 1;
1981 else if (o.timing_level == 1)
1982 desired_par = 1;
1983 else if (o.timing_level == 2)
1984 desired_par = 4;
1985 else if (o.timing_level == 3)
1986 desired_par = 10;
1987 else if (o.timing_level == 4)
1988 desired_par = 30;
1989 else if (o.timing_level == 5)
1990 desired_par = 50;
1991
1992 serv->ideal_parallelism = box(serv->min_connection_limit,
1993 serv->max_connection_limit, desired_par);
1994 }
1995
1996
1997 for (li = serv->connections.begin(); li != serv->connections.end(); li++) {
1998 if ((*li)->niod == nsi)
1999 break;
2000 }
2001 if (li == serv->connections.end()) /* this shouldn't happen */
2002 fatal("%s: invalid niod!", __func__);
2003
2004 SG->auth_rate_meter.update(con->login_attempts, NULL);
2005
2006 nsock_iod_delete(nsi, NSOCK_PENDING_SILENT);
2007 serv->connections.erase(li);
2008 delete con;
2009
2010 serv->active_connections--;
2011 SG->active_connections--;
2012
2013
2014 /*
2015 * Check if we had previously surpassed imposed connection limit so that
2016 * we remove service from 'services_full' list
2017 */
2018 if (serv->getListFull()
2019 && serv->active_connections < serv->ideal_parallelism)
2020 SG->popServiceFromList(serv, &SG->services_full);
2021
2022
2023 /*
2024 * If linear stealthy mode is enabled, then mark the corresponding state as DONE
2025 * since the connection just ended. If all connections from all services are done,
2026 * then the next active connection can start.
2027 */
2028 if (serv->getLinearState() == LINEAR_ACTIVE) {
2029 serv->setLinearState(LINEAR_DONE);
2030 serv->ideal_parallelism = 1;
2031 }
2032
2033
2034 /*
2035 * If service was on 'services_finishing' (credential list finished, pool
2036 * empty but still pending connections) then:
2037 * - if new pairs arrived into pool, remove from 'services_finishing'
2038 * - else if no more connections are pending, move to 'services_finished'
2039 */
2040 if (serv->getListFinishing()) {
2041 if (!serv->isMirrorPoolEmpty())
2042 SG->popServiceFromList(serv, &SG->services_finishing);
2043 else if (!serv->active_connections) {
2044 SG->pushServiceToList(serv, &SG->services_finished);
2045 if (o.verbose)
2046 log_write(LOG_STDOUT, "%s finished.\n", hostinfo);
2047 }
2048 }
2049
2050 if (o.debugging)
2051 log_write(LOG_STDOUT, "%s (EID %li) Attempts: total %lu completed %lu supported %lu "
2052 "--- rate %.2f \n", hostinfo, eid, serv->total_attempts,
2053 serv->finished_attempts, serv->supported_attempts,
2054 SG->auth_rate_meter.getCurrentRate());
2055
2056 /* Check if service finished for good. */
2057 if (serv->loginlist_fini && serv->isMirrorPoolEmpty()
2058 && !serv->active_connections && !serv->getListFinished()) {
2059 SG->pushServiceToList(serv, &SG->services_finished);
2060 if (o.verbose)
2061 log_write(LOG_STDOUT, "%s finished.\n", hostinfo);
2062 }
2063
2064
2065 /* see if we can initiate some more connections */
2066 if (serv->getListActive())
2067 return ncrack_probes(nsp, SG);
2068
2069 return;
2070 }
2071
2072
2073 void
ncrack_read_handler(nsock_pool nsp,nsock_event nse,void * mydata)2074 ncrack_read_handler(nsock_pool nsp, nsock_event nse, void *mydata)
2075 {
2076 enum nse_status status = nse_status(nse);
2077 enum nse_type type = nse_type(nse);
2078 ServiceGroup *SG = (ServiceGroup *) nsock_pool_get_udata(nsp);
2079 Connection *con = (Connection *) mydata;
2080 Service *serv = con->service;
2081 int pair_ret;
2082 int nbytes;
2083 int err;
2084 char *str;
2085 const char *hostinfo = serv->HostInfo();
2086 unsigned long eid = nsock_iod_id(con->niod);
2087
2088 assert(type == NSE_TYPE_READ);
2089
2090
2091 /* If service has already finished (probably due to the -f option), then
2092 * cancel this event and return immediately. The same happens with the rest
2093 * of the event handlers.
2094 */
2095 if (serv->getListFinished()) {
2096 nsock_event_cancel(nsp, nse_id(nse), 0);
2097 return;
2098 }
2099
2100 if (serv->timedOut(NULL)) {
2101 serv->end.reason = Strndup(SERVICE_TIMEDOUT, sizeof(SERVICE_TIMEDOUT));
2102 SG->pushServiceToList(serv, &SG->services_finished);
2103 if (o.verbose)
2104 log_write(LOG_STDOUT, "%s finished.\n", hostinfo);
2105 return ncrack_connection_end(nsp, con);
2106
2107 } else if (status == NSE_STATUS_SUCCESS) {
2108
2109 str = nse_readbuf(nse, &nbytes);
2110
2111 if (con->inbuf == NULL)
2112 con->inbuf = new Buf();
2113
2114 con->inbuf->append(str, nbytes);
2115
2116 return call_module(nsp, con);
2117
2118 } else if (status == NSE_STATUS_TIMEOUT) {
2119
2120 /* First check if we are just making sure the host hasn't closed
2121 * on us, and so we are still in ESTABLISHED state, instead of
2122 * CLOSE_WAIT - we do this by issuing a read call with a tiny timeout.
2123 * If we are still connected, then we can go on checking if we can make
2124 * another authentication attempt in this particular connection.
2125 */
2126 if (con->check_closed) {
2127 /* Make another authentication attempt only if:
2128 * 1. we hanen't surpassed the authentication limit per connection for
2129 * this service
2130 * 2. we still have enough login pairs from the pool
2131 */
2132 if ((!serv->auth_tries
2133 || con->login_attempts < (unsigned long)serv->auth_tries)
2134 && (pair_ret = serv->getNextPair(&con->user, &con->pass)) != -1) {
2135 if (pair_ret == 1)
2136 con->from_pool = true;
2137 return call_module(nsp, con);
2138 } else {
2139 con->close_reason = READ_EOF;
2140 }
2141 } else {
2142 /* This is a normal timeout */
2143 con->close_reason = READ_TIMEOUT;
2144 }
2145
2146 } else if (status == NSE_STATUS_EOF) {
2147 con->close_reason = READ_EOF;
2148
2149 } else if (status == NSE_STATUS_ERROR || status == NSE_STATUS_PROXYERROR) {
2150
2151 err = nse_errorcode(nse);
2152 if (o.debugging > 2)
2153 error("%s (EID %li) nsock READ error #%d (%s)", hostinfo, eid, err, strerror(err));
2154 serv->appendToPool(con->user, con->pass);
2155 if (serv->getListPairfini())
2156 SG->popServiceFromList(serv, &SG->services_pairfini);
2157
2158 } else if (status == NSE_STATUS_KILL) {
2159 if (o.debugging > 2)
2160 error("%s (EID %li) nsock READ nse_status_kill", hostinfo, eid);
2161
2162 } else
2163 if (o.debugging > 2)
2164 error("%s (EID %li) WARNING: nsock READ unexpected status %d", hostinfo,
2165 eid, (int) status);
2166
2167 return ncrack_connection_end(nsp, con);
2168 }
2169
2170
2171
2172
2173 void
ncrack_write_handler(nsock_pool nsp,nsock_event nse,void * mydata)2174 ncrack_write_handler(nsock_pool nsp, nsock_event nse, void *mydata)
2175 {
2176 enum nse_status status = nse_status(nse);
2177 Connection *con = (Connection *) mydata;
2178 ServiceGroup *SG = (ServiceGroup *) nsock_pool_get_udata(nsp);
2179 Service *serv = con->service;
2180 const char *hostinfo = serv->HostInfo();
2181 int err;
2182 unsigned long eid = nsock_iod_id(con->niod);
2183
2184 if (serv->getListFinished()) {
2185 nsock_event_cancel(nsp, nse_id(nse), 0);
2186 return;
2187 }
2188
2189 if (serv->timedOut(NULL)) {
2190 serv->end.reason = Strndup(SERVICE_TIMEDOUT, sizeof(SERVICE_TIMEDOUT));
2191 SG->pushServiceToList(serv, &SG->services_finished);
2192 if (o.verbose)
2193 log_write(LOG_STDOUT, "%s finished.\n", hostinfo);
2194 return ncrack_connection_end(nsp, con);
2195
2196 } else if (status == NSE_STATUS_SUCCESS)
2197 call_module(nsp, con);
2198 else if (status == NSE_STATUS_ERROR || status == NSE_STATUS_PROXYERROR) {
2199 err = nse_errorcode(nse);
2200 if (o.debugging > 2)
2201 error("%s (EID %li) nsock WRITE error #%d (%s)", hostinfo, eid, err, strerror(err));
2202 } else if (status == NSE_STATUS_KILL) {
2203 error("%s (EID %li) nsock WRITE nse_status_kill\n", hostinfo, eid);
2204 } else
2205 error("%s (EID %li) WARNING: nsock WRITE unexpected status %d",
2206 hostinfo, eid, (int) (status));
2207
2208 return;
2209 }
2210
2211
2212 void
ncrack_timer_handler(nsock_pool nsp,nsock_event nse,void * mydata)2213 ncrack_timer_handler(nsock_pool nsp, nsock_event nse, void *mydata)
2214 {
2215 enum nse_status status = nse_status(nse);
2216 Connection *con = (Connection *) mydata;
2217 Service *serv = con->service;
2218 const char *hostinfo = serv->HostInfo();
2219
2220 if (serv->getListFinished()) {
2221 nsock_event_cancel(nsp, nse_id(nse), 0);
2222 return;
2223 }
2224
2225 if (status == NSE_STATUS_SUCCESS) {
2226 call_module(nsp, con);
2227 }
2228 else
2229 error("%s nsock Timer handler error!", hostinfo);
2230
2231 return;
2232 }
2233
2234
2235
2236
2237 void
ncrack_connect_handler(nsock_pool nsp,nsock_event nse,void * mydata)2238 ncrack_connect_handler(nsock_pool nsp, nsock_event nse, void *mydata)
2239 {
2240 nsock_iod nsi = nse_iod(nse);
2241 enum nse_status status = nse_status(nse);
2242 enum nse_type type = nse_type(nse);
2243 ServiceGroup *SG = (ServiceGroup *) nsock_pool_get_udata(nsp);
2244 Connection *con = (Connection *) mydata;
2245 Service *serv = con->service;
2246 const char *hostinfo = serv->HostInfo();
2247 int err;
2248 unsigned long eid = nsock_iod_id(con->niod);
2249
2250 assert(type == NSE_TYPE_CONNECT || type == NSE_TYPE_CONNECT_SSL);
2251
2252 if (serv->getListFinished()) {
2253 nsock_event_cancel(nsp, nse_id(nse), 0);
2254 return;
2255 }
2256
2257 if (serv->timedOut(NULL)) {
2258 serv->end.reason = Strndup(SERVICE_TIMEDOUT, sizeof(SERVICE_TIMEDOUT));
2259 SG->pushServiceToList(serv, &SG->services_finished);
2260 if (o.verbose)
2261 log_write(LOG_STDOUT, "%s finished.\n", hostinfo);
2262 return ncrack_connection_end(nsp, con);
2263
2264 } else if (status == NSE_STATUS_SUCCESS) {
2265
2266 serv->failed_connections = 0;
2267
2268 #if HAVE_OPENSSL
2269 // Snag our SSL_SESSION from the nsi for use in subsequent connections.
2270 if (nsock_iod_check_ssl(nsi)) {
2271 if (con->ssl_session) {
2272 if (con->ssl_session == (SSL_SESSION *)(nsock_iod_get_ssl_session(nsi, 0))) {
2273 //nada
2274 } else {
2275 SSL_SESSION_free((SSL_SESSION*)con->ssl_session);
2276 con->ssl_session = (SSL_SESSION *)(nsock_iod_get_ssl_session(nsi, 1));
2277 }
2278 } else {
2279 con->ssl_session = (SSL_SESSION *)(nsock_iod_get_ssl_session(nsi, 1));
2280 }
2281 }
2282 #endif
2283
2284 return call_module(nsp, con);
2285
2286 } else if (status == NSE_STATUS_TIMEOUT || status == NSE_STATUS_ERROR
2287 || status == NSE_STATUS_PROXYERROR) {
2288
2289 /* This is not good. connect() really shouldn't generally be timing out. */
2290 if (o.debugging > 2) {
2291 err = nse_errorcode(nse);
2292 error("%s (EID %li) nsock CONNECT response with status %s error: %s", hostinfo,
2293 eid, nse_status2str(status), strerror(err));
2294 }
2295 serv->failed_connections++;
2296 serv->appendToPool(con->user, con->pass);
2297
2298 if (serv->failed_connections > serv->connection_retries) {
2299 SG->pushServiceToList(serv, &SG->services_finished);
2300 if (o.verbose)
2301 log_write(LOG_STDOUT, "%s finished. Too many failed attemps. \n", hostinfo);
2302 }
2303 /* Failure of connecting on first attempt means we should probably drop
2304 * the service for good. */
2305 if (serv->just_started) {
2306 SG->pushServiceToList(serv, &SG->services_finished);
2307 if (o.verbose)
2308 log_write(LOG_STDOUT, "%s finished.\n", hostinfo);
2309 }
2310 if (serv->getListPairfini())
2311 SG->popServiceFromList(serv, &SG->services_pairfini);
2312
2313 con->close_reason = CON_ERR;
2314
2315 } else if (status == NSE_STATUS_KILL) {
2316
2317 if (o.debugging)
2318 error("%s (EID %li) nsock CONNECT nse_status_kill", hostinfo, eid);
2319 serv->appendToPool(con->user, con->pass);
2320 if (serv->getListPairfini())
2321 SG->popServiceFromList(serv, &SG->services_pairfini);
2322
2323 } else
2324 error("%s (EID %li) WARNING: nsock CONNECT unexpected status %d",
2325 hostinfo, eid, (int) status);
2326
2327 return ncrack_connection_end(nsp, con);
2328 }
2329
2330
2331 /*
2332 * Poll for interactive user input every time this timer is called.
2333 */
2334 static void
status_timer_handler(nsock_pool nsp,nsock_event nse,void * mydata)2335 status_timer_handler(nsock_pool nsp, nsock_event nse, void *mydata)
2336 {
2337 int key_ret;
2338 enum nse_status status = nse_status(nse);
2339 ServiceGroup *SG = (ServiceGroup *) nsock_pool_get_udata(nsp);
2340 mydata = NULL; /* nothing in there */
2341
2342 key_ret = keyWasPressed();
2343 if (key_ret == KEYPRESS_STATUS)
2344 printStatusMessage(SG);
2345 else if (key_ret == KEYPRESS_CREDS)
2346 print_creds(SG);
2347
2348 if (status != NSE_STATUS_SUCCESS) {
2349 /* Don't reschedule timer again, since nsp seems to have been
2350 * deleted (NSE_STATUS_KILL sent) and we are done. */
2351 if (status == NSE_STATUS_KILL)
2352 return;
2353 else
2354 error("Nsock status timer handler error: %s\n", nse_status2str(status));
2355 }
2356
2357 /* Reschedule timer for the next polling. */
2358 nsock_timer_create(nsp, status_timer_handler, KEYPRESSED_INTERVAL, NULL);
2359
2360 }
2361
2362 static void
signal_timer_handler(nsock_pool nsp,nsock_event nse,void * mydata)2363 signal_timer_handler(nsock_pool nsp, nsock_event nse, void *mydata)
2364 {
2365 enum nse_status status = nse_status(nse);
2366 ServiceGroup *SG = (ServiceGroup *) nsock_pool_get_udata(nsp);
2367 mydata = NULL; /* nothing in there */
2368
2369 if (status != NSE_STATUS_SUCCESS) {
2370 /* Don't reschedule timer again, since nsp seems to have been
2371 * deleted (NSE_STATUS_KILL sent) and we are done. */
2372 if (status == NSE_STATUS_KILL) {
2373 sigcheck(SG);
2374 return;
2375 }
2376 else
2377 error("Nsock status timer handler error: %s\n", nse_status2str(status));
2378 }
2379
2380 /* Reschedule timer for the next polling. */
2381 nsock_timer_create(nsp, signal_timer_handler, SIGNAL_CHECK_INTERVAL, NULL);
2382
2383 /* Check for pending signals */
2384 sigcheck(SG);
2385 }
2386
2387
2388 static void
ncrack_probes(nsock_pool nsp,ServiceGroup * SG)2389 ncrack_probes(nsock_pool nsp, ServiceGroup *SG)
2390 {
2391 Service *serv;
2392 Connection *con;
2393 struct sockaddr_storage ss;
2394 size_t ss_len;
2395 list <Service *>::iterator li;
2396 struct timeval now;
2397 int pair_ret;
2398 char *login, *pass;
2399 const char *hostinfo;
2400 size_t i = 0;
2401
2402
2403 /* First check for every service if connection_delay time has already
2404 * passed since its last connection and move them back to 'services_active'
2405 * list if it has.
2406 */
2407 gettimeofday(&now, NULL);
2408 for (li = SG->services_wait.begin(); li != SG->services_wait.end(); li++) {
2409 if (timeval_msec_subtract(now, (*li)->last)
2410 >= (long long)(*li)->connection_delay) {
2411 li = SG->popServiceFromList(*li, &SG->services_wait);
2412 }
2413 }
2414
2415 if (SG->last_accessed == SG->services_active.end()) {
2416 li = SG->services_active.begin();
2417 } else {
2418 li = SG->last_accessed++;
2419 }
2420
2421
2422
2423 while (SG->active_connections < SG->connection_limit
2424 && SG->services_finished.size() != SG->total_services
2425 && SG->services_active.size() != 0) {
2426
2427 serv = *li;
2428 hostinfo = serv->HostInfo();
2429
2430 if (serv->timedOut(NULL)) {
2431 serv->end.reason = Strndup(SERVICE_TIMEDOUT, sizeof(SERVICE_TIMEDOUT));
2432 SG->pushServiceToList(serv, &SG->services_finished);
2433 if (o.verbose)
2434 log_write(LOG_STDOUT, "%s finished.\n", hostinfo);
2435 goto next;
2436 }
2437
2438 /*
2439 * If the service's last connection was earlier than 'connection_delay'
2440 * milliseconds ago, then temporarily move service to 'services_wait' list
2441 */
2442 gettimeofday(&now, NULL);
2443 if (timeval_msec_subtract(now, serv->last)
2444 < (long long)serv->connection_delay) {
2445 li = SG->pushServiceToList(serv, &SG->services_wait);
2446 goto next;
2447 }
2448
2449
2450 /* If the service's active connections surpass its imposed connection limit
2451 * then don't initiate any more connections for it and also move service in
2452 * the services_full list so that it won't be reaccessed in this loop.
2453 */
2454 if (serv->active_connections >= serv->ideal_parallelism) {
2455 li = SG->pushServiceToList(serv, &SG->services_full);
2456 goto next;
2457 }
2458
2459
2460 /*
2461 * To mark a service as completely finished, first make sure:
2462 * a) that the username list has finished being iterated through once
2463 * b) that the mirror pair pool, which holds temporary login pairs which
2464 * are currently being used, is empty
2465 * c) that no pending connections are left
2466 * d) that the service hasn't already finished
2467 */
2468 if (serv->loginlist_fini && serv->isMirrorPoolEmpty()
2469 && !serv->getListFinished()) {
2470 if (!serv->active_connections) {
2471 li = SG->pushServiceToList(serv, &SG->services_finished);
2472 if (o.verbose)
2473 log_write(LOG_STDOUT, "%s finished.\n", hostinfo);
2474 goto next;
2475 } else {
2476 li = SG->pushServiceToList(serv, &SG->services_finishing);
2477 goto next;
2478 }
2479 }
2480
2481 /*
2482 * If the username list iteration has finished, then don't initiate another
2483 * connection until our pair_pool has at least one element to grab another
2484 * pair from.
2485 */
2486 if (serv->loginlist_fini && serv->isPoolEmpty()
2487 && !serv->isMirrorPoolEmpty()) {
2488 li = SG->pushServiceToList(serv, &SG->services_pairfini);
2489 goto next;
2490 }
2491
2492 if ((pair_ret = serv->getNextPair(&login, &pass)) == -1)
2493 goto next;
2494
2495
2496 /*
2497 * If service belongs to list linear, then we have to wait until all others have
2498 * first iterated.
2499 */
2500 if ((serv->getLinearState() != LINEAR_INIT)
2501 && (serv->getLinearState() == LINEAR_ACTIVE || SG->checkLinearPending() == true)) {
2502 goto next;
2503 }
2504
2505 /* Schedule 1 connection for this service */
2506 con = new Connection(serv);
2507 SG->connections_total++;
2508
2509 if (o.stealthy_linear) {
2510 serv->setLinearState(LINEAR_ACTIVE);
2511 }
2512
2513 if (pair_ret == 1)
2514 con->from_pool = true;
2515 con->user = login;
2516 con->pass = pass;
2517
2518 if ((con->niod = nsock_iod_new(nsp, serv)) == NULL) {
2519 fatal("Failed to allocate Nsock I/O descriptor in %s()", __func__);
2520 }
2521
2522 if (o.debugging > 8)
2523 log_write(LOG_STDOUT, "%s (EID %li) Initiating new Connection\n", hostinfo, nsock_iod_id(con->niod));
2524
2525 gettimeofday(&now, NULL);
2526 serv->last = now;
2527 serv->connections.push_back(con);
2528 serv->active_connections++;
2529 SG->active_connections++;
2530
2531 serv->target->TargetSockAddr(&ss, &ss_len);
2532 if (serv->proto == IPPROTO_TCP) {
2533 if (!serv->ssl) {
2534 if (o.proxychain && o.socks4a) {
2535 if (!serv->target->targetname)
2536 fatal("Socks4a requires a hostname. Use socks4 for IPv4.");
2537 nsock_connect_tcp_socks4a(nsp, con->niod, ncrack_connect_handler,
2538 DEFAULT_CONNECT_TIMEOUT, con, serv->target->targetname,
2539 serv->portno);
2540 } else {
2541 nsock_connect_tcp(nsp, con->niod, ncrack_connect_handler,
2542 DEFAULT_CONNECT_TIMEOUT, con,
2543 (struct sockaddr *)&ss, ss_len,
2544 serv->portno);
2545 }
2546 } else {
2547 nsock_connect_ssl(nsp, con->niod, ncrack_connect_handler,
2548 DEFAULT_CONNECT_SSL_TIMEOUT, con,
2549 (struct sockaddr *) &ss, ss_len, serv->proto,
2550 serv->portno, con->ssl_session);
2551 }
2552 } else {
2553 assert(serv->proto == IPPROTO_UDP);
2554 nsock_connect_udp(nsp, con->niod, ncrack_connect_handler,
2555 serv, (struct sockaddr *) &ss, ss_len,
2556 serv->portno);
2557 }
2558
2559 next:
2560
2561 /*
2562 * this will take care of the case where the state of the services_active list
2563 * has been modified in the meantime by any pushToList or popFromList without
2564 * saving the state to the current li iterator thus showing to a non-valid
2565 * service
2566 */
2567 if (SG->prev_modified != li) {
2568 li = SG->services_active.end();
2569 }
2570
2571 SG->last_accessed = li;
2572 if (li == SG->services_active.end() || ++li == SG->services_active.end()) {
2573 li = SG->services_active.begin();
2574 }
2575
2576
2577 i++;
2578 if (o.stealthy_linear && i == SG->services_all.size())
2579 return;
2580
2581 }
2582
2583 return;
2584 }
2585
2586
2587
2588 static int
ncrack(ServiceGroup * SG)2589 ncrack(ServiceGroup *SG)
2590 {
2591 /* nsock variables */
2592 struct timeval now;
2593 enum nsock_loopstatus loopret;
2594 list <Service *>::iterator li;
2595 nsock_pool nsp;
2596 int nsock_timeout = 3000;
2597 int err;
2598
2599 /* create nsock p00l */
2600 if (!(nsp = nsock_pool_new(SG)))
2601 fatal("Can't create nsock pool.");
2602
2603 if (o.proxychain) {
2604 if (nsock_pool_set_proxychain(nsp, o.proxychain) == -1)
2605 fatal("Unable to set proxychain for nsock pool");
2606 }
2607
2608 gettimeofday(&now, NULL);
2609 nsock_set_loglevel(o.nsock_loglevel);
2610
2611 #if HAVE_OPENSSL
2612 /* We don't care about connection security, so cast Haste */
2613 nsock_pool_ssl_init(nsp, NSOCK_SSL_MAX_SPEED);
2614 #endif
2615
2616 SG->findMinDelay();
2617 /* We have to set the nsock_loop timeout to the minimum of the connection
2618 * delay, since we have to check every that time period for potential new
2619 * connection initiations. If the minimum connection delay is 0 however, we
2620 * don't need to do it, since that would make nsock_loop return immediately
2621 * and consume a lot of CPU.
2622 */
2623 if (SG->min_connection_delay != 0)
2624 nsock_timeout = SG->min_connection_delay;
2625
2626 /* Initiate time-out clocks */
2627 startTimeOutClocks(SG);
2628
2629 /* initiate all authentication rate meters */
2630 SG->auth_rate_meter.start();
2631 for (li = SG->services_all.begin(); li != SG->services_all.end(); li++)
2632 (*li)->auth_rate_meter.start();
2633
2634 /*
2635 * Since nsock can delay between each event due to the targets being really
2636 * slow, we need a way to make sure that we always poll for interactive user
2637 * input regardless of the above case. Thus we schedule a special timer event
2638 * that happens every KEYPRESSED_INTERVAL milliseconds and which reschedules
2639 * itself every time its handler is called.
2640 */
2641 nsock_timer_create(nsp, status_timer_handler, KEYPRESSED_INTERVAL, NULL);
2642
2643 /*
2644 * We do the same for checking pending signals every SIGNAL_CHECK_INTERVAL
2645 */
2646 nsock_timer_create(nsp, signal_timer_handler, SIGNAL_CHECK_INTERVAL, NULL);
2647
2648 ncrack_probes(nsp, SG);
2649
2650 /* nsock loop */
2651 do {
2652
2653 loopret = nsock_loop(nsp, nsock_timeout);
2654
2655 if (loopret == NSOCK_LOOP_ERROR) {
2656 err = nsock_pool_get_error(nsp);
2657 fatal("Unexpected nsock_loop error. Error code %d (%s)",
2658 err, strerror(err));
2659 }
2660
2661 ncrack_probes(nsp, SG);
2662
2663 } while (SG->services_finished.size() != SG->total_services);
2664
2665 nsock_pool_delete(nsp);
2666
2667 if (o.debugging > 4)
2668 log_write(LOG_STDOUT, "nsock_loop returned %d\n", loopret);
2669
2670 return 0;
2671 }
2672
2673