MNCTF 2017 Writeup

このイベントは2017/7/6 10:00(JST)~2017/7/6 11:30(JST)に
カンファレンスの一つとして開催されました。
個人戦の大会で、最初の確認の問題以外は100点が基準で
解いた人が多くなると点数が下がっていくというルール。
結果は151点であまり良くない成績でした。
解けた問題をWriteupとして書いておきます。

練習問題 (MISC 1)

フラグは問題に書かれていた。

MNCTF

昇進試験 (MISC 60)

Linuxコマンドに関するクロスワードの問題。
クロスワードを解くと、フラグが表示された。
f:id:satou-y:20170711215835p:plain

f148052f5b4eea45dd395d6f45fb19ea

脅迫文書 (MISC 90)

脅迫文の中の写真にURL(onionドメイン)とランダムな文字列がある。
まずTor BrowserでURLにアクセスする。パスワードを聞かれたので、写真のランダムな文字列を入れてみると、フラグが書いてあるページが表示された。
f:id:satou-y:20170711221311p:plain

TORPASTEBIN

SECUINSIDE CTF Quals 2017 Writeup

この大会は2017/7/1 9:00(JST)~2017/7/2 16:33(JST)に開催されました。
今回もチームで参戦。結果は60点で543チーム中153位でした。
自分で解けた問題は答えが書てあるものだけですが、Writeupとして書いておきます。

SANITY CHECK (MISC)

問題に書いてある。参加表明問題。

SECU[THIS_IS_FLAG]

CAT CARRIER (MISC)

これも一見隠されているフラグを探す問題かと思ったが、記載されているフラグが正解。

SECU[____MEOW_____MEOW____]

Trend Micro CTF 2017 - Raimund Genes Cup - Online Qualifier 参戦

この大会は2017/6/24 13:00(JST)~2017/6/25 13:00(JST)に開催されました。
今回もチームで参戦。結果は1702点で294チーム中30位でした。
今回も自分が得点した問題は1問もありませんでした。
う~ん、勉強期間と思うしかないな。無念・・・。

SHA2017 CTF Teaser round Writeup

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

Crypto Engine (Crypto 200)

いろいろ試して出力される色のRGBの組を確認する。まずは以下の点がわかる。

・3文字で一つのセルが生成される。
・3の倍数の文字でない場合は、3で割った余りの文字数分8ビットの16進数が表記されている。

このことからフラグの文字数は38文字であることがわかる。XORで算出された結果を色で表していると推測しながら、38文字でいろいろ試す。

■abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLの場合
RGB: 83 82 82 83 54 52 53 59 95 94 94 87 50 48 49 39 67 66 66 83 54 52 53 43 79 78 116 105 12 10 49 47 75 66 120 101 | 0x00 0x0e
文字列とRGBのXOR:
[50, 48, 49, 55, 83, 82, 82, 83, 54, 52, 53, 59, 95, 94, 94, 87, 50, 48, 49, 39, 67, 66, 66, 83, 54, 52, 53, 43, 79, 78, 116, 105, 12, 10, 49, 47, 75, 66]

■ZUHadnaopwefvnsudhaaiTjaksUkladauULandの場合
RGB: 104 101 121 86 12 11 24 57 124 124 125 95 10 18 14 42 110 122 111 75 7 46 5 42 108 93 80 65 0 60 52 32 117 105 120 65 | 0x1b 0x0d
文字列とRGBのXOR:
[50, 48, 49, 55, 104, 101, 121, 86, 12, 11, 24, 57, 124, 124, 125, 95, 10, 18, 14, 42, 110, 122, 111, 75, 7, 46, 5, 42, 108, 93, 80, 65, 0, 60, 52, 32, 117, 105]

■YZabcdefghijklMNOPqrstuVWxyzhaAjadsKKKの場合
RGB: 107 106 80 85 8 14 53 51 111 102 92 89 4 10 17 23 75 90 96 101 56 46 21 51 111 86 108 73 7 55 45 35 102 83 94 104 | 0x2d 0x18
文字列とRGBのXOR:
[50, 48, 49, 55, 107, 106, 80, 85, 8, 14, 53, 51, 111, 102, 92, 89, 4, 10, 17, 23, 75, 90, 96, 101, 56, 46, 21, 51, 111, 86, 108, 73, 7, 55, 45, 35, 102, 83]

■ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklの場合
RGB: 115 114 114 115 54 52 53 59 127 126 126 119 50 48 49 39 99 98 98 115 54 52 53 43 111 110 84 73 12 10 49 47 107 98 88 69 | 0x00 0x0e
文字列とRGBのXOR:
[50, 48, 49, 55, 115, 114, 114, 115, 54, 52, 53, 59, 127, 126, 126, 119, 50, 48, 49, 39, 99, 98, 98, 115, 54, 52, 53, 43, 111, 110, 84, 73, 12, 10, 49, 47, 107, 98]

以上を見ていて以下のことに気が付いた。

・XORキーの最初の4バイトは固定:50, 48, 49, 55
・XORキーの5バイト以降はRGBの値を順に並べている。

このことから復号コードを書く。

from PIL import Image

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

key = [50, 48, 49, 55]
enc = []
for x in range(1, w, 40):
    r, g, b = img.getpixel((x, 1))
    key.append(r)
    key.append(g)
    key.append(b)
    enc.append(r)
    enc.append(g)
    enc.append(b)
del key[-2:]
enc.append(0x2e)
enc.append(0x29)

flag = ''
for i in range(len(enc)):
    flag += chr(key[i] ^ enc[i])

print flag

この結果フラグがゲットできた。

flag{deaf983eb34e485ce9d2aff0ae44f852}

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