1
0
mirror of https://github.com/hashcat/hashcat.git synced 2024-11-23 00:28:11 +00: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

@ -31,15 +31,14 @@ u8 int_to_base32 (const u8 c);
u8 base32_to_int (const u8 c); u8 base32_to_int (const u8 c);
u8 int_to_base64 (const u8 c); u8 int_to_base64 (const u8 c);
u8 base64_to_int (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 int_to_itoa32 (const u8 c);
u8 itoa32_to_int (const u8 c); u8 itoa32_to_int (const u8 c);
u8 int_to_itoa64 (const u8 c); u8 int_to_itoa64 (const u8 c);
u8 itoa64_to_int (const u8 c); u8 itoa64_to_int (const u8 c);
u8 int_to_bf64 (const u8 c); u8 int_to_bf64 (const u8 c);
u8 bf64_to_int (const u8 c); u8 bf64_to_int (const u8 c);
u8 int_to_lotus64 (const u8 c); u8 int_to_lotus64 (const u8 c);
u8 lotus64_to_int (const u8 c); u8 lotus64_to_int (const u8 c);

View File

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

View File

@ -429,6 +429,44 @@ u8 base64_to_int (const u8 c)
return tbl[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) u8 int_to_bf64 (const u8 c)
{ {
const u8 tbl[0x40] = const u8 tbl[0x40] =

View File

@ -16215,18 +16215,18 @@ int jwt_parse_hash (u8 *input_buf, u32 input_len, hash_t *hash_buf, MAYBE_UNUSED
// we need to do this kind of check, otherwise an eventual matching hash from the potfile overwrites the kern_type with an eventual invalid one // we need to do this kind of check, otherwise an eventual matching hash from the potfile overwrites the kern_type with an eventual invalid one
if (hashconfig->kern_type == (u32) -1) 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 // 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; hashconfig->kern_type = KERN_TYPE_JWT_HS256;
} }
else if (signature_len == 96) else if (signature_len == 64)
{ {
hashconfig->kern_type = KERN_TYPE_JWT_HS384; hashconfig->kern_type = KERN_TYPE_JWT_HS384;
} }
else if (signature_len == 128) else if (signature_len == 86)
{ {
hashconfig->kern_type = KERN_TYPE_JWT_HS512; 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 else
{ {
if ((hashconfig->kern_type == KERN_TYPE_JWT_HS256) && (signature_len == 64)) if ((hashconfig->kern_type == KERN_TYPE_JWT_HS256) && (signature_len == 43))
{ {
// OK // 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 // 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 // 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 (esalt_len > 4096) return (PARSER_SALT_LENGTH);
if (is_valid_hex_string (signature_pos, signature_len) == false) return (PARSER_SALT_ENCODING);
/** /**
* store data * store data
*/ */
@ -16304,26 +16302,15 @@ int jwt_parse_hash (u8 *input_buf, u32 input_len, hash_t *hash_buf, MAYBE_UNUSED
// hash // hash
if (signature_len == 64) u8 tmp_buf[100] = { 0 };
{
u32 *digest = (u32 *) hash_buf->digest;
digest[ 0] = hex_to_u32 ((const u8 *) &signature_pos[ 0]); base64_decode (base64url_to_int, signature_pos, signature_len, tmp_buf);
digest[ 1] = hex_to_u32 ((const u8 *) &signature_pos[ 8]);
digest[ 2] = hex_to_u32 ((const u8 *) &signature_pos[16]); if (signature_len == 43)
digest[ 3] = hex_to_u32 ((const u8 *) &signature_pos[24]); {
digest[ 4] = hex_to_u32 ((const u8 *) &signature_pos[32]); memcpy (hash_buf->digest, tmp_buf, 32);
digest[ 5] = hex_to_u32 ((const u8 *) &signature_pos[40]);
digest[ 6] = hex_to_u32 ((const u8 *) &signature_pos[48]); u32 *digest = (u32 *) hash_buf->digest;
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;
digest[0] = byte_swap_32 (digest[0]); digest[0] = byte_swap_32 (digest[0]);
digest[1] = byte_swap_32 (digest[1]); 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[6] = byte_swap_32 (digest[6]);
digest[7] = byte_swap_32 (digest[7]); 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]); u64 *digest = (u64 *) hash_buf->digest;
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;
digest[0] = byte_swap_64 (digest[0]); digest[0] = byte_swap_64 (digest[0]);
digest[1] = byte_swap_64 (digest[1]); 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[3] = byte_swap_64 (digest[3]);
digest[4] = byte_swap_64 (digest[4]); digest[4] = byte_swap_64 (digest[4]);
digest[5] = byte_swap_64 (digest[5]); 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]); u64 *digest = (u64 *) hash_buf->digest;
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]);
digest[0] = byte_swap_64 (digest[0]); digest[0] = byte_swap_64 (digest[0]);
digest[1] = byte_swap_64 (digest[1]); 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) if (hashconfig->kern_type == KERN_TYPE_JWT_HS256)
{ {
snprintf (out_buf, out_len - 1, "%s.%08x%08x%08x%08x%08x%08x%08x%08x", digest_buf[0] = byte_swap_32 (digest_buf[0]);
(char *) jwt->salt_buf, digest_buf[1] = byte_swap_32 (digest_buf[1]);
digest_buf[0], digest_buf[2] = byte_swap_32 (digest_buf[2]);
digest_buf[1], digest_buf[3] = byte_swap_32 (digest_buf[3]);
digest_buf[2], digest_buf[4] = byte_swap_32 (digest_buf[4]);
digest_buf[3], digest_buf[5] = byte_swap_32 (digest_buf[5]);
digest_buf[4], digest_buf[6] = byte_swap_32 (digest_buf[6]);
digest_buf[5], digest_buf[7] = byte_swap_32 (digest_buf[7]);
digest_buf[6],
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) 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", memset (tmp_buf, 0, sizeof (tmp_buf));
(char *) jwt->salt_buf,
ptr[ 1], ptr[ 0], memcpy (tmp_buf, digest_buf64, 48);
ptr[ 3], ptr[ 2],
ptr[ 5], ptr[ 4], base64_encode (int_to_base64url, (const u8 *) tmp_buf, 48, (u8 *) ptr_plain);
ptr[ 7], ptr[ 6],
ptr[ 9], ptr[ 8], ptr_plain[64] = 0;
ptr[11], ptr[10]);
} }
else if (hashconfig->kern_type == KERN_TYPE_JWT_HS512) 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", memset (tmp_buf, 0, sizeof (tmp_buf));
(char *) jwt->salt_buf,
ptr[ 1], ptr[ 0], memcpy (tmp_buf, digest_buf64, 64);
ptr[ 3], ptr[ 2],
ptr[ 5], ptr[ 4], base64_encode (int_to_base64url, (const u8 *) tmp_buf, 64, (u8 *) ptr_plain);
ptr[ 7], ptr[ 6],
ptr[ 9], ptr[ 8], ptr_plain[86] = 0;
ptr[11], ptr[10],
ptr[13], ptr[12],
ptr[15], ptr[14]);
} }
snprintf (out_buf, out_len - 1, "%s.%s",
(char *) jwt->salt_buf,
(char *) ptr_plain);
} }
else if (hash_mode == 99999) 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::Skip32;
use Crypt::OpenSSH::ChachaPoly; use Crypt::OpenSSH::ChachaPoly;
use JSON; use JSON;
use MIME::Base64; use MIME::Base64 qw (encode_base64url decode_base64url);
use Authen::Passphrase::NTHash; use Authen::Passphrase::NTHash;
use Authen::Passphrase::MySQL323; use Authen::Passphrase::MySQL323;
use Authen::Passphrase::PHPass; use Authen::Passphrase::PHPass;
@ -9376,7 +9376,7 @@ END_CODE
{ {
my ($header_base64) = split (/\./, $salt_buf); 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); my $header = decode_json ($header_jwt);
@ -9384,22 +9384,22 @@ END_CODE
if ($alg eq "HS256") 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") 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") elsif ($alg eq "HS512")
{ {
$hash_buf = hmac_hex ($salt_buf, $word_buf, \&sha512, 128); $hash_buf = hmac ($salt_buf, $word_buf, \&sha512, 128);
} }
else else
{ {
die "not supported hash\n"; 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) elsif ($mode == 99999)
{ {
@ -11092,8 +11092,8 @@ sub get_random_jwt_salt
my $header_json = encode_json ($header); my $header_json = encode_json ($header);
my $payload_json = encode_json ($payload); my $payload_json = encode_json ($payload);
my $header_base64 = encode_base64 ($header_json, ""); my $header_base64 = encode_base64url ($header_json, "");
my $payload_base64 = encode_base64 ($payload_json, ""); my $payload_base64 = encode_base64url ($payload_json, "");
return $header_base64 . "." . $payload_base64; return $header_base64 . "." . $payload_base64;
} }