m0leCon CTF 2021 Teaser Writeup

この大会は2021/5/15 2:00(JST)~2021/5/16 2:00(JST)に開催されました。
今回もチームで参戦。結果は571点で282チーム中39位でした。
自分で解けた問題をWriteupとして書いておきます。

Proof-of-Work (mics, warmup)

そのまま添付のコードを実行する。

[+] Opening connection to challs.m0lecon.it on port 1337: Done
Solving PoW...
Solved!
[*] Switching to interactive mode
ptm{w3lc0me_t0_m0lecon_2021_t34ser_ctf_chall3ng3_++++}
[*] Got EOF while reading in interactive
ptm{w3lc0me_t0_m0lecon_2021_t34ser_ctf_chall3ng3_++++}

babysign (crypto, warmup)

signするメッセージは64バイトで切られるので、超えるまでmsgを指定して、signの値が変わらなくなる長さを見つける。その結果、フラグの長さは25バイトであることがわかる。
signの計算は以下のようになっている。

m[0]: msgの前半32バイト
m[1]: msgの後半32バイト

sign = pow(sha256(m[1]) ^ m[0], d, n)
→ pow(sign, e, n) = sha256(m[1]) ^ m[0]

前半32バイトと後半32バイトで分けて、signの値を出している。後半32バイトを含めて指定して、flag+msgのsignを出せば、m[0]を算出でき、フラグがわかる。

from pwn import remote #pip install pwntools
from hashlib import sha256
from Crypto.Util.number import *

def solvepow(p, n):
    s = p.recvline()
    starting = s.split(b'with ')[1][:10].decode()
    s1 = s.split(b'in ')[-1][:n]
    i = 0
    print("Solving PoW...")
    while True:
        if sha256((starting+str(i)).encode('ascii')).hexdigest()[-n:] == s1.decode():
            print("Solved!")
            p.sendline(starting + str(i))
            break
        i += 1

def exploit(p):
    p.interactive()

if __name__ == '__main__':
    p = remote('challs.m0lecon.it', 7012)
    solvepow(p, n = 5)

    # get flag length
    pre_sign = ''
    for i in range(1, 65):
        s = p.recvuntil('t\n').rstrip()
        print(s)
        print '2'
        p.sendline('2')
        msg = '1' * i
        print msg
        p.sendline(msg)
        s = p.recvline().rstrip()
        print(s)
        if pre_sign != s:
            pre_sign = s
        else:
            flag_len = 64 - (i - 1)
            sign = s
            print '[+] flag_len =', flag_len
            break

    # get parameter
    s = p.recvuntil('t\n').rstrip()
    print(s)
    print '4'
    p.sendline('4')
    s = p.recvline().rstrip()
    print(s)
    N = int(s.split(':')[1])
    s = p.recvline().rstrip()
    print(s)
    e = int(s.split(':')[1])

    # get flag
    xor_val = pow(int(sign, 16), e, N)
    val1 = bytes_to_long(sha256('1' * 32).digest())
    val2 = (xor_val ^ val1)
    flag = long_to_bytes(val2).rstrip('1')
    print flag

実行結果は以下の通り。

[+] Opening connection to challs.m0lecon.it on port 7012: Done
Solving PoW...
Solved!

1. Sign
2. Sign but better
3. Verify
4. See key
0. Exit
2
1
7654e86a9217f2cb45e6ccfd4a5c49ba9920f0ab021027e9905e5668dc319911d734ca7109c6d12e461ad8b491150466a1b20050b0e6020faf830e0fa720082e127ef5294bfeb9f92202ec0be604ac0a0e5dc75a33ec42d0936b8fe24dab171c4794c3870335aa36f5dc70cfc15c44bf30fc61f885ca8bc8c8991dc38a53be2047b70f7a5b3801c52d1c63be029065a09c94fb0f24896d4a5ed23f0d62b1a0d4c5d8bbca45b917ce059b7067e98052deb2f4f21bddd663d7d1f2b5d695534ae7bd51df7a264c36bca3c2e30162f67b155b7eb0b1836e36ed2379d3900b38e0030580ef1e5f5bfc7ba88525ffa088d3a143e94167d2eeca1a193cbfd5c7aedcaa

1. Sign
2. Sign but better
3. Verify
4. See key
0. Exit
2
11
90794aff81934d8e66dc01d8a48a0234ac258bfc01b13b0d2227965ccd7bdf66daba91e32ebb51272af4abff859e5c0b0f7b75eb3d5c2375105becb2688ab74c53d00fcbba0863a8974d9463910819d17867343097c03984c3eacec4e2462f675971cdffd66e415eb3c6e5d3f4a5030d84469293a64f39ef87b569edea04f26ff9d211e16d4e4e5964f5feb5e8b4adec4f330465ec9978e017938491cb94ec87a76aa936cf963825b62eb758dbf9c524893515ecf599f9dca28e48d47c277dd01225aebce78ff3b7e87df21423a779d946fd852bd3325c93ad61f92a627319846e52f0a7fce7d8d698b9f83fcd77a4270574f2a5c42a47e73b9f6c368069449b

1. Sign
2. Sign but better
3. Verify
4. See key
0. Exit
2
111
6534c3b2223db6f80dd2478920c85b5f83a4fc055a1cf598e37fca704581daa16f4d7a260b8a85bbb2bcbe5d414dd6cc893171cdee882392d4dfa2b44ce1df5d2f228046e34123dda8d958b32d0972b8e386c0304fda003b13e371a4c7b99ba8684e649057860cb2b1d43a8ee918bd57e770db8d26e24c42d745c7d26c7c9e67fe2cef22fc7fd98093e463852683d329bdb09ccb89e469f131cd283007fb976357bcca7bcfad2d78f5fd53b60a26fd59806fb2b3ca48f13f9e2a324af2389c0a98cc9cfaa25184117912bf5a00ada18187f32601a89e5b89c9d3e783b73241b0b232d10a780cfa9c8a9a6f4bffa8895d3f031ef18e293fb0f2ae1f37f7083b44

1. Sign
2. Sign but better
3. Verify
4. See key
0. Exit
2
1111
4668a6ec7f59235f43936abcc1a9981c44d1895d1a8a1bffbfd5a5346f40b7ec370aefac6a5d94aa29fa44e37d1da88464ebc72b2a5fd09915086bc0f246544c45ffa9789b295dbd8ade42fedb048a55f896ffe2a983cdb80570f650eb2a1cfcc3168f56ba1979cc089008676ba70f8a5cf6d6e364856d5709b275566385591d1f0cef3022d2ae64ea13f8459bdf99d289f82842a910b9c38d49d44ef2de16260460a1721e5c79983523970a2d779b0de4b6cf17c9ee69c4c2fce4986bd518f64ed31314dc4a0d2f542a104ed80c3c05cc876ac857af6e32981c705da842a4e82086d23beea873bd9be3916e1f41eb272360a3ae603b9d77e1c7ffb67826fbbc

                :

1. Sign
2. Sign but better
3. Verify
4. See key
0. Exit
2
111111111111111111111111111111111111111
3f482ae9b380ae40bf7baf5b7d9b20d9776bf4f7e9f1cfdb9a6c6520b41d93f82b7b975a98feab12856e5ee09dbf3edac9b2e66cce0b66ee4ac17e1beb9acc330a95f6c895038e26857327335013495156ad07fae53391fabe4fe1bb457b63347d6f2696fc7dfe7987cf81663f3b328fff517e6166256e2b8adbdc0a053599a7f49893c6debbe905944170735a367c05dc9377a792ec85734cda44049aa373a32efa1bb4957bd4b445d0e611456ce6c68b489d39de2620f34b9036090c3f154acdb1f5e6e3109973e84d6eacb8e8f5244b3c270e490904aec1302c61c8a3c8fd12f90870f0a84b9115df9a9b1e25b298df3d7e5a840fd75669cd9c8cbbe27b0c

1. Sign
2. Sign but better
3. Verify
4. See key
0. Exit
2
1111111111111111111111111111111111111111
3f482ae9b380ae40bf7baf5b7d9b20d9776bf4f7e9f1cfdb9a6c6520b41d93f82b7b975a98feab12856e5ee09dbf3edac9b2e66cce0b66ee4ac17e1beb9acc330a95f6c895038e26857327335013495156ad07fae53391fabe4fe1bb457b63347d6f2696fc7dfe7987cf81663f3b328fff517e6166256e2b8adbdc0a053599a7f49893c6debbe905944170735a367c05dc9377a792ec85734cda44049aa373a32efa1bb4957bd4b445d0e611456ce6c68b489d39de2620f34b9036090c3f154acdb1f5e6e3109973e84d6eacb8e8f5244b3c270e490904aec1302c61c8a3c8fd12f90870f0a84b9115df9a9b1e25b298df3d7e5a840fd75669cd9c8cbbe27b0c
[+] flag_len = 25

1. Sign
2. Sign but better
3. Verify
4. See key
0. Exit
4
N: 19444496506668057565703830709849574320119296023394552743554841106288876599982744410824562139626939984799109105140756569415987962251605405845574431989522509087927660918203612673476669357567232593612283314538320313077153463307443372271764546196165597912289325099399933625991423985237269731742331704718635784230127944001937032123837083823100411218004555265023043907327356201192573706917175963092954167020576450218169479787879017269282697810966173088094066379117109022908457751989745785332187858364088369306396333542665150480610191515201381727392976960502629656117629021217476064093045075121509083820256945142151229305921
e: 65537
ptm{n07_3v3n_4_ch4ll3n63}
[*] Closed connection to challs.m0lecon.it port 7012
ptm{n07_3v3n_4_ch4ll3n63}