nullcon HackIM Writeup

この大会は2017/2/11 1:30(JST)~2017/2/12 13:30(JST)に開催されました。
今回もチームで参戦。結果は1950点で363チーム中48位でした。
自分で解けた問題をWriteupとして書いておきます。

Programming Question 1 (Programming 200)

3色のデータが全部で528601個ある。
factordbで素因数分解すると、528601 = 569 × 929
幅、高さをこの長さにして画像にしてみる。

from PIL import Image

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

data = data[2:-3]
colors = data.split('), (')

WIDTH = 929
HEIGHT = 569 
img = Image.new('RGB', (WIDTH, HEIGHT), (255, 255, 255))

i = 0
for y in range(HEIGHT):
    for x in range(WIDTH):
        rgb = colors[i].split(', ')
        img.putpixel((x, y), (int(rgb[0]), int(rgb[1]), int(rgb[2])))
        i += 1

img.save('flag.png')

画像の右下にフラグがある。
f:id:satou-y:20170217224554p:plain

flag{Pil_PIL_PIL}

Programming Question 3 (Programming 300)

何重にもいろんなアーカイブ方法で圧縮されている。都度対応する展開・解凍方法で戻していく。

import subprocess
import os

cmd_file = 'file %s'
cmd_lzma = 'xz -d %s'
cmd_tar = 'tar xvf %s'
cmd_xz = 'xz -d %s'
cmd_gz = 'gzip -d %s'
cmd_bz2 = 'bzip2 -d %s'
cmd_shk = 'nulib2 -x %s'
cmd_lz = 'lzip --decompress %s'
cmd_zpaq = 'zpaq x %s'
cmd_zoo = 'zoo x %s'
cmd_7z = '7z e %s'
cmd_arj = 'arj e %s'
cmd_zip = 'unzip %s'

filename_base = '26685'
filename_lzma = '26685.lzma'
filename_tar = '26685.tar'
filename_xz = '26685.xz'
filename_gz = '26685.gz'
filename_bz2 = '26685.bz2'
filename_shk = '26685.shk'
filename_lz = '26685.lz'
filename_zpaq = '26685.zpaq'
filename_zoo = '26685.zoo'
filename_7z = '26685.7z'
filename_arj = '26685.arj'
filename_zip = '26685.zip'

i = 1
while True:
    print '%d times' % i
    cmd = cmd_file % filename_base
    ret = subprocess.check_output( cmd.split(" ") )
    print ret
    if 'LZMA compressed' in ret:
        os.rename(filename_base, filename_lzma)
        os.system(cmd_lzma % filename_lzma)
    elif 'tar archive' in ret:
        os.rename(filename_base, filename_tar)
        os.system(cmd_tar % filename_tar)
        os.remove(filename_tar)
    elif 'XZ compressed' in ret:
        os.rename(filename_base, filename_xz)
        os.system(cmd_xz % filename_xz)
    elif 'gzip compressed' in ret:
        os.rename(filename_base, filename_gz)
        os.system(cmd_gz % filename_gz)
    elif 'bzip2 compressed' in ret:
        os.rename(filename_base, filename_bz2)
        os.system(cmd_bz2 % filename_bz2)
    elif 'NuFile archive' in ret:
        os.rename(filename_base, filename_shk)
        os.system(cmd_shk % filename_shk)
        os.remove(filename_shk)
    elif 'lzip compressed' in ret:
        os.rename(filename_base, filename_lz)
        os.system(cmd_lz % filename_lz)
    elif 'ZPAQ stream' in ret:
        os.rename(filename_base, filename_zpaq)
        os.system(cmd_zpaq % filename_zpaq)
        os.remove(filename_zpaq)
    elif 'Zoo archive' in ret:
        os.rename(filename_base, filename_zoo)
        os.system(cmd_zoo % filename_zoo)
        os.remove(filename_zoo)
    elif '7-zip archive' in ret:
        os.rename(filename_base, filename_7z)
        os.system(cmd_7z % filename_7z)
        os.remove(filename_7z)
    elif 'ARJ archive' in ret:
        os.rename(filename_base, filename_arj)
        os.system(cmd_arj % filename_arj)
        os.remove(filename_arj)
    elif 'Zip archive' in ret:
        os.rename(filename_base, filename_zip)
        os.system(cmd_zip % filename_zip)
        os.remove(filename_zip)
    else:
        break
    i += 1

254回解凍すると、次のテキストが得られる。

total 120
drwx------ 2 root     root     28672 Dec 23 21:01 apt-dpkg-install-kKBLWj
-rw-r--r-- 1 root     root     71259 Dec 23 19:50 apt-fast.list
-rw-r--r-- 1 root     root         0 Dec 23 19:50 apt-fast.lock
-rw-r--r-- 1 root     root         0 Dec 23 21:03 secr
drwx------ 3 root     root      4096 Dec 23 19:30 systemd-private-20af98806288452f91376e836938dc35-colord.service-hbUpEj
drwx------ 3 root     flag      4096 Dec 23 19:30 63336C756448746861486C35634442684C565A686353467566513D3D

flagグループの16進数のファイル名をデコードしていくと、フラグが得られる。

enc ='63336C756448746861486C35634442684C565A686353467566513D3D'
print enc.decode('hex').decode('base64').decode('rot13')
flag{nullc0n-Ind!a}

Crypto Question 2 (Crypto 350)

図にあるa, bの組み合わせを答える問題。
f:id:satou-y:20170217224929p:plain
総当たりでa, bの組み合わせを探す。

def search_log(g, ga, q):
    list_log = []
    for i in range(2, 1001):
        if pow(g, i, q) == ga:
            list_log.append(i)
    return list_log

q = 541
g = 10
ga = 298
gb = 330
list_a = search_log(g, ga, q)
list_b = search_log(g, gb, q)

for a in list_a:
    for b in list_b:
        if pow(g, a * b, q) == 399:
            print 'flag{%d,%d}' % (a, b)

実行結果は以下の4通り。

flag{170,268}
flag{170,808}
flag{710,268}
flag{710,808}

フラグが通ったのは、このうち一つ。

flag{170,808}

Misc2 (Misc 300)

$ file artefact 
artefact: XZ compressed data
$ mv artefact artefact.xz
$ xz -d artefact.xz
$ file artefact 
artefact: Linux rev 1.0 ext3 filesystem data, UUID=c6666f0c-f641-4958-be07-bcc6540fdafd (large files)

FTK Imagerで開く。
[unallocated space]の09837がJPEGのようだ。
ヘッダを書き換えFF D8 FF E0にし、FF D9より後ろを切り落とすと、JPEG画像になりフラグが書いてあった。
f:id:satou-y:20170217225435j:plain

flag{i_h@te_stupid_color$}