mirror of
https://github.com/hashcat/hashcat.git
synced 2024-11-26 09:58:16 +00:00
fixes #1239: remove AES padding attack for 7zip since we can't guarantee that the padding is always zero
This commit is contained in:
parent
7bd391df71
commit
1f93d2060f
@ -808,11 +808,6 @@ typedef struct seven_zip_hook_salt
|
|||||||
char coder_attributes[5 + 1];
|
char coder_attributes[5 + 1];
|
||||||
u8 coder_attributes_len;
|
u8 coder_attributes_len;
|
||||||
|
|
||||||
u32 margin;
|
|
||||||
|
|
||||||
bool padding_check_full;
|
|
||||||
bool padding_check_fast;
|
|
||||||
|
|
||||||
int aes_len; // pre-computed length of the maximal (subset of) data we need for AES-CBC
|
int aes_len; // pre-computed length of the maximal (subset of) data we need for AES-CBC
|
||||||
|
|
||||||
} seven_zip_hook_salt_t;
|
} seven_zip_hook_salt_t;
|
||||||
|
186
src/interface.c
186
src/interface.c
@ -11854,21 +11854,6 @@ int seven_zip_parse_hash (u8 *input_buf, u32 input_len, hash_t *hash_buf, MAYBE_
|
|||||||
seven_zip->aes_len = aes_len;
|
seven_zip->aes_len = aes_len;
|
||||||
|
|
||||||
const u32 margin = data_len - unpack_size;
|
const u32 margin = data_len - unpack_size;
|
||||||
seven_zip->margin = margin;
|
|
||||||
|
|
||||||
seven_zip->padding_check_fast = (margin > 0) && (data_len >= 32);
|
|
||||||
|
|
||||||
if ((margin > 0) && (data_len < 32))
|
|
||||||
{
|
|
||||||
if ((data_len - aes_len) <= 16) // we need the same amount of AES BLOCKS (should always be true)!
|
|
||||||
{
|
|
||||||
seven_zip->padding_check_full = true; // determine if AES-CBC padding attack is possible
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
seven_zip->padding_check_full = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (data_type != 0x80)
|
if (data_type != 0x80)
|
||||||
{
|
{
|
||||||
@ -14798,14 +14783,7 @@ void seven_zip_hook_func (hc_device_param_t *device_param, hashes_t *hashes, con
|
|||||||
|
|
||||||
u8 data_type = seven_zip->data_type;
|
u8 data_type = seven_zip->data_type;
|
||||||
u32 *data_buf = seven_zip->data_buf;
|
u32 *data_buf = seven_zip->data_buf;
|
||||||
u32 data_len = seven_zip->data_len;
|
|
||||||
u32 unpack_size = seven_zip->unpack_size;
|
u32 unpack_size = seven_zip->unpack_size;
|
||||||
u32 margin = seven_zip->margin;
|
|
||||||
|
|
||||||
// can we use the padding attack:
|
|
||||||
|
|
||||||
u32 padding_check_fast = seven_zip->padding_check_fast;
|
|
||||||
u32 padding_check_full = seven_zip->padding_check_full;
|
|
||||||
|
|
||||||
for (u32 pw_pos = 0; pw_pos < pws_cnt; pw_pos++)
|
for (u32 pw_pos = 0; pw_pos < pws_cnt; pw_pos++)
|
||||||
{
|
{
|
||||||
@ -14823,99 +14801,6 @@ void seven_zip_hook_func (hc_device_param_t *device_param, hashes_t *hashes, con
|
|||||||
|
|
||||||
AES_set_decrypt_key (ukey, 256, &aes_key);
|
AES_set_decrypt_key (ukey, 256, &aes_key);
|
||||||
|
|
||||||
AES_KEY aes_key_copied;
|
|
||||||
|
|
||||||
memcpy (&aes_key_copied, &aes_key, sizeof (AES_KEY));
|
|
||||||
|
|
||||||
if (padding_check_fast == true) // use part of the data as initialization vector
|
|
||||||
{
|
|
||||||
u8 *data_buf_ptr = (u8 *) data_buf;
|
|
||||||
|
|
||||||
u32 data_tmp_buf[8];
|
|
||||||
|
|
||||||
memcpy (&data_tmp_buf, data_buf_ptr + data_len - 32, 32);
|
|
||||||
|
|
||||||
u32 data[4];
|
|
||||||
|
|
||||||
data[0] = data_tmp_buf[4];
|
|
||||||
data[1] = data_tmp_buf[5];
|
|
||||||
data[2] = data_tmp_buf[6];
|
|
||||||
data[3] = data_tmp_buf[7];
|
|
||||||
|
|
||||||
u32 out[4];
|
|
||||||
|
|
||||||
AES_decrypt (&aes_key, (u8*) data, (u8*) out);
|
|
||||||
|
|
||||||
out[0] ^= data_tmp_buf[0];
|
|
||||||
out[1] ^= data_tmp_buf[1];
|
|
||||||
out[2] ^= data_tmp_buf[2];
|
|
||||||
out[3] ^= data_tmp_buf[3];
|
|
||||||
|
|
||||||
switch (margin)
|
|
||||||
{
|
|
||||||
case 15: out[0] &= 0xffffff00;
|
|
||||||
break;
|
|
||||||
case 14: out[0] &= 0xffff0000;
|
|
||||||
break;
|
|
||||||
case 13: out[0] &= 0xff000000;
|
|
||||||
break;
|
|
||||||
case 12: out[0] = 0;
|
|
||||||
break;
|
|
||||||
case 11: out[0] = 0;
|
|
||||||
out[1] &= 0xffffff00;
|
|
||||||
break;
|
|
||||||
case 10: out[0] = 0;
|
|
||||||
out[1] &= 0xffff0000;
|
|
||||||
break;
|
|
||||||
case 9: out[0] = 0;
|
|
||||||
out[1] &= 0xff000000;
|
|
||||||
break;
|
|
||||||
case 8: out[0] = 0;
|
|
||||||
out[1] = 0;
|
|
||||||
break;
|
|
||||||
case 7: out[0] = 0;
|
|
||||||
out[1] = 0;
|
|
||||||
out[2] &= 0xffffff00;
|
|
||||||
break;
|
|
||||||
case 6: out[0] = 0;
|
|
||||||
out[1] = 0;
|
|
||||||
out[2] &= 0xffff0000;
|
|
||||||
break;
|
|
||||||
case 5: out[0] = 0;
|
|
||||||
out[1] = 0;
|
|
||||||
out[2] &= 0xff000000;
|
|
||||||
break;
|
|
||||||
case 4: out[0] = 0;
|
|
||||||
out[1] = 0;
|
|
||||||
out[2] = 0;
|
|
||||||
break;
|
|
||||||
case 3: out[0] = 0;
|
|
||||||
out[1] = 0;
|
|
||||||
out[2] = 0;
|
|
||||||
out[3] &= 0xffffff00;
|
|
||||||
break;
|
|
||||||
case 2: out[0] = 0;
|
|
||||||
out[1] = 0;
|
|
||||||
out[2] = 0;
|
|
||||||
out[3] &= 0xffff0000;
|
|
||||||
break;
|
|
||||||
case 1: out[0] = 0;
|
|
||||||
out[1] = 0;
|
|
||||||
out[2] = 0;
|
|
||||||
out[3] &= 0xff000000;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((out[0] != 0) || (out[1] != 0) || (out[2] != 0) || (out[3] != 0))
|
|
||||||
{
|
|
||||||
hook_item->hook_success = 0;
|
|
||||||
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// if the previous check was okay, we need to do some more staff to eliminate some possible false positives
|
|
||||||
|
|
||||||
int aes_len = seven_zip->aes_len;
|
int aes_len = seven_zip->aes_len;
|
||||||
|
|
||||||
u32 data[4];
|
u32 data[4];
|
||||||
@ -14941,7 +14826,7 @@ void seven_zip_hook_func (hc_device_param_t *device_param, hashes_t *hashes, con
|
|||||||
data[2] = data_buf[j + 2];
|
data[2] = data_buf[j + 2];
|
||||||
data[3] = data_buf[j + 3];
|
data[3] = data_buf[j + 3];
|
||||||
|
|
||||||
AES_decrypt (&aes_key_copied, (u8*) data, (u8*) out);
|
AES_decrypt (&aes_key, (u8*) data, (u8*) out);
|
||||||
|
|
||||||
out[0] ^= iv[0];
|
out[0] ^= iv[0];
|
||||||
out[1] ^= iv[1];
|
out[1] ^= iv[1];
|
||||||
@ -14966,7 +14851,7 @@ void seven_zip_hook_func (hc_device_param_t *device_param, hashes_t *hashes, con
|
|||||||
data[2] = data_buf[j + 2];
|
data[2] = data_buf[j + 2];
|
||||||
data[3] = data_buf[j + 3];
|
data[3] = data_buf[j + 3];
|
||||||
|
|
||||||
AES_decrypt (&aes_key_copied, (u8*) data, (u8*) out);
|
AES_decrypt (&aes_key, (u8*) data, (u8*) out);
|
||||||
|
|
||||||
out[0] ^= iv[0];
|
out[0] ^= iv[0];
|
||||||
out[1] ^= iv[1];
|
out[1] ^= iv[1];
|
||||||
@ -14978,73 +14863,6 @@ void seven_zip_hook_func (hc_device_param_t *device_param, hashes_t *hashes, con
|
|||||||
out_full[j + 2] = out[2];
|
out_full[j + 2] = out[2];
|
||||||
out_full[j + 3] = out[3];
|
out_full[j + 3] = out[3];
|
||||||
|
|
||||||
if (padding_check_full == true)
|
|
||||||
{
|
|
||||||
// do the check if margin > 0 but data_len < 32
|
|
||||||
|
|
||||||
switch (margin)
|
|
||||||
{
|
|
||||||
case 15: out[0] &= 0xffffff00;
|
|
||||||
break;
|
|
||||||
case 14: out[0] &= 0xffff0000;
|
|
||||||
break;
|
|
||||||
case 13: out[0] &= 0xff000000;
|
|
||||||
break;
|
|
||||||
case 12: out[0] = 0;
|
|
||||||
break;
|
|
||||||
case 11: out[0] = 0;
|
|
||||||
out[1] &= 0xffffff00;
|
|
||||||
break;
|
|
||||||
case 10: out[0] = 0;
|
|
||||||
out[1] &= 0xffff0000;
|
|
||||||
break;
|
|
||||||
case 9: out[0] = 0;
|
|
||||||
out[1] &= 0xff000000;
|
|
||||||
break;
|
|
||||||
case 8: out[0] = 0;
|
|
||||||
out[1] = 0;
|
|
||||||
break;
|
|
||||||
case 7: out[0] = 0;
|
|
||||||
out[1] = 0;
|
|
||||||
out[2] &= 0xffffff00;
|
|
||||||
break;
|
|
||||||
case 6: out[0] = 0;
|
|
||||||
out[1] = 0;
|
|
||||||
out[2] &= 0xffff0000;
|
|
||||||
break;
|
|
||||||
case 5: out[0] = 0;
|
|
||||||
out[1] = 0;
|
|
||||||
out[2] &= 0xff000000;
|
|
||||||
break;
|
|
||||||
case 4: out[0] = 0;
|
|
||||||
out[1] = 0;
|
|
||||||
out[2] = 0;
|
|
||||||
break;
|
|
||||||
case 3: out[0] = 0;
|
|
||||||
out[1] = 0;
|
|
||||||
out[2] = 0;
|
|
||||||
out[3] &= 0xffffff00;
|
|
||||||
break;
|
|
||||||
case 2: out[0] = 0;
|
|
||||||
out[1] = 0;
|
|
||||||
out[2] = 0;
|
|
||||||
out[3] &= 0xffff0000;
|
|
||||||
break;
|
|
||||||
case 1: out[0] = 0;
|
|
||||||
out[1] = 0;
|
|
||||||
out[2] = 0;
|
|
||||||
out[3] &= 0xff000000;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((out[0] != 0) || (out[1] != 0) || (out[2] != 0) || (out[3] != 0))
|
|
||||||
{
|
|
||||||
hook_item->hook_success = 0;
|
|
||||||
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (data_type > 2)
|
if (data_type > 2)
|
||||||
{
|
{
|
||||||
// This decompression is currently not supported
|
// This decompression is currently not supported
|
||||||
|
Loading…
Reference in New Issue
Block a user