DoubleS1405 CTF Writeup
Harekazeで参加。チームで 881ptを獲得し、順位は 9 位 (得点 130 チーム中)、私はそのうち250pt(+200pt)をとった。
[Rev 100] Exec
PowerPCのバイナリが渡される。powerpc-linux-gnu-objdump
で.rodata領域を見ると、flagis_MY_TRAP_CARD
という文字列と?\\x148\x05\x16k?7:0\x0d1?(p3"'
というバイト列が見つかる。バイナリの中身を読む前にXORを試したらフラグが出てきた。
Flag: Y0u_le4rned_pow3rpc
[Crypto 150] RSA
最初、渡されるスクリプト(の一部)が以下のようになっていたが、明らかに間違っている(recv==enc
という比較であれば、送られてきたencをそのまま渡せばよい)ので、enc_data
もしくはSECRET_LOGIC()
を行う前のデータとの比較であると想定した。
これは後ほど修正があった様子。
if True: enc_data = SECRET_LOGIC() enc = powmod(enc_data, e, n) conn.send("enc : %d\ne : %d\np : %d\nq : %d\n" % (enc, e, p, q)) recv = conn.recv(1024) if end - start > 1: conn.send("time out") conn.close() if recv == enc: conn.send(FLAG) conn.close() conn.send("wrong") conn.close() else: conn.close() print "error"
enc
, e
, p
, q
が送られてくるので、復号することは容易だが毎回送られてくるデータは異なる。そのうちの1つに着目すると、
復号結果: 8755777115341080594761456402455437710685895952551191971666112763595998769587018749591234410595235907226473499074309848886437298673992843291278177512204044380308909676435457547909426657896511491773395035272677030211195668187992227281682442084623728957
これを16進数に変換後、hexstringとみなしてデコードした結果:
NDU0NDM4NTQ2OTA1MzQxNjQ5NTY4MDE1MzY4Njk5MDAyNzY5MTgxODYyNTYyNjEwNDI0OTI4MzAxNzMwNjA3MzczMTI3ODM4OTEwNjA=
さらにこれをbase64とみなしてデコードした結果:
45443854690534164956801536869900276918186256261042492830173060737312783891060
これを16進数に変換後、hexstringとみなしてデコードした結果:
dxOmJnmqANLoRFzfGpfs1AW74l4VFlzt
というようになっていた。上でいうdxOmJnmqANLoRFzfGpfs1AW74l4VFlzt
を送り返すとFlagが貰える。
一応、以下のようなスクリプトを書いた。
from pwn import * from base64 import b64decode import Crypto.PublicKey.RSA r = remote('203.251.182.94', 4000) r.recvuntil('enc : ') enc = int(r.recvuntil('\n')[:-1]) r.recvuntil('e : ') e = int(r.recvuntil('\n')[:-1]) r.recvuntil('p : ') p = int(r.recvuntil('\n')[:-1]) r.recvuntil('q : ') q = int(r.recvuntil('\n')[:-1]) log.info(enc) log.info(e) log.info(p) log.info(q) def gcd(a, b): while b: a, b = b, a%b return a def lcm(a, b): return a * b / gcd(a,b) def gcd2(a, b): if b == 0: u = 1 v = 0 else: q = a / b r = a % b (u0, v0) = gcd2(b, r) u = v0 v = u0 - q * v0 return (u, v) d = gcd2(e,lcm((p-1),(q-1)))[0] rsa = Crypto.PublicKey.RSA.construct((p*q, long(e), d, p, q)) flag = hex(int(b64decode(hex(rsa.decrypt(enc))[2:].decode('hex'))))[2:].decode('hex') log.info(flag) r.send(flag) log.info(r.recv())
Flag: Y34hh_RSA_1S_S0_E4sy
([For 200] AI Mouse)
リンちゃん(@jtwp470)がUSBのパケットを解析->マウスの軌跡を画像化までやってくれていて、ほとんどFlagはとれていた。しかし、字が汚すぎて判別がつかないという問題があり、Flagの読み取りだけお手伝いさせてもらった。(ほとんど漁夫の利みたいな感じになってしまったので、申し訳ない気持ち)
Flag: c4tch_th3_m0us3!
なんだけど、どう見ても最初のcは大文字だし、最後のが!ってのは無理があると思う…