WORMCON 0x01 Writeup

この大会は2021/8/28 19:30(JST)~2021/8/29 19:30(JST)に開催されました。
今回もチームで参戦。結果は910点で157チーム中33位でした。
自分で解けた問題をWriteupとして書いておきます。

RoboXOR (CRYPTOGRAPHY)

XOR暗号。keyを求めて、復号する。

enc = '2506110631060d103c5a15582036045b3c075734640015580d10531e0d1c134a2f'
enc = enc.decode('hex')

flag_head = 'wormcon{'

key = ''
for i in range(len(flag_head)):
    key += chr(ord(flag_head[i]) ^ ord(enc[i]))

assert key[:4] == key[4:]
key = key[:4]
print '[+] key =', key

flag = ''
for i in range(len(enc)):
    flag += chr(ord(enc[i]) ^ ord(key[i%len(key)]))
print '[*] flag =', flag

実行結果は以下の通り。

[+] key = Rick
[*] flag = wormcon{n3v3r_g0nn4_6iv3_y0u_up!}
wormcon{n3v3r_g0nn4_6iv3_y0u_up!}

Exclusive (CRYPTOGRAPHY)

暗号処理の概要は以下の通り。

・FLAG: wormcon{}の中身
・FLAGの文字は英数字とアンダースコアのみ
・otp :ランダム8bit整数
・otpm: otpの上8bit
・otpl: otpの下8bit
・FLAGの各文字について
 ・偶数番目はencrypt(ord(ch), otpm, otpl)
 ・奇数番目はencrypt(ord(ch), otpl, otpm)
・暗号化データを16進表記で出力

otpをブルートフォースで実行し、英数字とアンダースコアになるようXORで復号する。

#!/usr/bin/env python3
def splitit(n):
    return (n >> 4), (n & 0xF)

def decrypt(n, key1, key2):
    m, l = splitit(n)
    d = ((m ^ key1) << 4) | (l ^ key2)
    return d

def is_alpha(s):
    alpha = b'0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_'
    for c in s:
        if c not in alpha:
            return False
    return True

with open('out.txt', 'r') as f:
    cipher = bytes.fromhex(f.read().split(' ')[-1])

for otp in range(256):
    otpm, otpl = splitit(otp)
    FLAG = []
    for i, ch in enumerate(cipher):
        if i % 2 == 0:
            dec = decrypt(ch, otpm, otpl)
        else:
            dec = decrypt(ch, otpl, otpm)
        FLAG.append(dec)
    FLAG = bytes(FLAG)
    if is_alpha(FLAG):
        break

flag = 'wormcon{%s}' % FLAG.decode()
print(flag)
wormcon{x0r_n1bbl3_c1ph3r_15_4_h0m3_br3w3d_c1ph3r}

Fake Encryption (CRYPTOGRAPHY)

DES-ECBモードなので、ブロック単位で同じ平文は同じ暗号文に対応する。ブロック単位でシャッフルしているが、その関係性は変わらないので、対応する平文を構成していけばよい。

with open('flag.png.enc', 'rb') as f:
    flag_enc = f.read()

with open('ff_error.png', 'rb') as f:
    pt = f.read()

with open('ff_error.png.enc', 'rb') as f:
    ct = f.read()

pt = [pt[i:i+8] for i in range(0, len(pt), 8)]
ct = [ct[i:i+8] for i in range(0, len(ct), 8)]

flag = ''
for i in range(0, len(flag_enc), 8):
    index = ct.index(flag_enc[i:i+8])
    flag += pt[index]

with open('flag.png', 'wb') as f:
    f.write(flag)

f:id:satou-y:20210902074206p:plain

wormcon{ECB_lacks_diffiusion}

Invisible Cipher (CRYPTOGRAPHY)

換字式暗号。Unicodeで対応していることに注意して、まずはASCII文字に変換する。また6バイト目が頻度的にスペースと推測できるので、その変換をする。

with open('flag.enc', 'rb') as f:
    enc = f.read()

enc = enc.replace('\xe3\x81\x83', 'A')
enc = enc.replace('\xe3\x80\xB7', 'B')
enc = enc.replace('\xe3\x80\xB4', 'C')
enc = enc.replace('\xe3\x81\x81', 'D')
enc = enc.replace('\xe3\x81\x8A', 'E')
enc = enc.replace('\xe3\x81\x86', 'F')
enc = enc.replace('\xe3\x80\xB0', 'G')
enc = enc.replace('\xe3\x81\x82', 'H')
enc = enc.replace('\xe3\x80\xBE', 'I')
enc = enc.replace('\xe3\x80\xBD', 'J')
enc = enc.replace('\xe3\x80\xB2', 'K')
enc = enc.replace('\xe3\x80\xBA', 'L')
enc = enc.replace('\xe3\x80\xB8', 'M')
enc = enc.replace('\xe3\x80\xB6', 'N')
enc = enc.replace('\xe3\x80\xB5', 'O')
enc = enc.replace('\xe3\x80\xBB', 'P')
enc = enc.replace('\xe3\x80\xB3', 'Q')
enc = enc.replace('\xe3\x80\xBC', 'R')
enc = enc.replace('\xe3\x80\xB1', 'S')
enc = enc.replace('\xe3\x81\x84', 'T')
enc = enc.replace('\xe3\x81\x85', 'U')
enc = enc.replace('\xe3\x81\x88', 'V')
enc = enc.replace('\xe3\x81\x87', 'W')
enc = enc.replace('\xe3\x80\xBF', 'X')
enc = enc.replace('\xe3\x81\x80', 'Y')
enc = enc.replace('\xe3\x80\xB9', 'Z')

enc = enc.replace('E', ' ')
print enc

あとはquipqiupで復号する。

THERE WAS ONCE A KING OF SCOTLAND WHOSE NAME WAS ROBERT BRUCE HE HAD NEED TO BE BOTH BRAVE AND WISE FOR THE TIMES IN WHICH HE LIVED WERE WILD AND RUDE THE KING OF ENGLAND WAS AT WAR WITH HIM AND HAD LED A GREAT ARMY INTO SCOTLAND TO DRIVE HIM OUT OF THE LAND BATTLE AFTER BATTLE HAD BEEN FOUGHT SIX TIMES HAD BRUCE LED HIS BRAVE LITTLE ARMY AGAINST HIS FOES AND SIX TIMES HAD HIS MEN BEEN BEATEN AND DRIVEN INTO FLIGHT AT LAST HIS ARMY WAS SCATTERED AND HE WAS FORCED TO HIDE HIMSELF IN THE WOODS AND IN LONELY PLACES AMONG THE MOUNTAINS ONE RAINY DAY BRUCE LAY ON THE GROUND UNDER A RUDE SHED LISTENING TO THE PATTER OF THE DROPS ON THE ROOF ABOVE HIM HE WAS TIRED AND SICK AT HEART AND READY TO GIVE UP ALL HOPE IT SEEMED TO HIM THAT THERE WAS NO USE FOR HIM TO TRY TO DO ANYTHING MORE AS HE LAY THINKING HE SAW A SPIDER OVER HIS HEAD MAKING READY TO WEAVE HER WEB HE WATCHED HER AS SHE TOILED SLOWLY AND WITH GREAT CARE SIX TIMES SHE TRIED TO THROW HER FRAIL THREAD FROM ONE BEAM TO ANOTHER AND SIX TIMES IT FELL SHORT POOR THING SAID BRUCE YOU TOO KNOW WHAT IT IS TO FAIL BUT THE SPIDER DID NOT LOSE HOPE WITH THE SIXTH FAILURE WITH STILL MORE CARE SHE MADE READY TO TRY FOR THE SEVENTH TIME BRUCE ALMOST FORGOT HIS OWN TROUBLES AS HE WATCHED HER SWING HERSELF OUT UPON THE SLENDER LINE WOULD SHE FAIL AGAIN NO THE THREAD WAS CARRIED SAFELY TO THE BEAM AND FASTENED THERE I TOO WILL TRY A SEVENTH TIME CRIED BRUCE HE AROSE AND CALLED HIS MEN TOGETHER HE TOLD THEM OF HIS PLANS AND SENT THEM OUT WITH MESSAGES OF CHEER TO HIS DISHEARTENED PEOPLE SOON THERE WAS AN ARMY OF BRAVE SCOTCHMEN AROUND HIM ANOTHER BATTLE WAS FOUGHT AND THE KING OF ENGLAND WAS GLAD TO GO BACK INTO HIS OWN COUNTRY I HAVE HEARD IT SAID THAT AFTER THAT DAY NO ONE BY THE NAME OF BRUCE WOULD EVER HURT A SPIDER THE LESSON WHICH THE LITTLE CREATURE HAD TAUGHT THE KING WAS NEVER FORGOTTEN HE TOLD US THE FLAG WAS CAREFUL FREQUENCY ANALYSIS BREAKS SUBSTITUTION CIPHER HE ALSO SUGGESTS THE USER TO JOIN THE WORDS WITH UNDERSCORE AND PUT THE RESULT IN THE FLAG WRAPPER BEFORE SUBMISSION
wormcon{CAREFUL_FREQUENCY_ANALYSIS_BREAKS_SUBSTITUTION_CIPHER}

Feedback (FEEDBACK)

アンケートに答えたら、フラグが表示された。

wormcon{Th4nK5_f0R_F33dB4ck}