From d83b872c5502bbbabeee1f95c9d7748f94ade20f Mon Sep 17 00:00:00 2001 From: Milan Broz Date: Fri, 20 Jul 2012 00:15:20 +0200 Subject: [PATCH] Add example of dictionary search. --- misc/dict_search/Makefile | 17 +++++++ misc/dict_search/README | 17 +++++++ misc/dict_search/luks_dict.c | 111 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 145 insertions(+) create mode 100644 misc/dict_search/Makefile create mode 100644 misc/dict_search/README create mode 100644 misc/dict_search/luks_dict.c diff --git a/misc/dict_search/Makefile b/misc/dict_search/Makefile new file mode 100644 index 0000000..5fe3e8c --- /dev/null +++ b/misc/dict_search/Makefile @@ -0,0 +1,17 @@ +TARGET=luks_dict +CFLAGS=-O2 -g -Wall -D_GNU_SOURCE +LDLIBS=-lcryptsetup +CC=gcc + +SOURCES=$(wildcard *.c) +OBJECTS=$(SOURCES:.c=.o) + +all: $(TARGET) + +$(TARGET): $(OBJECTS) + $(CC) -o $@ $^ $(LDLIBS) + +clean: + rm -f *.o *~ core $(TARGET) + +.PHONY: clean diff --git a/misc/dict_search/README b/misc/dict_search/README new file mode 100644 index 0000000..06e2ff7 --- /dev/null +++ b/misc/dict_search/README @@ -0,0 +1,17 @@ +Simple example how to use libcryptsetup +for password search. + +Run: luks_dict [cpus] + + is LUKS device or image + is list of passphrases to try +(note trailing EOL is stripped) + +cpus - number of processes to start in parallel + +Format of dictionary file is simple one password per line, +if first char on line s # it is skiped as comment. + +You have it run as root (device-mapper cannot +create dmcrypt devices as nrmal user. Code need +to map keyslots as temporary dmcrypt device.) diff --git a/misc/dict_search/luks_dict.c b/misc/dict_search/luks_dict.c new file mode 100644 index 0000000..847de9a --- /dev/null +++ b/misc/dict_search/luks_dict.c @@ -0,0 +1,111 @@ +/* + * Example of LUKS password dictionary search + * + * Run this as root, e.g. ./luks_check test.img /usr/share/john/password.lst 4 + * + * Copyright (C) 2012 Milan Broz + * + * This copyrighted material is made available to anyone wishing to use, + * modify, copy, or redistribute it subject to the terms and conditions + * of the GNU General Public License v.2. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define MAX_LEN 512 + +static void check(struct crypt_device *cd, const char *pwd_file, unsigned my_id, unsigned max_id) +{ + FILE *f; + int len, r; + unsigned long line = 0; + char pwd[MAX_LEN]; + + if (fork()) + return; + + /* open password file, now in separate process */ + f = fopen(pwd_file, "r"); + if (!f) { + printf("Cannot open %s.\n", pwd_file); + exit(EXIT_FAILURE); + } + + while (fgets(pwd, MAX_LEN, f)) { + + /* every process tries N-th line, skip others */ + if (line++ % max_id != my_id) + continue; + + len = strlen(pwd); + + /* lines starting "#" are comments */ + if (pwd[0] == '#') + continue; + + /* strip EOL - this is like a input from tty */ + if (len && pwd[len - 1] == '\n') { + pwd[len - 1] = '\0'; + len--; + } + + //printf("%d: checking %s\n", my_id, pwd); + r = crypt_activate_by_passphrase(cd, NULL, CRYPT_ANY_SLOT, pwd, len, 0); + if (r >= 0) { + printf("Found passphrase for slot %d: %s\n", r, pwd); + break; + } + } + + fclose(f); + crypt_free(cd); + exit(0); +} + +int main(int argc, char *argv[]) +{ + int i, status, procs = 4; + struct crypt_device *cd; + + if (argc < 3 || argc > 4) { + printf("Use: %s [#processes] %d\n", argv[0], argc); + exit(EXIT_FAILURE); + } + + if (argc == 4 && sscanf(argv[3], "%i", &procs) != 1) { + printf("Wrong number of processes.\n"); + exit(EXIT_FAILURE); + } + + /* signal all children if anything happens */ + prctl(PR_SET_PDEATHSIG, SIGHUP); + setpriority(PRIO_PROCESS, 0, -5); + + /* we are not going to modify anything, so common init is ok */ + if (crypt_init(&cd, argv[1]) || crypt_load(cd, CRYPT_LUKS1, NULL)) { + printf("Cannot open %s.\n", argv[1]); + exit(EXIT_FAILURE); + } + + /* run scan in separate processes */ + for (i = 0; i < procs; i++) + check(cd, argv[2], i, procs); + + /* wait until at least one finishes */ + wait(&status); + kill(0, SIGHUP); + return 0; +} -- 2.7.4