📄 loader.c
字号:
/* * This file is part of John the Ripper password cracker, * Copyright (c) 1996-99 by Solar Designer */#include <stdio.h>#include <sys/stat.h>#include <unistd.h>#include <errno.h>#include <string.h>#include "arch.h"#include "misc.h"#include "params.h"#include "path.h"#include "memory.h"#include "list.h"#include "signals.h"#include "formats.h"#include "loader.h"/* * Flags for read_file(). */#define RF_ALLOW_MISSING 1#define RF_ALLOW_DIR 2/* * Word separator characters for ldr_split_words(), used on GECOS fields. */#define issep \ "!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~\177"static char issep_map[0x100];static int issep_initialized = 0;static void read_file(struct db_main *db, char *name, int flags, void (*process_line)(struct db_main *db, char *line)){ struct stat file_stat; FILE *file; char line[LINE_BUFFER_SIZE]; if (flags & RF_ALLOW_DIR) { if (stat(name, &file_stat)) { if (flags & RF_ALLOW_MISSING) if (errno == ENOENT) return; pexit("stat: %s", path_expand(name)); } else if (S_ISDIR(file_stat.st_mode)) return; } if (!(file = fopen(path_expand(name), "r"))) { if ((flags & RF_ALLOW_MISSING) && errno == ENOENT) return; pexit("fopen: %s", path_expand(name)); } while (fgets(line, sizeof(line), file)) { process_line(db, line); check_abort(); } if (ferror(file)) pexit("fgets"); if (fclose(file)) pexit("fclose");}static void ldr_init_issep(void){ char *pos; if (issep_initialized) return; memset(issep_map, 0, sizeof(issep_map)); memset(issep_map, 1, 33); for (pos = issep; *pos; pos++) issep_map[ARCH_INDEX(*pos)] = 1; issep_initialized = 1;}void ldr_init_database(struct db_main *db, struct db_options *options){ db->loaded = 0; db->options = mem_alloc_copy(sizeof(struct db_options), MEM_ALIGN_WORD, options); db->salts = NULL; if (options->flags & DB_CRACKED) { db->salt_hash = NULL; db->password_hash = NULL; db->cracked_hash = mem_alloc( CRACKED_HASH_SIZE * sizeof(struct db_cracked *)); memset(db->cracked_hash, 0, CRACKED_HASH_SIZE * sizeof(struct db_cracked *)); } else { db->salt_hash = mem_alloc( SALT_HASH_SIZE * sizeof(struct db_salt *)); memset(db->salt_hash, 0, SALT_HASH_SIZE * sizeof(struct db_salt *)); db->password_hash = mem_alloc(LDR_HASH_SIZE); memset(db->password_hash, 0, LDR_HASH_SIZE); db->cracked_hash = NULL; if (options->flags & DB_WORDS) { options->flags |= DB_LOGIN; ldr_init_issep(); } } if (!options->max_pps) db->options->max_pps = (unsigned int)~0 >> 1; list_init(&db->plaintexts); db->salt_count = db->password_count = db->guess_count = 0; db->format = NULL;}static char *ldr_get_field(char **ptr){ char *res, *pos; if (!*ptr) return ""; if ((pos = strchr(res = *ptr, ':'))) { *pos++ = 0; *ptr = pos; } else { pos = res; do { if (*pos == '\r' || *pos == '\n') *pos = 0; } while (*pos++); *ptr = NULL; } return res;}static int ldr_check_list(struct list_main *list, char *s1, char *s2){ struct list_entry *current; char *data; if (!(current = list->head)) return 0; if (*current->data == '-') { data = current->data + 1; do { if (!strcmp(s1, data) || !strcmp(s2, data)) return 1; if ((current = current->next)) data = current->data; } while (current); } else { do { data = current->data; if (!strcmp(s1, data) || !strcmp(s2, data)) return 0; } while ((current = current->next)); return 1; } return 0;}static int ldr_check_shells(struct list_main *list, char *shell){ char *name; if (list->head) { if ((name = strrchr(shell, '/'))) name++; else name = shell; return ldr_check_list(list, shell, name); } return 0;}static int ldr_split_line(char **login, char **ciphertext, char **gecos, char **home, char *source, struct fmt_main **format, struct db_options *options, char *line){ char *uid = NULL, *gid = NULL, *shell = NULL; char *tmp; int count; *login = ldr_get_field(&line); if (!strcmp(*login, "+") || !strncmp(*login, "+@", 2)) return 0; if (!*(*ciphertext = ldr_get_field(&line))) if (!line) return 0; if (source) strcpy(source, line ? line : ""); uid = ldr_get_field(&line); if (strlen(uid) == 32) { tmp = *ciphertext; *ciphertext = uid; uid = tmp; if (!strncmp(*ciphertext, "NO PASSWORD", 11)) *ciphertext = ""; if (source) sprintf(source, "%s:%s", uid, line); } if (options->flags & DB_WORDS || options->shells->head) { gid = ldr_get_field(&line); do { *gecos = ldr_get_field(&line); *home = ldr_get_field(&line); shell = ldr_get_field(&line); } while (!**gecos && !strcmp(*home, "0") && !strcmp(shell, "0")); } else if (options->groups->head) { gid = ldr_get_field(&line); } if (ldr_check_list(options->users, *login, uid)) return 0; if (ldr_check_list(options->groups, gid, gid)) return 0; if (ldr_check_shells(options->shells, shell)) return 0; if (*format) return (*format)->methods.valid(*ciphertext); if ((*format = fmt_list)) do { if ((count = (*format)->methods.valid(*ciphertext))) { fmt_init(*format); return count; } } while ((*format = (*format)->next)); return -1;}static void ldr_split_string(struct list_main *dst, char *src){ char *word, *pos; pos = src; do { word = pos; while (*word && issep_map[ARCH_INDEX(*word)]) word++; if (!*word) break; pos = word; while (!issep_map[ARCH_INDEX(*pos)]) pos++; if (*pos) *pos++ = 0; list_add_unique(dst, word); } while (*pos && dst->count < LDR_WORDS_MAX);}static struct list_main *ldr_init_words(char *login, char *gecos, char *home){ struct list_main *words; char *pos; list_init(&words); list_add(words, login); ldr_split_string(words, gecos); ldr_split_string(words, login); if ((pos = strrchr(home, '/'))) list_add_unique(words, pos + 1); return words;}static void ldr_load_pw_line(struct db_main *db, char *line){ struct fmt_main *format; int index, count; char *login, *ciphertext, *gecos, *home; char *piece; void *binary, *salt; int salt_hash, pw_hash; struct db_salt *current_salt, *last_salt; struct db_password *current_pw, *last_pw; struct list_main *words; size_t pw_size, salt_size; count = ldr_split_line(&login, &ciphertext, &gecos, &home, NULL, &db->format, db->options, line); if (count <= 0) return; if (count >= 2) db->options->flags |= DB_SPLIT; format = db->format; words = NULL; if (db->options->flags & DB_WORDS) { pw_size = sizeof(struct db_password); salt_size = sizeof(struct db_salt); } else { if (db->options->flags & DB_LOGIN) pw_size = sizeof(struct db_password) - sizeof(struct list_main *); else pw_size = sizeof(struct db_password) - (sizeof(char *) + sizeof(struct list_main *)); salt_size = sizeof(struct db_salt) - sizeof(struct db_keys *); } for (index = 0; index < count; index++) { piece = format->methods.split(ciphertext, index); binary = format->methods.binary(piece); pw_hash = LDR_HASH_FUNC(binary); if ((current_pw = db->password_hash[pw_hash])) do { if (!strcmp(current_pw->source, piece)) { if (!(db->options->flags & DB_WORDS)) break; if (!strcmp(current_pw->login, login)) break; } } while ((current_pw = current_pw->next_hash)); if (current_pw) continue; salt = format->methods.salt(piece); salt_hash = format->methods.salt_hash(salt); if ((current_salt = db->salt_hash[salt_hash])) do { if (!memcmp( current_salt->salt, salt, format->params.salt_size)) break; } while ((current_salt = current_salt->next)); if (!current_salt) { last_salt = db->salt_hash[salt_hash]; current_salt = db->salt_hash[salt_hash] = mem_alloc_tiny(sizeof(struct db_salt), MEM_ALIGN_WORD); current_salt->next = last_salt; current_salt->salt = mem_alloc_copy( format->params.salt_size, MEM_ALIGN_WORD, salt); current_salt->index = fmt_dummy_hash; current_salt->list = NULL; current_salt->hash = ¤t_salt->list; current_salt->hash_size = -1; current_salt->count = 0;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -