Telegram and hashcat.
#9
okay, I just spend a couple of free minutes to come up with this perl script (POC):
telegram_desktop.pl
Code:
#!/usr/bin/env perl # Author: philsmd # Date: February 2020 # License: public domain, credits go to philsmd and hashcat use strict; use warnings; use Crypt::PBKDF2; use Digest::SHA1 qw (sha1); use Crypt::Mode::ECB; # # Constants: # my $AES256_IGE_BLOCK_SIZE = 16; # # Helper functions: # sub exclusive_or { my $in1 = shift; my $in2 = shift; # MIN () function (should always be 16 for us): # my $len = (length ($in1) <= length ($in2)) ? length ($in2) : length ($in1); # padding if input not multiple of block size: # $in1 .= "\x00" x ($AES256_IGE_BLOCK_SIZE - $len); # $in2 .= "\x00" x ($AES256_IGE_BLOCK_SIZE - $len); my $out = ""; for (my $i = 0; $i < $AES256_IGE_BLOCK_SIZE; $i++) # $i < $len { $out .= chr (ord (substr ($in1, $i, 1)) ^ ord (substr ($in2, $i, 1))); } return $out; } sub aes256_decrypt_ige { my $key = shift; my $iv = shift; my $in = shift; my $x_prev = substr ($iv, 0, $AES256_IGE_BLOCK_SIZE); my $y_prev = substr ($iv, $AES256_IGE_BLOCK_SIZE, $AES256_IGE_BLOCK_SIZE); my $m = Crypt::Mode::ECB->new ('AES', 0); my $out = ""; for (my $i = 0; $i < length ($in); $i += $AES256_IGE_BLOCK_SIZE) { my $x = substr ($in, $i, $AES256_IGE_BLOCK_SIZE); my $y_xor = exclusive_or ($x, $y_prev); my $y_final = $m->decrypt ($y_xor, $key); # $y_final .= "\x00" x ($AES256_IGE_BLOCK_SIZE - length ($y_final)); my $y = exclusive_or ($y_final, $x_prev); $x_prev = $x; $y_prev = $y; $out .= $y; } return $out; } # # Example: # # examples from JTR: https://github.com/magnumripper/JohnTheRipper/blob/b7cea20625354e8a009a3a66e9061792babefef2/src/telegram_common_plug.c#L14-L15 # Example 1: # $telegram$1*4000*e693c27ff92fe83a5a247cce198a8d6a0f3a89ffedc6bcddbc39586bb1bcb50b*d6fb7ebda06a23a9c42fc57c39e2c3128da4ee1ff394f17c2fc4290229e13d1c9e45c42ef1aee64903e5904c28cffd49498358fee96eb01888f2251715b7a5e71fa130918f46da5a2117e742ad7727700e924411138bb8d4359662da0ebd4f4357d96d1aa62955e44d4acf2e2ac6e0ce057f48fe24209090fd35eeac8a905aca649cafb2aade1ef7a96a7ab44a22bd7961e79a9291b7fea8749dd415f2fcd73d0293cdb533554f396625f669315c2400ebf6f1f30e08063e88b59b2d5832a197b165cdc6b0dc9d5bfa6d5e278a79fa101e10a98c6662cc3d623aa64daada76f340a657c2cbaddfa46e35c60ecb49e8f1f57bc170b8064b70aa2b22bb326915a8121922e06e7839e62075ee045b8c82751defcba0e8fb75c32f8bbbdb8b673258:openwall123 my $iterations = 4000; my $word = "openwall123"; my $salt = pack ("H*", "e693c27ff92fe83a5a247cce198a8d6a0f3a89ffedc6bcddbc39586bb1bcb50b"); my $data = pack ("H*", "d6fb7ebda06a23a9c42fc57c39e2c3128da4ee1ff394f17c2fc4290229e13d1c9e45c42ef1aee64903e5904c28cffd49498358fee96eb01888f2251715b7a5e71fa130918f46da5a2117e742ad7727700e924411138bb8d4359662da0ebd4f4357d96d1aa62955e44d4acf2e2ac6e0ce057f48fe24209090fd35eeac8a905aca649cafb2aade1ef7a96a7ab44a22bd7961e79a9291b7fea8749dd415f2fcd73d0293cdb533554f396625f669315c2400ebf6f1f30e08063e88b59b2d5832a197b165cdc6b0dc9d5bfa6d5e278a79fa101e10a98c6662cc3d623aa64daada76f340a657c2cbaddfa46e35c60ecb49e8f1f57bc170b8064b70aa2b22bb326915a8121922e06e7839e62075ee045b8c82751defcba0e8fb75c32f8bbbdb8b673258"); # Example 2: # $telegram$1*4000*e693c27ff92fe83a5a247cce198a8d6a0f3a89ffedc6bcddbc39586bb1bcb50b*7c04a5becb2564fe4400c124f5bb5f1896117327d8a21f610bd431171f606fa6e064c088aacc59d8eae4e6dce539abdba5ea552f5855412c26284bc851465d6b31949b276f4890fc212d63d73e2ba132d6098688f2a6408b9d9d69c3db4bcd13dcc3a5f80a7926bb11eb2c99c7f02b5d9fd1ced974d18ed9d667deae4be8df6a4a97ed8fae1da90d5131a7536535a9bfa8094ca7f7465deabef00ab4c715f151d016a879197b328c74dfad5b1f854217c741cf3e0297c63c3fb4d5d672d1e31d797b2c01cb8a254f80a37b6c9a011d864c21c4145091f22839a52b6daf23ed2f350f1deb275f1b0b4146285ada0f0b168ce54234854b19ec6657ad0a92ffb0f3b86547c8b8cc3655a29797c398721e740ed606a71018d16545c78ee240ff3635:öye # my $iterations = 4000; # # my $word = "öye"; # # my $salt = pack ("H*", "e693c27ff92fe83a5a247cce198a8d6a0f3a89ffedc6bcddbc39586bb1bcb50b"); # my $data = pack ("H*", "7c04a5becb2564fe4400c124f5bb5f1896117327d8a21f610bd431171f606fa6e064c088aacc59d8eae4e6dce539abdba5ea552f5855412c26284bc851465d6b31949b276f4890fc212d63d73e2ba132d6098688f2a6408b9d9d69c3db4bcd13dcc3a5f80a7926bb11eb2c99c7f02b5d9fd1ced974d18ed9d667deae4be8df6a4a97ed8fae1da90d5131a7536535a9bfa8094ca7f7465deabef00ab4c715f151d016a879197b328c74dfad5b1f854217c741cf3e0297c63c3fb4d5d672d1e31d797b2c01cb8a254f80a37b6c9a011d864c21c4145091f22839a52b6daf23ed2f350f1deb275f1b0b4146285ada0f0b168ce54234854b19ec6657ad0a92ffb0f3b86547c8b8cc3655a29797c398721e740ed606a71018d16545c78ee240ff3635"); # # Start: # my $pbkdf = Crypt::PBKDF2->new ( hash_class => 'HMACSHA1', iterations => $iterations, output_len => 136 # 256 ); my $authkey = $pbkdf->PBKDF2 ($salt, $word); my $data_a = "\x00" x 48; my $data_b = "\x00" x 48; my $data_c = "\x00" x 48; my $data_d = "\x00" x 48; my $message_key = substr ($data, 0, 16); my $message = substr ($data, 16); substr ($data_a, 0, 16) = $message_key; # memcpy () substr ($data_b, 16, 16) = $message_key; substr ($data_c, 32, 16) = $message_key; substr ($data_d, 0, 16) = $message_key; substr ($data_a, 16, 32) = substr ($authkey, 8, 32); substr ($data_b, 0, 16) = substr ($authkey, 40, 16); substr ($data_b, 32, 16) = substr ($authkey, 56, 16); substr ($data_c, 0, 32) = substr ($authkey, 72, 32); substr ($data_d, 16, 32) = substr ($authkey, 104, 32); my $sha1_a = sha1 ($data_a); my $sha1_b = sha1 ($data_b); my $sha1_c = sha1 ($data_c); my $sha1_d = sha1 ($data_d); my $aes_key = substr ($sha1_a, 0, 8) . # 8 + 12 + 12 = 32 substr ($sha1_b, 8, 12) . substr ($sha1_c, 4, 12); my $aes_iv = substr ($sha1_a, 8, 12) . # 12 + 8 + 4 + 8 = 32 substr ($sha1_b, 0, 8) . substr ($sha1_c, 16, 4) . substr ($sha1_d, 0, 8); # AES256 IGE decrypt: my $decrypted_data = aes256_decrypt_ige ($aes_key, $aes_iv, $message); # "checksum" of raw data: my $hash = sha1 ($decrypted_data); $hash = substr ($hash, 0, 16); # compare: if ($hash eq $message_key) { print "Password found: '$word'\n"; }


the only "problem" is the non-widely use AES IGE mode of operation (basically mostly used in Telegram only):
aes256_ige.pl (translated to perl from https://mgp25.com/AESIGE/#php-implementation)
Code:
#!/usr/bin/env perl # Author: philsmd # Date: February 2020 # License: public domain, credits go to philsmd and hashcat use strict; use warnings; use Crypt::Mode::ECB; # # Constants: # my $AES256_IGE_BLOCK_SIZE = 16; # # Helper functions: # sub exclusive_or { my $in1 = shift; my $in2 = shift; # MIN () function (should always be 16 for us): # my $len = (length ($in1) <= length ($in2)) ? length ($in2) : length ($in1); # padding if input not multiple of block size: # $in1 .= "\x00" x ($AES256_IGE_BLOCK_SIZE - $len); # $in2 .= "\x00" x ($AES256_IGE_BLOCK_SIZE - $len); my $out = ""; for (my $i = 0; $i < $AES256_IGE_BLOCK_SIZE; $i++) # $i < $len { $out .= chr (ord (substr ($in1, $i, 1)) ^ ord (substr ($in2, $i, 1))); } return $out; } sub aes256_encrypt_ige { my $key = shift; my $iv = shift; my $in = shift; my $x_prev = substr ($iv, $AES256_IGE_BLOCK_SIZE, $AES256_IGE_BLOCK_SIZE); my $y_prev = substr ($iv, 0, $AES256_IGE_BLOCK_SIZE); my $m = Crypt::Mode::ECB->new ('AES', 0); my $out = ""; for (my $i = 0; $i < length ($in); $i += $AES256_IGE_BLOCK_SIZE) { my $x = substr ($in, $i, $AES256_IGE_BLOCK_SIZE); my $y_xor = exclusive_or ($x, $y_prev); my $y_final = $m->encrypt ($y_xor, $key); # $y_final .= "\x00" x ($AES256_IGE_BLOCK_SIZE - length ($y_final)); my $y = exclusive_or ($y_final, $x_prev); $x_prev = $x; $y_prev = $y; $out .= $y; } return $out; } sub aes256_decrypt_ige { my $key = shift; my $iv = shift; my $in = shift; my $x_prev = substr ($iv, 0, $AES256_IGE_BLOCK_SIZE); my $y_prev = substr ($iv, $AES256_IGE_BLOCK_SIZE, $AES256_IGE_BLOCK_SIZE); my $m = Crypt::Mode::ECB->new ('AES', 0); my $out = ""; for (my $i = 0; $i < length ($in); $i += $AES256_IGE_BLOCK_SIZE) { my $x = substr ($in, $i, $AES256_IGE_BLOCK_SIZE); my $y_xor = exclusive_or ($x, $y_prev); my $y_final = $m->decrypt ($y_xor, $key); # $y_final .= "\x00" x ($AES256_IGE_BLOCK_SIZE - length ($y_final)); my $y = exclusive_or ($y_final, $x_prev); $x_prev = $x; $y_prev = $y; $out .= $y; } return $out; } # # Examples: # # take from https://mgp25.com/AESIGE/#test-vectors: # Example 1: my $key = pack ("H*", "000102030405060708090a0b0c0d0e0f"); my $iv = pack ("H*", "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f"); my $plain_text = pack ("H*", "0000000000000000000000000000000000000000000000000000000000000000"); my $cipher_text = pack ("H*", "1a8519a6557be652e9da8e43da4ef4453cf456b4ca488aa383c79c98b34797cb"); # Example 2: # my $key = pack ("H*", "5468697320697320616e20696d706c65"); # my $iv = pack ("H*", "6d656e746174696f6e206f6620494745206d6f646520666f72204f70656e5353"); # my $plain_text = pack ("H*", "99706487a1cde613bc6de0b6f24b1c7aa448c8b9c3403e3467a8cad89340f53b"); # my $cipher_text = pack ("H*", "4c2e204c6574277320686f70652042656e20676f74206974207269676874210a"); # # Start # # encrypt: print unpack ("H*", aes256_encrypt_ige ($key, $iv, $plain_text)) . "\n"; # decrypt: print unpack ("H*", aes256_decrypt_ige ($key, $iv, $cipher_text)) . "\n";

so now I've already managed to perform the most important/difficult part to come up with a POC perl script (that we could copy-paste to our test modules in tools/test_modules/)... the missing parts now would be to see what are some input restrictions (data length, salt, iter min/max values) and write the host and kernel code in hashcat. We would probably need that somebody explains this in a github issue with some further examples and facts ... after that a developer could easily start implementing it (if there is enough interest in this algo !?).
Reply


Messages In This Thread
Telegram and hashcat. - by Hack3rcon - 01-16-2020, 11:36 AM
RE: Telegram and hashcat. - by philsmd - 01-16-2020, 11:44 AM
RE: Telegram and hashcat. - by Hack3rcon - 01-16-2020, 12:41 PM
RE: Telegram and hashcat. - by philsmd - 01-16-2020, 01:10 PM
RE: Telegram and hashcat. - by zamgold - 01-20-2020, 05:07 PM
RE: Telegram and hashcat. - by undeath - 01-20-2020, 07:07 PM
RE: Telegram and hashcat. - by zamgold - 01-20-2020, 07:30 PM
RE: Telegram and hashcat. - by philsmd - 02-26-2020, 01:19 PM
RE: Telegram and hashcat. - by philsmd - 02-28-2020, 04:45 PM
RE: Telegram and hashcat. - by philsmd - 04-08-2020, 12:13 PM