44 lines
1.3 KiB
Python
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()
|