BITSCTF Writeup

BITSCTFにTeam:Harekazeの一員として参加してました。得点は520点で順位は18位でした。 自分が問いた1問のWriteupを記します。

[Crypto 40pts] Beginner’s Luck

問題から渡されるのはBITSCTFfullhd.pngとenc27.pyというファイル

pythonファイルの方を見ると、適当な鍵ファイルからfullhd.pngファイルを暗号化してBITSCTFfullhd.pngファイルを出力しているのが分かる。

PNGのヘッダには固定の部分があること、またスクリプトで最後にpaddingを使っていることからこの2つの部分があれば鍵の復元は可能ということで組んだスクリプトがこちら 適当なpngファイルを用いて復元を行った。

 #!/usr/bin/env python

def supa_encryption(s1, s2):
    res = [chr(0)]*24
    for i in range(len(res)):
        q = ord(s1[i])
        d = ord(s2[i])
        k = q ^ d
        res[i] = chr(k)
    res = ''.join(res)
    return res

def add_pad(msg):
    L = 24 - len(msg)%24
    msg += chr(L)*L
    return msg

with open('BITSCTFfullhd.png','rb') as f:
    data = f.read()
with open('test.png','rb') as f:
    test = f.read()


org = test[0:24]

# search key
key = [chr(0)]*24
for i in range(len(org)):
    q = ord(org[i])
    k = ord(data[i])
    d = k ^ q
    key[i] = chr(d)

#end of file
last = data[len(data)-24:len(data)]
for i in range(len(last)):
    print(ord(last[i]))

このスクリプトでkeyの大部分の特定とpaddingが19であることがわかる。またkeyが間違っているのが19,20,24番目というのもわかるので、スクリプトに追加して鍵を特定する。(適当に選んだ結果23番の鍵があってたのは運の問題、本来は19,20,23,24番目のkeyが違う)

mes =[chr(0)]*24
# missing key is 19 20 24
# original padding is 19
q = 19
k = ord(last[18])
d = k ^ q
key[18] = chr(d)
q = 19
k = ord(last[19])
d = k ^ q
key[19] = chr(d)
q = 19
k = ord(last[23])
d = k ^ q
key[23] = chr(d)

for i in range(len(last)):
    k = ord(last[i])
    d = ord(key[i])
    q = k ^ d
    mes[i] = chr(q)
mes = ''.join(mes)
for i in range(len(mes)):
    print(ord(mes[i]))
    print(mes[i])
print(mes)
print(''.join(key))

この結果key = rkh%QP4g0&3g46@4*%f(UN#\となる あとはこのkeyを用いて復号を行う。復号のスクリプトはこちら

#!/usr/bin/env python

def supa_encryption(s1, s2):
    res = [chr(0)]*24
    for i in range(len(res)):
        q = ord(s1[i])
        d = ord(s2[i])
        k = q ^ d
        res[i] = chr(k)
    res = ''.join(res)
    return res

def dec(s1,s2):
    res=[chr(0)]*len(s1)
    for i in range(len(res)):
        d = ord(s2[i])
        k = ord(s1[i])
        q = k ^ d
        res[i] = chr(q)
    res = ''.join(res)
    return res

def add_pad(msg):
    L = 24 - len(msg)%24
    msg += chr(L)*L
    return msg
        

with open('BITSCTFfullhd.png','rb') as f:
    data = f.read()

#data = add_pad(data)
padding = 19


with open('key.txt') as f:
    key = f.read()
    
dec_data = ''
for i in range(0, len(data), 24):
    #enc = supa_encryption(data[i:i+24], key)
    #enc_data += enc
        if i == len(data)-24:
            decdata = dec(data[i:i+4],key)
            dec_data += decdata
        else:
            decdata = dec(data[i:i+24],key)
            dec_data += decdata
        

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

f:id:kataware8136:20170206105528p:plain

という画像ができる。FLAGはBITSCTF{p_en_gee}

終わり

結構時間かかってしまった。もっとチームに貢献できるようにがんばりたい…..