squarectf2018 writeup
なかなか時間が確保できない今日この頃だが、脳死で解けそうなcrypto問があったので一応解いておいた。
C2: flipping bits
以下問題文。
Disabling C2 requires cracking a RSA message. You have two ciphertexts. The public key is (e1, n). Fortunately (this time), space rabiation caused some bit flibs and the second ciphertext was encrypted with a faulty public key (e2, n). Can you recover the plaintexts?
ダウンロードしたjarを展開すると以下の内容のテキストファイルが出てくる。
ct1: 13981765388145083997703333682243956434148306954774120760845671024723583618341148528952063316653588928138430524040717841543528568326674293677228449651281422762216853098529425814740156575513620513245005576508982103360592761380293006244528169193632346512170599896471850340765607466109228426538780591853882736654 ct2: 79459949016924442856959059325390894723232586275925931898929445938338123216278271333902062872565058205136627757713051954083968874644581902371182266588247653857616029881453100387797111559677392017415298580136496204898016797180386402171968931958365160589774450964944023720256848731202333789801071962338635072065 e1: 13 e2: 15 modulus: 103109065902334620226101162008793963504256027939117020091876799039690801944735604259018655534860183205031069083254290258577291605287053538752280231959857465853228851714786887294961873006234153079187216285516823832102424110934062954272346111907571393964363630079343598511602013316604641904852018969178919051627 You have two captured ciphertexts. The public key is (e1, n). But, due to a transient bit flip, the second ciphertext was encrypted with a faulty public key: (e2, n). Recover the plaintexts. (The algorithm is RSA.)
bit flipとか書いてあってめんどくさそうな気がめちゃくちゃしたが、とりあえずRSA問ということで、いつもどおり使える攻撃が何かないか探してみる。
elliptic-shiho.hatenablog.com
今回はm(平文)
とn
が共通でe
が異なるc(暗号文)
の組みがあるので、Common Modulus Attackが利用できそう。
適当にコードを書く。(勢い余ってpython2で書いてしまった)
import sys import gmpy import binascii def common_modulus_attack(c1, c2, e1, e2, n): gcd, s1, s2 = gmpy.gcdext(e1, e2) if s1 < 0: s1 = -s1 c1 = gmpy.invert(c1, n) elif s2 < 0: s2 = -s2 c2 = gmpy.invert(c2, n) v = pow(c1, s1, n) w = pow(c2, s2, n) m = (v * w) % n return m if __name__ == '__main__': n = 103109065902334620226101162008793963504256027939117020091876799039690801944735604259018655534860183205031069083254290258577291605287053538752280231959857465853228851714786887294961873006234153079187216285516823832102424110934062954272346111907571393964363630079343598511602013316604641904852018969178919051627 e1 = 13 e2 = 15 c1 = 13981765388145083997703333682243956434148306954774120760845671024723583618341148528952063316653588928138430524040717841543528568326674293677228449651281422762216853098529425814740156575513620513245005576508982103360592761380293006244528169193632346512170599896471850340765607466109228426538780591853882736654 c2 = 79459949016924442856959059325390894723232586275925931898929445938338123216278271333902062872565058205136627757713051954083968874644581902371182266588247653857616029881453100387797111559677392017415298580136496204898016797180386402171968931958365160589774450964944023720256848731202333789801071962338635072065 print binascii.unhexlify(hex(common_modulus_attack(c1, c2, e1, e2, n))[2:])
解けた。FLAGはflag-54d3db5c1efcd7afa579c37bcb560ae0
。
所感
スコアリングの方式は謎だったが、問題の難易度的にはクソ雑魚の自分でも楽しめるくらいだったようだ。(そろそろ難しい問題にも挑戦していけ!?)
来年もできれば参加したい。