mirror of
https://github.com/hashcat/hashcat
synced 2024-12-27 05:13:45 +01:00
Stick to original JWT format from jwt.io
This commit is contained in:
parent
0796c074c3
commit
ce0cee0ac4
@ -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);
|
||||
|
@ -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,
|
||||
|
||||
|
@ -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] =
|
||||
|
149
src/interface.c
149
src/interface.c
@ -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)
|
||||
{
|
||||
|
@ -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;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user