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 + * + * 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 + * + */ + +#include +#include + +#include "common.h" +#include "formats.h" + +#include + +#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> 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 + * + * 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 + * + */ + +#include +#include + +#include "common.h" +#include "formats.h" + +#include + +#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> 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 \