1
mirror of https://github.com/hashcat/hashcat synced 2024-11-13 17:28:58 +01:00

Stick to original JWT format from jwt.io

This commit is contained in:
jsteube 2018-01-21 19:57:24 +01:00
parent 0796c074c3
commit ce0cee0ac4
5 changed files with 131 additions and 105 deletions

View File

@ -27,21 +27,20 @@ void u8_to_hex_lower (const u8 v, u8 hex[2]);
void u32_to_hex_lower (const u32 v, u8 hex[8]);
void u64_to_hex_lower (const u64 v, u8 hex[16]);
u8 int_to_base32 (const u8 c);
u8 base32_to_int (const u8 c);
u8 int_to_base64 (const u8 c);
u8 base64_to_int (const u8 c);
u8 int_to_itoa32 (const u8 c);
u8 itoa32_to_int (const u8 c);
u8 int_to_itoa64 (const u8 c);
u8 itoa64_to_int (const u8 c);
u8 int_to_bf64 (const u8 c);
u8 bf64_to_int (const u8 c);
u8 int_to_lotus64 (const u8 c);
u8 lotus64_to_int (const u8 c);
u8 int_to_base32 (const u8 c);
u8 base32_to_int (const u8 c);
u8 int_to_base64 (const u8 c);
u8 base64_to_int (const u8 c);
u8 int_to_base64url (const u8 c);
u8 base64url_to_int (const u8 c);
u8 int_to_itoa32 (const u8 c);
u8 itoa32_to_int (const u8 c);
u8 int_to_itoa64 (const u8 c);
u8 itoa64_to_int (const u8 c);
u8 int_to_bf64 (const u8 c);
u8 bf64_to_int (const u8 c);
u8 int_to_lotus64 (const u8 c);
u8 lotus64_to_int (const u8 c);
int base32_decode (u8 (*f) (const u8), const u8 *in_buf, int in_len, u8 *out_buf);
int base32_encode (u8 (*f) (const u8), const u8 *in_buf, int in_len, u8 *out_buf);

View File

@ -1336,8 +1336,8 @@ typedef enum display_len
DISPLAY_LEN_MAX_16300 = 11 + 1 + 1248 + 1 + 40 + 1 + 32,
DISPLAY_LEN_MIN_16400 = 10 + 32 + 32,
DISPLAY_LEN_MAX_16400 = 10 + 32 + 32,
DISPLAY_LEN_MIN_16500 = 1 + 1 + 1 + 1 + 64,
DISPLAY_LEN_MAX_16500 = 2047 + 1 + 2047 + 1 + 128,
DISPLAY_LEN_MIN_16500 = 1 + 1 + 1 + 1 + 43,
DISPLAY_LEN_MAX_16500 = 2047 + 1 + 2047 + 1 + 86,
DISPLAY_LEN_MIN_99999 = 1,
DISPLAY_LEN_MAX_99999 = 55,

View File

@ -429,6 +429,44 @@ u8 base64_to_int (const u8 c)
return tbl[c];
}
u8 int_to_base64url (const u8 c)
{
const u8 tbl[0x40] =
{
0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50,
0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66,
0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76,
0x77, 0x78, 0x79, 0x7a, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x2d, 0x5f,
};
return tbl[c];
}
u8 base64url_to_int (const u8 c)
{
const u8 tbl[0x100] =
{
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x00,
0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e,
0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x00, 0x00, 0x00, 0x00, 0x3f,
0x00, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28,
0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31, 0x32, 0x33, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
};
return tbl[c];
}
u8 int_to_bf64 (const u8 c)
{
const u8 tbl[0x40] =

View File

@ -16216,17 +16216,17 @@ int jwt_parse_hash (u8 *input_buf, u32 input_len, hash_t *hash_buf, MAYBE_UNUSED
if (hashconfig->kern_type == (u32) -1)
{
if (signature_len == 64)
{
// it would be more accurate to base64 decode the header_pos buffer and then to string match HS256 - same goes for the other algorithms
if (signature_len == 43)
{
hashconfig->kern_type = KERN_TYPE_JWT_HS256;
}
else if (signature_len == 96)
else if (signature_len == 64)
{
hashconfig->kern_type = KERN_TYPE_JWT_HS384;
}
else if (signature_len == 128)
else if (signature_len == 86)
{
hashconfig->kern_type = KERN_TYPE_JWT_HS512;
}
@ -16237,15 +16237,15 @@ int jwt_parse_hash (u8 *input_buf, u32 input_len, hash_t *hash_buf, MAYBE_UNUSED
}
else
{
if ((hashconfig->kern_type == KERN_TYPE_JWT_HS256) && (signature_len == 64))
if ((hashconfig->kern_type == KERN_TYPE_JWT_HS256) && (signature_len == 43))
{
// OK
}
else if ((hashconfig->kern_type == KERN_TYPE_JWT_HS384) && (signature_len == 96))
else if ((hashconfig->kern_type == KERN_TYPE_JWT_HS384) && (signature_len == 64))
{
// OK
}
else if ((hashconfig->kern_type == KERN_TYPE_JWT_HS512) && (signature_len == 128))
else if ((hashconfig->kern_type == KERN_TYPE_JWT_HS512) && (signature_len == 86))
{
// OK
}
@ -16257,8 +16257,6 @@ int jwt_parse_hash (u8 *input_buf, u32 input_len, hash_t *hash_buf, MAYBE_UNUSED
if (esalt_len > 4096) return (PARSER_SALT_LENGTH);
if (is_valid_hex_string (signature_pos, signature_len) == false) return (PARSER_SALT_ENCODING);
/**
* store data
*/
@ -16304,26 +16302,15 @@ int jwt_parse_hash (u8 *input_buf, u32 input_len, hash_t *hash_buf, MAYBE_UNUSED
// hash
if (signature_len == 64)
{
u32 *digest = (u32 *) hash_buf->digest;
u8 tmp_buf[100] = { 0 };
digest[ 0] = hex_to_u32 ((const u8 *) &signature_pos[ 0]);
digest[ 1] = hex_to_u32 ((const u8 *) &signature_pos[ 8]);
digest[ 2] = hex_to_u32 ((const u8 *) &signature_pos[16]);
digest[ 3] = hex_to_u32 ((const u8 *) &signature_pos[24]);
digest[ 4] = hex_to_u32 ((const u8 *) &signature_pos[32]);
digest[ 5] = hex_to_u32 ((const u8 *) &signature_pos[40]);
digest[ 6] = hex_to_u32 ((const u8 *) &signature_pos[48]);
digest[ 7] = hex_to_u32 ((const u8 *) &signature_pos[56]);
digest[ 8] = 0;
digest[ 9] = 0;
digest[10] = 0;
digest[11] = 0;
digest[12] = 0;
digest[13] = 0;
digest[14] = 0;
digest[15] = 0;
base64_decode (base64url_to_int, signature_pos, signature_len, tmp_buf);
if (signature_len == 43)
{
memcpy (hash_buf->digest, tmp_buf, 32);
u32 *digest = (u32 *) hash_buf->digest;
digest[0] = byte_swap_32 (digest[0]);
digest[1] = byte_swap_32 (digest[1]);
@ -16334,18 +16321,11 @@ int jwt_parse_hash (u8 *input_buf, u32 input_len, hash_t *hash_buf, MAYBE_UNUSED
digest[6] = byte_swap_32 (digest[6]);
digest[7] = byte_swap_32 (digest[7]);
}
else if (signature_len == 96)
else if (signature_len == 64)
{
u64 *digest = (u64 *) hash_buf->digest;
memcpy (hash_buf->digest, tmp_buf, 48);
digest[0] = hex_to_u64 ((const u8 *) &signature_pos[ 0]);
digest[1] = hex_to_u64 ((const u8 *) &signature_pos[ 16]);
digest[2] = hex_to_u64 ((const u8 *) &signature_pos[ 32]);
digest[3] = hex_to_u64 ((const u8 *) &signature_pos[ 48]);
digest[4] = hex_to_u64 ((const u8 *) &signature_pos[ 64]);
digest[5] = hex_to_u64 ((const u8 *) &signature_pos[ 80]);
digest[6] = 0;
digest[7] = 0;
u64 *digest = (u64 *) hash_buf->digest;
digest[0] = byte_swap_64 (digest[0]);
digest[1] = byte_swap_64 (digest[1]);
@ -16353,21 +16333,12 @@ int jwt_parse_hash (u8 *input_buf, u32 input_len, hash_t *hash_buf, MAYBE_UNUSED
digest[3] = byte_swap_64 (digest[3]);
digest[4] = byte_swap_64 (digest[4]);
digest[5] = byte_swap_64 (digest[5]);
digest[6] = byte_swap_64 (digest[6]);
digest[7] = byte_swap_64 (digest[7]);
}
else if (signature_len == 128)
else if (signature_len == 86)
{
u64 *digest = (u64 *) hash_buf->digest;
memcpy (hash_buf->digest, tmp_buf, 64);
digest[0] = hex_to_u64 ((const u8 *) &signature_pos[ 0]);
digest[1] = hex_to_u64 ((const u8 *) &signature_pos[ 16]);
digest[2] = hex_to_u64 ((const u8 *) &signature_pos[ 32]);
digest[3] = hex_to_u64 ((const u8 *) &signature_pos[ 48]);
digest[4] = hex_to_u64 ((const u8 *) &signature_pos[ 64]);
digest[5] = hex_to_u64 ((const u8 *) &signature_pos[ 80]);
digest[6] = hex_to_u64 ((const u8 *) &signature_pos[ 96]);
digest[7] = hex_to_u64 ((const u8 *) &signature_pos[112]);
u64 *digest = (u64 *) hash_buf->digest;
digest[0] = byte_swap_64 (digest[0]);
digest[1] = byte_swap_64 (digest[1]);
@ -20339,45 +20310,63 @@ int ascii_digest (hashcat_ctx_t *hashcat_ctx, char *out_buf, const size_t out_le
if (hashconfig->kern_type == KERN_TYPE_JWT_HS256)
{
snprintf (out_buf, out_len - 1, "%s.%08x%08x%08x%08x%08x%08x%08x%08x",
(char *) jwt->salt_buf,
digest_buf[0],
digest_buf[1],
digest_buf[2],
digest_buf[3],
digest_buf[4],
digest_buf[5],
digest_buf[6],
digest_buf[7]);
digest_buf[0] = byte_swap_32 (digest_buf[0]);
digest_buf[1] = byte_swap_32 (digest_buf[1]);
digest_buf[2] = byte_swap_32 (digest_buf[2]);
digest_buf[3] = byte_swap_32 (digest_buf[3]);
digest_buf[4] = byte_swap_32 (digest_buf[4]);
digest_buf[5] = byte_swap_32 (digest_buf[5]);
digest_buf[6] = byte_swap_32 (digest_buf[6]);
digest_buf[7] = byte_swap_32 (digest_buf[7]);
memset (tmp_buf, 0, sizeof (tmp_buf));
memcpy (tmp_buf, digest_buf, 32);
base64_encode (int_to_base64url, (const u8 *) tmp_buf, 32, (u8 *) ptr_plain);
ptr_plain[43] = 0;
}
else if (hashconfig->kern_type == KERN_TYPE_JWT_HS384)
{
u32 *ptr = digest_buf;
digest_buf64[0] = byte_swap_64 (digest_buf64[0]);
digest_buf64[1] = byte_swap_64 (digest_buf64[1]);
digest_buf64[2] = byte_swap_64 (digest_buf64[2]);
digest_buf64[3] = byte_swap_64 (digest_buf64[3]);
digest_buf64[4] = byte_swap_64 (digest_buf64[4]);
digest_buf64[5] = byte_swap_64 (digest_buf64[5]);
snprintf (out_buf, out_len - 1, "%s.%08x%08x%08x%08x%08x%08x%08x%08x%08x%08x%08x%08x",
(char *) jwt->salt_buf,
ptr[ 1], ptr[ 0],
ptr[ 3], ptr[ 2],
ptr[ 5], ptr[ 4],
ptr[ 7], ptr[ 6],
ptr[ 9], ptr[ 8],
ptr[11], ptr[10]);
memset (tmp_buf, 0, sizeof (tmp_buf));
memcpy (tmp_buf, digest_buf64, 48);
base64_encode (int_to_base64url, (const u8 *) tmp_buf, 48, (u8 *) ptr_plain);
ptr_plain[64] = 0;
}
else if (hashconfig->kern_type == KERN_TYPE_JWT_HS512)
{
u32 *ptr = digest_buf;
digest_buf64[0] = byte_swap_64 (digest_buf64[0]);
digest_buf64[1] = byte_swap_64 (digest_buf64[1]);
digest_buf64[2] = byte_swap_64 (digest_buf64[2]);
digest_buf64[3] = byte_swap_64 (digest_buf64[3]);
digest_buf64[4] = byte_swap_64 (digest_buf64[4]);
digest_buf64[5] = byte_swap_64 (digest_buf64[5]);
digest_buf64[6] = byte_swap_64 (digest_buf64[6]);
digest_buf64[7] = byte_swap_64 (digest_buf64[7]);
snprintf (out_buf, out_len - 1, "%s.%08x%08x%08x%08x%08x%08x%08x%08x%08x%08x%08x%08x%08x%08x%08x%08x",
(char *) jwt->salt_buf,
ptr[ 1], ptr[ 0],
ptr[ 3], ptr[ 2],
ptr[ 5], ptr[ 4],
ptr[ 7], ptr[ 6],
ptr[ 9], ptr[ 8],
ptr[11], ptr[10],
ptr[13], ptr[12],
ptr[15], ptr[14]);
memset (tmp_buf, 0, sizeof (tmp_buf));
memcpy (tmp_buf, digest_buf64, 64);
base64_encode (int_to_base64url, (const u8 *) tmp_buf, 64, (u8 *) ptr_plain);
ptr_plain[86] = 0;
}
snprintf (out_buf, out_len - 1, "%s.%s",
(char *) jwt->salt_buf,
(char *) ptr_plain);
}
else if (hash_mode == 99999)
{

View File

@ -34,7 +34,7 @@ use Crypt::UnixCrypt_XS qw (crypt_rounds fold_password base64_to_int24 block_to_
use Crypt::Skip32;
use Crypt::OpenSSH::ChachaPoly;
use JSON;
use MIME::Base64;
use MIME::Base64 qw (encode_base64url decode_base64url);
use Authen::Passphrase::NTHash;
use Authen::Passphrase::MySQL323;
use Authen::Passphrase::PHPass;
@ -9376,7 +9376,7 @@ END_CODE
{
my ($header_base64) = split (/\./, $salt_buf);
my $header_jwt = decode_base64 ($header_base64);
my $header_jwt = decode_base64url ($header_base64);
my $header = decode_json ($header_jwt);
@ -9384,22 +9384,22 @@ END_CODE
if ($alg eq "HS256")
{
$hash_buf = hmac_hex ($salt_buf, $word_buf, \&sha256, 64);
$hash_buf = hmac ($salt_buf, $word_buf, \&sha256, 64);
}
elsif ($alg eq "HS384")
{
$hash_buf = hmac_hex ($salt_buf, $word_buf, \&sha384, 128);
$hash_buf = hmac ($salt_buf, $word_buf, \&sha384, 128);
}
elsif ($alg eq "HS512")
{
$hash_buf = hmac_hex ($salt_buf, $word_buf, \&sha512, 128);
$hash_buf = hmac ($salt_buf, $word_buf, \&sha512, 128);
}
else
{
die "not supported hash\n";
}
$tmp_hash = sprintf ("%s.%s", $salt_buf, $hash_buf);
$tmp_hash = sprintf ("%s.%s", $salt_buf, encode_base64url ($hash_buf, ""));
}
elsif ($mode == 99999)
{
@ -11092,8 +11092,8 @@ sub get_random_jwt_salt
my $header_json = encode_json ($header);
my $payload_json = encode_json ($payload);
my $header_base64 = encode_base64 ($header_json, "");
my $payload_base64 = encode_base64 ($payload_json, "");
my $header_base64 = encode_base64url ($header_json, "");
my $payload_base64 = encode_base64url ($payload_json, "");
return $header_base64 . "." . $payload_base64;
}