この大会は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 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のみチェックをつけるとフラグが表示される。
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}