LINE CTF 2022 writeup

Participated the LINE CTF 2022. The 0007 article.

f:id:Berrys:20220327085531p:plain

I did some rev challenges when the CTF started, it was too hard for me. So, I decided to see the difficulty of each problem. After 20 hours from the beginning, I took some easy problems, and I could solve one cryptography problem.


ss-puzzle

f:id:Berrys:20220327085615p:plain

Two files containing the 32 bytes of data and one python file for encoding below were given.

f:id:Berrys:20220327090213p:plain

#!/usr/bin/env python
# -*- coding: utf-8 -*-

# 64 bytes
FLAG = b'LINECTF{...}'

def xor(a:bytes, b:bytes) -> bytes:
    return bytes(i^j for i, j in zip(a, b))


S = [None]*4
R = [None]*4
Share = [None]*5

S[0] = FLAG[0:8]
S[1] = FLAG[8:16]
S[2] = FLAG[16:24]
S[3] = FLAG[24:32]

# Ideally, R should be random stream. (Not hint)
R[0] = FLAG[32:40]
R[1] = FLAG[40:48]
R[2] = FLAG[48:56]
R[3] = FLAG[56:64]

Share[0] = R[0]            + xor(R[1], S[3]) + xor(R[2], S[2]) + xor(R[3],S[1])
Share[1] = xor(R[0], S[0]) + R[1]            + xor(R[2], S[3]) + xor(R[3],S[2])
Share[2] = xor(R[0], S[1]) + xor(R[1], S[0]) + R[2]            + xor(R[3],S[3])
Share[3] = xor(R[0], S[2]) + xor(R[1], S[1]) + xor(R[2], S[0]) + R[3]
Share[4] = xor(R[0], S[3]) + xor(R[1], S[2]) + xor(R[2], S[1]) + xor(R[3],S[0])


# This share is partially broken.
Share[1] = Share[1][0:8]   + b'\x00'*8       + Share[1][16:24] + Share[1][24:32]

with open('./Share1', 'wb') as f:
    f.write(Share[1])
    f.close()

with open('./Share4', 'wb') as f:
    f.write(Share[4])
    f.close()
We know the value of S[0] is "LINECTF{", so we can calculate a simultaneous equation for every 8 bytes in hexadecimal.
This text file is a summary of what went on in my head.
share1[ 0: 8] 25243e2a31202715
share1[ 8:16] 0000000000000000
share1[16:24] 2b0719073a0d2c2f
share1[24:32] 0214251c09404813


share4[ 0: 8] 1d08081b2d1d1231
share4[ 8:16] 0331361e3319061c
share4[16:24] 0607001b3a0f311f
share4[24:32] 3933342926756706


xor(r[0], s[0], r[0], s[3]) = xor(s[0], s[3]) = 382c36311c3d3524
xor(r[1], s[2], r[1]      ) = !!!!!
xor(r[2], s[1], r[2], s[3]) = xor(s[1], s[3]) = 2d00191c00021d30
xor(r[3], s[0], r[3], s[2]) = xor(s[0], s[2]) = 3b2711352f352f15

xor(s[0], s[3], s[0], s[2]) = xor(s[3], s[2]) = 030b270433081a31
xor(s[0], s[3], s[1], s[3]) = xor(s[0], s[1]) = 152c2f2d1c3f2814

r[0] = xor(r[0], s[3]) ^ s[3]
r[1] = xor(r[1], s[2]) ^ s[2]
r[2] = xor(r[2], s[1]) ^ s[1]
r[3] = xor(r[3], s[0]) ^ s[0]


s[0] = 4c494e454354467b = LINECTF{
s[1] = 596561685f6b6e6f
s[2] = 776e5f706c61696e
s[3] = 746578745f69735f

r[0] = 696d706f7274616e
r[1] = 745f696e5f786f72
r[2] = 5f62617365645f70
r[3] = 757a7a6c6521217d
Join R to S, and Convert to a string from hexadecimal. Finally, we can get the FLAG.

f:id:Berrys:20220327092158p:plain