static void ldr_show_pot_line(struct db_main *db, char *line) { char *ciphertext, *pos; int hash; struct db_cracked *current, *last; ciphertext = ldr_get_field(&line); if (line) { pos = line; do { if (*pos == '\r' || *pos == '\n') *pos = 0; } while (*pos++); if (db->options->flags & DB_PLAINTEXTS) { list_add(db->plaintexts, line); return; } hash = ldr_cracked_hash(ciphertext); last = db->cracked_hash[hash]; current = db->cracked_hash[hash] = mem_alloc_tiny(sizeof(struct db_cracked), MEM_ALIGN_WORD); current->next = last; current->ciphertext = str_alloc_copy(ciphertext); current->plaintext = str_alloc_copy(line); } }
static void ldr_load_pot_line(struct db_main *db, char *line) { struct fmt_main *format = db->format; char *ciphertext; void *binary; int hash; struct db_password *current; ciphertext = ldr_get_field(&line); if (format->methods.valid(ciphertext, format) != 1) return; ciphertext = format->methods.split(ciphertext, 0, format); binary = format->methods.binary(ciphertext); hash = db->password_hash_func(binary); if ((current = db->password_hash[hash])) do { if (!current->binary) /* already marked for removal */ continue; if (memcmp(binary, current->binary, format->params.binary_size)) continue; if (strcmp(ciphertext, format->methods.source(current->source, current->binary))) continue; current->binary = NULL; /* mark for removal */ } while ((current = current->next_hash)); }
static void ldr_load_pot_line(struct db_main *db, char *line) { struct fmt_main *format = db->format; char *ciphertext, *unprepared; void *binary; int hash; struct db_password *current; char *flds[10]; int i; unprepared = ldr_get_field(&line, db->options->field_sep_char); for (i = 0; i < 10; ++i) flds[i] = ""; flds[1] = unprepared; ciphertext = format->methods.prepare(flds, format); if (format->methods.valid(ciphertext,format) != 1) return; ciphertext = format->methods.split(ciphertext, 0); binary = format->methods.binary(ciphertext); hash = db->password_hash_func(binary); if ((current = db->password_hash[hash])) do { if (current->binary && !memcmp(current->binary, binary, format->params.binary_size) && !strcmp(current->source, ciphertext)) current->binary = NULL; } while ((current = current->next_hash)); }
static void ldr_load_pot_line(struct db_main *db, char *line) { struct fmt_main *format = db->format; char *ciphertext; void *binary; int hash; struct db_password *current; ciphertext = ldr_get_field(&line); if (format->methods.valid(ciphertext) != 1) return; ciphertext = format->methods.split(ciphertext, 0); binary = format->methods.binary(ciphertext); hash = LDR_HASH_FUNC(binary); if ((current = db->password_hash[hash])) do { if (current->binary && !memcmp(current->binary, binary, format->params.binary_size) && !strcmp(current->source, ciphertext)) current->binary = NULL; } while ((current = current->next_hash)); }
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) { struct fmt_main *alt; char *fields[10], *uid, *gid, *shell; int i, retval; fields[0] = *login = ldr_get_field(&line); fields[1] = *ciphertext = ldr_get_field(&line); /* Check for NIS stuff */ if ((!strcmp(*login, "+") || !strncmp(*login, "+@", 2)) && strlen(*ciphertext) < 10 && strncmp(*ciphertext, "$dummy$", 7)) return 0; if (!**ciphertext && !line) { /* Possible hash on a line on its own (no colons) */ char *p = *login; /* Skip leading and trailing whitespace */ while (*p == ' ' || *p == '\t') p++; *ciphertext = p; p += strlen(p) - 1; while (p > *ciphertext && (*p == ' ' || *p == '\t')) p--; p++; /* Some valid dummy hashes may be shorter than 10 characters, so don't subject * them to the length checks. */ if (strncmp(*ciphertext, "$dummy$", 7) && p - *ciphertext != 10 /* not tripcode */) { /* Check for a special case: possibly a traditional crypt(3) hash with * whitespace in its invalid salt. Only support such hashes at the very start * of a line (no leading whitespace other than the invalid salt). */ if (p - *ciphertext == 11 && *ciphertext - *login == 2) (*ciphertext)--; if (p - *ciphertext == 12 && *ciphertext - *login == 1) (*ciphertext)--; if (p - *ciphertext < 13) return 0; } *p = 0; fields[0] = *login = no_username; fields[1] = *ciphertext; } if (source) strcpy(source, line ? line : ""); /* * This check is just a loader performance optimization, so that we can parse * fewer fields when we know we won't need the rest. It should be revised or * removed when there are formats that use higher-numbered fields in prepare(). */ if ((options->flags & DB_WORDS) || options->shells->head) { /* Parse all fields */ for (i = 2; i < 10; i++) fields[i] = ldr_get_field(&line); } else { /* Parse some fields only */ for (i = 2; i < 4; i++) fields[i] = ldr_get_field(&line); for (; i < 10; i++) fields[i] = "/"; } /* /etc/passwd */ uid = fields[2]; gid = fields[3]; *gecos = fields[4]; *home = fields[5]; shell = fields[6]; if (fields[5][0] != '/' && ((!strcmp(fields[5], "0") && !strcmp(fields[6], "0")) || fields[8][0] == '/' || fields[9][0] == '/')) { /* /etc/master.passwd */ *gecos = fields[7]; *home = fields[8]; shell = fields[9]; } else if (fields[3] - fields[2] == 32 + 1) { /* PWDUMP */ uid = fields[1]; *ciphertext = fields[2]; if (!strncmp(*ciphertext, "NO PASSWORD", 11)) *ciphertext = ""; gid = shell = ""; *gecos = fields[4]; *home = fields[5]; /* Re-introduce the previously removed uid field */ if (source) { int shift = strlen(uid); memmove(source + shift + 1, source, strlen(source) + 1); memcpy(source, uid, shift); source[shift] = ':'; } } 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) { char *prepared; int valid; prepared = (*format)->methods.prepare(fields, *format); if (prepared) valid = (*format)->methods.valid(prepared, *format); else valid = 0; if (valid) { *ciphertext = prepared; return valid; } alt = fmt_list; do { if (alt == *format) continue; if (alt->params.flags & FMT_WARNED) continue; #ifdef HAVE_CRYPT if (alt == &fmt_crypt && #ifdef __sun strncmp(*ciphertext, "$md5$", 5) && strncmp(*ciphertext, "$md5,", 5) && #endif strncmp(*ciphertext, "$5$", 3) && strncmp(*ciphertext, "$6$", 3)) continue; #endif prepared = alt->methods.prepare(fields, alt); if (alt->methods.valid(prepared, alt)) { alt->params.flags |= FMT_WARNED; fprintf(stderr, "Warning: only loading hashes of type " "\"%s\", but also saw type \"%s\"\n" "Use the \"--format=%s\" option to force " "loading hashes of that type instead\n", (*format)->params.label, alt->params.label, alt->params.label); break; } } while ((alt = alt->next)); return 0; } retval = -1; if ((alt = fmt_list)) do { char *prepared; int valid; #ifdef HAVE_CRYPT /* * Only probe for support by the current system's crypt(3) if this is forced * from the command-line or/and if the hash encoding string looks like one of * those that are only supported in that way. Avoid the probe in other cases * because it may be slow and undesirable (false detection is possible). */ if (alt == &fmt_crypt && fmt_list != &fmt_crypt /* not forced */ && #ifdef __sun strncmp(*ciphertext, "$md5$", 5) && strncmp(*ciphertext, "$md5,", 5) && #endif strncmp(*ciphertext, "$5$", 3) && strncmp(*ciphertext, "$6$", 3)) continue; #endif prepared = alt->methods.prepare(fields, alt); if (!prepared) continue; valid = alt->methods.valid(prepared, alt); if (!valid) continue; if (retval < 0) { retval = valid; *ciphertext = prepared; fmt_init(*format = alt); #ifdef LDR_WARN_AMBIGUOUS if (!source) /* not --show */ continue; #endif break; } #ifdef LDR_WARN_AMBIGUOUS fprintf(stderr, "Warning: detected hash type \"%s\", but the string is " "also recognized as \"%s\"\n" "Use the \"--format=%s\" option to force loading these " "as that type instead\n", (*format)->params.label, alt->params.label, alt->params.label); #endif } while ((alt = alt->next)); return retval; }
static int ldr_split_line(char **login, char **ciphertext, char **gecos, char **home, char *source, struct fmt_main **format, struct db_options *db_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 = ""; /* NT loader hack starts here ! */ if (options.format && (strncmp(options.format, "nt", 2)==0)) { tmp = ldr_get_field(&line); *ciphertext = tmp; if (!strncmp(*ciphertext, "NO PASSWORD", 11)) *ciphertext = ""; else if(strlen(*ciphertext) == 32) { *ciphertext -= 4; strncpy(*ciphertext,"$NT$",4); } else { return 0; } } /* NT loader hack ends here ! */ if (source) sprintf(source, "%s:%s", uid, line); } if (db_options->flags & DB_WORDS || db_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 (db_options->groups->head) { gid = ldr_get_field(&line); } if (ldr_check_list(db_options->users, *login, uid)) return 0; if (ldr_check_list(db_options->groups, gid, gid)) return 0; if (ldr_check_shells(db_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 int ldr_split_line(char **login, char **ciphertext, char **gecos, char **home, char *source, struct fmt_main **format, struct db_options *db_options, char *line) { struct fmt_main *alt; char *uid = NULL, *gid = NULL, *shell = NULL; char *split_fields[10]; int i, retval, valid; // Note, only 7 are 'defined' in the passwd format. We load 10, so that // other formats can add specific extra stuff. for (i = 0; i < 10; ++i) { split_fields[i] = ldr_get_field(&line, db_options->field_sep_char); if (!line && i == 1 && split_fields[1][0] == 0) { /* Possible hash on a line on its own (no colons) */ char *p = split_fields[0]; /* Skip leading and trailing whitespace */ while (*p == ' ' || *p == '\t') p++; split_fields[1] = p; p += strlen(p) - 1; while (p > split_fields[1] && (*p == ' ' || *p == '\t')) p--; p++; /* Some valid dummy hashes may be shorter than 10 characters, so don't subject * them to the length checks. */ if (strncmp(split_fields[1], "$dummy$", 7) && p - split_fields[1] != 10 /* not tripcode */) { /* Check for a special case: possibly a traditional crypt(3) hash with * whitespace in its invalid salt. Only support such hashes at the very start * of a line (no leading whitespace other than the invalid salt). */ if (p - split_fields[1] == 11 && split_fields[1] - split_fields[0] == 2) split_fields[1]--; if (p - split_fields[1] == 12 && split_fields[1] - split_fields[0] == 1) split_fields[1]--; if (p - split_fields[1] < 13) return 0; } *p = 0; split_fields[0] = no_username; } if (i == 1 && source) strcpy(source, line ? line : ""); } *login = split_fields[0]; *ciphertext = split_fields[1]; /* Check for NIS stuff */ if ((!strcmp(*login, "+") || !strncmp(*login, "+@", 2)) && strlen(*ciphertext) < 10 && strncmp(*ciphertext, "$dummy$", 7)) return 0; /* SPLFLEN(n) is a macro equiv. of strlen(split_fields[n]) (but faster) */ if (SPLFLEN(1) > 0 && SPLFLEN(1) < 7 && (SPLFLEN(3) == 32 || SPLFLEN(2) == 32)) { /* uid for pwdump files. */ uid = split_fields[1]; gid = *gecos = *home = shell = ""; } else if (SPLFLEN(1) == 0 && SPLFLEN(3) >= 16 && SPLFLEN(4) >= 32 && SPLFLEN(5) >= 16) { /* l0phtcrack-style input */ uid = gid = *home = shell = ""; *gecos = split_fields[2]; // in case there's a domain name here } else { /* normal passwd-style input */ uid = split_fields[2]; gid = split_fields[3]; *gecos = split_fields[4]; *home = split_fields[5]; shell = split_fields[6]; } if (ldr_check_list(db_options->users, *login, uid)) return 0; if (ldr_check_list(db_options->groups, gid, gid)) return 0; if (ldr_check_shells(db_options->shells, shell)) return 0; if (*format) { *ciphertext = (*format)->methods.prepare(split_fields, *format); valid = (*format)->methods.valid(*ciphertext, *format); if (!valid) { alt = fmt_list; do { if (alt == *format) continue; if (alt->params.flags & FMT_WARNED) continue; #ifdef HAVE_CRYPT if (alt == &fmt_crypt && #ifdef __sun strncmp(*ciphertext, "$md5$", 5) && strncmp(*ciphertext, "$md5,", 5) && #endif strncmp(*ciphertext, "$5$", 3) && strncmp(*ciphertext, "$6$", 3)) continue; #endif if (alt->methods.valid(*ciphertext,alt)) { alt->params.flags |= FMT_WARNED; #ifdef HAVE_MPI if (mpi_id == 0) #endif fprintf(stderr, "Warning: only loading hashes " "of type \"%s\", but also saw " "type \"%s\"\n" "Use the " "\"--format=%s\" option to force " "loading hashes of that type " "instead\n", (*format)->params.label, alt->params.label, alt->params.label); break; } } while ((alt = alt->next)); } return valid; } retval = -1; if ((alt = fmt_list)) do { int valid; char *prepared_CT = alt->methods.prepare(split_fields, alt); if (!prepared_CT || !*prepared_CT) continue; #ifdef HAVE_CRYPT /* * Only probe for support by the current system's crypt(3) if this is forced * from the command-line or/and if the hash encoding string looks like one of * those that are only supported in that way. Avoid the probe in other cases * because it may be slow and undesirable (false detection is possible). */ if (alt == &fmt_crypt && fmt_list != &fmt_crypt /* not forced */ && #ifdef __sun strncmp(prepared_CT, "$md5$", 5) && strncmp(prepared_CT, "$md5,", 5) && #endif strncmp(prepared_CT, "$5$", 3) && strncmp(prepared_CT, "$6$", 3)) continue; #endif if (!(valid = alt->methods.valid(prepared_CT, alt))) continue; if (retval < 0) { fmt_init(*format = alt); retval = valid; *ciphertext = prepared_CT; #ifdef LDR_WARN_AMBIGUOUS if (!source) /* not --show */ continue; #endif break; } #ifdef LDR_WARN_AMBIGUOUS #ifdef HAVE_MPI if (mpi_id == 0) #endif fprintf(stderr, "Warning: detected hash type \"%s\", but the string is " "also recognized as \"%s\"\n" "Use the \"--format=%s\" option to force loading these " "as that type instead\n", (*format)->params.label, alt->params.label, alt->params.label); #endif } while ((alt = alt->next)); return retval; }