Let Decrypt Again

The challenge has the most code in it so far, but should not take too long to realize the task we had to do. This follows the same idea as the prequel challenge Let’s Decrypt - that is to find an appropriate N, e such that the pow(sig, e, N) is equal to the value of the PKCS1 padded messages. However, in this challenge, we had a twist - we can only use one non-prime modulus N but has to generate three es such that pow(sig, e_n, N) = m_n with e_n being the public exponent correlated to the nth message m_n....

December 20, 2022 · 5 min · qvinhprolol

Vote for Pedro

First, the modulus is big (2048 bits) and the public exponent e is small (3), hence we may use a small number and the arithmetic operation under the modulo N is the same as in $\mathcal Z$ Pedro is not exactly careful with the padding, indeed: 1 2 3 4 5 6 7 8 vote = int(your_input['vote'], 16) verified_vote = long_to_bytes(pow(vote, ALICE_E, ALICE_N)) # remove padding vote = verified_vote.split(b'\00')[-1] if vote == b'VOTE FOR PEDRO': return {"flag": FLAG} Anything in the verified_vote variable before the null byte is discarded, hence a message of the form <SOME RANDOM STUFF>\x00VOTE FOR PEDRO is still valid....

December 19, 2022 · 2 min · qvinhprolol

Blinding Light

RSA signing with malleability, we can sign anything but the admin token to retrieve the flag. My approach is to get the signature of the hex string b'\x02', in numeric value is $2^d$, with $d$ being the private key. Then we request for the message that is twice the value of the admin token, then we get the value of $(2m)^d$. Then retrieving the value of $m^d$ should be trivial....

December 16, 2022 · 3 min · qvinhprolol