nullcon HackIM 2020 Writeup

この大会は2020/2/8 2:00(JST)~2020/2/9 14:00(JST)に開催されました。
今回もチームで参戦。結果は 2771点で1208チーム中19位でした。
自分で解けた問題をWriteupとして書いておきます。

misc (ez pz sanity check)

問題にフラグが書いてあった。

hackim20{no_insanity}

RockPaperScissors (crypto)

$ nc crypto1.ctf.nullcon.net 5000
Beat me in Rock Paper Scissors 20 consecutive times to get the flag
Here are the possible commitments, the first one is my move: 730410d206f3590d195761ec450b9f6 9285f09386b28c6a79f955c22cde8669 b177913018de0598cc3089b157545b43
Your move:s
My move was: p Secret was: d0aaa45cc4bb87c90fdab0bc725852b8
Here are the possible commitments, the first one is my move: 20990c13987ce962715f00af106ebf50 eb58f8676627189b03e67f38d9fc2b3e a92f16f746bd96e4941b1bf2eb8c028b
Your move:r
My move was: p Secret was: b249c208df3c840b101b826104e7e819
You lose!

20回じゃんけんで勝てば、フラグが得られる。AESのsboxもどきを使っているが、逆算できる。逆算すると、相手のじゃんけんの手がわかるので、スクリプトにする。

#!/usr/bin/env python3
import socket
import itertools
from Crypto.Util.number import *

sbox = [221, 229, 120, 8, 119, 143, 33, 79, 22, 93, 239, 118, 130, 12, 63, 207, 90, 240, 199, 20, 181, 4, 139, 98, 78, 32, 94, 108, 100, 223, 1, 173, 220, 238, 217, 152, 62, 121, 117, 132, 2, 55, 125, 6, 34, 201, 254, 0, 228, 48, 250, 193, 147, 248, 89, 127, 174, 210, 57, 38, 216, 225, 43, 15, 142, 66, 70, 177, 237, 169, 67, 192, 30, 236, 131, 158, 136, 159, 9, 148, 103, 179, 141, 11, 46, 234, 36, 18, 191, 52, 231, 23, 88, 145, 101, 17, 74, 44, 122, 75, 235, 175, 54, 40, 27, 109, 73, 202, 129, 215, 83, 186, 7, 163, 29, 115, 243, 13, 105, 184, 68, 124, 189, 39, 140, 138, 165, 219, 161, 150, 59, 233, 208, 226, 176, 144, 113, 146, 19, 224, 111, 126, 222, 178, 47, 252, 99, 87, 134, 249, 69, 198, 164, 203, 194, 170, 26, 137, 204, 157, 180, 168, 162, 56, 81, 253, 213, 45, 21, 58, 24, 171, 37, 82, 53, 50, 84, 196, 232, 242, 244, 64, 80, 10, 114, 212, 187, 205, 28, 51, 182, 16, 107, 245, 211, 85, 92, 195, 5, 197, 200, 31, 183, 61, 123, 86, 167, 154, 41, 151, 35, 247, 246, 153, 95, 206, 149, 76, 112, 71, 230, 106, 188, 172, 241, 72, 156, 49, 14, 214, 155, 110, 102, 116, 128, 160, 135, 104, 77, 91, 190, 60, 42, 185, 96, 97, 251, 218, 133, 209, 65, 227, 3, 166, 255, 25]
p = [5, 9, 1, 8, 3, 11, 0, 12, 7, 4, 14, 13, 10, 15, 6, 2]
round = 16

def recvuntil(s, tail):
    data = b''
    while True:
        if tail in data:
            return data.decode()
        data += s.recv(1)

def pad(data, size = 16):
    pad_byte = (size - len(data) % size) % size
    data = data + bytearray([pad_byte]) * pad_byte
    return data

def repeated_xor(p, k):
    return bytearray([p[i] ^ k[i % len(k)] for i in range(len(p))])

def int_to_bytes(x):
    return long_to_bytes(x, 16)

def unhash2(hex_data, rps):
    state = int_to_bytes(int(hex_data, 16))

    roundkey = pad(rps)
    for _ in range(round):
        temp = bytearray(16)
        for i in range(len(state)):
            temp[i] = state[p[i]]
        state = temp
        for i in range(len(state)):
            state[i] = sbox.index(state[i])
        state = repeated_xor(state, roundkey)

    return state

def get_move(a, b, c):
    rps = [b'r', b'p', b's']
    for seq in list(itertools.permutations(rps)):
        x = unhash2(a, seq[0])
        y = unhash2(b, seq[1])
        z = unhash2(c, seq[2])
        if x == y and y == z:
            return seq[0]

def get_win(move):
    if move == b'r':
        return b'p'
    elif move == b's':
        return b'r'
    elif move == b'p':
        return b's'

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(('crypto1.ctf.nullcon.net', 5000))

for i in range(20):
    data = recvuntil(s, b'Your move:')

    hash_list = data.split('\n')[1].split(' ')[-3:]
    move = get_move(hash_list[0], hash_list[1], hash_list[2])
    inp = get_win(move)

    print(data + inp.decode())
    s.sendall(inp + b'\n')

for i in range(3):
    data = recvuntil(s, b'\n').rstrip()
    print(data)

実行結果は以下の通り。

Beat me in Rock Paper Scissors 20 consecutive times to get the flag
Here are the possible commitments, the first one is my move: b2029a996bf195cca5a5703d783a9f9b 378b3b71bb9c7d2145166ea6eafae11d 9184bda70c3169d0f626c36e1d4e8900
Your move:s
My move was: p Secret was: cf6a9f81b0f920fbd0fbe81395a5cfac
Here are the possible commitments, the first one is my move: c327f00086b538492387b4bab7026efa d20041922062f7eb9a5063993b332b01 6ee7ed62378b489a347c676002e10236
Your move:s
My move was: p Secret was: d109dd8e7e2d9d9396c7f756ae28770f
Here are the possible commitments, the first one is my move: c3f9c87c9ed5e2cda9cf2ba2d58e4f1 4aabb14030c0fc36d07cd799dbbab0a7 9542acf33c435df6d9501c605445e7eb
Your move:s
My move was: p Secret was: 751a5ec186f0ebdb61683d0efe39c336
Here are the possible commitments, the first one is my move: eed997081d0f53c2244ff28a4c8b96bc 11d3a27ad3e1ef485d991cf4be4bb228 186773eb24d814077400d7d327c57086
Your move:s
My move was: p Secret was: 9d93c9ef46e004a651bccb7c02bbc0e3
Here are the possible commitments, the first one is my move: edfdbf253c3b4adc74366cad7cb781bd 9e4adb18f196162a2497a9140861cda0 6aa5a35c9a1bb51c8647dd8878a5a91
Your move:s
My move was: p Secret was: 718b597b0ae8c3489c07f3db2ffadf04
Here are the possible commitments, the first one is my move: abcf3f516028bb7048836f6ec2be0df4 d43bd2e71e3616bfa21d2da6109aad78 c76f5e4804af4ade9907f917ebbf9d90
Your move:p
My move was: r Secret was: 754a30c328bf9a076116559df57477f0
Here are the possible commitments, the first one is my move: 6af2ac08b9d29279338bc31f46541db ed483960648921c59bdbc6fc08daf7fb c198e4dd9e1abf06523faf6f87b3429d
Your move:s
My move was: p Secret was: 2eb689219086d39005e79c0a4f3f4e59
Here are the possible commitments, the first one is my move: c4a33c7461c87a28471a009139b8cdbc ea8189a921faf8cd16e837dc3825ad7 2b14c3f5e5b7f84479fb7fe1648f1b28
Your move:p
My move was: r Secret was: 52584af12a894cc6a150ec9bb86a0697
Here are the possible commitments, the first one is my move: f527ad4c0ede9eb8e377981987b60c4d 861bd752b7b2cb684f5ebfea08563dd8 a6e74819e26fdbdd0e06dd6c7cf0940c
Your move:p
My move was: r Secret was: a6d0813cf8912a58b6722af13d8c4ffa
Here are the possible commitments, the first one is my move: 642f0e6617d9d6e8495a3f3c98996319 8399f15413ee0f5b92128905d2063134 8b1fff3c80dc49f0e7dc55c9d116a3d4
Your move:s
My move was: p Secret was: cc6746616f093a7eb85a79026864684f
Here are the possible commitments, the first one is my move: e2c31057768056ed62d4a884264a8abd 4249a9641b66b046a4e21db44a190891 87f1404e8aa02f75397f6dd214b93b7b
Your move:p
My move was: r Secret was: d39764665fac45418bec287e7e64fd2e
Here are the possible commitments, the first one is my move: 35e22f6079f6e941941691948048deb2 7728a8c02a5f18cbd4a5288f715dda89 d7124256d5ce96a1719bd811962928c6
Your move:s
My move was: p Secret was: 269f46b5dd77fb85a3e87264d2e9fb0e
Here are the possible commitments, the first one is my move: 9a4756d16a7139650e417252abc359d5 38d87fa02d92d6f30d318d7f2b75777d fb5a8c07b9130f14e30a0ccd1fe46cab
Your move:p
My move was: r Secret was: 6fe06b3546b18cee67b51fe6eb5e54fb
Here are the possible commitments, the first one is my move: 95a02c255632f0678c962249b51bf8b0 c18233582520781b0928f1269bc6b4a 49796a18f925a701580184ccbf83ffea
Your move:s
My move was: p Secret was: 5dd18305f83d1a8b78153d588c004c8c
Here are the possible commitments, the first one is my move: ae4fe4b6a1a79b72c7a85c990b728d62 60eca540a37bad3e9c882053a9f399c3 6bf52af3de56f2f52afc9abae577f0ee
Your move:s
My move was: p Secret was: cc4e610ca4c3fbfe11dad254bc8a976f
Here are the possible commitments, the first one is my move: ac027672edd07a68cfd962012c647636 daa589e54ae2afb8a82ff04957f24d01 b48b241026b0f804d7f7a3cc0f2101fa
Your move:p
My move was: r Secret was: 3cdd23ac0814ba18302c158c790b8dee
Here are the possible commitments, the first one is my move: 4685eabe2d7223e547d62fdc89028d20 34306444b9cd118ecca1d0bfb233f076 1077b5096ad4fe78d1d12eb9f67a855d
Your move:r
My move was: s Secret was: b44fcf89db23fd2f243714c16b92a875
Here are the possible commitments, the first one is my move: 73fd41ebdadb27042c1ac64c6763223c e4aa91f4878a326888fbbc2c45289e63 bf4af008c18cabb82d476a86203806f7
Your move:s
My move was: p Secret was: babeb542a21e3103785c585f22b0d18f
Here are the possible commitments, the first one is my move: c1589343050ef12fc659a1150023d6d5 9e99d96e1f9b2dd419353ef3a64638ab ed2fc5a8cdd62a247ccd5af9ef309b7d
Your move:p
My move was: r Secret was: e3229f2e7bdd2fdf84c1d14b4db758c0
Here are the possible commitments, the first one is my move: b808f5d814f3fc516e14d2f444455fa2 52e65131120d5d2a362966d3b1baab81 242070c5b4b85ef869eca647e140d184
Your move:r
My move was: s Secret was: cd2a0df9cad7f05a1b6b08d21f29b7c9
You win
Your reward is hackim20{b4d_pr1mitiv3_beats_all!1!_7f65}
hackim20{b4d_pr1mitiv3_beats_all!1!_7f65}