Files

44 lines
1.3 KiB
Python

"""
EXAMPLE: SECCON 2017 Quals — "Ps and Qs" (Crypto, 200p)
https://github.com/p4-team/ctf/tree/master/2017-12-09-seccon-quals/crypto_ps_and_qs
VULN: Two RSA public keys (pub1.pub, pub2.pub) share a prime (common factor).
FACT: gcd(n1, n2) = p -> recover q1 = n1/p, q2 = n2/p -> private keys -> decrypt.
Run:
cd /home/code/ctfkit
python3 examples/ps_and_qs.py
Expected flag: SECCON{1234567890ABCDEF}
"""
import sys
from Crypto.PublicKey import RSA
from Crypto.Util.number import long_to_bytes
sys.path.insert(0, "/home/code/ctfkit")
from lib.crypto_utils import gcd, modinv
HERE = __file__.rsplit("/", 1)[0]
def main():
pub1 = RSA.importKey(open(f"{HERE}/pub1.pub").read())
pub2 = RSA.importKey(open(f"{HERE}/pub2.pub").read())
p = gcd(pub1.n, pub2.n)
q1 = pub1.n // p
q2 = pub2.n // p
assert p * q1 == pub1.n and p * q2 == pub2.n, "common-factor failed"
msg = int.from_bytes(open(f"{HERE}/cipher", "rb").read(), "big")
d1 = modinv(pub1.e, (p - 1) * (q1 - 1))
pt = long_to_bytes(pow(msg, d1, pub1.n)).decode(errors="replace")
import re
m = re.search(r"SECCON\{[^}]+\}", pt)
flag = m.group(0) if m else pt
print("shared prime p =", p)
print("FLAG =", flag)
return flag
if __name__ == "__main__":
main()