--- hydra.c.orig 2004-02-05 13:15:18.000000000 -0600 +++ hydra.c 2004-02-06 11:53:13.000000000 -0600 @@ -78,7 +78,7 @@ static pid_t addr_pids[MAXSERVERS]; // moved for restore feature -int tasks = 1, servers = SERVERS, exit_found = 0; +int scans = 0, tasks = 1, servers = SERVERS, exit_found = 0; unsigned char options = 0; int try_password_same_as_login = 0, try_null_password = 0, restore = 0; char *colonfile = NULL, *outfile_ptr = NULL, *infile_ptr = NULL; @@ -337,6 +337,7 @@ } } } + free(buf); rewind(fp); size++; extra = size; @@ -584,6 +585,9 @@ tasks = 1; } i = 1; + if (miscptr == NULL) { + bail("You must supply a testing method via the -m option.\n\tValid methods are: L, LH, D, DH, B, BH.\n\tSee README for more information.\n"); + } } #endif if (strcmp(service, "pcnfs") == 0) { @@ -795,6 +799,7 @@ proxy_authentication = malloc(strlen(tmpptr) * 2); strcpy(proxy_authentication, tmpptr); hydra_tobase64(proxy_authentication); + free(proxy_authentication); } } @@ -911,7 +916,6 @@ if (rc == 'N') { write(addr_socketpairs[sID][0], "N", 1); } else if (rc == 'Q') { - write(addr_socketpairs[sID][0], "Q", 1); process_restore = 0; if (dont_unlink == 0) unlink(RESTOREFILE); @@ -1043,7 +1047,7 @@ pids[as] = 0; } (void) wait3(NULL, WNOHANG, NULL); - write(addr_socketpairs[sID][0], "N", 1); + write(addr_socketpairs[sID][0], "Q", 1); elapsed2 = elapsed = time(NULL); printf("[DATA] %d passwords found on %s, %lu attempts made in %02lu:%02luh\n", found, t_ipaddr_str, sent, (elapsed - starttime) / 3600, ((elapsed - starttime) % 3600) / 60 + 1); @@ -1062,15 +1066,17 @@ sent += countpass - b; b = 0; } else { - rc = 'X'; - b = countpass; - sent = todo; - done = 1; + //rc = 'X'; + //b = countpass; + //sent = todo; + //done = 1; } if (verbose) printf("The password for \"%s\" was found, skipping to next login (pairs already sent to childrens will still be tried)\n", cracked_login); } } + + free(cracked_login); } if (rc == 'N' || rc == 'F') { done = 1; @@ -1163,14 +1169,15 @@ } else i++; } - if (i >= tasks || killed >= tasks) { + //if (i >= tasks || gkilled >= tasks) { + if (i >= tasks) { printf("All childrens are dead.\n"); if (process_restore == 1) { dont_unlink = 1; hydra_restore_write(); } fprintf(stderr, "Server (%s) scan complete\n", t_ipaddr_str); - write(addr_socketpairs[sID][0], "N", 1); + write(addr_socketpairs[sID][0], "Q", 1); elapsed = time(NULL); printf("[DATA] %d passwords found on %s, %lu attempts made in %02lu:%02luh\n", found, t_ipaddr_str, sent, (elapsed - starttime) / 3600, ((elapsed - starttime) % 3600) / 60 + 1); @@ -1215,7 +1222,7 @@ t_pass_ptr = t_login_ptr; while (*t_pass_ptr != '\0' && *t_pass_ptr != ':') t_pass_ptr++; - if (*t_pass_ptr == ':') { + if (*t_pass_ptr == ':' || *t_pass_ptr == '\0') { *t_pass_ptr = '\0'; t_pass_ptr++; } else { @@ -1273,7 +1280,7 @@ kill(pids[i], SIGTERM); fprintf(stderr, "Server (%s) scan complete\n", t_ipaddr_str); - write(addr_socketpairs[sID][0], "N", 1); + write(addr_socketpairs[sID][0], "Q", 1); elapsed = time(NULL); printf("[DATA] %d passwords found on %s, %lu attempts made in %02lu:%02luh\n", found, t_ipaddr_str, sent, (elapsed - starttime) / 3600, ((elapsed - starttime) % 3600) / 60 + 1); for (i = 0; i < tasks; i++) { @@ -1306,22 +1313,15 @@ } /* feed the children with ip address data - be a good mom */ - alive = servers; - while (done < countservers || alive > 0) { + + scans = 0, done = 0; + while (done < countinfile) { for (a = 0; a < servers; a++) { - i = 0; if (read(addr_socketpairs[a][1], &rc, 1) > 0) { read(addr_socketpairs[a][1], &rc, 1); - if (rc == 'N') { - if (done >= countservers) { - write(addr_socketpairs[a][1], "Q", 1); - addr_pids[a] = 0; - } else { - if (done > 0) { - while (*ipaddr_ptr != '\0') - ipaddr_ptr++; - ipaddr_ptr++; - } + if ((rc == 'N') && (scans < countinfile)) { + scans++; + /* resolve target */ if (inet_pton(AF_INET, ipaddr_ptr, &in) <= 0) { if ((target = gethostbyname(ipaddr_ptr)) != NULL) @@ -1335,26 +1335,28 @@ fprintf(stderr, "Error: invalid server address: %s\n", ipaddr_ptr); write(addr_socketpairs[a][1], "N", 1); } else { - done++; write(addr_socketpairs[a][1], "Y", 1); write(addr_socketpairs[a][1], &ip, sizeof(ip)); } + + if (scans < countinfile) { + while (*ipaddr_ptr != '\0') ipaddr_ptr++; + ipaddr_ptr++; } + } else if (rc == 'N') { + write(addr_socketpairs[a][1], "Q", 1); } else if (rc == 'Q') { done++; + if (scans < countinfile) + write(addr_socketpairs[a][1], "N", 1); + else { write(addr_socketpairs[a][1], "Q", 1); addr_pids[a] = 0; } - } else if (errno != EAGAIN) - i++; } - if (i == servers) { - done = servers; - alive = 0; } } - for (a = 0; a < servers; a++) - write(addr_socketpairs[a][1], "Q", 1); + } /* yeah we did it */ printf("%s finished at %s\n", PROGRAM, hydra_build_time()); --- hydra-smbnt.c.orig 2004-02-05 15:59:30.000000000 -0600 +++ hydra-smbnt.c 2004-02-05 18:05:27.000000000 -0600 @@ -19,11 +19,38 @@ [Copyright (C) Patrik Karlsson 2001] This code allows Hydra to directly test NTLM hashes against - a Windows host via '-m HASH'. This may be useful for an - auditor who has aquired a sam._ or pwdump file and would - like to quickly determine which are valid entries. This - module can also be used to test SMB passwords against devices - that do not allow clear text LanMan passwords. + a Windows. This may be useful for an auditor who has aquired + a sam._ or pwdump file and would like to quickly determine + which are valid entries. This module can also be used to test + SMB passwords against devices that do not allow clear text + LanMan passwords. + + The "-m 'METHOD'" option is required for this module. The + following are valid methods: L, LH, D, DH, B and BH + (in quotes). + + L == Check local account. + D == Check credentials against this hosts primary + domain controller via this host. + B == Check both. This leaves the workgroup field set + blank and then attempts to check the credentials + against the host. If the account does not exist + locally on the host being tested, that host then + queries its domain controller. + H == Use a NTLM hash rather than a password. + + Be careful of mass domain account lockout with this. For + example, assume you are checking several accounts against + many domain workstations. If you are not using the 'L' + options and these accounts do not exist locally on the + workstations, each workstation will in turn check their + respective domain controller. This could cause a bunch of + lockouts. Of course, it'd look like the workstations, not + you, were doing it. ;) + + **FYI, this code does not appear to currently work against + Windows XP hosts which are NOT a member of a domain. Will + look into this... See http://www.foofus.net/m0j0/passhash.html for further examples. @@ -33,6 +60,8 @@ extern char *HYDRA_EXIT; char challenge[8]; +u_char workgroup[16]; +int hashFlag, accntFlag; static u_char Get7Bits(u_char * input, int startBit) @@ -98,7 +127,7 @@ int HexValue; /* Use NTLM Hash instead of password */ - if ((miscptr != NULL) && (strcmp(miscptr, "HASH") == 0)) { + if (hashFlag) { // 1000:D42E35E1A1E4C22BD32E2170E4857C20:5E20780DD45857A68402938C7629D3B2::: p = pass; while ((*p != '\0') && (i < 2)) { @@ -109,6 +138,7 @@ if (*p == '\0') { fprintf(stderr, "Error reading PWDUMP file.\n"); + hydra_child_exit(); exit(1); } @@ -123,6 +153,7 @@ if (!(((HexChar >= 0x30) && (HexChar <= 0x39)) || /* 0 - 9 */ ((HexChar >= 0x61) && (HexChar <= 0x66)))) { /* a - f */ //fprintf(stderr, "Error invalid char (%c) for hash.\n", HexChar); + //hydra_child_exit(); //exit(1); HexChar = 0x30; } @@ -243,6 +274,14 @@ // retrieve the challenge memcpy(challenge, rbuf + 73, sizeof(challenge)); + // find the primary domain/workgroup name + memset(workgroup, 0, 16); + int i = 0; + while ((rbuf[81+i*2] != 0) && (i<16)) { + workgroup[i] = rbuf[81+i*2]; + i++; + } + return 2; } @@ -282,7 +321,6 @@ u_char buf[512]; u_char *NTLMhash; u_char LMhash[24]; - u_char workgroup[16]; u_char rbuf[400]; int userlen; @@ -290,9 +328,11 @@ memset(NTLMhash, 0, 24); memset(LMhash, 0, 24); - memset(workgroup, 0, 16); memset(rbuf, 0, 400); + if (accntFlag == 0) { strcpy(workgroup, "sqlc25.carrierzone.com"); } + else if (accntFlag == 2) { memset(workgroup, 0, 16); } + HashNTLM(&NTLMhash, pass, challenge, miscptr); memset(buf, 0, 512); @@ -362,6 +402,29 @@ int run = 1, next_run, sock = -1; int myport = PORT_SMB, mysslport = PORT_SMB_SSL; + if ((strcmp(miscptr, "L") == 0)) { + accntFlag = 0; + hashFlag = 0; + } else if ((strcmp(miscptr, "LH") == 0)) { + accntFlag = 0; + hashFlag = 1; + } else if ((strcmp(miscptr, "D") == 0)) { + accntFlag = 1; + hashFlag = 0; + } else if ((strcmp(miscptr, "DH") == 0)) { + accntFlag = 1; + hashFlag = 1; + } else if ((strcmp(miscptr, "B") == 0)) { + accntFlag = 2; + hashFlag = 0; + } else if ((strcmp(miscptr, "BH") == 0)) { + accntFlag = 2; + hashFlag = 1; + } else { + printf("SMBNT Module requires -m METHOD\n"); + hydra_child_exit(); + } + hydra_register_socket(sp); if (memcmp(hydra_get_next_pair(), &HYDRA_EXIT, sizeof(HYDRA_EXIT)) == 0) return; --- README.orig 2004-02-05 18:09:04.000000000 -0600 +++ README 2004-02-05 17:57:29.000000000 -0600 @@ -45,10 +45,12 @@ service module optional parameter ============== ================================================= ldap specifies the DN (OPTIONAL - you can also specify the DN as login) -smbnt value "HASH" interprets passwords as NTLM hashes (OPTIONAL) cisco-enable specified the logon password for the cisco device (REQUIRED) www / http specified the page to authentication at (REQUIRED) ssl / https specified the page to authentication at (REQUIRED) +smbnt value [L,LH,D,DH,B,BH] (REQUIRED) + (L) Check local accounts, (D) Domain Accounts, (B) Either + (H) interpret passwords as NTLM hashes An example for how to use this with the www module to hand over the web page to authenticate to: @@ -56,7 +58,7 @@ or hydra -m /members/ -l jdoe -P /tmp/passlist www.attack.com http or - hydra -m HASH -l administrator -P sam.dump nt.microsoft.com smbnt + hydra -m 'LH' -l administrator -P sam.dump nt.microsoft.com smbnt RESTORING AN ABORTED/CRASHED SESSION