|
|
|
|
|
by Moodles
1458 days ago
|
|
I think I understand the attack at a high level but I’m still not sure on some details. Could someone explain how the math works to provide the oracle? In particular, the exact values the malicious server inserts as the encrypted sid and q^(-1), and why, if the guess for q is lower than the real q the plaintext sid the client sends back is 0, and why it’s not zero if the guess is higher? Am I right in thinking the attacker simply randomly flips a bit in q^(-1)? Why do they need to do this? Do they flip different bits on different guesses? And then how do they encode their guess for q in the encrypted sid? And why, exactly does this provide an oracle? How does the subsequent lattice search need only half as many guesses as binary search? Finally, does this attack require the victim to actually type their password in 512 times? |
|
We're in the bizarre circumstance of being able to get our target to use a partially corrupted version of their own secret RSA key to decrypt a message of our choosing (this never happens! Only with Mega!).
We're looking for q, one of two factors of our private key. We set m, the plaintext message we get to choose, to the middle of the range of possible q's. Remember, q is smaller than m; we've got a 2048 bit RSA key, and so q is 1024 bits; the client is effectively going to pad it out, and then blindly extract the 2nd though 45th bytes from it.
What we're going to do resembles a fault attack (we're sort of simulating one by scrambling qInv). One of two things will happen:
* If m < q, the message is going to miss our faulted qInv (it won't wrap the modulus for the q part of the CRT calculation, by definition, which cancels out the qInv part of the calculation) and thus decrypts properly. After padding and extraction, the client will pull 0's out of the decrypted message --- remember, q is much smaller than the whole message space of m, and remember, the client doesn't bother to check the padding! the number of things that went wrong here is bananas! --- and post it back.
* If m >= q, our qInv fucks up the decryption; we decrypt (I assume) random gibberish, all the way through the space of m. We extract 43 bytes of the random gibberish, posting back a non-zero value.
It's described in detail in III.B.2 of https://mega-awry.io/pdf/mega-malleable-encryption-goes-awry...