diff --git a/AUTHORS b/AUTHORS index 6d44df3..4b1bb72 100644 --- a/AUTHORS +++ b/AUTHORS @@ -1 +1,2 @@ -2014-2015 Guillaume LE VAILLANT +2014-2016 Guillaume LE VAILLANT +2016-2016 Petr Špaček diff --git a/ChangeLog b/ChangeLog index 39a67ec..a606afb 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2016-01-10 Guillaume LE VAILLANT + Version 1.2.0 + Root privileges are not required anymore. + 2015-10-31 Guillaume LE VAILLANT Version 1.1 Print progress info when sending a USR1 signal to the process. diff --git a/NEWS b/NEWS index ee8f6cc..90f13bc 100644 --- a/NEWS +++ b/NEWS @@ -1,4 +1,4 @@ -Version 1.2 +Version 1.2.0 2016-01-08 Root privileges are not required anymore because cryptsetup is called in dry-run mode which does not actually change device mapper configuration. diff --git a/README b/README index 023966f..f99a033 100644 --- a/README +++ b/README @@ -70,6 +70,13 @@ the passwords contained in a dictionary file: bruteforce-luks -t 6 -f dictionary.txt /dev/sdd1 +Instead of passing a block device to the program, you can copy the beginning +of the LUKS volume to a file and pass this file to the program: + + sudo dd if=/dev/sda1 of=/tmp/luks-header bs=1M count=10 + bruteforce-luks -t 4 -l 5 -m 5 /tmp/luks-header + + Print progress info: pkill -USR1 -f bruteforce-luks diff --git a/configure.ac b/configure.ac index 70fb042..6bb5571 100644 --- a/configure.ac +++ b/configure.ac @@ -1,4 +1,4 @@ -AC_INIT(bruteforce_luks, 1.2) +AC_INIT(bruteforce_luks, 1.2.0) AM_INIT_AUTOMAKE AC_CONFIG_SRCDIR(src/bruteforce-luks.c) diff --git a/contrib/gentoo/app-crypt/bruteforce-luks/bruteforce-luks-1.2.0.ebuild b/contrib/gentoo/app-crypt/bruteforce-luks/bruteforce-luks-1.2.0.ebuild new file mode 100644 index 0000000..d6dc852 --- /dev/null +++ b/contrib/gentoo/app-crypt/bruteforce-luks/bruteforce-luks-1.2.0.ebuild @@ -0,0 +1,32 @@ +# Copyright 2014 Guillaume LE VAILLANT +# Distributed under the terms of the GNU General Public License v3 + +EAPI="5" + +inherit eutils autotools + +DESCRIPTION="A bruteforce cracker for LUKS encrypted volumes." +HOMEPAGE="https://github.com/glv2/${PN}" +SRC_URI="https://github.com/glv2/${PN}/archive/${PV}.tar.gz -> ${P}.tar.gz" + +LICENSE="GPL-3" +SLOT="0" +KEYWORDS="~amd64 ~arm ~x86" + +DEPEND=" + sys-fs/cryptsetup +" +RDEPEND="${DEPEND}" + +src_prepare() { + eautoreconf +} + +src_configure() { + econf +} + +src_install() { + einstall + dodoc AUTHORS ChangeLog NEWS README +} diff --git a/doc/bruteforce-luks.1 b/doc/bruteforce-luks.1 index a242a3e..4d04a0b 100644 --- a/doc/bruteforce-luks.1 +++ b/doc/bruteforce-luks.1 @@ -1,120 +1,104 @@ -.TH BRUTEFORCE-LUKS "1" "Nov 2015" "BRUTEFORCE-LUKS 1.1" "Bruteforce LUKS encrypted volume" +.TH BRUTEFORCE-LUKS "1" "January 2016" "BRUTEFORCE-LUKS 1.2.0" "Bruteforce LUKS encrypted volume" .SH NAME -bruteforce-luks \- try to find the password of a LUKS volume +bruteforce-luks - try to find the password of a LUKS volume .SH SYNOPSIS -\fBbruteforce-luks\fP [\fBoptions\fP] <\fIpath to LUKS volume\fP> +.B bruteforce-luks [options] +.I .SH DESCRIPTION -The program tries to decrypt at least one of the key slots by trying -all the possible passwords. It is especially useful if you know -something about the password (i.e. you forgot a part of your password but still -remember most of it). Finding the password of a volume without knowing -anything about it would take way too much time (unless the password is really -short and/or weak). -.PP -There are command line options to specify: +The purpose of this program is to try to find the password of a LUKS +encrypted volume. +.P +It can be used in two ways: .RS -.IP \(bu 2 -the minimum password length to try -.IP \(bu 2 -the maximum password length to try -.IP \(bu 2 -the beginning of the password -.IP \(bu 2 -the end of the password -.IP \(bu 2 -the character set to use (among the characters of the current locale) +.P +\(bu brute force attack: try all the possible passwords given a character set. +It is especially useful if you know something about the password (i.e. you +forgot a part of your password but still remember most of it). Finding the +password of a volume without knowing anything about it would take way too much +time (unless the password is really short and/or weak). +.P +\(bu dictionary attack: try all the passwords in a file. +.RE +.P +The program can use several threads (the number of threads can be specified +with the +.I -t +command line option). +.P +Sending a USR1 signal to a running +.B bruteforce-luks +process makes it print progress info to standard error and continue. .SH OPTIONS -.TP -.B \-b .nf +.TP +.B -b Beginning of the password. -.nf Default: "" .TP -.B \-e -.nf +.B -e End of the password. -.nf Default: "" .TP -.B \-f -.nf +.B -f Read the passwords from a file instead of generating them. .TP -.B \-h -.nf +.B -h Show help and quit. .TP -.B \-l -.nf +.B -l Minimum password length (beginning and end included). -.nf Default: 1 .TP -.B \-m -.nf +.B -m Maximum password length (beginning and end included). -.nf Default: 8 .TP -.B \-s -.nf +.B -s Password character set. -.nf Default: "0123456789ABCDEFGHIJKLMNOPQRSTU VWXYZabcdefghijklmnopqrstuvwxyz" .TP -.B \-t -.nf +.B -t Number of threads to use. -.nf Default: 1 -.PP -Sending a USR1 signal to a running \fBbruteforce-luks\fP process -makes it print progress info to standard error and continue. .SH EXAMPLES Try to find the password of a LUKS encrypted volume using 4 threads, trying only passwords with 5 characters: -.PP +.sp .nf -.fam C bruteforce-luks -t 4 -l 5 -m 5 /dev/sdb1 - - -.fam T +.P .fi Try to find the password of a LUKS encrypted volume using 8 threads, trying only passwords with 5 to 10 characters beginning with "W4l" and ending with "z": -.PP +.sp .nf -.fam C bruteforce-luks -t 8 -l 5 -m 10 -b "W4l" -e "z" /dev/sda2 - - -.fam T +.P .fi Try to find the password of a LUKS encrypted volume using 8 threads, trying only passwords with 10 characters using the character set "P情8ŭ": -.PP +.sp .nf -.fam C bruteforce-luks -t 8 -l 10 -m 10 -s "P情8ŭ" /dev/sdc3 - - -.fam T +.P .fi Try to find the password of a LUKS encrypted volume using 6 threads, trying the passwords contained in a dictionary file: -.PP +.sp .nf -.fam C bruteforce-luks -t 6 -f dictionary.txt /dev/sdd1 - - -.fam T +.P +.fi +Instead of passing a block device to the program, you can copy the beginning +of the LUKS volume to a file and pass this file to the program: +.sp +.nf + sudo dd if=/dev/sda1 of=/tmp/luks-header bs=1M count=10 + bruteforce-luks -t 4 -l 5 -m 5 /tmp/luks-header +.P .fi Print progress info: -.PP +.sp .nf -.fam C pkill -USR1 -f bruteforce-luks diff --git a/src/bruteforce-luks.c b/src/bruteforce-luks.c index d56ed16..085db01 100644 --- a/src/bruteforce-luks.c +++ b/src/bruteforce-luks.c @@ -1,7 +1,7 @@ /* Bruteforce a LUKS volume. -Copyright 2014-2015 Guillaume LE VAILLANT +Copyright 2014-2016 Guillaume LE VAILLANT This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -94,6 +94,10 @@ void * decryption_func_bruteforce(void *arg) index_start = dfargs->index_start; index_end = dfargs->index_end; + /* Load the LUKS volume header */ + crypt_init(&cd, path); + crypt_load(cd, CRYPT_LUKS1, NULL); + /* For every possible length */ for(len = min_len - prefix_len - 1 - suffix_len; len + 1 <= max_len - prefix_len - suffix_len; len++) { @@ -131,8 +135,6 @@ void * decryption_func_bruteforce(void *arg) wcstombs(pwd, password, pwd_len + 1); /* Decrypt the LUKS volume with the password */ - crypt_init(&cd, path); - crypt_load(cd, CRYPT_LUKS1, NULL); ret = crypt_activate_by_passphrase(cd, NULL, CRYPT_ANY_SLOT, pwd, pwd_len, CRYPT_ACTIVATE_READONLY); dfargs->counter++; if(ret >= 0) @@ -150,7 +152,6 @@ void * decryption_func_bruteforce(void *arg) fprintf(stderr, "Error: access to the LUKS volume denied.\n\n"); stop = 1; } - crypt_free(cd); free(pwd); @@ -173,6 +174,8 @@ void * decryption_func_bruteforce(void *arg) } } + crypt_free(cd); + pthread_exit(NULL); } @@ -246,6 +249,10 @@ void * decryption_func_dictionary(void *arg) dfargs = (struct decryption_func_locals *) arg; + /* Load the LUKS volume header */ + crypt_init(&cd, path); + crypt_load(cd, CRYPT_LUKS1, NULL); + do { ret = read_dictionary_line(&pwd, &pwd_len); @@ -253,8 +260,6 @@ void * decryption_func_dictionary(void *arg) break; /* Decrypt the LUKS volume with the password */ - crypt_init(&cd, path); - crypt_load(cd, CRYPT_LUKS1, NULL); ret = crypt_activate_by_passphrase(cd, NULL, CRYPT_ANY_SLOT, pwd, pwd_len, CRYPT_ACTIVATE_READONLY); dfargs->counter++; if(ret >= 0) @@ -272,12 +277,13 @@ void * decryption_func_dictionary(void *arg) fprintf(stderr, "Error: access to the LUKS volume denied.\n\n"); stop = 1; } - crypt_free(cd); free(pwd); } while(stop == 0); + crypt_free(cd); + pthread_exit(NULL); } @@ -524,7 +530,7 @@ int main(int argc, char **argv) ret = check_path(path); if(ret == 0) { - fprintf(stderr, "Error: %s is not a valid LUKS volume.\n\n", path); + fprintf(stderr, "Error: either %s is not a valid LUKS volume, or you don't have permission to access it.\n\n", path); exit(EXIT_FAILURE); } diff --git a/src/version.h b/src/version.h index 6373ba2..9093ac1 100644 --- a/src/version.h +++ b/src/version.h @@ -1,7 +1,7 @@ /* Bruteforce a LUKS volume. -Copyright 2014-2015 Guillaume LE VAILLANT +Copyright 2014-2016 Guillaume LE VAILLANT This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -20,6 +20,6 @@ along with this program. If not, see . #ifndef VERSION_H #define VERSION_H 1 -#define VERSION_NUMBER "1.1" +#define VERSION_NUMBER "1.2.0" #endif