Takoma Park CTF Writeup

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

Sanity Check (Slightly More Trivial 1)

問題に書かれているフラグを記載するだけ。

tpctf{this-is-a-flag}

Zalgo (Slightly More Trivial 2)

問題にフラグが書いてあるが、見にくい。文字をコピーした後に、通常のASCII文字を拾えばよい。

tpctf{he_comes}

trivial rev (Slightly More Trivial 2)

実行するだけ。

tpctf{ez_pz}

trivial rsa (Slightly More Trivial 3)

nをfactordbで素因数分解する。

65561 = 53 * 1237

あとは通常通りRSA暗号の復号方法で復号する。

n = 65561
e = 65537
c = 27830
p = 53
q = 1237

phi = (p - 1) * (q - 1)

x = 0
while True:
    if (phi * x + 1) % e == 0:
        d = (phi * x + 1) / e
        break
    x = x + 1

m = pow(c, d, n)

flag =  'tpctf{%d}' % m
print flag
tpctf{31337}

trivial stego (Slightly More Trivial 3)

添付のPNGファイルのIENDチャンクの後ろにフラグがある。

tpctf{steg!}

trivial arithmetic (Slightly More Trivial 4)

pythonで計算してみる。

>python
Python 2.7.14 (v2.7.14:84471935ed, Sep 16 2017, 20:19:30) [MSC v.1500 32 bit (Intel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> 0.1+0.2
0.30000000000000004
tpctf{0.30000000000000004}

Ads (Web 20)

ソースからリンクしているファイルを見てみる。
https://tpctf.com/static/user.cssにフラグが書いてある。

tpctf{thx_4_n0_adb1ock}

Demo File (Forensics 90)

添付のdocxファイルを解凍し、demo\word\mediaにある画像を調べる。image4.pngのIENDチャンクの後ろにかなり大きいサイズの文字列が入っていて、ダミーフラグが大量にある。正規表現を使いプログラムでダミーフラグを取り除いていく。最終的なコードは以下の通り。

import re

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

data = data.replace('TPCTF stands for Teaching Primary Care Trust Flag. ', '')
data = re.sub(r'The flag isn\'t TPCTF{[a-z:)]+}\. ', '', data)
data = data.replace('Clarence Lam is a TPCTF organizer. He is also a TPCTF disorganizer. ', '')
data = re.sub(r'TPCTF stands for T[a-z]+ P[a-z]+ Capture The Flag, and it was made by current and former T[a-z]+ P[a-z]+ students. ', '', data)
data = re.sub(r'TPCTF stands for T[a-z]+ P[a-z]+ Cat The Flag.txt, where participants around the world attempt to \'cat flag.txt\' and get something like TPCTF{[a-z:)]+}. Of course, that isn\'t the flag. ', '', data)
data = re.sub(r'TPCTF{[a-z:)]+} is not the flag. ', '', data)
data = re.sub(r'TPCTF stands for T[a-z]+ Paper Capture The Flag, and it was made by current and former T[a-z]+ Paper students. ', '', data)
data = re.sub(r'Some of Clarence Lam\'s nicknames are Calvin, clam, clam~, c-lam, and TPCTF{[a-z:)]+}. Actually, the last one isn\'t true. ', '', data)
data = re.sub(r'Clarence Lam has a flag that he doesn\'t want anyone to find out about. It\'s not TPCTF{[a-z:)]+} though. ', '', data)
data = re.sub(r'Clarence Lam is a TPCTF organizer and he thinks the flag is TPCTF{[a-z:)]+} but it isn\'t. ', '', data)
data = re.sub(r'Fun fact: TPCTF{[a-z:)]+} is a fake flag. ', '', data)
data = re.sub(r'Fun fact: TPCTF{[a-z:)]+} starts with TPCTF. ', '', data)
data = re.sub(r'Fun fact: TPCTF{[a-z:)]+} has 18 letters in between the braces. ', '', data)
data = re.sub(r'Fun fact: All the letters in TPCTF{[a-z:)]+} are lowercase except for the TPCTF at the start. ', '', data)
data = re.sub(r'Clarence Lam is a TPCTF organizer and he doesn\'t like strings of text like TPCTF{[a-z:)]+}. ', '', data)
data = re.sub(r'Clarence Lam is a TPCTF organizer and his least favorite string is TPCTF{[a-z:)]+}. ', '', data)
data = re.sub(r'Clarence Lam is part of a group that organized TPCTF and the flag is not quite TPCTF{[a-z:)]+}. ', '', data)
data = re.sub(r'Clarence Lam is a TPCTF organizer and favorite string is TPCTF{[a-z:)]+}. ', '', data)
data = data.replace('Just kidding! ', '')
data = re.sub(r'The flag TPCTF{[a-z:)]+} isn\'t actually real. ', '', data)
data = re.sub(r'Clarence Lam writes TPCTF problems, some of which contain flags, such as TPCTF{[a-z:)]+}. This isn\'t a real flag. ', '', data)
data = re.sub(r'The flag TPCTF{[a-z:)]+} isn\'t actually real. ', '', data)
data = re.sub(r'Clarence Lam wrote a few problems for TPCTF and his least favorite string of text isn\'t not TPCTF{[a-z:)]+}. ', '', data)
data = re.sub(r'Did you know that Clarence Lam\'s favorite command is TPCTF{[a-z:)]+}\'; DROP TABLE flags; -- \? Of course you didn\'t. It\'s not true! ', '', data)
data = re.sub(r'Clarence Lam is a TPCTF organizer and the flag isn\'t TPCTF{[a-z:)]+}. ', '', data)

print data

最後に残ったメッセージは以下の通り。

Clarence Lam is a TPCTF organizer and his favorite string is TPCTF{ohnoivebeendocxxed}.
TPCTF{ohnoivebeendocxxed}

Bad Restaurant (Crypto 5)

シーザー暗号。https://www.geocachingtoolbox.com/index.php?lang=en&page=caesarCipher で復号する。

tpctf{all_roads_lead_to_rome}

768 (Crypto 30)

nを素因数分解する。

p = 33478071698956898786044169848212690817704794983713768568912431388982883793878002287614711652531743087737814467999489
q = 36746043666799590428244633799627952632279158164343087642676032283815739666511279233373417143396810270092798736308917

あとはRSA暗号の通常通り、復号する。

n = 0xCAD984557C97E039431A226AD727F0C6D43EF3D418469F1B375049B229843EE9F83B1F97738AC274F5F61F401F21F1913E4B64BB31B55A38D398C0DFED00B1392F0889711C44B359E7976C617FCC734F06E3E95C26476091B52F462E79413DB5
e = 0x10001
c = 0x3F808414886E7C91F1D78AEB7EF920D2C9294AC384DCBB1A48032E8CAB79131AB3C1852896EEEECB5BA055AE77BBB619741FDE4D01AAC7D56F4E44508A8FC81A86DDB929A112AA80C4A7221B3C651E14E2D701B52E295152813CD9EFB4B51CB
p = 33478071698956898786044169848212690817704794983713768568912431388982883793878002287614711652531743087737814467999489
q = 36746043666799590428244633799627952632279158164343087642676032283815739666511279233373417143396810270092798736308917

phi = (p - 1) * (q - 1)

x = 0
while True:
    if (phi * x + 1) % e == 0:
        d = (phi * x + 1) / e
        break
    x = x + 1

m = pow(c, d, n)

flag = ('%x' % m).decode('hex')
print flag

復号結果は次の通り。

It appears that you have managed to solve the challenge.
Flag is tpctf{omg_b1c_m0dulus}.
tpctf{omg_b1c_m0dulus}

That's not latin... (Misc 10)

フラグが書かれているが、eだけ全角になっているので、半角にする。

tpctf{nev3r_7h15_3z}

Not Quite LSD (Steganography 30)

添付のPNGファイルをStegSolveで開き、Data ExtractでRGBのLSBのみチェックをつけるとフラグが表示される。
f:id:satou-y:20171210214310p:plain

TPCTF{1sB_i5_K00l}

Woah! (Steganography 40)

添付のPNGファイルのIENDチェンクの後ろに以下の文字列がある。

c=23273044714507614583919107642780731232409437015529456693716961465133831310123918470882082327335507219289041144186168765420579209702030715438341449893348841695639896994241125

素因数分解してみる。

c=2855076403049907408196032392213367306890430676224579762045^3

RSA暗号のnが大きく、eが3で小さいパターンの復号の問題とみて、復号する。

>>> ('%x' % 2855076403049907408196032392213367306890430676224579762045).decode('hex')
'tpctf{rs4_and_st3g0_w0w}'
tpctf{rs4_and_st3g0_w0w}