extern int unique(int argc, char **argv);
static struct db_main database;
static struct fmt_main dummy_format;
static void john_register_one(struct fmt_main *format)
{
if (options.format)
if (strcmp(options.format, format->params.label)) return;
fmt_register(format);
}
static void john_register_all()
{
if (options.format) strlwr(options.format);
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);
if (!fmt_list) {
fprintf(stderr, "Unknown ciphertext format name requested\n");
error();
}
}
static void john_load()
{
struct list_entry *current;
umask(077);
if (options.flags & FLG_EXTERNAL_CHK)
ext_init(options.external);
if (options.flags & FLG_MAKECHARS_CHK) {
options.loader.flags |= DB_CRACKED;
ldr_init_database(&database, &options.loader);
if (options.flags & FLG_PASSWD) {
ldr_show_pot_file(&database, LOG_NAME);
database.options->flags |= DB_PLAINTEXTS;
if ((current = options.passwd->head))
do {
ldr_show_pw_file(&database, current->data);
} while ((current = current->next));
} else {
database.options->flags |= DB_PLAINTEXTS;
ldr_show_pot_file(&database, LOG_NAME);
}
return;
}
if (options.flags & FLG_STDOUT) {
ldr_init_database(&database, &options.loader);
database.format = &dummy_format;
memset(&dummy_format, 0, sizeof(dummy_format));
dummy_format.params.plaintext_length = options.length;
dummy_format.params.flags = FMT_CASE | FMT_8_BIT;
}
if (options.flags & FLG_PASSWD) {
if (options.flags & FLG_SHOW_CHK) {
options.loader.flags |= DB_CRACKED;
ldr_init_database(&database, &options.loader);
ldr_show_pot_file(&database, LOG_NAME);
if ((current = options.passwd->head))
do {
ldr_show_pw_file(&database, current->data);
} while ((current = current->next));
printf("%s%d password%s cracked, %d left\n",
database.guess_count ? "\n" : "",
database.guess_count,
database.guess_count != 1 ? "s" : "",
database.password_count -
database.guess_count);
return;
}
if (options.flags & (FLG_SINGLE_CHK | FLG_BATCH_CHK))
options.loader.flags |= DB_WORDS;
else
if (mem_saving_level)
options.loader.flags &= ~DB_LOGIN;
ldr_init_database(&database, &options.loader);
if ((current = options.passwd->head))
do {
ldr_load_pw_file(&database, current->data);
} while ((current = current->next));
ldr_load_pot_file(&database, LOG_NAME);
ldr_fix_database(&database);
printf("Loaded %d password%s%s",
database.password_count,
database.password_count != 1 ? "s" : "",
database.password_count ? "" : ", exiting...");
if (database.password_count > 1) {
printf(" with ");
printf(database.salt_count != 1 ? "%d" : "no",
database.salt_count);
printf(" different salts");
}
if (database.password_count)
printf(" (%s [%s])\n",
database.format->params.format_name,
database.format->params.algorithm_name);
else
putchar('\n');
if ((options.flags & FLG_PWD_REQ) && !database.salts) exit(0);
}
}
static void john_init(int argc, char **argv)
{
#if CPU_DETECT
if (!CPU_detect()) {
#if CPU_REQ
fprintf(stderr, "Sorry, %s is required\n", CPU_NAME);
error();
#endif
}
#endif
path_init(argv);
cfg_init(CFG_NAME);
status_init(NULL, 1);
opt_init(argc, argv);
john_register_all();
common_init();
sig_init(idle_yield);
john_load();
}
static void john_run()
{
if (options.flags & FLG_TEST_CHK)
benchmark_all();
else
if (options.flags & FLG_MAKECHARS_CHK)
do_makechars(&database, options.charset);
else
if (options.flags & FLG_CRACKING_CHK) {
if (!(options.flags & FLG_STDOUT)) log_init(LOG_NAME);
tty_init();
if (options.flags & FLG_SINGLE_CHK)
do_single_crack(&database);
else
if (options.flags & FLG_WORDLIST_CHK)
do_wordlist_crack(&database, options.wordlist,
(options.flags & FLG_RULES) != 0);
else
if (options.flags & FLG_INC_CHK)
do_incremental_crack(&database, options.charset);
else
if (options.flags & FLG_EXTERNAL_CHK)
do_external_crack(&database);
else
if (options.flags & FLG_BATCH_CHK)
do_batch_crack(&database);
status_print();
tty_done();
if (!(options.flags & FLG_STDOUT)) log_done();
}
}
static void john_done()
{
path_done();
check_abort();
}
int main(int argc, char **argv)
{
char *name;
#ifdef __DJGPP__
if (--argc <= 0) return 1;
if ((name = strrchr(argv[0], '/')))
strcpy(name + 1, argv[1]);
name = argv[1];
argv[1] = argv[0];
argv++;
#else
if (!argv[0])
name = "";
else
if ((name = strrchr(argv[0], '/')))
name++;
else
name = argv[0];
#endif
#ifdef __CYGWIN32__
if (strlen(name) > 4)
if (!strcmp(strlwr(name) + strlen(name) - 4, ".exe"))
name[strlen(name) - 4] = 0;
#endif
if (!strcmp(name, "john")) {
john_init(argc, argv);
john_run();
john_done();
return 0;
}
if (!strcmp(name, "unshadow"))
return unshadow(argc, argv);
if (!strcmp(name, "unafs"))
return unafs(argc, argv);
if (!strcmp(name, "unique"))
return unique(argc, argv);
fprintf(stderr, "Sorry, I can't find myself\n");
return 1;
}
Файл des_bs.c
#include <string.h>
#include "arch.h"
#include "DES_std.h"
#include "DES_bs.h"
DES_bs_combined DES_bs_all;
int DES_bs_mem_saving = 0;
extern void DES_bs_body();
void DES_bs_init()
{
int index, bit;
for (index = 0; index < 0x300; index++) {
bit = DES_K_bits[index];
bit -= bit >> 3;
DES_bs_all.Kp[index] = &DES_bs_all.K[55 - bit];
}
}
void DES_bs_set_salt(ARCH_WORD salt)
{
register int src, dst;
register ARCH_WORD mask;
mask = 1;
for (dst = 0; dst < 48; dst++) {
if (dst == 24) mask = 1;
if (salt & mask) {
if (dst < 24) src = dst + 24; else src = dst - 24;
} else src = dst;
DES_bs_all.E[dst] = &DES_bs_all.B[DES_E[src]];
DES_bs_all.E[dst + 48] = &DES_bs_all.B[DES_E[src] + 32];
mask <<= 1;
}
}
void DES_bs_clear_keys()
{
memset(DES_bs_all.K, 0, sizeof(DES_bs_all.K));
}
void DES_bs_set_key(char *key, int index)
{
register char *ptr;
register int ofs, bit;
register ARCH_WORD value;
ofs = 56;
for (ptr = key; *ptr && ofs; ptr++) {
bit = (ofs -= 7);
value = *ptr & 0x7F;
do {
DES_bs_all.K[bit++] |= (value & 1) << index;
} while (value >>= 1);
}
}
void DES_bs_crypt(int count)
{
register int bit;
register ARCH_WORD R, L;
memset(DES_bs_all.B, 0, sizeof(DES_bs_all.B));
do {
DES_bs_body();
if (!--count) break;
for (bit = 0; bit < 32; bit++) {
R = DES_bs_all.B[bit];
L = DES_bs_all.B[bit + 32];
DES_bs_all.B[bit + 32] = R;
DES_bs_all.B[bit] = L;
}
} while (1);
}
ARCH_WORD *DES_bs_get_binary(char *ciphertext)
{
static ARCH_WORD out[64];
ARCH_WORD *raw;
int bit;
int index, shift;
int value;
raw = DES_raw_get_binary(ciphertext);
out[1] = out[0] = 0;
for (bit = 0; bit < 64; bit++) {
index = bit >> 4;
/* Swap L and R here instead of doing it one more time in DES_bs_crypt() */
index ^= 2;
/* Calculate the number of one of the 16 data bits in raw[index] */
shift = ((bit & 0xC) << 1) + (bit & 3) + 1;
/* Get the bit */
value = (raw[index] >> shift) & 1;
if (DES_bs_mem_saving)
/* Memory saving: pack the bits into two words */
out[bit >> 5] |= value << (bit & 0x1F);
else
/* We either set or clear all the bits in every word */
out[bit] = value ? ~(ARCH_WORD)0 : 0;
}
return out;
}
int DES_bs_binary_hash(ARCH_WORD *binary, int count)
{
int bit, result;
if (DES_bs_mem_saving)
return (int)*binary & ((1 << count) - 1);
result = 0;
for (bit = 0; bit < count; bit++)
if (binary[bit]) result |= 1 << bit;
return result;
}
int DES_bs_get_hash(int index, int count)
{
register int bit, result;
register ARCH_WORD mask;
mask = (ARCH_WORD)1 << index;
result = 0;
for (bit = 0; bit < count; bit++)
if (DES_bs_all.B[bit] & mask) result |= 1 << bit;
return result;
}
/*
* The trick I used here allows to compare one ciphertext against all the
* DES_bs_crypt() outputs in just O(log2(ARCH_BITS)) operations.
*/
int DES_bs_cmp_all(ARCH_WORD *binary, int count)
{
register int bit;
register ARCH_WORD mask;
mask = 0;
if (DES_bs_mem_saving)
for (bit = 0; bit < ((count < 32) ? count : 32); bit++) {
mask |= DES_bs_all.B[bit] ^
((binary[0] & (1 << bit)) ? ~(ARCH_WORD)0 : 0);
if (mask == ~(ARCH_WORD)0) return 0;
}
else
for (bit = 0; bit < count; bit++) {
mask |= DES_bs_all.B[bit] ^ binary[bit];
if (mask == ~(ARCH_WORD)0) return 0;
}
return 1;
}
int DES_bs_cmp_one(ARCH_WORD *binary, int count, int index)
{
register int bit;
register ARCH_WORD mask;
if (DES_bs_mem_saving) {
for (bit = 0; bit < count; bit++)
if (((DES_bs_all.B[bit] >> index) ^
(binary[bit >> 5] >> (bit & 0x1F))) & 1) return 0;
return 1;
}
mask = (ARCH_WORD)1 << index;
for (bit = 0; bit < count; bit++)
if ((DES_bs_all.B[bit] ^ binary[bit]) & mask) return 0;
return 1;
}