Skip to content

Commit 237ad40

Browse files
magnumrippersolardiz
authored andcommitted
Telegram CPU format: Support Telegram Desktop >= 2.2.0
Basically this changed algorithm to SHA-512 for the KDF and bumped default iteration count to 100,000. Also adds tests in valid() for unset passwords. We didn't handle them correctly until now. See openwall#4387
1 parent 9dc3333 commit 237ad40

5 files changed

+232
-137
lines changed

doc/NEWS

+4-1
Original file line numberDiff line numberDiff line change
@@ -149,7 +149,10 @@ Major changes from 1.9.0-jumbo-1 (May 2019) in this bleeding-edge version:
149149
Mark the latter as deprecated in config file comments. [magnum; 2020]
150150

151151
- Add alternative syntax to --salts option for loading "N most populated
152-
salts" as opposed to "salts having at least N hashes" [magnum; 2020]
152+
salts" as opposed to "salts having at least N hashes". [magnum; 2020]
153+
154+
- Add support for Telegram Desktop >= 2.2.0/2.1.14b, CPU-only for now.
155+
[philsmd, magnum; 2020]
153156

154157

155158
Major changes from 1.8.0-jumbo-1 (December 2014) to 1.9.0-jumbo-1 (May 2019):

src/opencl_telegram_fmt_plug.c

+2
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ john_register_one(&fmt_opencl_telegram);
2424

2525
#include "formats.h"
2626
#include "common.h"
27+
#define OPENCL_FORMAT
2728
#include "telegram_common.h"
2829
#include "options.h"
2930
#include "jumbo.h"
@@ -51,6 +52,7 @@ typedef struct {
5152

5253
typedef struct {
5354
pbkdf2_salt pbkdf2;
55+
uint32_t version;
5456
uint32_t encrypted_blob_length;
5557
unsigned char encrypted_blob[ENCRYPTED_BLOB_LEN];
5658
} telegram_salt;

src/telegram_common.h

+5-5
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
#define ENCRYPTED_BLOB_LEN 512
1818

1919
struct custom_salt {
20+
uint32_t version;
2021
uint32_t iterations;
2122
unsigned char salt[SALTLEN];
2223
uint32_t salt_length;
@@ -26,8 +27,7 @@ struct custom_salt {
2627

2728
extern struct fmt_tests telegram_tests[];
2829

29-
int telegram_valid(char *ciphertext, struct fmt_main *self);
30-
31-
void *telegram_get_salt(char *ciphertext);
32-
33-
unsigned int telegram_iteration_count(void *salt);
30+
extern int telegram_check_password(unsigned char *authkey, struct custom_salt *cs);
31+
extern int telegram_valid(char *ciphertext, struct fmt_main *self);
32+
extern void *telegram_get_salt(char *ciphertext);
33+
extern unsigned int telegram_iteration_count(void *salt);

src/telegram_common_plug.c

+148-31
Original file line numberDiff line numberDiff line change
@@ -6,20 +6,160 @@
66
*/
77

88
#include "arch.h"
9+
/* We undefine these locally, for scalar PBKDF2 functions used in check_unset_password() */
10+
#undef SIMD_COEF_32
11+
#undef SIMD_COEF_64
12+
#include "pbkdf2_hmac_sha1.h"
13+
#include "pbkdf2_hmac_sha512.h"
14+
#include "aes_ige.h"
915
#include "telegram_common.h"
1016
#include "jumbo.h"
17+
#include "john.h"
1118

1219
struct fmt_tests telegram_tests[] = {
1320
// Telegram Desktop 1.3.9 on Ubuntu 18.04 LTS
1421
{"$telegram$1*4000*e693c27ff92fe83a5a247cce198a8d6a0f3a89ffedc6bcddbc39586bb1bcb50b*d6fb7ebda06a23a9c42fc57c39e2c3128da4ee1ff394f17c2fc4290229e13d1c9e45c42ef1aee64903e5904c28cffd49498358fee96eb01888f2251715b7a5e71fa130918f46da5a2117e742ad7727700e924411138bb8d4359662da0ebd4f4357d96d1aa62955e44d4acf2e2ac6e0ce057f48fe24209090fd35eeac8a905aca649cafb2aade1ef7a96a7ab44a22bd7961e79a9291b7fea8749dd415f2fcd73d0293cdb533554f396625f669315c2400ebf6f1f30e08063e88b59b2d5832a197b165cdc6b0dc9d5bfa6d5e278a79fa101e10a98c6662cc3d623aa64daada76f340a657c2cbaddfa46e35c60ecb49e8f1f57bc170b8064b70aa2b22bb326915a8121922e06e7839e62075ee045b8c82751defcba0e8fb75c32f8bbbdb8b673258", "openwall123"},
1522
{"$telegram$1*4000*e693c27ff92fe83a5a247cce198a8d6a0f3a89ffedc6bcddbc39586bb1bcb50b*7c04a5becb2564fe4400c124f5bb5f1896117327d8a21f610bd431171f606fa6e064c088aacc59d8eae4e6dce539abdba5ea552f5855412c26284bc851465d6b31949b276f4890fc212d63d73e2ba132d6098688f2a6408b9d9d69c3db4bcd13dcc3a5f80a7926bb11eb2c99c7f02b5d9fd1ced974d18ed9d667deae4be8df6a4a97ed8fae1da90d5131a7536535a9bfa8094ca7f7465deabef00ab4c715f151d016a879197b328c74dfad5b1f854217c741cf3e0297c63c3fb4d5d672d1e31d797b2c01cb8a254f80a37b6c9a011d864c21c4145091f22839a52b6daf23ed2f350f1deb275f1b0b4146285ada0f0b168ce54234854b19ec6657ad0a92ffb0f3b86547c8b8cc3655a29797c398721e740ed606a71018d16545c78ee240ff3635", "öye"},
23+
#ifndef OPENCL_FORMAT
24+
// Newer version, starting with 2.1.14 beta or 2.2.0 major release
25+
{"$telegram$2*100000*0970f6c043d855aa895703b8a1cc086109cf081f72a77b6504f7f4bf3db06420*129294a5eac3196a4c9a88e556f7507b0957f6dd45d704db8abe607ec6d807270c02635289056256a6044a6408e7ef5d33f98c561f16f8aedd2b3ae33ddffddc63c8584dcb232c9f610953f461adb8d29da83f2b01e32db98101febffae4072703bfbfd492e1dd6abeb0926d3df2ed3b47dee4eb6c9f42ab657f89f19d7314c07e2ffc843e448c6d324e9f8d2c3e877a25b0b153736fddb35f5205737620ba2f96aa47f799366150b4de89a0c6e12caa4f03553d164ce9e2e975aadc83538e6ae3df93acb6026f97ac9f6f017a6bbc6607767e591b2c732e3c0ac844584c69dae89ca3272c996eb83b4e66976e3851cfc89be11dc602bb8c0cdf578d9a0a9dbc2296888fa5ee7e58d985a9bf9a1dbc75d2ddfd6ce222c5ee9f3bb40f6e25c2cd", "0404"},
26+
{"$telegram$2*100000*77461dcb457ce9539f8e4235d33bd12455b4a38446e63b52ecdf2e7b65af4476*f705dda3247df6d690dfc7f44d8c666979737cae9505d961130071bcc18eeadaef0320ac6985e4a116834c0761e55314464aae56dadb8f80ab8886c16f72f8b95adca08b56a60c4303d84210f75cfd78a3e1a197c84a747988ce2e1b247397b61041823bdb33932714ba16ca7279e6c36b75d3f994479a469b50a7b2c7299a4d7aadb775fb030d3bb55ca77b7ce8ac2f5cf5eb7bdbcc10821b8953a4734b448060246e5bb93f130d6d3f2e28b9e04f2a064820be562274c040cd849f1473d45141559fc45da4c54abeaf5ca40d2d57f8f8e33bdb232c7279872f758b3fb452713b5d91c855383f7cec8376649a53b83951cf8edd519a99e91b8a6cb90153088e35d9fed332c7253771740f49f9dc40c7da50352656395bbfeae63e10f754d24a", "hashcat"},
27+
#endif
1628
{NULL}
1729
};
1830

31+
int telegram_check_password(unsigned char *authkey, struct custom_salt *cs)
32+
{
33+
AES_KEY aeskey;
34+
unsigned char data_a[48];
35+
unsigned char data_b[48];
36+
unsigned char data_c[48];
37+
unsigned char data_d[48];
38+
unsigned char sha1_a[20];
39+
unsigned char sha1_b[20];
40+
unsigned char sha1_c[20];
41+
unsigned char sha1_d[20];
42+
unsigned char message_key[16];
43+
unsigned char aes_key[32];
44+
unsigned char aes_iv[32];
45+
unsigned char encrypted_data[ENCRYPTED_BLOB_LEN];
46+
unsigned char decrypted_data[ENCRYPTED_BLOB_LEN];
47+
int encrypted_data_length = cs->encrypted_blob_length - 16;
48+
SHA_CTX ctx;
49+
50+
// setup buffers
51+
memcpy(message_key, cs->encrypted_blob, 16);
52+
memcpy(encrypted_data, cs->encrypted_blob + 16, encrypted_data_length);
53+
54+
memcpy(data_a, message_key, 16);
55+
memcpy(data_b + 16, message_key, 16);
56+
memcpy(data_c + 32, message_key, 16);
57+
memcpy(data_d, message_key, 16);
58+
59+
memcpy(data_a + 16, authkey + 8, 32);
60+
memcpy(data_b, authkey + 40, 16);
61+
memcpy(data_b + 32, authkey + 56, 16);
62+
memcpy(data_c, authkey + 72, 32);
63+
memcpy(data_d + 16, authkey + 104, 32);
64+
65+
// kdf
66+
SHA1_Init(&ctx);
67+
SHA1_Update(&ctx, data_a, 48);
68+
SHA1_Final(sha1_a, &ctx);
69+
70+
SHA1_Init(&ctx);
71+
SHA1_Update(&ctx, data_b, 48);
72+
SHA1_Final(sha1_b, &ctx);
73+
74+
SHA1_Init(&ctx);
75+
SHA1_Update(&ctx, data_c, 48);
76+
SHA1_Final(sha1_c, &ctx);
77+
78+
SHA1_Init(&ctx);
79+
SHA1_Update(&ctx, data_d, 48);
80+
SHA1_Final(sha1_d, &ctx);
81+
82+
memcpy(aes_key, sha1_a, 8);
83+
memcpy(aes_key + 8, sha1_b + 8, 12);
84+
memcpy(aes_key + 20, sha1_c + 4, 12);
85+
86+
memcpy(aes_iv, sha1_a + 8, 12);
87+
memcpy(aes_iv + 12, sha1_b, 8);
88+
memcpy(aes_iv + 20, sha1_c + 16, 4);
89+
memcpy(aes_iv + 24, sha1_d, 8);
90+
91+
// decrypt
92+
AES_set_decrypt_key(aes_key, 256, &aeskey);
93+
JtR_AES_ige_encrypt(encrypted_data, decrypted_data, encrypted_data_length, &aeskey, aes_iv, AES_DECRYPT);
94+
95+
// verify
96+
SHA1_Init(&ctx);
97+
SHA1_Update(&ctx, decrypted_data, encrypted_data_length);
98+
SHA1_Final(sha1_a, &ctx);
99+
100+
return !memcmp(sha1_a, message_key, 16);
101+
}
102+
103+
void *telegram_get_salt(char *ciphertext)
104+
{
105+
static struct custom_salt cs;
106+
char *ctcopy = strdup(ciphertext);
107+
char *keeptr = ctcopy;
108+
char *p;
109+
int i;
110+
111+
memset(&cs, 0, sizeof(struct custom_salt));
112+
ctcopy += TAG_LENGTH;
113+
p = strtokm(ctcopy, "*");
114+
cs.version = atoi(p);
115+
p = strtokm(NULL, "*");
116+
cs.iterations = atoi(p);
117+
p = strtokm(NULL, "*");
118+
cs.salt_length = strlen(p) / 2;
119+
for (i = 0; i < cs.salt_length; i++)
120+
cs.salt[i] = (atoi16[ARCH_INDEX(p[2 * i])] << 4) | atoi16[ARCH_INDEX(p[2 * i + 1])];
121+
p = strtokm(NULL, "*");
122+
cs.encrypted_blob_length = strlen(p) / 2;
123+
for (i = 0; i < cs.encrypted_blob_length; i++)
124+
cs.encrypted_blob[i] = (atoi16[ARCH_INDEX(p[2 * i])] << 4) | atoi16[ARCH_INDEX(p[2 * i + 1])];
125+
126+
MEM_FREE(keeptr);
127+
128+
return &cs;
129+
}
130+
131+
static int check_unset_password(char *ciphertext, struct fmt_main *self)
132+
{
133+
struct custom_salt *salt = telegram_get_salt(ciphertext);
134+
unsigned char pkey[256];
135+
136+
if (salt->version == 1)
137+
pbkdf2_sha1((unsigned char*)"", 0, salt->salt, salt->salt_length, 4, pkey, 136, 0);
138+
else { /* if (salt->version == 2) */
139+
SHA512_CTX ctx;
140+
unsigned char pbkdf2_key[64];
141+
142+
/* This is the $s.$p.$s, but with an empty password */
143+
SHA512_Init(&ctx);
144+
SHA512_Update(&ctx, salt->salt, salt->salt_length);
145+
SHA512_Update(&ctx, salt->salt, salt->salt_length);
146+
SHA512_Final(pbkdf2_key, &ctx);
147+
148+
pbkdf2_sha512(pbkdf2_key, 64, salt->salt, salt->salt_length, 1, pkey, 136, 0);
149+
}
150+
if (telegram_check_password(pkey, salt)) {
151+
if (john_main_process)
152+
fprintf(stderr, "%s: Note: No password set for '%.35s(...)', ignoring\n", self->params.label, ciphertext);
153+
return 0;
154+
}
155+
156+
return 1;
157+
}
158+
19159
int telegram_valid(char *ciphertext, struct fmt_main *self)
20160
{
21161
char *ctcopy, *keeptr, *p;
22-
int value, extra;
162+
int version, extra;
23163

24164
if (strncmp(ciphertext, FORMAT_TAG, TAG_LENGTH) != 0)
25165
return 0;
@@ -32,8 +172,12 @@ int telegram_valid(char *ciphertext, struct fmt_main *self)
32172
goto err;
33173
if (!isdec(p))
34174
goto err;
35-
value = atoi(p);
36-
if (value != 1)
175+
version = atoi(p);
176+
#ifdef OPENCL_FORMAT
177+
if (version != 1)
178+
#else
179+
if (version != 1 && version != 2)
180+
#endif
37181
goto err;
38182
if ((p = strtokm(NULL, "*")) == NULL) // rounds
39183
goto err;
@@ -49,40 +193,13 @@ int telegram_valid(char *ciphertext, struct fmt_main *self)
49193
goto err;
50194

51195
MEM_FREE(keeptr);
52-
return 1;
196+
return check_unset_password(ciphertext, self);
53197

54198
err:
55199
MEM_FREE(keeptr);
56200
return 0;
57201
}
58202

59-
void *telegram_get_salt(char *ciphertext)
60-
{
61-
static struct custom_salt cs;
62-
char *ctcopy = strdup(ciphertext);
63-
char *keeptr = ctcopy;
64-
char *p;
65-
int i;
66-
67-
memset(&cs, 0, sizeof(struct custom_salt));
68-
ctcopy += TAG_LENGTH;
69-
p = strtokm(ctcopy, "*");
70-
p = strtokm(NULL, "*");
71-
cs.iterations = atoi(p);
72-
p = strtokm(NULL, "*");
73-
cs.salt_length = strlen(p) / 2;
74-
for (i = 0; i < cs.salt_length; i++)
75-
cs.salt[i] = (atoi16[ARCH_INDEX(p[2 * i])] << 4) | atoi16[ARCH_INDEX(p[2 * i + 1])];
76-
p = strtokm(NULL, "*");
77-
cs.encrypted_blob_length = strlen(p) / 2;
78-
for (i = 0; i < cs.encrypted_blob_length; i++)
79-
cs.encrypted_blob[i] = (atoi16[ARCH_INDEX(p[2 * i])] << 4) | atoi16[ARCH_INDEX(p[2 * i + 1])];
80-
81-
MEM_FREE(keeptr);
82-
83-
return &cs;
84-
}
85-
86203
unsigned int telegram_iteration_count(void *salt)
87204
{
88205
struct custom_salt *cs = (struct custom_salt*)salt;

0 commit comments

Comments
 (0)