読者です 読者をやめる 読者になる 読者になる

School CTF 2016 Writeup

CTF writeup

この大会は2016/11/6 14:00(JST)~2016/11/6 22:00(JST)に開催されました。
今回もチームで参戦。結果は700点でNon-School428チーム中80位でした。
自分で解けた問題をWriteupとして書いておきます。

MassQR (ppc 300)

QRコードがたくさん書いてあるPNGファイルが与えられている。
まず、QRコードを1つずつの画像に分解する。

import Image

img = Image.open('qr_eb3bdc766963045a2afa3d0ce8747c7cf4f291c8.png').convert('RGB')
num = 65250 / 290
for i in range(num):
    img_div = Image.new('RGB', (290,290), (255, 255, 255))
    for y in range(290):
        for x in range(290):
            r, g, b = img.getpixel((i * 290 + x, y))
            img_div.putpixel((x, y), (r, g, b))
    filename = 'div\\qr%03d.png' % i
    img_div.save(filename)

次にQRコードを黒の部分をX、白の部分を空白のテキストデータに変換する。

from PIL import Image

BLACK = 'X'
WHITE = ' '

quiet_zone_size = 40
cell_size = 10

num = 65250 / 290
for i in range(num):
    s_filename = 'div\\qr%03d.png' % i
    d_filename = 'qrtxt\\qr%03d.txt' % i

    img = Image.open(s_filename).convert('RGB')
    w, h = img.size

    data = ''
    for y in range(quiet_zone_size, h - quiet_zone_size, cell_size):
        for x in range(quiet_zone_size, w - quiet_zone_size, cell_size):
            r, g, b = img.getpixel((x, y))
            if r == 255 and g == 255 and b == 255:
                data += WHITE
            else:
                data += BLACK
        data += '\n'

    with open(d_filename, 'w') as f:
        f.write(data)

sqrd.pyを使って、QRコードを順に読む。

import subprocess

CMD_FORMAT = 'python sqrd.py qrtxt\\qr%03d.txt'

data = ''
for i in range(225):
    cmd = CMD_FORMAT % i
    ret = subprocess.check_output( cmd.split(" ") )
    ret = ret.replace('\r\n', '')
    ret = ret.replace('\r', '')
    ret = ret.replace('\n', '')
    data += ret

print data

PHPのコードになり、実行するとフラグが表示される。

SchoolCTF{Aw3s0m3_p5p_3wrerYwhEr3}

0011000100110000 (stegano 100)

英文の文章が与えられているが、問題文からZ,E,R,O,Nのみ抜き出し、ZEROは0に、ONEは1に置き換えてみる。
この01の文字列を2進数として読み込み、文字に変換する。

with open('ZeroOne.txt', 'r') as f:
    data = f.read()

data01 = ''
for i in range(len(data)):
    c = data[i:i+1]
    if c == 'Z' or c == 'E' or c == 'R' or c == 'O' or c == 'N':
        data01 += c

data01 = data01.replace('ZERO', '0')
data01 = data01.replace('ONE', '1')

flag = ''
for i in range(0, len(data01), 8):
    code = int(data01[i:i+8], 2)
    flag += chr(code)

print flag
SchoolCTF{ZOMG_u_G00d_R3ader}

Virus (stegano 200)

PNGファイルが与えられている。PNGファイルに他のファイルが結合しているようなので、foremostで分解してみる。

$ foremost task.png 

抽出したjpgファイルにフラグが書かれている。
f:id:satou-y:20161110221654j:plain

SchoolCTF{v1rus_ar7_is_r34l_art}

Wonder Web (web 100)

レスポンスヘッダを見てみると、フラグに関する情報が含まれている。

Content-Meaning: none; flag-part-number=5 part-content=54f3};

全部でパーツは5つ。最後のパーツは 54f3}

Flag-First-Part-Is-Here: encoding=base64; part1=U2Nob29sQ1RGezUwbTNkNHk=;

1つ目のパーツの情報。Base64デコードすればよい。

$ echo 'U2Nob29sQ1RGezUwbTNkNHk=' | base64 -d
SchoolCTF{50m3d4y
Task: category=joy; ucucuga=sure; encoding=none; justString=true; flagPresent=1; flagPart2=17; flagPart4=b3

2つ目と4つ目のパーツの情報。

X-ShellShock-vector: (){;}; echo "Want flag?"; python -c 'part3="77316c6c"; print part3.decode("hex")'

3つ目のパーツの情報。hexデコードする。

>python
Python 2.7.10 (default, May 23 2015, 09:40:32) [MSC v.1500 32 bit (Intel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> part3="77316c6c"
>>> part3.decode("hex")
'w1ll'
Flag-Parts-Connector: character=_; charCode=95; hexCharCode=0x5f;

各パーツをつなげる文字の情報。

以上の情報からフラグを作る。

SchoolCTF{50m3d4y_17_w1ll_b3_54f3}