Created a tool using openssl crypto library. The tool can decrypt and
dump user's session key chain to stdout.
This commit is contained in:
parent
15ad4aec02
commit
f4eab5a202
9
CASA/test/micasa_dump/Makefile
Normal file
9
CASA/test/micasa_dump/Makefile
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
CFLAGS=-fpermissive -g
|
||||||
|
|
||||||
|
all: micasa-decrypt.exe
|
||||||
|
|
||||||
|
micasa-decrypt.exe: main.cpp
|
||||||
|
g++ $(CFLAGS) $^ -o $@ -lcrypto
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -f micasa-decrypt.exe
|
193
CASA/test/micasa_dump/main.cpp
Normal file
193
CASA/test/micasa_dump/main.cpp
Normal file
@ -0,0 +1,193 @@
|
|||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <assert.h>
|
||||||
|
#include <openssl/aes.h>
|
||||||
|
#include <openssl/evp.h>
|
||||||
|
#include <openssl/sha.h>
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
#define AES_KEY_128 128
|
||||||
|
#define AES_KEY_256 256
|
||||||
|
#define AES_KEY_BYTES_128 (AES_KEY_128/8)
|
||||||
|
#define AES_KEY_BYTES_256 (AES_KEY_256/8)
|
||||||
|
|
||||||
|
int password_to_key(const string *password,
|
||||||
|
const unsigned char *salt,
|
||||||
|
size_t salt_len,
|
||||||
|
unsigned char *key,
|
||||||
|
size_t key_len)
|
||||||
|
{
|
||||||
|
int rc;
|
||||||
|
unsigned char hash[20];
|
||||||
|
assert(key_len == AES_KEY_BYTES_128);
|
||||||
|
assert(salt_len == 64);
|
||||||
|
|
||||||
|
rc = PKCS5_PBKDF2_HMAC_SHA1(password->c_str(),
|
||||||
|
password->length(),
|
||||||
|
salt,
|
||||||
|
salt_len,
|
||||||
|
1000 /*iter*/,
|
||||||
|
key_len,
|
||||||
|
key);
|
||||||
|
|
||||||
|
return (rc == 1)? 0 : 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int decrypt(const unsigned char *in,
|
||||||
|
unsigned char *out,
|
||||||
|
size_t len,
|
||||||
|
const unsigned char *key,
|
||||||
|
size_t key_len,
|
||||||
|
const unsigned char *IV,
|
||||||
|
size_t IV_len)
|
||||||
|
{
|
||||||
|
AES_KEY key_dec;
|
||||||
|
|
||||||
|
assert((key_len == AES_KEY_BYTES_128) || (key_len = AES_KEY_BYTES_256));
|
||||||
|
assert(IV_len == AES_KEY_BYTES_128);
|
||||||
|
|
||||||
|
assert(len % 16 == 0);
|
||||||
|
|
||||||
|
AES_set_decrypt_key(key, key_len*8, &key_dec);
|
||||||
|
AES_cbc_encrypt(in, out, len, &key_dec, IV, AES_DECRYPT);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* decrypt and validate checksum. in := (256 bit checksum) | (cipher text) */
|
||||||
|
int decrypt_and_validate(const unsigned char *in,
|
||||||
|
unsigned char *out,
|
||||||
|
size_t *len,
|
||||||
|
const unsigned char *key,
|
||||||
|
size_t key_len,
|
||||||
|
const unsigned char *IV,
|
||||||
|
size_t IV_len) {
|
||||||
|
int rc, l = *len;
|
||||||
|
const unsigned char *hash = in, *CT = in + 32;
|
||||||
|
unsigned char *h, md[32];
|
||||||
|
|
||||||
|
assert(*len > 32);
|
||||||
|
|
||||||
|
rc = decrypt(CT, out, *len - 32, key, key_len, IV, IV_len);
|
||||||
|
|
||||||
|
*len = (*len - 32) - out[*len - 32 - 1];
|
||||||
|
bzero(out + *len, l - *len);
|
||||||
|
h = SHA256(out, *len, md);
|
||||||
|
assert(memcmp(md, hash, 32) == 0);
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
int decrypt_and_validate_file(string file,
|
||||||
|
unsigned char *out,
|
||||||
|
size_t *len,
|
||||||
|
const unsigned char *key,
|
||||||
|
size_t key_len)
|
||||||
|
{
|
||||||
|
int rc, l, in_len = *len;
|
||||||
|
unsigned char IV[16], *CT;
|
||||||
|
FILE *fd;
|
||||||
|
|
||||||
|
/* Open the encrypted file and read contents */
|
||||||
|
fd = fopen(file.c_str(), "r");
|
||||||
|
assert(fd != NULL);
|
||||||
|
CT = new unsigned char[*len];
|
||||||
|
*len = fread((void *)CT, 1, *len, fd);
|
||||||
|
assert(*len < in_len);
|
||||||
|
fclose(fd);
|
||||||
|
|
||||||
|
/* Read the IV */
|
||||||
|
file.append(".IV");
|
||||||
|
fd = fopen(file.c_str(), "r");
|
||||||
|
assert(fd != NULL);
|
||||||
|
l = fread((void *)IV, 1, sizeof(IV), fd);
|
||||||
|
assert(l == sizeof(IV));
|
||||||
|
/* Add a check to ensure that file size is exactly 16 bytes */
|
||||||
|
fclose(fd);
|
||||||
|
|
||||||
|
/* Decrypt */
|
||||||
|
rc = decrypt_and_validate(CT, out, len, key, key_len, IV, sizeof(IV));
|
||||||
|
|
||||||
|
bzero(out + (*len), in_len - (*len));
|
||||||
|
|
||||||
|
delete [] CT;
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
main()
|
||||||
|
{
|
||||||
|
int rc;
|
||||||
|
size_t len;
|
||||||
|
FILE *fd;
|
||||||
|
unsigned char passcode[16], key[32];
|
||||||
|
string user, user_store;
|
||||||
|
|
||||||
|
cout << "User: ";
|
||||||
|
cin >> user;
|
||||||
|
|
||||||
|
user_store = "/home/.casa/" + user + "/";
|
||||||
|
|
||||||
|
/* Get passcode. Usually encrypted with desktop password */
|
||||||
|
{
|
||||||
|
unsigned char salt[64], passcode_dec[32], IV[16];
|
||||||
|
unsigned char passcode_enc[128], password_key[16];
|
||||||
|
string password;
|
||||||
|
|
||||||
|
/* Read salt */
|
||||||
|
fd = fopen((user_store + ".miCASAPCByDesktop.salt").c_str(), "r");
|
||||||
|
len = fread((void *)salt, 1, sizeof(salt), fd);
|
||||||
|
assert(len == sizeof(salt));
|
||||||
|
fclose(fd);
|
||||||
|
|
||||||
|
/* Read IV */
|
||||||
|
fd = fopen((user_store + ".miCASAPCByDesktop.IV").c_str(), "r");
|
||||||
|
len = fread((void *)IV, 1, sizeof(IV), fd);
|
||||||
|
assert(len == sizeof(IV));
|
||||||
|
fclose(fd);
|
||||||
|
|
||||||
|
/* Prompt user for password and convert password to key */
|
||||||
|
cout << "Password: ";
|
||||||
|
cin >> password;
|
||||||
|
password_to_key(&password, salt, sizeof(salt), password_key, sizeof(password_key));
|
||||||
|
|
||||||
|
/* Read encrypted passcode */
|
||||||
|
fd = fopen((user_store + ".miCASAPCByDesktop").c_str(), "r");
|
||||||
|
len = fread((void *)passcode_enc, 1, sizeof(passcode_enc), fd);
|
||||||
|
assert(len == sizeof(passcode_dec));
|
||||||
|
fclose(fd);
|
||||||
|
|
||||||
|
/* Decrypt */
|
||||||
|
rc = decrypt(passcode_enc, passcode_dec, len, password_key,
|
||||||
|
sizeof(password_key), IV, sizeof(IV));
|
||||||
|
assert(rc == 0);
|
||||||
|
|
||||||
|
memcpy(passcode, passcode_dec, sizeof(passcode));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* get secret key from .miCASAKey */
|
||||||
|
{
|
||||||
|
unsigned char plain_text[128];
|
||||||
|
|
||||||
|
len = sizeof(plain_text);
|
||||||
|
rc = decrypt_and_validate_file(user_store + ".miCASAKey",
|
||||||
|
plain_text, &len, passcode,
|
||||||
|
sizeof(passcode));
|
||||||
|
assert(len == sizeof(key));
|
||||||
|
memcpy(key, plain_text, sizeof(key));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Decrypt micasa store */
|
||||||
|
{
|
||||||
|
unsigned char plain_text[4096];
|
||||||
|
|
||||||
|
len = sizeof(plain_text);
|
||||||
|
rc = decrypt_and_validate_file(user_store + ".miCASA",
|
||||||
|
plain_text, &len, key,
|
||||||
|
sizeof(key));
|
||||||
|
puts(plain_text);
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user