CTF

[Project SEKAI CTF 2022] Crypto - Time Capsul

오호츠크해 기단 2022. 11. 17. 22:08
728x90

Time Capsul

암호화에는 두 가지 단계가 있다.

  • Stage 1: [0, 8]의 임의 순열을 기반으로 한 암호화
  • Stage 2: 현재 시간은 시드로 사용되며 암호화된 메시지에 추가된다. 0x42로 XOR 연산을 수행하여 최종 바이트 배열을 가져온다.

다음 방법을 사용하여 암호를 해독했다.

  1. 시간을 복구하려면 출력의 마지막 18바이트를 가져오고 0x42를 사용하여 XOR 작업을 수행하십시오.
  2. 이 시간을 2단계로 보내 1단계에서 암호화된 메시지를 가져온다. (시간이 원래 메시지와 무관하므로 마지막 18자 제거)
  3. 1단계에서 8! 순열을 가진 키를 강제로 무차별적으로 적용하여 암호화를 되돌립니다.

[해결 파이썬 코드]

#!/usr/bin/env python3
import random
import sys
import time
import itertools

def dec(ctxt, key):
    groups = []
    i = 0

    for k in range(8):
        grp = []
        tmp = 0
        if key[k] < len(ctxt)%8: tmp = 1
        for j in range(int(len(ctxt)/8) + tmp):
            grp += [ctxt[i+j]]
        groups += [grp]
        i += j+1
    
    # arrange the letters wrt key
    m = ['*']*len(ctxt)
    for k in range(8):
        i = 0
        for j in range(key[k], len(ctxt), 8):
            m[j] = groups[k][i]
            i += 1

    return ''.join(m)

with open("flag.enc", "rb") as f:
    enc = list(f.read())
    time = []
    for i in enc[len(enc) - 18:len(enc)]:
        time.append(i ^ 0x42)
    msg = enc[:len(enc) - 18]

    random.seed(''.join([chr(i) for i in time]))

    key = [random.randrange(256) for _ in msg]
    c = [int(m) ^ int(k) for (m, k) in zip(msg + time, key + [0x42] * len(time))]

    answer = ''.join([chr(i) for i in c])
    answer = answer[:len(answer)-18] # remove time info
    
    allPossibleKeys = list(itertools.permutations([0, 1, 2, 3, 4, 5, 6, 7]))
    print('플래그: ')

    # bruteforce the key
    for key in allPossibleKeys:
        m = answer
        for _ in range(42):
            m = dec(m, key)
        if "SEKAI{" in m and m[-1] == '}':
            print(m)

SEKAI{T1m3_15_pr3C10u5_s0_Enj0y_ur_L1F5!!!}