Openwall GNU/*/Linux - a small security-enhanced Linux distro for servers
[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Date: Sun, 10 May 2015 21:43:45 +0300
From: Aleksey Cherepanov <lyosha@...nwall.com>
To: john-dev@...ts.openwall.com
Subject: displaying full meta information about hashes with --show=types

I implemented --show=types option that prints all meta information
about hashes from file. It tries all formats against all hashes and
prints result in machine parseable format. It applies even formats
that are disabled. It tries generic crypt always. It respects
--format= option. It does not bypass john's heuristics for generic
crypt.

The format:
Once for hash:
  login,
  original ciphertext,
  uid,
  gid,
  gecos,
  home,
  shell.
For each valid format (may be nothing):
  label,
  is format disabled? (1/0),
  number of parts.
  For each part of splitted/canonical hash:
    is it same as oringal ciphertext? (1/0),
    canonical hash or empty string (if the format is disabled).
All fields are separated by field_sep_char.
Additional field_sep_char occurs at the end of line:
it does not break numeration of fields but
it allows parser to get field_sep_char from the line.


There are some TODOs in the code. I need comments on them.


magnum - I'll prepare a pull request for you. I feel guilty each time
you apply my patches manually. This patch does not have author
information. I'd like to add it. Also I'd like to add documentation.


BTW there is the following line in loader.c

 * ...with heavy changes in the jumbo patch, by magnum and various authors

Should I add my copyright there?


The patch is attached. It is against bleeding-jumbo.

Mathieu - I hope there won't be huge changes. You may start using the
patch to implement Johnny's 1.5.2:
 2. Hash type suggestion/guessing for individual hashes (which is the
    best way? do we have any support from JtR jumbo with that)


Example:

$ ../run/john --show=types ../../t.pw

Input:
NONE:0ed7dd550afb451ac5b94cb644310b09

Output:
NONE:0ed7dd550afb451ac5b94cb644310b09:::/:/:/::LM:0:2:0:$LM$0ed7dd550afb451a:0:$LM$c5b94cb644310b09:HAVAL-128-4:0:1:0:$haval$0ed7dd550afb451ac5b94cb644310b09:lotus5:0:1:1::MD2:0:1:1::mdc2:0:1:1::mscash:0:1:1::mscash2:0:1:1::NT:0:1:0:$NT$0ed7dd550afb451ac5b94cb644310b09:Raw-MD4:0:1:0:$MD4$0ed7dd550afb451ac5b94cb644310b09:Raw-MD5:0:1:0:$dynamic_0$0ed7dd550afb451ac5b94cb644310b09:Raw-MD5u:0:1:0:$dynamic_29$0ed7dd550afb451ac5b94cb644310b09:ripemd-128:0:1:0:$ripemd$0ed7dd550afb451ac5b94cb644310b09:Snefru-128:0:1:1::NT-old:0:1:0:$NT$0ed7dd550afb451ac5b94cb644310b09:


With breaks to describe parts:

About hash: login, hash, ...
NONE:0ed7dd550afb451ac5b94cb644310b09:::/:/:/::

By type:

     number of parts
     v     hash 1                 hash 2
LM:0:2:0:$LM$0ed7dd550afb451a:0:$LM$c5b94cb644310b09:
HAVAL-128-4:0:1:0:$haval$0ed7dd550afb451ac5b94cb644310b90:

           the canonical hash is the same as input hash
           | so there is empty string here
           v v
lotus5:0:1:1::
MD2:0:1:1::mdc2:0:1:1::
mscash:0:1:1::
mscash2:0:1:1::
NT:0:1:0:$NT$0ed7dd550afb451ac5b94cb644310b09:
Raw-MD4:0:1:0:$MD4$0ed7dd550afb451ac5b94cb644310b09:
Raw-MD5:0:1:0:$dynamic_0$0ed7dd550afb451ac5b94cb644310b09:
Raw-MD5u:0:1:0:$dynamic_29$0ed7dd550afb451ac5b94cb644310b09:
ripemd-128:0:1:0:$ripemd$0ed7dd550afb451ac5b94cb644310b09:
Snefru-128:0:1:1::
NT-old:0:1:0:$NT$0ed7dd550afb451ac5b94cb644310b09:

And it produces such detailed output for each input line.

Thanks!

-- 
Regards,
Aleksey Cherepanov

diff --git a/src/loader.c b/src/loader.c
index 777cece..9323a95 100644
--- a/src/loader.c
+++ b/src/loader.c
@@ -446,6 +446,90 @@ static int ldr_split_line(char **login, char **ciphertext,
 	if (ldr_check_list(db_opts->groups, gid, gid)) return 0;
 	if (ldr_check_shells(db_opts->shells, shell)) return 0;
 
+        /* TODO: Should john_main_process be checked? */
+	if (db_opts->showtypes) {
+		int fs = db_opts->field_sep_char;
+		/* To suppress warnings,
+		 * particularly from generic crypt's valid() (c3_fmt.c)
+		 */
+		/* TODO: Shoud a separate var be made? */
+		ldr_in_pot = 1;
+		/* TODO: right about \0 and \n? */
+		/* \0 and \n are not possible in any field. */
+		/* TODO: right field_sep_char? What about prepare that insert username into the hash? */
+		/* field_sep_char is not possible in any field too. */
+		/* The format:
+		 * Once for hash:
+		 *   login,
+		 *   original ciphertext,
+		 *   uid,
+		 *   gid,
+		 *   gecos,
+		 *   home,
+		 *   shell.
+		 * For each valid format (may be nothing):
+		 *   label,
+		 *   is format disabled? (1/0),
+		 *   number of parts.
+		 *   For each part of splitted/canonical hash:
+		 *     is it same as oringal ciphertext? (1/0),
+		 *     canonical hash or empty string (if the format is disabled).
+		 * All fields are separated by field_sep_char.
+		 * Additional field_sep_char occurs at the end of line:
+		 * it does not break numeration of fields but
+		 * it allows parser to get field_sep_char from the line.
+		 */
+		/* TODO: at the moment NONE from uid field becomes empty line. Is it ok? */
+		printf("%s%c%s%c%s%c%s%c%s%c%s%c%s%c",
+		       *login,
+		       fs, *ciphertext,
+		       fs, *uid,
+		       fs, gid,
+		       fs, *gecos,
+		       fs, *home,
+		       fs, shell,
+		       fs);
+		alt = fmt_list;
+		do {
+			char *prepared;
+			int disabled = 0;
+			int valid;
+			int part;
+			/* We don't skip generic crypt. */
+			/* Format disabled in john.conf */
+			if (cfg_get_bool(SECTION_DISABLED, SUBSECTION_FORMATS,
+			                 alt->params.label, 0)) {
+				/* TODO: should not I skip disabled formats? */
+				disabled = 1;
+			}
+			prepared = alt->methods.prepare(fields, alt);
+			if (!prepared)
+				continue;
+			valid = alt->methods.valid(prepared, alt);
+			if (!valid)
+				continue;
+			ldr_set_encoding(alt);
+			/* TODO: alt->params.label is the name of format? */
+			/* TODO: Is it guaranteed that format's label does not contain spaces? */
+			printf("%c%s%c%d%c%d",
+			       fs, alt->params.label,
+			       fs, disabled,
+			       fs, valid);
+			/* Canonical hash or hashes (like halfs of LM) */
+			for (part = 0; part < valid; part++) {
+				char *splitted = alt->methods.split(*ciphertext, part, alt);
+				/* TODO: handle splitted == 0; it should be a bug then */
+				int same = !strcmp(splitted, *ciphertext);
+				printf("%c%d%c%s",
+				       fs, same,
+				       fs, same ? "" : splitted);
+			}
+		} while ((alt = alt->next));
+		printf("%c\n", fs);
+		return 0;
+	}
+
+
 	if (*format) {
 		char *prepared;
 		int valid;
diff --git a/src/loader.h b/src/loader.h
index c74e844..ef2463d 100644
--- a/src/loader.h
+++ b/src/loader.h
@@ -198,6 +198,9 @@ struct db_options {
 /* if --show=left is used, john dumps the non-cracked hashes */
 	int showuncracked;
 
+/* if --show=types is used, john shows all hashes in machine readable form */
+	int showtypes;
+
 /* Field separator (normally ':') */
 	char field_sep_char;
 
diff --git a/src/options.c b/src/options.c
index 03ee4bc..5fa0aad 100644
--- a/src/options.c
+++ b/src/options.c
@@ -905,8 +905,11 @@ void opt_init(char *name, int argc, char **argv, int show_usage)
 			// instead of normal loading if we are in 'normal' show mode)
 			options.flags &= ~FLG_SHOW_CHK;
 		}
+		else if (!strcasecmp(show_uncracked_str, "types")) {
+			options.loader.showtypes = 1;
+		}
 		else {
-			fprintf(stderr, "Invalid option in --show switch.\nOnly --show or --show=left are valid\n");
+			fprintf(stderr, "Invalid option in --show switch.\nOnly --show , --show=left or --show=types are valid\n");
 			error();
 		}
 	}

Powered by blists - more mailing lists

Your e-mail address:

Powered by Openwall GNU/*/Linux - Powered by OpenVZ