Exemple #1
0
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);
	}
}
Exemple #2
0
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));
}
Exemple #3
0
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));
}
Exemple #4
0
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));
}
Exemple #5
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)
{
	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;
}
Exemple #6
0
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;
}
Exemple #7
0
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;
}