Description
The service prints the RSA modulus N, public exponent e, and the encrypted flag. Because N is even (one prime is 2), phi(N) collapses to q − 1, letting us recover the private key instantly.
Setup
Connect to `verbal-sleep.picoctf.net 51434` and copy the N, e, and ciphertext values you receive.
Plug those numbers into a short Python script that factors N/2, builds phi, and decrypts the ciphertext.
nc verbal-sleep.picoctf.net 51434
python3 - <<'PY'
from Crypto.Util.number import long_to_bytes
N = 17537614138261784213928370696328752813986709042120259741743863531969271925248508130709263987579968737098825108090143054462035829031497144145084077726439478
e = 65537
c = 1862202474168637121872319135644317889384481444154089212360721245109801826108338981069221317033529716486407831083567338102494200390951480362472079543955817
q = N // 2
phi = q - 1
d = pow(e, -1, phi)
m = pow(c, d, N)
print(long_to_bytes(m).decode())
PY
Solution
- Step 1Capture the challenge outputEach netcat connection emits a fresh set of RSA parameters. Grab N, e, and the ciphertext before disconnecting. N always divides evenly by 2, so you only need one large odd factor q = N / 2.
- Step 2Exploit the even modulusBecause p = 2, Euler’s totient is simply φ(N) = (2 − 1) × (q − 1) = q − 1. Invert e modulo φ(N) to obtain the private exponent d and run a modular exponentiation to recover the plaintext.d = pow(e, -1, q - 1)m = pow(ciphertext, d, N)
- Step 3Convert the integer to bytesUse `Crypto.Util.number.long_to_bytes` (from pycryptodome) to transform the decrypted integer into ASCII, and the result is the picoCTF flag.from Crypto.Util.number import long_to_bytesprint(long_to_bytes(m).decode())
Flag
picoCTF{tw0_1$_pr!m38177...}
If the script throws a ValueError, double-check you copied the current N/e/c set. The values change with every connection.