44 lines
2.8 KiB
Python
44 lines
2.8 KiB
Python
"""
|
|
EXAMPLE: HITCON 2019 Quals — "Lost modulus" (Crypto, 200p)
|
|
https://github.com/p4-team/ctf/tree/master/2019-10-12-hitcon/lost_modulus
|
|
|
|
VULN: RSA where the printed key leaks `e, d, iqmp=inv(q,p), ipmq=inv(p,q)`
|
|
but NOT n. Recover n via a quadratic equation in phi, then decrypt.
|
|
(p4's __str__ printed self.d labelled as n.)
|
|
|
|
Run:
|
|
cd /home/code/ctfkit
|
|
python3 examples/lost_modulus/solve.py
|
|
Expected flag: hitcon{1t_is_50_easy_t0_find_th3_modulus_back@@!!@!@!@@!}
|
|
"""
|
|
import sys
|
|
from Crypto.Util.number import long_to_bytes
|
|
|
|
sys.path.insert(0, "/home/code/ctfkit")
|
|
from lib.crypto_utils import recover_n_from_keys
|
|
|
|
HERE = __file__.rsplit("/", 1)[0]
|
|
|
|
|
|
def main():
|
|
# parsed from `output`
|
|
e = 1048583
|
|
d = 20899585599499852848600179189763086698516108548228367107221738096450499101070075492197700491683249172909869748620431162381087017866603003080844372390109407618883775889949113518883655204495367156356586733638609604914325927159037673858380872827051492954190012228501796895529660404878822550757780926433386946425164501187561418082866346427628551763297010068329425460680225523270632454412376673863754258135691783420342075219153761633410012733450586771838248239221434791288928709490210661095249658730871114233033907339401132548352479119599592161475582267434069666373923164546185334225821332964035123667137917080001159691927
|
|
ipmq = 22886390627173202444468626406642274959028635116543626995297684671305848436910064602418012808595951325519844918478912090039470530649857775854959462500919029371215000179065185673136642143061689849338228110909931445119687113803523924040922470616407096745128917352037282612768345609735657018628096338779732460743
|
|
iqmp = 138356012157150927033117814862941924437637775040379746970778376921933744927520585574595823734209547857047013402623714044512594300691782086053475259157899010363944831564630625623351267412232071416191142966170634950729938561841853176635423819365023039470901382901261884795304947251115006930995163847675576699331
|
|
ct = 0x32074de818f2feeb788e36d7d3ee09f0000381584a72b2fba0dcc9a2ebe5fd79cf2d6fd40c4dbfea27d3489704f2c1a30b17a783baa67229d02043c5bc9bdb995ae984d80a96bd79370ea2c356f39f85a12d16983598c1fb772f9183441fea5dfeb5b26455df75de18ce70a6a9e9dbc0a4ca434ba94cf4d1e5347395cf7aafa756c8a5bd6fd166bc30245a4bded28f5baac38d024042a166369f7515e8b0c479a1965b5988b350064648738f6585c0a0d1463bd536d11a105bb926b44236593b5c6c71ef5b132cd9c211e8ad9131aa53ffde88f5b0df18e7c45bcdb6244edcaa8d386196d25297c259fca3be37f0f2015f40cb5423a918c51383390dfd5a8703
|
|
|
|
res = recover_n_from_keys(e, d, ipmq, iqmp)
|
|
assert res, "recover_n failed"
|
|
p, q = res
|
|
n = p * q
|
|
m = pow(ct, d, n)
|
|
flag = long_to_bytes(m).decode(errors="replace")
|
|
print("recovered n bits:", n.bit_length())
|
|
print("FLAG =", flag)
|
|
return flag
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|