Attack All Around

今やCTFと競プロばかりだが、トビタテ生のアメリカ留学やTOEFL奮闘記

ICHSA CTF 2021 writeup

今回のwriteupは以前の記事を多用します。ご了承ください。

ICHSA CTF

Result


f:id:partender810:20210603000348p:plain
まあまあよかった?

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))

Crypto.Cipher.AES

上のサイトより、このモジュールはデフォルトで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) で素因数分解できることは分かりました。ただそれ以降は分からず…。

Problem&Solver

GitHub - ksbowler/ICHSA_CTF_2021