Open solardiz opened 3 years ago
FWIW, here's a first attempt at hacking our GPG format to support ProtonMail instead of normal GPG keys. This pretends to work (with --skip-self-test
since the test vectors aren't updated), but I don't know if it actually works right or not.
diff --git a/src/gpg_common_plug.c b/src/gpg_common_plug.c
index 99618a2..2e38957 100644
--- a/src/gpg_common_plug.c
+++ b/src/gpg_common_plug.c
@@ -102,7 +102,7 @@ struct fmt_tests gpg_common_gpg_tests[] = {
};
// mul is at most (PLAINTEXT_LENGTH + SALT_LENGTH)
-#define KEYBUFFER_LENGTH ((PLAINTEXT_LENGTH + SALT_LENGTH) * 64)
+#define KEYBUFFER_LENGTH ((256 + SALT_LENGTH) * 64)
// Returns the block size (in bytes) of a given cipher
uint32_t gpg_common_blockSize(char algorithm)
@@ -574,7 +574,7 @@ static void S2KItSaltedSHA256Generator(char *password, unsigned char *key, int l
SHA256_Update(&ctx, "\0", 1);
}
// Find multiplicator
- tl = strlen(password) + SALT_LENGTH;
+ tl = 256/*strlen(password)*/ + SALT_LENGTH;
mul = 1;
while (mul < tl && ((64 * mul) % tl)) {
++mul;
@@ -583,7 +583,7 @@ static void S2KItSaltedSHA256Generator(char *password, unsigned char *key, int l
bs = mul * 64;
bptr = keybuf + tl;
n = bs / tl;
- memcpy(keybuf + SALT_LENGTH, password, strlen(password));
+ memcpy(keybuf + SALT_LENGTH, password, 256/*strlen(password)*/);
while (n-- > 1) {
memcpy(bptr, keybuf, tl);
bptr += tl;
diff --git a/src/gpg_fmt_plug.c b/src/gpg_fmt_plug.c
index 706c20b..9ee7ba2 100644
--- a/src/gpg_fmt_plug.c
+++ b/src/gpg_fmt_plug.c
@@ -37,6 +37,9 @@ john_register_one(&fmt_gpg);
#include <omp.h>
#endif
+#include <assert.h>
+#include "crypt_blowfish-1.3/crypt_blowfish.c"
+
#include "arch.h"
#include "params.h"
#include "common.h"
@@ -124,7 +127,25 @@ static int crypt_all(int *pcount, struct db_salt *salt)
int res;
unsigned char keydata[64];
- gpg_common_cur_salt->s2kfun(saved_key[index], keydata, ks);
+ static const uint8_t modulus[] = {put, your, 256, byte, values, here};
+ struct {
+ char bcrypt_out[60];
+ uint8_t modulus[256];
+ uint8_t i;
+ } buf;
+ assert(sizeof(buf) == 60 + 256 + 1);
+ BF_crypt(saved_key[index], "$2y$10$your.22.char.salt.here", buf.bcrypt_out, sizeof(buf), 0);
+ assert(sizeof(modulus) == sizeof(buf.modulus));
+ memcpy(buf.modulus, modulus, sizeof(buf.modulus));
+ char promises[4 * 64];
+ SHA512_CTX ctx;
+ for (buf.i = 0; buf.i < 4; buf.i++) {
+ SHA512_Init(&ctx);
+ SHA512_Update(&ctx, &buf, sizeof(buf));
+ SHA512_Final((unsigned char *)&promises[buf.i * 64], &ctx);
+ }
+
+ gpg_common_cur_salt->s2kfun(promises, keydata, ks);
res = gpg_common_check(keydata, ks);
if (res) {
cracked[index] = 1;
ProtonMail uses OpenPGP keys, but with custom bcrypt-based key derivation (prior to the usual s2k?). We can probably add a format that would crack ProtonMail login password (in their one-password mode, or the mailbox password otherwise?) given an OpenPGP private key extracted from a memory dump and bcrypt salt and SRP modulus obtained when trying to log in, as I explained here:
https://github.com/ProtonMail/WebClient/issues/38#issuecomment-811028444
Anyone wants to try and implement this?