Fixed tabs vs spaces and line endings.
This commit is contained in:
parent
716e1154fa
commit
cd4eeead62
6 changed files with 1044 additions and 1027 deletions
17
.gitattributes
vendored
Executable file
17
.gitattributes
vendored
Executable file
|
@ -0,0 +1,17 @@
|
||||||
|
# Set the default behavior, in case people don't have core.autocrlf set.
|
||||||
|
* text=auto
|
||||||
|
|
||||||
|
# Explicitly declare text files you want to always be normalized and converted
|
||||||
|
# to native line endings on checkout.
|
||||||
|
*.c text
|
||||||
|
*.h text
|
||||||
|
*.txt text
|
||||||
|
*.md text
|
||||||
|
|
||||||
|
# Declare files that will always have CRLF line endings on checkout.
|
||||||
|
*.sln text eol=crlf
|
||||||
|
|
||||||
|
# Denote all files that are truly binary and should not be modified.
|
||||||
|
*.png binary
|
||||||
|
*.jpg binary
|
||||||
|
*.exe binary
|
|
@ -175,7 +175,7 @@ cleanup:
|
||||||
|
|
||||||
bool aes_decrypt_check(m0_kdbx_header_entry_t *hdr, uint8_t *masterkey, m0_kdbx_payload_t *payload)
|
bool aes_decrypt_check(m0_kdbx_header_entry_t *hdr, uint8_t *masterkey, m0_kdbx_payload_t *payload)
|
||||||
{
|
{
|
||||||
bool res = false;
|
bool res = false;
|
||||||
|
|
||||||
BCRYPT_ALG_HANDLE aes = NULL;
|
BCRYPT_ALG_HANDLE aes = NULL;
|
||||||
BCRYPT_KEY_HANDLE ctx = NULL;
|
BCRYPT_KEY_HANDLE ctx = NULL;
|
||||||
|
@ -298,7 +298,7 @@ cleanup:
|
||||||
|
|
||||||
int sha256_hash(uint8_t *hash, uint8_t *data, size_t len)
|
int sha256_hash(uint8_t *hash, uint8_t *data, size_t len)
|
||||||
{
|
{
|
||||||
int res = 0;
|
int res = 0;
|
||||||
NTSTATUS status;
|
NTSTATUS status;
|
||||||
BCRYPT_ALG_HANDLE sha = NULL;
|
BCRYPT_ALG_HANDLE sha = NULL;
|
||||||
BCRYPT_HASH_HANDLE ctx = NULL;
|
BCRYPT_HASH_HANDLE ctx = NULL;
|
||||||
|
|
350
mod0keecrack.c
350
mod0keecrack.c
|
@ -50,70 +50,70 @@ static char *kdbx_filename;
|
||||||
|
|
||||||
size_t kdbx_headerentries_free(m0_kdbx_header_entry_t *e)
|
size_t kdbx_headerentries_free(m0_kdbx_header_entry_t *e)
|
||||||
{
|
{
|
||||||
size_t i = 0;
|
size_t i = 0;
|
||||||
|
|
||||||
for(i=0; i<HEADERIDCOUNT;i++) {
|
for(i=0; i<HEADERIDCOUNT;i++) {
|
||||||
|
|
||||||
if(e[i].data != NULL) {
|
if(e[i].data != NULL) {
|
||||||
free(e[i].data);
|
free(e[i].data);
|
||||||
memset(&e[i], 0, sizeof(m0_kdbx_header_entry_t));
|
memset(&e[i], 0, sizeof(m0_kdbx_header_entry_t));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t kdbx_headerentries_read(FILE *kdbx_fd, m0_kdbx_header_entry_t *entries)
|
size_t kdbx_headerentries_read(FILE *kdbx_fd, m0_kdbx_header_entry_t *entries)
|
||||||
{
|
{
|
||||||
size_t ret = 0;
|
size_t ret = 0;
|
||||||
size_t result = 0;
|
size_t result = 0;
|
||||||
|
|
||||||
uint8_t id = 0;
|
uint8_t id = 0;
|
||||||
|
|
||||||
if (entries == NULL)
|
if (entries == NULL)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
do {
|
do {
|
||||||
|
|
||||||
// headers have variable lengths.
|
// headers have variable lengths.
|
||||||
// we need to read: [1 byte hdr-id] [1 word data-len] [data-len bytes of value]
|
// we need to read: [1 byte hdr-id] [1 word data-len] [data-len bytes of value]
|
||||||
// if hdr-id == 0x00: header ends, encrypted payload starts.
|
// if hdr-id == 0x00: header ends, encrypted payload starts.
|
||||||
|
|
||||||
ret = fread(&id, sizeof(uint8_t), 1, kdbx_fd);
|
ret = fread(&id, sizeof(uint8_t), 1, kdbx_fd);
|
||||||
|
|
||||||
if ( ret != 1)
|
if ( ret != 1)
|
||||||
printf("[!] fread(id) failed.");
|
printf("[!] fread(id) failed.");
|
||||||
|
|
||||||
if(id > HEADERIDCOUNT) {
|
if(id > HEADERIDCOUNT) {
|
||||||
id = END;
|
id = END;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
entries[id].id = id;
|
entries[id].id = id;
|
||||||
|
|
||||||
ret = fread(&entries[id].len, sizeof(uint16_t), 1, kdbx_fd);
|
ret = fread(&entries[id].len, sizeof(uint16_t), 1, kdbx_fd);
|
||||||
|
|
||||||
if ( ret != 1)
|
if ( ret != 1)
|
||||||
printf("[!] fread(hdrlen) failed.");
|
printf("[!] fread(hdrlen) failed.");
|
||||||
|
|
||||||
entries[id].data = (uint8_t *)malloc(entries[id].len);
|
entries[id].data = (uint8_t *)malloc(entries[id].len);
|
||||||
|
|
||||||
if(entries[id].data == NULL) {
|
if(entries[id].data == NULL) {
|
||||||
printf("[!] malloc(entries[id].len) failed.");
|
printf("[!] malloc(entries[id].len) failed.");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = fread(entries[id].data, entries[id].len, 1, kdbx_fd);
|
ret = fread(entries[id].data, entries[id].len, 1, kdbx_fd);
|
||||||
|
|
||||||
if ( ret != 1)
|
if ( ret != 1)
|
||||||
printf("[!] fread(entries[%d].data) failed.", id);
|
printf("[!] fread(entries[%d].data) failed.", id);
|
||||||
|
|
||||||
if( (id == 3) || (id==10) ) {
|
if( (id == 3) || (id==10) ) {
|
||||||
memcpy(&entries[id].dw, entries[id].data, 4);
|
memcpy(&entries[id].dw, entries[id].data, 4);
|
||||||
memcpy(&entries[id].qw, entries[id].data, 4);
|
memcpy(&entries[id].qw, entries[id].data, 4);
|
||||||
} else if( id == 6 ) {
|
} else if( id == 6 ) {
|
||||||
memcpy(&entries[id].qw, entries[id].data, 8);
|
memcpy(&entries[id].qw, entries[id].data, 8);
|
||||||
}
|
}
|
||||||
result++;
|
result++;
|
||||||
|
|
||||||
} while (id != END);
|
} while (id != END);
|
||||||
|
|
||||||
|
@ -122,8 +122,8 @@ size_t kdbx_headerentries_read(FILE *kdbx_fd, m0_kdbx_header_entry_t *entries)
|
||||||
|
|
||||||
void kdbx_headerentries_dump(m0_kdbx_header_entry_t *h)
|
void kdbx_headerentries_dump(m0_kdbx_header_entry_t *h)
|
||||||
{
|
{
|
||||||
printf("[*] kdbx headerentries:\n");
|
printf("[*] kdbx headerentries:\n");
|
||||||
printf("[-] END: "); print_hex_buf(h[0].data, h[0].len); puts("");
|
printf("[-] END: "); print_hex_buf(h[0].data, h[0].len); puts("");
|
||||||
printf("[-] COMMENT: "); print_hex_buf(h[1].data, h[1].len); puts("");
|
printf("[-] COMMENT: "); print_hex_buf(h[1].data, h[1].len); puts("");
|
||||||
printf("[-] CIPHERID: "); print_hex_buf(h[2].data, h[2].len); puts("");
|
printf("[-] CIPHERID: "); print_hex_buf(h[2].data, h[2].len); puts("");
|
||||||
printf("[-] COMPRESSIONFLAGS: %08x\n", h[3].dw );
|
printf("[-] COMPRESSIONFLAGS: %08x\n", h[3].dw );
|
||||||
|
@ -139,21 +139,21 @@ void kdbx_headerentries_dump(m0_kdbx_header_entry_t *h)
|
||||||
|
|
||||||
size_t kdbx_header_read(FILE *kdbx_fd, m0_kdbx_header_t *header)
|
size_t kdbx_header_read(FILE *kdbx_fd, m0_kdbx_header_t *header)
|
||||||
{
|
{
|
||||||
size_t ret = 0;
|
size_t ret = 0;
|
||||||
|
|
||||||
if (header == NULL)
|
if (header == NULL)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
ret = fread(header, sizeof(m0_kdbx_header_t), 1, kdbx_fd);
|
ret = fread(header, sizeof(m0_kdbx_header_t), 1, kdbx_fd);
|
||||||
if ( ret != 1)
|
if ( ret != 1)
|
||||||
printf("[!] fread(m0_kdbx_header) failed.");
|
printf("[!] fread(m0_kdbx_header) failed.");
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
void kdbx_header_dump(m0_kdbx_header_t h)
|
void kdbx_header_dump(m0_kdbx_header_t h)
|
||||||
{
|
{
|
||||||
printf("[*] kdbx header:\n");
|
printf("[*] kdbx header:\n");
|
||||||
printf("[-] file magic: %08x\n", h.magic);
|
printf("[-] file magic: %08x\n", h.magic);
|
||||||
printf("[-] file identifier: %08x\n", h.identifier);
|
printf("[-] file identifier: %08x\n", h.identifier);
|
||||||
printf("[-] file minor version: %04x\n", (h.minor_version));
|
printf("[-] file minor version: %04x\n", (h.minor_version));
|
||||||
|
@ -163,13 +163,13 @@ void kdbx_header_dump(m0_kdbx_header_t h)
|
||||||
|
|
||||||
size_t kdbx_payload_read(FILE *kdbx_fd, m0_kdbx_payload_t *p)
|
size_t kdbx_payload_read(FILE *kdbx_fd, m0_kdbx_payload_t *p)
|
||||||
{
|
{
|
||||||
size_t ret = 0;
|
size_t ret = 0;
|
||||||
size_t payload_len = 0;
|
size_t payload_len = 0;
|
||||||
off_t off_start = 0;
|
off_t off_start = 0;
|
||||||
off_t off_end = 0;
|
off_t off_end = 0;
|
||||||
|
|
||||||
if (p == NULL)
|
if (p == NULL)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
off_start = ftell(kdbx_fd);
|
off_start = ftell(kdbx_fd);
|
||||||
|
|
||||||
|
@ -177,27 +177,27 @@ size_t kdbx_payload_read(FILE *kdbx_fd, m0_kdbx_payload_t *p)
|
||||||
off_end = ftell(kdbx_fd);
|
off_end = ftell(kdbx_fd);
|
||||||
fseek(kdbx_fd, off_start, SEEK_SET);
|
fseek(kdbx_fd, off_start, SEEK_SET);
|
||||||
|
|
||||||
p->offset_start = off_start;
|
p->offset_start = off_start;
|
||||||
p->len = (off_end-off_start);
|
p->len = (off_end-off_start);
|
||||||
p->encrypted = (uint8_t *)malloc(p->len);
|
p->encrypted = (uint8_t *)malloc(p->len);
|
||||||
|
|
||||||
if(p->encrypted == NULL) {
|
if(p->encrypted == NULL) {
|
||||||
printf("[!] malloc(payload->encrypted) failed.");
|
printf("[!] malloc(payload->encrypted) failed.");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
memset(p->encrypted, 0, p->len);
|
memset(p->encrypted, 0, p->len);
|
||||||
|
|
||||||
ret = fread(p->encrypted, p->len, 1, kdbx_fd);
|
ret = fread(p->encrypted, p->len, 1, kdbx_fd);
|
||||||
if ( ret != 1)
|
if ( ret != 1)
|
||||||
printf("[!] fread(payload) failed.");
|
printf("[!] fread(payload) failed.");
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
void kdbx_payload_dump(m0_kdbx_payload_t p)
|
void kdbx_payload_dump(m0_kdbx_payload_t p)
|
||||||
{
|
{
|
||||||
printf("[*] kdbx payload:\n");
|
printf("[*] kdbx payload:\n");
|
||||||
printf("[-] payload offset: %llx\n", p.offset_start);
|
printf("[-] payload offset: %llx\n", p.offset_start);
|
||||||
printf("[-] payload len: %x\n", p.len);
|
printf("[-] payload len: %x\n", p.len);
|
||||||
|
|
||||||
|
@ -207,48 +207,48 @@ void kdbx_payload_dump(m0_kdbx_payload_t p)
|
||||||
bool kdbx_payload_crack(m0_kdbx_database_t *db, FILE *wordlist_fd)
|
bool kdbx_payload_crack(m0_kdbx_database_t *db, FILE *wordlist_fd)
|
||||||
{
|
{
|
||||||
bool res = false;
|
bool res = false;
|
||||||
char pass[1024] = {0};
|
char pass[1024] = {0};
|
||||||
FILE *keyfd = NULL;
|
FILE *keyfd = NULL;
|
||||||
uint8_t *key_hash = NULL;
|
uint8_t *key_hash = NULL;
|
||||||
uint8_t *key_data = NULL;
|
uint8_t *key_data = NULL;
|
||||||
size_t key_len = 0;
|
size_t key_len = 0;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
// if there is a file named <databasename>.key, we use this key in addition to the password.
|
// if there is a file named <databasename>.key, we use this key in addition to the password.
|
||||||
// otherwise, only the password is used to unlock the database.
|
// otherwise, only the password is used to unlock the database.
|
||||||
keyfd = fopen(kdbx_filename, "rb");
|
keyfd = fopen(kdbx_filename, "rb");
|
||||||
|
|
||||||
if (!keyfd) {
|
if (!keyfd) {
|
||||||
printf("[*] Not using keyfile\n");
|
printf("[*] Not using keyfile\n");
|
||||||
key_hash = NULL;
|
key_hash = NULL;
|
||||||
} else {
|
} else {
|
||||||
printf("[*] Using keyfile %s\n", kdbx_filename);
|
printf("[*] Using keyfile %s\n", kdbx_filename);
|
||||||
key_hash = (uint8_t *)malloc(32);
|
key_hash = (uint8_t *)malloc(32);
|
||||||
if(!key_hash) {
|
if(!key_hash) {
|
||||||
printf("[!] key_hash = malloc(32) failed.");
|
printf("[!] key_hash = malloc(32) failed.");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
fseek(keyfd, 0, SEEK_END);
|
fseek(keyfd, 0, SEEK_END);
|
||||||
key_len = ftell(keyfd);
|
key_len = ftell(keyfd);
|
||||||
fseek(keyfd, 0, SEEK_SET);
|
fseek(keyfd, 0, SEEK_SET);
|
||||||
key_data = (uint8_t *)malloc(key_len);
|
key_data = (uint8_t *)malloc(key_len);
|
||||||
|
|
||||||
if(!key_data) {
|
if(!key_data) {
|
||||||
printf("[!] key_data = malloc(%d) failed.", key_len);
|
printf("[!] key_data = malloc(%d) failed.", key_len);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = fread(key_data, key_len, 1, keyfd);
|
ret = fread(key_data, key_len, 1, keyfd);
|
||||||
|
|
||||||
if ( ret != 1)
|
if ( ret != 1)
|
||||||
printf("[!] fread(key_data) failed.");
|
printf("[!] fread(key_data) failed.");
|
||||||
|
|
||||||
sha256_hash(key_hash, key_data, key_len);
|
sha256_hash(key_hash, key_data, key_len);
|
||||||
printf("[+] key hash: "); print_hex_buf(key_hash, 32); puts("");
|
printf("[+] key hash: "); print_hex_buf(key_hash, 32); puts("");
|
||||||
}
|
}
|
||||||
|
|
||||||
printf("[*] kdbx crack:\n");
|
printf("[*] kdbx crack:\n");
|
||||||
|
|
||||||
if( wordlist_fd == NULL )
|
if( wordlist_fd == NULL )
|
||||||
return false;
|
return false;
|
||||||
|
@ -258,8 +258,8 @@ bool kdbx_payload_crack(m0_kdbx_database_t *db, FILE *wordlist_fd)
|
||||||
if(len > 0)
|
if(len > 0)
|
||||||
pass[len-1] = 0x00;
|
pass[len-1] = 0x00;
|
||||||
|
|
||||||
res = kdbx_decrypt_payload(db, pass, key_hash);
|
res = kdbx_decrypt_payload(db, pass, key_hash);
|
||||||
if(res) {
|
if(res) {
|
||||||
printf("[*] decryption successful with password %s\n", pass);
|
printf("[*] decryption successful with password %s\n", pass);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -270,75 +270,75 @@ bool kdbx_payload_crack(m0_kdbx_database_t *db, FILE *wordlist_fd)
|
||||||
|
|
||||||
bool kdbx_decrypt_payload(m0_kdbx_database_t *db, char *pass, uint8_t *key_hash)
|
bool kdbx_decrypt_payload(m0_kdbx_database_t *db, char *pass, uint8_t *key_hash)
|
||||||
{
|
{
|
||||||
bool res = false;
|
bool res = false;
|
||||||
uint8_t hash[32] = {0};
|
uint8_t hash[32] = {0};
|
||||||
uint8_t composite_key[32] = {0};
|
uint8_t composite_key[32] = {0};
|
||||||
uint8_t composite_data[64] = {0};
|
uint8_t composite_data[64] = {0};
|
||||||
uint8_t transform_key[32] = {0};
|
uint8_t transform_key[32] = {0};
|
||||||
uint8_t master_key[32] = {0};
|
uint8_t master_key[32] = {0};
|
||||||
uint8_t *masterkey_input = NULL;
|
uint8_t *masterkey_input = NULL;
|
||||||
size_t masterkey_input_len = 0;
|
size_t masterkey_input_len = 0;
|
||||||
|
|
||||||
m0_kdbx_header_entry_t *hdr = &db->kdbxheader;
|
m0_kdbx_header_entry_t *hdr = &db->kdbxheader;
|
||||||
|
|
||||||
memset(composite_data, 0, 64);
|
memset(composite_data, 0, 64);
|
||||||
memset(transform_key, 0, 32);
|
memset(transform_key, 0, 32);
|
||||||
memset(master_key, 0, 32);
|
memset(master_key, 0, 32);
|
||||||
|
|
||||||
printf("[+] trying: %s\r", pass);
|
printf("[+] trying: %s\r", pass);
|
||||||
|
|
||||||
sha256_hash(hash, pass, strlen(pass));
|
sha256_hash(hash, pass, strlen(pass));
|
||||||
|
|
||||||
if(key_hash == NULL) {
|
if(key_hash == NULL) {
|
||||||
sha256_hash(composite_key, hash, sizeof(hash));
|
sha256_hash(composite_key, hash, sizeof(hash));
|
||||||
} else {
|
} else {
|
||||||
memcpy(composite_data, hash, sizeof(hash));
|
memcpy(composite_data, hash, sizeof(hash));
|
||||||
memcpy(composite_data+sizeof(hash), key_hash, sizeof(composite_data)-sizeof(hash));
|
memcpy(composite_data+sizeof(hash), key_hash, sizeof(composite_data)-sizeof(hash));
|
||||||
sha256_hash(composite_key, composite_data, sizeof(composite_data));
|
sha256_hash(composite_key, composite_data, sizeof(composite_data));
|
||||||
}
|
}
|
||||||
|
|
||||||
memcpy(transform_key, composite_key, sizeof(transform_key));
|
memcpy(transform_key, composite_key, sizeof(transform_key));
|
||||||
|
|
||||||
// aes_transformkey() is platform specific.
|
// aes_transformkey() is platform specific.
|
||||||
// For Windows, CNG is used and implemented in crypto-ms.c
|
// For Windows, CNG is used and implemented in crypto-ms.c
|
||||||
aes_transformkey(&db->kdbxheader, transform_key, sizeof(transform_key));
|
aes_transformkey(&db->kdbxheader, transform_key, sizeof(transform_key));
|
||||||
|
|
||||||
sha256_hash(transform_key, transform_key, sizeof(transform_key));
|
sha256_hash(transform_key, transform_key, sizeof(transform_key));
|
||||||
|
|
||||||
masterkey_input_len = sizeof(transform_key) + hdr[MASTERSEED].len;
|
masterkey_input_len = sizeof(transform_key) + hdr[MASTERSEED].len;
|
||||||
masterkey_input = (uint8_t *)malloc(masterkey_input_len);
|
masterkey_input = (uint8_t *)malloc(masterkey_input_len);
|
||||||
|
|
||||||
if(masterkey_input_len < hdr[MASTERSEED].len) {
|
if(masterkey_input_len < hdr[MASTERSEED].len) {
|
||||||
// should never happen, as masterkey len is (currently) 16 bit
|
// should never happen, as masterkey len is (currently) 16 bit
|
||||||
puts("[!] masterkey_input len integer overflow.");
|
puts("[!] masterkey_input len integer overflow.");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
memcpy(masterkey_input, hdr[MASTERSEED].data, hdr[MASTERSEED].len);
|
memcpy(masterkey_input, hdr[MASTERSEED].data, hdr[MASTERSEED].len);
|
||||||
memcpy(masterkey_input+hdr[MASTERSEED].len, transform_key, sizeof(transform_key));
|
memcpy(masterkey_input+hdr[MASTERSEED].len, transform_key, sizeof(transform_key));
|
||||||
|
|
||||||
sha256_hash(master_key, masterkey_input, masterkey_input_len);
|
sha256_hash(master_key, masterkey_input, masterkey_input_len);
|
||||||
|
|
||||||
// aes_decrypt_check() is platform specific.
|
// aes_decrypt_check() is platform specific.
|
||||||
// For Windows, CNG is used and implemented in crypto-ms.c
|
// For Windows, CNG is used and implemented in crypto-ms.c
|
||||||
res = aes_decrypt_check(hdr, master_key, &db->payload);
|
res = aes_decrypt_check(hdr, master_key, &db->payload);
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(int ac, char** av)
|
int main(int ac, char** av)
|
||||||
{
|
{
|
||||||
FILE *kdbx_fd = NULL;
|
FILE *kdbx_fd = NULL;
|
||||||
FILE *wordlist_fd = NULL;
|
FILE *wordlist_fd = NULL;
|
||||||
|
|
||||||
char *kdbx_path = NULL;
|
char *kdbx_path = NULL;
|
||||||
char *tmp = NULL;
|
char *tmp = NULL;
|
||||||
char *wordlist_path = NULL;
|
char *wordlist_path = NULL;
|
||||||
size_t filename_len = 0;
|
size_t filename_len = 0;
|
||||||
|
|
||||||
m0_kdbx_database_t kdbx_db = {0};
|
m0_kdbx_database_t kdbx_db = {0};
|
||||||
|
|
||||||
if(ac < 2)
|
if(ac < 2)
|
||||||
usage(av[0]);
|
usage(av[0]);
|
||||||
else if(ac > 2) {
|
else if(ac > 2) {
|
||||||
// wordlist from file
|
// wordlist from file
|
||||||
wordlist_path = av[2];
|
wordlist_path = av[2];
|
||||||
|
@ -346,65 +346,65 @@ int main(int ac, char** av)
|
||||||
// wordlist == stdin
|
// wordlist == stdin
|
||||||
}
|
}
|
||||||
|
|
||||||
memset(&kdbx_db, 0, sizeof(kdbx_db));
|
memset(&kdbx_db, 0, sizeof(kdbx_db));
|
||||||
|
|
||||||
kdbx_path = av[1];
|
kdbx_path = av[1];
|
||||||
filename_len = strlen(kdbx_path);
|
filename_len = strlen(kdbx_path);
|
||||||
kdbx_filename = (char *) malloc(filename_len + 5);
|
kdbx_filename = (char *) malloc(filename_len + 5);
|
||||||
memset(kdbx_filename, 0, filename_len+5);
|
memset(kdbx_filename, 0, filename_len+5);
|
||||||
|
|
||||||
if(filename_len > filename_len+5)
|
if(filename_len > filename_len+5)
|
||||||
exit(1);
|
exit(1);
|
||||||
|
|
||||||
memcpy(kdbx_filename, kdbx_path, filename_len);
|
memcpy(kdbx_filename, kdbx_path, filename_len);
|
||||||
tmp = strrchr(kdbx_filename, '.');
|
tmp = strrchr(kdbx_filename, '.');
|
||||||
|
|
||||||
if(tmp)
|
if(tmp)
|
||||||
memcpy(tmp, ".key\x00", 5);
|
memcpy(tmp, ".key\x00", 5);
|
||||||
else
|
else
|
||||||
strcat(kdbx_filename, ".key");
|
strcat(kdbx_filename, ".key");
|
||||||
|
|
||||||
printf("[*] using db: %s\n[*] using key: %s\n", kdbx_path, kdbx_filename);
|
printf("[*] using db: %s\n[*] using key: %s\n", kdbx_path, kdbx_filename);
|
||||||
|
|
||||||
kdbx_fd = fopen(kdbx_path, "rb");
|
kdbx_fd = fopen(kdbx_path, "rb");
|
||||||
|
|
||||||
if (!kdbx_fd) {
|
if (!kdbx_fd) {
|
||||||
printf("[!] Can't open kdbx %s\n", kdbx_path);
|
printf("[!] Can't open kdbx %s\n", kdbx_path);
|
||||||
exit(2);
|
exit(2);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(wordlist_path) {
|
if(wordlist_path) {
|
||||||
wordlist_fd = fopen(wordlist_path, "r");
|
wordlist_fd = fopen(wordlist_path, "r");
|
||||||
if (!wordlist_fd) {
|
if (!wordlist_fd) {
|
||||||
printf("[!] Can't open wordlist %s\n", wordlist_path);
|
printf("[!] Can't open wordlist %s\n", wordlist_path);
|
||||||
exit(2);
|
exit(2);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
wordlist_fd = stdin; //fdopen(stdin, "r");
|
wordlist_fd = stdin; //fdopen(stdin, "r");
|
||||||
if (!wordlist_fd) {
|
if (!wordlist_fd) {
|
||||||
printf("[!] Can't open wordlist from stdin\n");
|
printf("[!] Can't open wordlist from stdin\n");
|
||||||
exit(2);
|
exit(2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
kdbx_header_read(kdbx_fd, &kdbx_db.fileheader);
|
kdbx_header_read(kdbx_fd, &kdbx_db.fileheader);
|
||||||
kdbx_header_dump(kdbx_db.fileheader);
|
kdbx_header_dump(kdbx_db.fileheader);
|
||||||
|
|
||||||
kdbx_headerentries_read(kdbx_fd, &kdbx_db.kdbxheader);
|
kdbx_headerentries_read(kdbx_fd, &kdbx_db.kdbxheader);
|
||||||
kdbx_headerentries_dump(&kdbx_db.kdbxheader);
|
kdbx_headerentries_dump(&kdbx_db.kdbxheader);
|
||||||
|
|
||||||
kdbx_payload_read(kdbx_fd, &kdbx_db.payload);
|
kdbx_payload_read(kdbx_fd, &kdbx_db.payload);
|
||||||
kdbx_payload_dump(kdbx_db.payload);
|
kdbx_payload_dump(kdbx_db.payload);
|
||||||
|
|
||||||
kdbx_payload_crack(&kdbx_db, wordlist_fd);
|
kdbx_payload_crack(&kdbx_db, wordlist_fd);
|
||||||
|
|
||||||
kdbx_headerentries_free(&kdbx_db.kdbxheader);
|
kdbx_headerentries_free(&kdbx_db.kdbxheader);
|
||||||
fclose(kdbx_fd);
|
fclose(kdbx_fd);
|
||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void usage(char *prog)
|
static void usage(char *prog)
|
||||||
{
|
{
|
||||||
printf("[+] usage: %s <keepassx-file.kdbx> ...\n", prog);
|
printf("[+] usage: %s <keepassx-file.kdbx> ...\n", prog);
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
|
@ -38,55 +38,55 @@
|
||||||
#ifndef _MOD0KEECRACK_H
|
#ifndef _MOD0KEECRACK_H
|
||||||
#define _MOD0KEECRACK_H
|
#define _MOD0KEECRACK_H
|
||||||
|
|
||||||
typedef uintmax_t off_t;
|
typedef uintmax_t off_t;
|
||||||
|
|
||||||
|
|
||||||
enum _m0_kdbx_headerid {
|
enum _m0_kdbx_headerid {
|
||||||
END,
|
END,
|
||||||
COMMENT,
|
COMMENT,
|
||||||
CIPHERID,
|
CIPHERID,
|
||||||
COMPRESSIONFLAGS,
|
COMPRESSIONFLAGS,
|
||||||
MASTERSEED,
|
MASTERSEED,
|
||||||
TRANSFORMSEED, // 5
|
TRANSFORMSEED, // 5
|
||||||
TRANSFORMROUNDS,
|
TRANSFORMROUNDS,
|
||||||
ENCRYPTIONIV,
|
ENCRYPTIONIV,
|
||||||
PROTECTEDSTREAMKEY,
|
PROTECTEDSTREAMKEY,
|
||||||
STREAMSTARTBYTES,
|
STREAMSTARTBYTES,
|
||||||
INNERRANDOMSTREAMID, // 10
|
INNERRANDOMSTREAMID, // 10
|
||||||
HEADERIDCOUNT
|
HEADERIDCOUNT
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef enum _m0_kdbx_headerid m0_kdbx_headerid_t;
|
typedef enum _m0_kdbx_headerid m0_kdbx_headerid_t;
|
||||||
|
|
||||||
typedef struct _m0_kdbx_header_entry {
|
typedef struct _m0_kdbx_header_entry {
|
||||||
uint8_t id;
|
uint8_t id;
|
||||||
uint16_t len;
|
uint16_t len;
|
||||||
uint8_t *data;
|
uint8_t *data;
|
||||||
uint32_t dw;
|
uint32_t dw;
|
||||||
uint64_t qw;
|
uint64_t qw;
|
||||||
} m0_kdbx_header_entry_t;
|
} m0_kdbx_header_entry_t;
|
||||||
|
|
||||||
|
|
||||||
typedef struct _m0_kdbx_header {
|
typedef struct _m0_kdbx_header {
|
||||||
uint32_t magic;
|
uint32_t magic;
|
||||||
uint32_t identifier;
|
uint32_t identifier;
|
||||||
uint16_t minor_version;
|
uint16_t minor_version;
|
||||||
uint16_t major_version;
|
uint16_t major_version;
|
||||||
} m0_kdbx_header_t;
|
} m0_kdbx_header_t;
|
||||||
|
|
||||||
typedef struct _m0_kdbx_payload {
|
typedef struct _m0_kdbx_payload {
|
||||||
off_t offset_start;
|
off_t offset_start;
|
||||||
off_t pos;
|
off_t pos;
|
||||||
size_t len;
|
size_t len;
|
||||||
uint8_t *encrypted;
|
uint8_t *encrypted;
|
||||||
uint8_t *decrypted;
|
uint8_t *decrypted;
|
||||||
|
|
||||||
} m0_kdbx_payload_t;
|
} m0_kdbx_payload_t;
|
||||||
|
|
||||||
typedef struct _m0kdbx_data {
|
typedef struct _m0kdbx_data {
|
||||||
m0_kdbx_header_t header;
|
m0_kdbx_header_t header;
|
||||||
size_t data_len;
|
size_t data_len;
|
||||||
uint8_t *data;
|
uint8_t *data;
|
||||||
} m0_kbdx_data_t;
|
} m0_kbdx_data_t;
|
||||||
|
|
||||||
typedef struct _m0_kdbx_database {
|
typedef struct _m0_kdbx_database {
|
||||||
|
|
Loading…
Reference in a new issue