Security Fest 2017 Writeup

この大会は2017/5/31 21:00(JST)~2017/6/2 1:00(JST)に開催されました。
今回もチームで参戦。結果は1460点で447チーム中14位でした。
自分で解けた問題をWriteupとして書いておきます。

#makeircgreatagain (Misc 10)

freenodeで#securityfest-ctfチャネルに入る。

21:01 *topic : DL server problems, WORKING ON IT! https://securityfest.ctf.rocks - SCTF{Welcome_to_SECURITYFEST_CTF_2017!} -  start: https://goo.gl/L9Ltwj
SCTF{Welcome_to_SECURITYFEST_CTF_2017!}

Empty (Misc 100)

何も書かれていない空のPDFファイルが与えられている。

$ strings empty.pdf
     :
/LastChar 25
/Widths[/Widths[83 67 84 70 123 115 116 114 52 110 103 51 95 111 98 106 51 99 116 95 99 104 114 95 49 110 95 112 108 52 49 110 95 115 49 116 51 125]
/FontDescriptor 12 0 R
     :

Widthsの値がASCIIコードの羅列に見える。文字に置き換えてみる。

codes_str = '83 67 84 70 123 115 116 114 52 110 103 51 95 111 98 106 51 99 116 95 99 104 114 95 49 110 95 112 108 52 49 110 95 115 49 116 51 125'
codes = codes_str.split(' ')

flag = ''
for code in codes:
    flag += chr(int(code))

print flag

フラグの文字列だった。

SCTF{str4ng3_obj3ct_chr_1n_pl41n_s1t3}

Qr code madness (Misc 200)

QRコードの画像が複数ある。1つの画像で1文字を読め、なんとなくBase64の文字種別になっていることがわかる。
あとはどの順番で読むかを考える。更新日付順で最後に読めたのが「=」になっていることがわかったので、その順で並び替えればよそさう。
まずはタイムスタンプをファイル名にして、QRコードをテキストにする。

import os
import time
import datetime
from PIL import Image

BLACK = 'X'
WHITE = ' '
UNKNOWN = '?'

quiet_zone_size = 12
cell_size = 3

QR_DIR = 'qrcodemadness\\'
TXT_DIR = 'qrtext\\'

files = os.listdir(QR_DIR)
for file in files:
    img = Image.open(QR_DIR + file)
    width, height = img.size

    pixels = img.load()
    output = ""
    y = quiet_zone_size + 1

    qrtxt = ''
    while y < height - quiet_zone_size:
        x = quiet_zone_size + 1
        while x < width - quiet_zone_size:
            if pixels[x, y] == 0:
                qrtxt += BLACK
            else:
                qrtxt += WHITE
            x += cell_size
        qrtxt += '\n'
        y += cell_size

    utime = datetime.datetime.fromtimestamp(os.stat(QR_DIR + file).st_mtime)
    o_filename = TXT_DIR + str(int(time.mktime(utime.timetuple()))) + '.txt'
    with open(o_filename, 'w') as f:
        f.write(qrtxt)

次にQRコードを読み取り、最初の1文字を除いて、Base64デコードする。

import os
import subprocess

TXT_DIR = 'qrtext\\'
CMD_FORMAT = 'python sqrd.py qrtext\\%s'

files = os.listdir(TXT_DIR)

b64str = ''
for file in files:
    cmd = CMD_FORMAT % file
    ret = subprocess.check_output( cmd.split(" ") )
    ret = ret.replace('\r\n', '')
    ret = ret.replace('\r', '')
    ret = ret.replace('\n', '')
    b64str += ret

print b64str[1:].decode('base64')
SCTF{Th3s3_d4mn_QR_c0d3_k33p_p0p1ng_up}

I heart cats (Misc 50)

空白やタブが目立つHTMLが与えられている。
空白8バイトを0、タブを1として、2進数のコードにして読込む。

with open('index.html', 'r') as f:
    data = f.read()

data = data.replace('        ', ' ')

bin_code = ''
for i in range(len(data)):
    if data[i] == ' ':
        bin_code += '0'
    elif data[i] == '\t':
        bin_code += '1'

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

print flag
SCTF{Wh1735p4c35_4r3_84d_4u!}

Fair play! (Crypto 50)

問題のタイトルからもPlayfair暗号と推測。オンラインのツールなどで復号してみたが、うまくいかない。CryptoCrackを使って、ブルートフォースで復号する。
この結果、キーはCOKBVQARNDXYEPWSHMZILFTGU。復号結果は以下の通り。

THEFLAGISTHENEXTFORTYONECHARACTERSPLAYFAIRISAFUNCIPHERTOCRACKDONTYOUTHINKSOIHOPEYOUENIOYEDTHECHALXLENGESPORTSMANSHIPISANASPIRATIONORETHOSTHATASPORTORACTIVITYWILLBEXENIOYEDFORITSOWNSAKEWITHPROPERCONSIDERATIONFORFAIRNESXSETHICSRESPECTANDASENSEOFXFELXLOWSHIPWITHONESCOMPETITORSASORELOSERREFERSTOONEWHODOESNOTXTAKEDEFEATWELXLWHEREASAGOXODSPORTMEANSBEINGAGOODWINXNERASWELLASBEINGAGOXODLOSERSOMEONEWHOSHOWSCOURTESYTOWARDSANOTHERINASPORTSGAMESPORTSMANSHIPCANBECONCEPTUALIZEDASANENDURINGANDRELATIVELYSTABLECHARACTERISTICORDISPOSITIONSUCHTHATINDIVIDUALSDIFXFERINTHEWAYTHEYAREGENERALXLYEXPECTEDTOBEHAVEINSPORTSITUATIONSINGENERALSPORTSMANSHIPREFERSTOVIRTUESSUCHASFAIRNESXSXSELFCONTROLCOURAGEANDPERSISTENCEANDHASBEENASSOCIATEDWITHINTERPERSONALCONCEPTSOFTREATINGOTHERSANDBEINGTREATEDFAIRLYMAINTAININGSELFCONTROLIFDEALINGWITHOTHERSANDRESPECTFORBOTHAUTHORITYANDOPPONENTSXSPORTSMANSHIPISALSOLOXOKEDATASBEINGTHEWAYONEREACTSTOASPORTGAMEPLAYERTHEFOURELEMENTSOFSPORTSMANSHIPAREOFTENSHOWNBEINGGOODFORMTHEWILLTOWINEQUITYANDFAIRNESSALXLFOURELEMENTSARECRITICALANDABALANCEMUSTBEFOUNDAMONGALXLFOURFORTRUESPORTSMANSHIPTOBEILXLUSTRATEDTHESEELEMENTSMAYALSOCAUSECONFLICTASAPERSONMAYDESIRETOWINMORETHANPLAYINEQUITYANDFAIRNESXSANDTHUSRESULTINGINACLASHWITHINTHEASPECTSOFSPORTSMANSHIPTHISWILXLCAUSEPROBLEMSASTHEPERSONBELIEVESTHEYAREBEINGAGOODSPORTSMANBUTTHEYAREDEFEATINGTHEPURPOSEOFTHISIDEAASTHEYAREIGNORINGTWOKEYCOMPONENTSOFBEINGSPORTSMANLIKEWHENATHLETESBECOMETOXOSELFCENTREDTHEIDEAOFSPORTSMANSHIPISDISMISSEDTODAYSXSPORTINGCULTUREINPARTICULARTHEBASEOFELITESPORTPLACESGREATIMPORTANCEONTHEIDEAOFCOMPETITIONANDWINXNINGANDTHUSXSPORTSMANSHIPTAKESABACKSEATASARESULTINMOSTIFNOTALXLSPORTSXSPORTSMENATXTHEXELITELEVELMAKETHESTANDARDSONSPORTSMANSHIPANDNOMATXTERWHETHERTHEYLIKEITORNOTXTHEYARESEXENASLEADERSANDROLEMODELSINSOCIETYSINCEEVERYSPORTISRULEDRIVENTHEMOSTCOMMONOFXFENCEOFBADSPORTSMANSHIPISTHEACTOFCHEATINGORBREAKINGTHERULESTOGAINANUNFAIRADVANTAGEACOMPETITORWHOEXHIBITSPOORSPORTSMANSHIPAFTERLOSINGAGAMEORCONTESTISOFTENCALLEDASORELOSERTHOSEWHOSHOWPOXORSPORTSMANSHIPAFTERWINXNINGARETYPICALLYCALXLEDBADCHAMPSSORELOSERBEHAVIOURINCLUDESBLAMINGOTHERSFORTHELOSSNOTACCEPTINGRESPONSIBILITYFORPERSONALACTIONSTHATCONTRIBUTEDTOTHEDEFEATREACTINGTOTHELOSXSINANIMXMATUREORIMPROPERFASHIONMAKINGEXCUSESFORTHEDEFEATANDCITINGUNFAVOURABLECONDITIONSOROTHERPETXTYISSUESASREASONSFORTHEDEFEATABADWINNERACTSINASHALLOWFASHIONAFTERHISORHERVICTORYSUCHASBYGLOATINGABOUTHISORHERWINRUBXBINGTHEWININTHEFACESOFTHEOPXPONENTSANDLOWERINGTHEOPXPONENTSXSXSELFESTEEMBYCONSTANTLYREMINDINGTHEOPPONENTSOFPOXORPERFORMANCEINCOMPARISONEVENIFTHEOPPONENTSCOMPETEDWELLNOTSHOWINGRESPECTTOTHEOTHERTEAMISCONSIDEREDTOBEINGABADSPORTSMANANDCOULDLEADTODEMORALISINGEFFECTSASLESLIEHOWEDESCRIBESIFAPITCHERINBASEBALXLDECIDESTOPITCHNOTTOHISMAXIMUMABILITYSUGGESTTHATTHEBATTERISNOTATANADEQUATELEVELANDCOULDLEADTOTHEBATXTERTOHAVELOWSELFCONFIDENCEORWORTHTHEREARESIXDIFXFERENTCATEGORIESRELATINGTOSPORTSMANSHIPTHEELEMENTSOFSPORTSTHEXELEMENTSOFSPORTSMANSHIPCLARIFICATIONSCONFLICTSBALANCEANDIRREDUCIBILITYALLSIXOFTHESECHARACTERIZEAPERSONWITHGOODSPORTSMANSHIPEVENTHOUGHTHEREISSOMEAFFINITYBETWEXENSOMEOFTHECATEGORIESTHEYAREDISTINCTELEMENTSINESSENCEPLAYHASFORITSDIRECTEDANDIMXMEDIATEXENDIOYPLEASUREANDXDELIGHTSANDWHICHISDOMINATEDBYASPIRITOFMODERATIONANDGENEROSITYATHLETICSONTHEOTHERHANDISESSENTIALXLYACOMPETITIVEACTIVITYWHICHXHASFORITSENDVICTORYINTHECONTESTANDWHICHISCHARACTERIZEDOFDEDICATIONSACRIFICEANDINTENSITYFEXELEZZPPHENCETHEVIRTUESOFAPLAYERARERADICALXLYDIFXFERENTFROMTHEVIRTUESOFANATHLETEFEXELEZZPPWHENTALKINGABOUTMISUNDERSTANDINGSPORTSMANSHIPRUDXDANDSTOLLPROVIDEANEXAMPLEFROMAUSHIGHSCHOOLATHLETICLEAGUEBANXNEDTHEPOSTGAMEHANDSHAKETHATWASAPARTOFSPORTSXSUCHASFOOTBALXLANDBASKETBALXLTHEHANDSHAKINGWASBANXNEDBECAUSEOFFIGHTSTHATWEREENSUINGAFTERTHEHANDSHAKEPXPMOSTPLAYERSAREINFLUENCEDBYTHELEADERSAROUNDTHEMSUCHASCOACHESANDOLDERPLAYERSIFTHEREARECOACHESANDADMINISTRATORSWHODONTUNDERSTANDSPORTSMANSHIPTHENWHATABOUTTHEPLAYERS

スペースを入れて読みやすくすると、先頭部分にはこう書いてある。

THE FLAG IS THE NEXT FORTYONE CHARACTERS

次の41文字がフラグ。

PLAYFAIRISAFUNCIPHERTOCRACKDONTYOUTHINKSO