WhiteHat Challenge 04 Writeup

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

misc01 (Miscellaneous 15)

Pythonスクリプトが与えられているが、Base64データになっている。デコードすると、exec関数でASCIIコードで文字列が連結されている。その文字列はまたBase64文字列になっていて、デコードするとまたexec関数でASCIIコードで文字列が連結されている。execの中身をデコードすることを繰り返す。

def exec_decode(data):
    if data.startswith('exec(') == False:
        return ''
    data = data.replace('exec(chr(', '')
    data = data.replace(')+chr(', ' ')
    data = data.replace('))', '')
    data = data.split(' ')

    dec = ''
    for i in range(len(data)):
        dec += chr(int(data[i]))
    return dec

with open('python_beginner.py', 'r') as f:
    data = f.read()

data = data.decode('base64')

while True:
    dec = exec_decode(data)
    if dec == '':
        print data
        break
    data = dec
flag = "scr1pt_w1th_pyth0n_1s_ez"
priint flag
$ echo -n scr1pt_w1th_pyth0n_1s_ez | sha1sum
6c67866ad716bc4bb5ff9e7a09d15cb04707f238  -
WhiteHat{6c67866ad716bc4bb5ff9e7a09d15cb04707f238}

crypto01 (Cryptography 10)

Googleの画像検索で調べる。
http://forum.artemis-fowl.com/viewtopic.php?t=5982
ここに対応表が載っているので、1.jpgから復号する。

FLAG IS HAVE FUN
$ echo -n 'HAVE FUN' | sha1sum
78fd26881b713984b6a49a74d8621ae7ae8ccde0  -
WhiteHat{78fd26881b713984b6a49a74d8621ae7ae8ccde0}
→これはダメだった。

小文字にしてみる。

$ echo -n 'have fun' | sha1sum
eeb5dd49132e82a02cacec1c0fc4889bd6373192  -
WhiteHat{eeb5dd49132e82a02cacec1c0fc4889bd6373192}

crypto02 (Cryptography 20)

ある暗号方法でBase64文字列を入力すると、暗号化文字列を返すシステムがある。ソースコードもダウンロードできて、次のようになっている。

import sys
from Crypto.Hash import SHA256
from Crypto.Cipher.AES import AESCipher
from flag import flag as create
def encrypt(m):
	flag = create()
	key = SHA256.new(flag).digest()
	s = 'something!' + m.decode('base64') + flag
	p = 16 - (len(s) % 16)
	s = s + (chr(p) * p)
	return AESCipher(key).encrypt(s).encode("base64")

平文は「something![text][flag]」という形式。ブロック暗号であることを利用してパディング文字数を調整しながら、先頭からフラグを探り当てる。
以下のようなことを繰り返すイメージ。

123456789012345
something!#####[FLAG]
something!#####[FLAG1文字目をBFで回す]

something!####[FLAG]
something!####E[FLAG2文字目をBFで回す]

  :
import urllib
import urllib2
import re
import string

def query(text):
    pattern = '<p> (.+)\n</p>'
    url = 'http://chall04-crypto02.wargame.whitehat.vn/'
    req = {'crypto': text.encode('base64')}
    params = urllib.urlencode(req)
    request = urllib2.Request(url, params)
    response = urllib2.urlopen(request)
    data = response.read()
    m = re.search(pattern, data, re.DOTALL)
    enc = m.group(1).decode('base64')
    return enc

header = 'something!'
flag = ''
while True:
    padding = '#' * ((- len(header + flag) - 1) % 16)
    size = len(header + padding + flag) + 1
    correct = query(padding)[0:size]
    found = False
    for c in string.printable:
        try_str = query(padding + flag + c)[0:size]
        if try_str == correct:
            found = True
            flag += c
            print c,
            break
    if found == False:
        break

print flag

実行結果は次の通り。

E a s y _ p o i n t _ c 1 3 Easy_point_c13
$ echo -n Easy_point_c13 | sha1sum
1ffe5f92c181a89dd267cfd4b6ec2c80c6202391  -
WhiteHat{1ffe5f92c181a89dd267cfd4b6ec2c80c6202391}