Index: john-1.7.0.2-patched/src/inc.c
===================================================================
--- john-1.7.0.2-patched/src/inc.c	(revision 700)
+++ john-1.7.0.2-patched/src/inc.c	(revision 713)
@@ -23,6 +23,7 @@
 #include "cracker.h"
 
 extern struct fmt_main fmt_LM;
+extern struct fmt_main fmt_NETLM;
 
 typedef char (*char2_table)
 	[CHARSET_SIZE + 1][CHARSET_SIZE + 1];
@@ -377,6 +378,8 @@
 	if (!mode) {
 		if (db->format == &fmt_LM)
 			mode = "LanMan";
+		else if (db->format == &fmt_NETLM)
+			mode = "LanMan";
 		else
 			mode = "All";
 	}
Index: john-1.7.0.2-patched/src/NETLM_fmt.c
===================================================================
--- john-1.7.0.2-patched/src/NETLM_fmt.c	(revision 0)
+++ john-1.7.0.2-patched/src/NETLM_fmt.c	(revision 713)
@@ -0,0 +1,219 @@
+/*
+ * NETLM_fmt.c -- LM Challenge/Response 
+ * Copyright (c) 2007 JoMo-Kun <jmk@foofus.net>
+ *
+ * This file is based on code from John the Ripper,
+ *   Copyright (c) 1996-99 by Solar Designer
+ * Additionally, NT_fmt.c
+ *   Copyright (c) 2001 Olle Segerdahl <olle@nxs.se>
+ *
+ */
+
+#include <stdio.h>
+#include <string.h>
+
+#include "common.h"
+#include "formats.h"
+
+#include <openssl/des.h>
+
+#ifndef uchar
+#define uchar unsigned char
+#endif
+
+/*preprocessor constants that John The Ripper likes*/
+#define FORMAT_LABEL         "netlm"
+#define FORMAT_NAME          "LM DES"
+#define ALGORITHM_NAME       "netlm"
+#define BENCHMARK_COMMENT    ""
+#define BENCHMARK_LENGTH     -1
+#define PLAINTEXT_LENGTH     14
+#define BINARY_SIZE          24
+#define SALT_SIZE            8
+#define CIPHERTEXT_LENGTH    48
+#define MIN_KEYS_PER_CRYPT   1
+#define MAX_KEYS_PER_CRYPT   1
+
+/* Some passwords to test the methods for correct operation (or NULL for no
+ * self test, and no benchmark), terminated with a NULL ciphertext. */
+static struct fmt_tests tests[] = {
+  {"$NETLM$1122334455667788$6E1EC36D3417CE9E09A4424309F116C4C991948DAEB4ADAD", "G3rg3P00!"},
+  {"$NETLM$1122334455667788$16A7FDFE0CA109B937BFFB041F0E5B2D8B94A97D3FCA1A18", "HiyaGerge"},
+  {"$NETLM$1122334455667788$B3A1B87DBBD4DF3CFA296198DD390C2F4E2E93C5C07B1D8B", "MedusaFgDump12"},
+  {"$NETLM$1122334455667788$0836F085B124F33895875FB1951905DD2F85252CC731BB25", "cory21"},
+  {NULL}
+};
+
+uchar saved_plain[PLAINTEXT_LENGTH + 1];
+uchar challenge[SALT_SIZE + 1];
+uchar output[BINARY_SIZE + 1];
+
+/* Checks if an ASCII ciphertext is valid for this format. Returns zero for
+ * invalid ciphertexts, or a number of parts the ciphertext should be split
+ * into (up to 9, will usually be 1). */
+static int netlm_valid(char *ciphertext)
+{
+  char *pos;
+
+  if (strncmp(ciphertext, "$NETLM$", 5)!=0) return 0;
+  if (ciphertext[23] != '$') return 0;
+
+  for (pos = &ciphertext[24]; atoi16[ARCH_INDEX(*pos)] != 0x7F; pos++);
+    if (!*pos && pos - ciphertext - 24 == CIPHERTEXT_LENGTH)
+      return 1;
+    else
+      return 0;
+}
+
+static void *netlm_get_binary(char *ciphertext)
+{
+  static uchar binary[BINARY_SIZE];
+  int i;
+
+  ciphertext+=24;
+  for (i=0; i<BINARY_SIZE; i++)
+  {
+    binary[i] = (atoi16[ARCH_INDEX(ciphertext[i*2])])<<4;
+    binary[i] |= (atoi16[ARCH_INDEX(ciphertext[i*2+1])]);
+  }
+
+  return binary;
+}
+
+void setup_des_key(unsigned char key_56[], des_key_schedule *ks)
+{
+  des_cblock key;
+
+  key[0] = key_56[0];
+  key[1] = (key_56[0] << 7) | (key_56[1] >> 1);
+  key[2] = (key_56[1] << 6) | (key_56[2] >> 2);
+  key[3] = (key_56[2] << 5) | (key_56[3] >> 3);
+  key[4] = (key_56[3] << 4) | (key_56[4] >> 4);
+  key[5] = (key_56[4] << 3) | (key_56[5] >> 5);
+  key[6] = (key_56[5] << 2) | (key_56[6] >> 6);
+  key[7] = (key_56[6] << 1);
+
+  des_set_key(&key, *ks);
+}
+
+static void netlm_crypt_all(int count)
+{
+  static unsigned char magic[] = {0x4b, 0x47, 0x53, 0x21, 0x40, 0x23, 0x24, 0x25};
+  des_key_schedule ks;
+  unsigned char password[14 + 1];
+  unsigned char lm[21];
+  int i;
+
+  memset(password, 0, 14 + 1);
+  memset(lm, 0, 21);
+  memset(output, 0, 24);
+
+  /* Upper-case password */
+  strncpy(password, saved_plain, 14);
+  for(i=0; i<14; i++)
+    if ((password[i] >= 'a') && (password[i] <= 'z')) password[i] ^= 0x20;
+
+  /* Generate 16-byte LM hash */
+  setup_des_key(password, &ks);
+  des_ecb_encrypt((des_cblock*)magic, (des_cblock*)lm, ks, DES_ENCRYPT);
+  setup_des_key(&password[7], &ks);
+  des_ecb_encrypt((des_cblock*)magic, (des_cblock*)&lm[8], ks, DES_ENCRYPT);
+
+  /* 
+    NULL-pad 16-byte LM hash to 21-bytes
+    Split resultant value into three 7-byte thirds
+    DES-encrypt challenge using each third as a key
+    Concatenate three 8-byte resulting values to form 24-byte LM response
+  */ 
+  setup_des_key(lm, &ks);
+  des_ecb_encrypt((des_cblock*)challenge, (des_cblock*)output, ks, DES_ENCRYPT);
+  setup_des_key(&lm[7], &ks);
+  des_ecb_encrypt((des_cblock*)challenge, (des_cblock*)&output[8], ks, DES_ENCRYPT);
+  setup_des_key(&lm[14], &ks);
+  des_ecb_encrypt((des_cblock*)challenge, (des_cblock*)&output[16], ks, DES_ENCRYPT);
+}
+
+static int netlm_cmp_all(void *binary, int count)
+{
+  return !memcmp(output, binary, BINARY_SIZE);
+}
+
+static int netlm_cmp_one(void *binary, int index)
+{
+  return !memcmp(output, binary, BINARY_SIZE);
+}
+
+static int netlm_cmp_exact(char *source, int index)
+{
+  return !memcmp(output, netlm_get_binary(source), BINARY_SIZE);
+}
+
+static void *netlm_get_salt(char *ciphertext)
+{
+  static unsigned char binary_salt[SALT_SIZE];
+  int i;
+
+  ciphertext += 7;
+  for (i = 0; i < SALT_SIZE; ++i)
+    binary_salt[i] = (atoi16[ARCH_INDEX(ciphertext[i*2])] << 4) + atoi16[ARCH_INDEX(ciphertext[i*2+1])];
+
+  return (void*)binary_salt;
+}
+
+static void netlm_set_salt(void *salt)
+{
+  memcpy(challenge, salt, SALT_SIZE);
+}
+
+static void netlm_set_key(char *key, int index)
+{
+  strncpy(saved_plain, key, PLAINTEXT_LENGTH);
+  saved_plain[PLAINTEXT_LENGTH] = 0;
+}
+
+static char *netlm_get_key(int index)
+{
+  return saved_plain;
+}
+
+struct fmt_main fmt_NETLM = {
+  {
+    FORMAT_LABEL,
+    FORMAT_NAME,
+    ALGORITHM_NAME,
+    BENCHMARK_COMMENT,
+    BENCHMARK_LENGTH,
+    PLAINTEXT_LENGTH,
+    BINARY_SIZE,
+    SALT_SIZE,
+    MIN_KEYS_PER_CRYPT,
+    MAX_KEYS_PER_CRYPT,
+    FMT_8_BIT | FMT_BS | FMT_SPLIT_UNIFIES_CASE,
+    tests
+  }, {
+    fmt_default_init,
+    netlm_valid,
+    fmt_default_split,
+    netlm_get_binary,
+    netlm_get_salt,
+    {
+      fmt_default_binary_hash,
+      fmt_default_binary_hash,
+      fmt_default_binary_hash
+    },
+    fmt_default_salt_hash,
+    netlm_set_salt,
+    netlm_set_key,
+    netlm_get_key,
+    fmt_default_clear_keys,
+    netlm_crypt_all,
+    {
+      fmt_default_get_hash,
+      fmt_default_get_hash,
+      fmt_default_get_hash
+    },
+    netlm_cmp_all,
+    netlm_cmp_one,
+    netlm_cmp_exact
+  }
+};
Index: john-1.7.0.2-patched/src/NETNTLM_fmt.c
===================================================================
--- john-1.7.0.2-patched/src/NETNTLM_fmt.c	(revision 0)
+++ john-1.7.0.2-patched/src/NETNTLM_fmt.c	(revision 713)
@@ -0,0 +1,213 @@
+/*
+ * NETNTLM_fmt.c -- NTLM Challenge/Response 
+ * Copyright (c) 2007 JoMo-Kun <jmk@foofus.net>
+ *
+ * This file is based on code from John the Ripper,
+ *   Copyright (c) 1996-99 by Solar Designer
+ * Additionally, NT_fmt.c
+ *   Copyright (c) 2001 Olle Segerdahl <olle@nxs.se>
+ *
+ */
+
+#include <stdio.h>
+#include <string.h>
+
+#include "common.h"
+#include "formats.h"
+
+#include <openssl/des.h>
+
+#ifndef uchar
+#define uchar unsigned char
+#endif
+
+/*preprocessor constants that John The Ripper likes*/
+#define FORMAT_LABEL         "netntlm"
+#define FORMAT_NAME          "NT MD4 DES"
+#define ALGORITHM_NAME       "netntlm"
+#define BENCHMARK_COMMENT    ""
+#define BENCHMARK_LENGTH     -1
+#define PLAINTEXT_LENGTH     54 /* ?127? */
+#define BINARY_SIZE          24
+#define SALT_SIZE            8
+#define CIPHERTEXT_LENGTH    48
+#define MIN_KEYS_PER_CRYPT   1
+#define MAX_KEYS_PER_CRYPT   1
+
+/* Some passwords to test the methods for correct operation (or NULL for no
+ * self test, and no benchmark), terminated with a NULL ciphertext. */
+static struct fmt_tests tests[] = {
+  {"$NETNTLM$1122334455667788$BFCCAF26128EC95F9999C9792F49434267A1D9B0EF89BFFB", "g3rg3g3rg3g3rg3"},
+  {"$NETNTLM$1122334455667788$E463FAA5D868ECE20CAE622474A2F440A652D642156AF863", "M1xedC4se%^&*@)##(blahblah!@#"},
+  {"$NETNTLM$1122334455667788$35B62750E1B9B3205C50D6BA351092C12A1B9B3CDC65D44A", "FooBarGerg"},
+  {"$NETNTLM$1122334455667788$A4765EBFE83D345A7CB1660B8899251905164029F8086DDE", "visit www.foofus.net"},
+  {"$NETNTLM$1122334455667788$B2B2220790F40C88BCFF347C652F67A7C4A70D3BEBD70233", "cory21"},
+  {NULL}
+};
+
+uchar saved_plain[PLAINTEXT_LENGTH + 1];
+uchar challenge[SALT_SIZE + 1];
+uchar output[BINARY_SIZE + 1];
+
+extern void E_md4hash(uchar *passwd, uchar *p16);
+extern void setup_des_key(unsigned char key_56[], des_key_schedule *ks);
+
+/* Checks if an ASCII ciphertext is valid for this format. Returns zero for
+ * invalid ciphertexts, or a number of parts the ciphertext should be split
+ * into (up to 9, will usually be 1). */
+static int netntlm_valid(char *ciphertext)
+{
+  char *pos;
+
+  if (strncmp(ciphertext, "$NETNTLM$", 9)!=0) return 0;
+  if (ciphertext[25] != '$') return 0;
+
+  for (pos = &ciphertext[26]; atoi16[ARCH_INDEX(*pos)] != 0x7F; pos++);
+    if (!*pos && pos - ciphertext - 26 == CIPHERTEXT_LENGTH)
+      return 1;
+    else
+      return 0;
+}
+
+static void *netntlm_get_binary(char *ciphertext)
+{
+  static uchar binary[BINARY_SIZE];
+  int i;
+
+  ciphertext+=26;
+  for (i=0; i<BINARY_SIZE; i++)
+  {
+    binary[i] = (atoi16[ARCH_INDEX(ciphertext[i*2])])<<4;
+    binary[i] |= (atoi16[ARCH_INDEX(ciphertext[i*2+1])]);
+  }
+
+  return binary;
+}
+
+/*
+void setup_des_key(unsigned char key_56[], des_key_schedule *ks)
+{
+  des_cblock key;
+
+  key[0] = key_56[0];
+  key[1] = (key_56[0] << 7) | (key_56[1] >> 1);
+  key[2] = (key_56[1] << 6) | (key_56[2] >> 2);
+  key[3] = (key_56[2] << 5) | (key_56[3] >> 3);
+  key[4] = (key_56[3] << 4) | (key_56[4] >> 4);
+  key[5] = (key_56[4] << 3) | (key_56[5] >> 5);
+  key[6] = (key_56[5] << 2) | (key_56[6] >> 6);
+  key[7] = (key_56[6] << 1);
+
+  des_set_key(&key, *ks);
+}
+*/
+
+static void netntlm_crypt_all(int count)
+{
+  des_key_schedule ks;
+  unsigned char ntlm[21];
+
+  memset(output, 0, 24);
+  memset(ntlm, 0, 21);
+
+  /* Generate 16-byte NTLM hash */
+  E_md4hash(saved_plain, ntlm);
+  
+  /* Hash is NULL padded to 21-bytes */
+  ntlm[16] = ntlm[17] = ntlm[18] = ntlm[19] = ntlm[20] = 0;
+  
+  /* Split into three 7-byte segments for use as DES keys
+     Use each key to DES encrypt challenge 
+     Concatenate output to for 24-byte NTLM response */
+  setup_des_key(ntlm, &ks);
+  des_ecb_encrypt((des_cblock*)challenge, (des_cblock*)output, ks, DES_ENCRYPT);
+  setup_des_key(&ntlm[7], &ks);
+  des_ecb_encrypt((des_cblock*)challenge, (des_cblock*)&output[8], ks, DES_ENCRYPT);
+  setup_des_key(&ntlm[14], &ks);
+  des_ecb_encrypt((des_cblock*)challenge, (des_cblock*)&output[16], ks, DES_ENCRYPT);
+}
+
+static int netntlm_cmp_all(void *binary, int count)
+{
+  return !memcmp(output, binary, BINARY_SIZE);
+}
+
+static int netntlm_cmp_one(void *binary, int index)
+{
+  return !memcmp(output, binary, BINARY_SIZE);
+}
+
+static int netntlm_cmp_exact(char *source, int index)
+{
+  return !memcmp(output, netntlm_get_binary(source), BINARY_SIZE);
+}
+
+static void *netntlm_get_salt(char *ciphertext)
+{
+  static unsigned char binary_salt[SALT_SIZE];
+  int i;
+
+  ciphertext += 9;
+  for (i = 0; i < SALT_SIZE; ++i)
+    binary_salt[i] = (atoi16[ARCH_INDEX(ciphertext[i*2])] << 4) + atoi16[ARCH_INDEX(ciphertext[i*2+1])];
+
+  return (void*)binary_salt;
+}
+
+static void netntlm_set_salt(void *salt)
+{
+  memcpy(challenge, salt, SALT_SIZE);
+}
+
+static void netntlm_set_key(char *key, int index)
+{
+  strncpy(saved_plain, key, PLAINTEXT_LENGTH);
+  saved_plain[PLAINTEXT_LENGTH] = 0;
+}
+
+static char *netntlm_get_key(int index)
+{
+  return saved_plain;
+}
+
+struct fmt_main fmt_NETNTLM = {
+  {
+    FORMAT_LABEL,
+    FORMAT_NAME,
+    ALGORITHM_NAME,
+    BENCHMARK_COMMENT,
+    BENCHMARK_LENGTH,
+    PLAINTEXT_LENGTH,
+    BINARY_SIZE,
+    SALT_SIZE,
+    MIN_KEYS_PER_CRYPT,
+    MAX_KEYS_PER_CRYPT,
+    FMT_CASE | FMT_8_BIT,
+    tests
+  }, {
+    fmt_default_init,
+    netntlm_valid,
+    fmt_default_split,
+    netntlm_get_binary,
+    netntlm_get_salt,
+    {
+      fmt_default_binary_hash,
+      fmt_default_binary_hash,
+      fmt_default_binary_hash
+    },
+    fmt_default_salt_hash,
+    netntlm_set_salt,
+    netntlm_set_key,
+    netntlm_get_key,
+    fmt_default_clear_keys,
+    netntlm_crypt_all,
+    {
+      fmt_default_get_hash,
+      fmt_default_get_hash,
+      fmt_default_get_hash
+    },
+    netntlm_cmp_all,
+    netntlm_cmp_one,
+    netntlm_cmp_exact
+  }
+};
Index: john-1.7.0.2-patched/src/john.c
===================================================================
--- john-1.7.0.2-patched/src/john.c	(revision 700)
+++ john-1.7.0.2-patched/src/john.c	(revision 713)
@@ -48,6 +48,8 @@
 extern struct fmt_main fmt_rawSHA1;
 extern struct fmt_main fmt_lotus5;
 extern struct fmt_main fmt_DOMINOSEC;
+extern struct fmt_main fmt_NETLM;
+extern struct fmt_main fmt_NETNTLM;
 
 extern int unshadow(int argc, char **argv);
 extern int unafs(int argc, char **argv);
@@ -90,6 +92,8 @@
 	john_register_one(&fmt_MYSQL);
 	john_register_one(&fmt_lotus5);
 	john_register_one(&fmt_DOMINOSEC);
+	john_register_one(&fmt_NETLM);
+	john_register_one(&fmt_NETNTLM);
 
 	if (!fmt_list) {
 		fprintf(stderr, "Unknown ciphertext format name requested\n");
Index: john-1.7.0.2-patched/src/options.c
===================================================================
--- john-1.7.0.2-patched/src/options.c	(revision 700)
+++ john-1.7.0.2-patched/src/options.c	(revision 713)
@@ -101,7 +101,7 @@
 "--salts=[-]COUNT           load salts with[out] at least COUNT passwords " \
 	"only\n" \
 "--format=NAME              force ciphertext format NAME: " \
-	"DES/BSDI/MD5/BF/AFS/LM/NT/PO/raw-MD5/IPB2/raw-sha1/md5a/KRB5/bfegg/nsldap/MYSQL/mscash/lotus5/DOMINOSEC\n" \
+	"DES/BSDI/MD5/BF/AFS/LM/NT/PO/raw-MD5/IPB2/raw-sha1/md5a/KRB5/bfegg/nsldap/MYSQL/mscash/lotus5/DOMINOSEC/NETLM/NETNTLM\n" \
 "--save-memory=LEVEL        enable memory saving, at LEVEL 1..3\n"
 
 void opt_init(char *name, int argc, char **argv)
Index: john-1.7.0.2-patched/src/loader.c
===================================================================
--- john-1.7.0.2-patched/src/loader.c	(revision 700)
+++ john-1.7.0.2-patched/src/loader.c	(revision 713)
@@ -203,7 +203,7 @@
 		tmp = *ciphertext;
 		*ciphertext = uid;
 		uid = tmp;
-
+  
 		if (!strncmp(*ciphertext, "NO PASSWORD", 11))
 			*ciphertext = "";
 
@@ -226,7 +226,26 @@
 
 		if (source) sprintf(source, "%s:%s", uid, line);
 	}
+  else if (options.format && ((strncmp(options.format, "netlm", 5)==0) || 
+           (strncmp(options.format, "netntlm", 7)==0))) {
+    char *netlm = ldr_get_field(&line);
+    char *netntlm = ldr_get_field(&line);
+    char *challenge = ldr_get_field(&line);
 
+    if (strncmp(options.format, "netlm", 5)==0) { 
+      tmp = (char *) mem_alloc(7 + strlen(challenge) + strlen(netlm) + 1);
+      memset(tmp, 0, 7 + strlen(challenge) + strlen(netlm) + 1);
+      sprintf(tmp, "$NETLM$%s$%s", challenge, netlm);
+      *ciphertext = tmp;
+    }
+    else {
+      tmp = (char *) mem_alloc(9 + strlen(challenge) + strlen(netntlm) + 1);
+      memset(tmp, 0, 9 + strlen(challenge) + strlen(netntlm) + 1);
+      sprintf(tmp, "$NETNTLM$%s$%s", challenge, netntlm);
+      *ciphertext = tmp;
+    }
+  }
+
 	if (db_options->flags & DB_WORDS || db_options->shells->head) {
 		gid = ldr_get_field(&line);
 		do {
@@ -686,7 +705,6 @@
                         sprintf(ciphertext2, "M$%s#%s", login, ciphertext);
                         ciphertext = ciphertext2;
                 }
-
 	} else {
 		split = fmt_default_split;
 		count = 1;
Index: john-1.7.0.2-patched/src/Makefile
===================================================================
--- john-1.7.0.2-patched/src/Makefile	(revision 700)
+++ john-1.7.0.2-patched/src/Makefile	(revision 713)
@@ -16,8 +16,10 @@
 NULL = /dev/null
 
 CFLAGS = -c -Wall -O2 -fomit-frame-pointer -I/usr/local/include -L/usr/local/lib
+#CFLAGS = -g -c -Wall -O2 -I/usr/local/include -L/usr/local/lib
 ASFLAGS = -c
 LDFLAGS = -s
+#LDFLAGS =
 OPT_NORMAL = -funroll-loops
 OPT_INLINE = -finline-functions
 LIBS = -lcrypto -lssl
@@ -42,6 +44,8 @@
 	IPB2_fmt.o \
 	rawSHA1_fmt.o \
 	NSLDAP_fmt.o sha1.o base64.o \
+	NETLM_fmt.o \
+	NETNTLM_fmt.o \
 	NT_fmt.o \
 	md4.o smbencrypt.o \
 	mscash_fmt.o \
