--- 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
