试着在ubuntu下安装了John the Ripper最新版本1.7.9,非常不给面子,不成功,
总是报"No password hashes loaded"的错误。
最终参照这篇文章,将JRT换成1.7.3.4 版本,让它跑了起来。。。
http://pka.engr.ccny.cuny.edu/~jmao/node/26
简而言之,共有如下步骤
1. 下载JRT 1.7.3.4版
(目前最新版为1.7.9,但1.7.9在ubuntu 10.04上没有跑成功)
网址: http://www.openwall.com/john/
2. 解压
tar -zxvf john-1.7.4.2.tar.gz cd john-1.7.4.2/src
3. 打patch
(这是核心的一步,不打patch,仍然会报No password hash loaded错误)
有三个文件要修改 Makefile, crypt_fmt.c , john.c.
Append "-lcrypt" to line "LDFLAGS = -s", making the line reads as:
在Makefile中将LDFLAGS = -s改为
LDFLAGS = -s -lcrypt
创建crypt_fmt.c,内容如下
/* public domain proof-of-concept code by Solar Designer */ #define _XOPEN_SOURCE /* for crypt(3) */ #include <string.h> #include <unistd.h> #include "arch.h" #include "params.h" #include "formats.h" #define FORMAT_LABEL "crypt" #define FORMAT_NAME "generic crypt(3)" #define ALGORITHM_NAME "?/" ARCH_BITS_STR #define BENCHMARK_COMMENT "" #define BENCHMARK_LENGTH 0 #define PLAINTEXT_LENGTH 72 #define BINARY_SIZE 128 #define SALT_SIZE BINARY_SIZE #define MIN_KEYS_PER_CRYPT 1 #define MAX_KEYS_PER_CRYPT 1 static struct fmt_tests tests[] = { {"CCNf8Sbh3HDfQ", "U*U*U*U*"}, {"CCX.K.MFy4Ois", "U*U***U"}, {"CC4rMpbg9AMZ.", "U*U***U*"}, {"XXxzOu6maQKqQ", "*U*U*U*U"}, {"SDbsugeBiC58A", ""}, {NULL} }; static char saved_key[PLAINTEXT_LENGTH + 1]; static char saved_salt[SALT_SIZE]; static char *crypt_out; static int valid(char *ciphertext) { #if 1 int l = strlen(ciphertext); return l >= 13 && l < BINARY_SIZE; #else /* Poor load time, but more effective at rejecting bad/unsupported hashes */ char *r = crypt("", ciphertext); int l = strlen(r); return !strncmp(r, ciphertext, 2) && l == strlen(ciphertext) && l >= 13 && l < BINARY_SIZE; #endif } static void *binary(char *ciphertext) { static char out[BINARY_SIZE]; strncpy(out, ciphertext, sizeof(out)); /* NUL padding is required */ return out; } static void *salt(char *ciphertext) { static char out[SALT_SIZE]; int cut = sizeof(out); #if 1 /* This piece is optional, but matching salts are not detected without it */ switch (strlen(ciphertext)) { case 13: case 24: cut = 2; break; case 20: if (ciphertext[0] == '_') cut = 9; break; case 34: if (!strncmp(ciphertext, "$1$", 3)) { char *p = strchr(ciphertext + 3, '$'); if (p) cut = p - ciphertext; } break; case 59: if (!strncmp(ciphertext, "$2$", 3)) cut = 28; break; case 60: if (!strncmp(ciphertext, "$2a$", 4)) cut = 29; break; } #endif /* NUL padding is required */ memset(out, 0, sizeof(out)); memcpy(out, ciphertext, cut); return out; } static int binary_hash_0(void *binary) { return ((unsigned char *)binary)[12] & 0xF; } static int binary_hash_1(void *binary) { return ((unsigned char *)binary)[12] & 0xFF; } static int binary_hash_2(void *binary) { return (((unsigned char *)binary)[12] & 0xFF) | ((int)(((unsigned char *)binary)[11] & 0xF) << 8); } static int get_hash_0(int index) { return (unsigned char)crypt_out[12] & 0xF; } static int get_hash_1(int index) { return (unsigned char)crypt_out[12] & 0xFF; } static int get_hash_2(int index) { return ((unsigned char)crypt_out[12] & 0xFF) | ((int)((unsigned char)crypt_out[11] & 0xF) << 8); } static int salt_hash(void *salt) { int pos = strlen((char *)salt) - 2; return (((unsigned char *)salt)[pos] & 0xFF) | ((int)(((unsigned char *)salt)[pos + 1] & 3) << 8); } static void set_salt(void *salt) { strcpy(saved_salt, salt); } static void set_key(char *key, int index) { strcpy(saved_key, key); } static char *get_key(int index) { return saved_key; } static void crypt_all(int count) { crypt_out = crypt(saved_key, saved_salt); } static int cmp_all(void *binary, int count) { return !strcmp((char *)binary, crypt_out); } static int cmp_exact(char *source, int index) { return 1; } struct fmt_main fmt_crypt = { { 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, valid, fmt_default_split, binary, salt, { binary_hash_0, binary_hash_1, binary_hash_2 }, salt_hash, set_salt, set_key, get_key, fmt_default_clear_keys, crypt_all, { get_hash_0, get_hash_1, get_hash_2 }, cmp_all, cmp_all, cmp_exact } };
John.c中要加两行,红色部分
extern struct fmt_main fmt_DES, fmt_BSDI, fmt_MD5, fmt_BF; extern struct fmt_main fmt_AFS, fmt_LM; extern struct fmt_main fmt_crypt;
john_register_one(&fmt_DES); john_register_one(&fmt_BSDI); john_register_one(&fmt_MD5); john_register_one(&fmt_BF); john_register_one(&fmt_AFS); john_register_one(&fmt_LM); john_register_one(&fmt_crypt);
修改Makefile中JOHN_OBJS_MINIMAL的依赖
JOHN_OBJS_MINIMAL = \ DES_fmt.o DES_std.o DES_bs.o \ BSDI_fmt.o \ MD5_fmt.o MD5_std.o \ BF_fmt.o BF_std.o \ AFS_fmt.o \ LM_fmt.o \ batch.o bench.o charset.o common.o compiler.o config.o cracker.o \ crc32.o external.o formats.o getopt.o idle.o inc.o john.o list.o \ loader.o logger.o math.o memory.o misc.o options.o params.o path.o \ recovery.o rpp.o rules.o signals.o single.o status.o tty.o wordlist.o \ unshadow.o \ unafs.o \ unique.o \ crypt_fmt.o
4. 执行指令
make clean generic
5. 执行John
sudo unshadow /etc/passwd /etc/shadow> shadowfile ./john shadowfile
执行结果
vigar@vigar-laptop:~/software/john-1.7.3.4/run$ ./john shadowfile Loaded 6 password hashes with 6 different salts (generic crypt(3) [?/32]) test (test) aaa (aaa)
...