ICHSA CTF 2021 writeup
今回のwriteupは以前の記事を多用します。ご了承ください。
Result
writeup
Crime Cloud 150pt
I got a notification from my cloud storage provider that they added strong OTP "protection" to their service.
They want 10,000 BTC for a CrimeCloud decryptor.
I think they should have named themselves CrimeSomware those thiefs!
Now I can't read my precious data anymore :-(
My H@ck3r friend was able to recover their server-side source code but he said OTP is "prefectly-secure" so I should give up.
Maybe u have an idea how to beat those CrimeLords?
Connect: nc crime.ichsa.ctf.today 8008
Note
Flag contains only lower ASCII characters and underscore. Regex it should obey ICHSA_CTF{[a-z_]+} (perl syntax).
ファイル:source.py
picoCTF 2021でも出たこの問題と全く同じですね。ただ途中にあるrand(32)のせいで、まあまあ上手くいかないです。上手くいくと長さが95になるのでそうなるまでグルグル回します。
picoCTF 2021 writeup - Attack All Around
HOST, PORT = "crime.ichsa.ctf.today", 8008 s, f = sock(HOST, PORT) for _ in range(3): read_until(f) flag = "ICHSA_CTF{" candi = "abcdefghijklmnopqrstuvwxyz_}" while True: ans = "" for c1 in candi: read_until(f,"Your input: ") mes = flag + c1 s.send(mes.encode()+b"\n") m = read_until(f).strip() read_until(f) m = base64.b64decode(m.encode()) if len(m) == 95: print("update!") ans_len = len(m) ans = c1 flag += ans print(flag) if "}" in ans: break
ICHSA_CTF{d0n7_7ruzt_DeF4uL7_V4lu3z}
Baby Homework 150pt
My teacher gave some homework in crypto. HELP!!!!!!
Connect: nc baby_homework.ichsa.ctf.today 8010
ファイル:best_crypto_service.py
以下が初耳でした。
from Crypto.Cipher.AES import AESCipher AESCipher(os.environ.get('KEY')).encrypt(padding(data))
上のサイトより、このモジュールはデフォルトでECBモードと分かりました。flagの先頭16文字を特定するため、暗号文の第一ブロックと第二ブロックが一致するよう頑張ります。
HeroCTF v3 writeup - Attack All Around
またしても以前のサイトで申し訳ないですが、これと同じ方法でflagを出します。下のsolverでは、"0"が15文字+(一文字brute force)+"0"が15文字を送ります。(一文字brute force)がflagの先頭文字と一致すると暗号文の1, 2ブロック目が等しくなります。
HOST, PORT = "baby_homework.ichsa.ctf.today", 8010 flag = "" while True: isfin = True for i in range(48,126): print(i,chr(i)) s, f = sock(HOST, PORT) read_until(f) mes = "0"*(16-(len(flag)%16)-1) + flag + chr(i) + "0"*(16-(len(flag)%16)-1) s.send(mes.encode()+b"\n") m = read_until(f).strip() s.close() if m[32:64] == m[96:128]: isfin = False flag += chr(i) print(flag,len(flag)) break if isfin: break print("ICHSA_CTF{"+flag+"}")
最後変なpadding入るので注意です。
ICHSA_CTF{d0n7_7ruzt_DeF4uL7_V4lu3z}
Poodle 1 200pt
I lost my beloved poodle :(
did you see it?
maybe the oracle will be able to find it... can you talk with her for me? please?
Connect: nc poodle1.ichsa.ctf.today 8003
ファイル:poodle1.py
これはpadding oracle attackですね。1はDecryption Attackなのでしょう。こちらのサイトをcheck!
Padding Oracle Attack 分かりやすく解説したい - Attack All Around
def modifyXor(d): if len(d) == 0: return "" x = len(d)//2 + 1 ret = "" for i in range(0,len(d),2): #print("xor",x,x-1-(i//2)) t = int(d[i:i+2],16)^x^(x-1-(i//2)) t = hex(t)[2:] if len(t) == 1: t = "0"+t ret += t #print("ret:",ret) return ret #HOSTはIPアドレスでも可 HOST, PORT = "poodle1.ichsa.ctf.today", 8003 s, f = sock(HOST, PORT) for _ in range(5): read_until(f) enc = read_until(f).strip() print("enc:",enc) for _ in range(5): read_until(f) d2 = "" dec2 = "" for j in range(16): print(j) hen = True for i in range(256): read_until(f) read_until(f,">> ") h = hex(i)[2:] #print("h:",h) if len(h) == 1: h = "0"+h print("h:",h) mes = enc[:32] + "00"*(15-j)+ h + modifyXor(d2) + enc[64:] #print("mes:",mes) assert len(mes) == 96 s.send(mes.encode()+b"\n") recv_m = read_until(f).strip() print(recv_m) if "mmm" in recv_m: hen = False print("Find!") d2 = h + d2 t = i^(j+1) t = hex(t)[2:] if len(t) == 1: t = "0"+t dec2 = t + dec2 break if hen: print("okashii") break p2 = long_to_bytes(int(dec2,16)^int(enc[32:64],16)) print(p2) d1 = "" dec1 = "" for j in range(16): print(j) hen = True for i in range(256): read_until(f) read_until(f,">> ") h = hex(i)[2:] #print("h:",h) if len(h) == 1: h = "0"+h print("h:",h) mes = "00"*(15-j)+ h + modifyXor(d1) + enc[32:64] #print("mes:",mes) assert len(mes) == 64 s.send(mes.encode()+b"\n") recv_m = read_until(f).strip() print(recv_m) if "mmm" in recv_m: hen = False print("Find!") d1 = h + d1 t = i^(j+1) t = hex(t)[2:] if len(t) == 1: t = "0"+t dec1 = t + dec1 break if hen: print("okashii") break p1 = long_to_bytes(int(dec1,16)^int(enc[:32],16)) print(p1) print(p1+p2)
ICHSA_CTF{I_d0nt_like_oracl3s}
Poodle 2 300pt
I lost my poodle again :(:(:(
let's try the oracle again?
Connect: nc poodle2.ichsa.ctf.today 8004
ファイル:poodle2.py
こちらはEncryption Attackですね。cをkeyでdecryptした値を求めてb"givemetheflag"とxorしたのを暗号文にします。
d1 = "" dec1 = "" for j in range(16): print(j) hen = True for i in range(256): read_until(f) read_until(f,">> ") h = hex(i)[2:] #print("h:",h) if len(h) == 1: h = "0"+h print("h:",h) mes = "00"*(15-j)+ h + modifyXor(d1) + enc[32:64] #print("mes:",mes) assert len(mes) == 64 s.send(mes.encode()+b"\n") recv_m = read_until(f).strip() print(recv_m) if "mmm" in recv_m: hen = False print("Find!") d1 = h + d1 t = i^(j+1) t = hex(t)[2:] if len(t) == 1: t = "0"+t dec1 = t + dec1 break if hen: print("okashii") break m = b"givemetheflag\x03\x03\x03" c = hex(int(dec1,16)^bytes_to_long(m))[2:] assert len(c) <= 32 while len(c) < 32: c = "0" + c c += "00"*16 read_until(f) read_until(f,">> ") s.send(c.encode()+b"\n") while True: print(read_until(f))
ICHSA_CTF{y3s_y0u_c4n_als0_encrypt_in_tha7_w4y_a660a2}
Unsolved
Pikatchu's Fault 100pt
I have a pretty weird girlfriend, she gave me a device to decrypt her secret messages to me. She said not to worry it is an efficient RSA implementation using CRT - whatever.
One time my pikatchu got an uncommon cold and sneezed exacty when I fed her secret message to the decryptor. I got unreadable nonsense as a result I suspect it's my pikatchu's fault for having an electric sneeze and it confused the decryptor. My confidence about it raised after I tried to decrypt again and got a readable message.
I wonder though if it is possible to get the private key from that faulty message.
N: 14428106165822100311240179104702593030922229606910261061860621459798477042443217675708638511393783602097391544907229222395222465303690975922805833664159517707002845392996861764206707180372733989400577838887924912395532925065643238637812097531657082837158436848594708309238918390308191361234059534178077141595873018313112575974600539522798755895311426362091301356794727864093165846318233065617022292712839240223002241134094765005135404901074586741323378531189871102865921045940469715763216120732916020528427859371641401521785824628585853094123501351577248220567930583676467206786442597142305655569749177107891502253803
e: 65537
M: 4c6f766520616e64206b69737365732c206d697373696e6720796f7521000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2
M': 1a36d7ecad4b18bc765ff0e3d3ecde7cae84bf1cc445a6fdcb48c335d9d3a043817fc014d55bfad94b51eb522b4ff719d33f012afe1498efafe660b97d1cb806d4ff7985a40a14f9bec9d93e2eb20f3820423ba0e34302adc82156673fa164822779174e9b7a84a417873358d1d774ccdfdb1f36de6aa8249b00184aac2feb003782f16fb3f5d7b113387989f662062452793bbaad87014b1ebd4a020342a11a19d95f4d3b29dd5449c57ea0fd3b881542a7b8b0bdbc9dcb7b19337f40e723439365dc29625cb775e91aef886d79d1403725c5aefa21b3d69f8cacbbbafb8b35c86822113e71bd272ca7cdf68da0ab397c658cb6cc14225732bc07726155ecd1
gcd(M'-M, N) で素因数分解できることは分かりました。ただそれ以降は分からず…。