[Writeup] TJCTF 2019 (1)

TJCTF 是一場高中生的 CTF
我們隊賽前的目標是前 10
不過後來排名從第一天的第 6 ,第二天的第 8 ,第四天比賽結束前的第 10 ,到比賽結束時的第 12
僅僅 100 分,約一題的差距就可以進到前 10 了…
無奈 Binary (Pwn) 都不會解…
下次練好再來吧@@

隊名: admin’
得分: 1055
排名: 12 / 483

[Web] Blurry - 5pts

Written by boomo

I found this slightly sketchy site that deals flags, but my mom hasn’t given me my allowance yet :(. You tryna help me out?

Solution

連結畫面:

F12:

Flag tjctf{cl0se_1nspecti0n}

[Crypto] Double Duty - 5pts

Written by boomo

Everyone knows that caesar ciphers aren’t very good. So I caesared my message 2000 times. Good luck trying to decode that!

yfn uzu pfl tirtb dp katkw{jvbivk_tfuv}

Solution

Just Caesar it!

Original: yfn uzu pfl tirtb dp katkw{jvbivk_tfuv}
Shift 9: how did you crack my tjctf{sekret_code}

Flag tjctf{sekret_code}

[Forensics] MC Woes - 5pts

Written by boomo

My world won’t launch anymore! I’m sure its something in the files…

Solution

解壓縮稍微翻一下,會發現 .dat 檔其實是 gzip 檔
/worlddata/level.dat 卻無法成功解壓縮
strings 出來後就會發現 Flag 在裡面了

Flag tjctf{_g3t_sn4ck5}

[Crypto] Touch Base - 5pts

Written by rj9

Decode this string for an easy flag!

Encoded: dGpjdGZ7ajJzdF9zMG0zX2I0c2U2NH0=

Solution

因為最後的等號 (=) ,可以猜測是 Base 64 encoded
Decode 一下就可以拿到 Flag 了

Flag tjctf{j2st_s0m3_b4se64}

[Forensics] Corsair - 5pts

Written by rj9

Here is a picture of my favorite plane!

corsair

Solution

Here is a picture of my favorite plane!

這題可以用 StegSolve 去觀察圖片在不同 Plane 下的長相
在 Blue plane 5 可以清楚地看到這題的 Flag

Flag tjctf{c0l0r_pl4n3s_ar3_c00l}

[Reversing] Python in One Line - 10pts

Written by boomo

It’s not code golf but it’s something…

one.py This is printed when you input the flag: .. - / .. ... -. - / -- --- .-. ... / -.-. --- -.. .

Solution

直接反過來查詢 value 對應到的 key 即可

1
2
3
4
5
6
7
a = {'a':'...-', 'b':'--..', 'c':'/', 'd':'-.--', 'e':'.-.', 'f':'...', 'g':'.-..', 'h':'--', 'i':'---', 'j':'-', 'k':'-..-', 'l':'-..', 'm':'..', 'n':'.--', 'o':'-.-.', 'p':'--.-', 'q':'-.-', 'r':'.-', 's':'-...', 't':'..', 'u':'....', 'v':'--.', 'w':'.---', 'y':'..-.', 'x':'..-', 'z':'.--.', '{':'-.', '}':'.'}

msg = ".. - / .. ... -. - / -- --- .-. ... / -.-. --- -.. ."

for i in msg.split():
id = [k for (k, v) in a.iteritems() if v == i]
print(id)

Flag tjctf{jchiefcoil}

[Crypto] Sportsmanship - 10pts

Written by rj9

It is simply this: do not tire, never lose interest, never grow indifferent—lose your invaluable curiosity and you let yourself die. It’s as simple as that.” “I’m a liar and a cheat and a coward, but I will never, ever, let a friend down. Unless of course not letting them down requires honesty, fair play, or bravery.

ciphertext: ROEFICFEENEBZDLFPY

key: UNPROBLEMATICDFGHKQSVWXYZ

Flag format is tjctf{plaintext}

Solution

很基本的 Playfair 加密,找個線上的 decoder 解密就好

Flag tjctf{practicalplayfairx}

[Crypto] Guess My Hashword - 10pts

Written by boomo

I bet you’ll never guess my password!

I hashed tjctf{[word]} - my word has a captial letter, two lowercase letters, a digit, and an underscore. ex: hash(‘tjctf{o0Bo}’) or hash(‘tjctf{Aaa0}’)

Here’s the md5 hash: 31f40dc5308fa2a311d2e2ba8955df6c

Solution

因為 Flag 大括號中的文字只有一個大寫字母、兩個小寫字母、一個數字以及一個底線
組合數不多,可以直接暴力破解

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import md5, string, itertools

target = "31f40dc5308fa2a311d2e2ba8955df6c"

for i in string.ascii_uppercase:
for j in string.ascii_lowercase:
for k in string.ascii_lowercase:
for l in string.digits:
lst = [i, j, k, l, '_']
for s in list(itertools.permutations(lst)):
str = "tjctf{" + ''.join(_ for _ in s) + "}"
m = md5.new()
m.update(str)
if m.hexdigest() == target:
print(str)
exit()

Flag tjctf{w0w_E}

[Misc] Journey - 20pts

Written by boomo

Every journey starts on step one

nc p1.tjctf.org 8009

Solution

這題要回傳引號中的文字

不過因為總共有 3720 筆,跑起來可能會超時,所以我分成很多段跑

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
from pwn import *

HOST = "p1.tjctf.org"
PORT = 8009

ans = open("ans.txt", "r").read().replace("[", "").replace("]", "").replace(",", "").replace("'", "").split()

while True:
r = remote(HOST, PORT)

if len(ans) != 0:
r.sendline(''.join(i + '\n' for i in ans))
r.recvlines(len(ans))

while True:
try:
q = r.recvline()
r.recv()
except IndexError:
with open("ans.txt", "w") as f:
f.write(str(ans))
r.close()
break

if "{" in q:
print(q)
exit()

tmp = q.split("'")[1]
print(tmp)
r.sendline(tmp)
ans.append(tmp)

Flag tjctf{an_38720_step_journey}

[Forensics] All the Zips - 20pts

Written by boomo

140 zips in the zip, all protected by a dictionary word.

All the zips

Solution

題目說所有 .zip 檔的密碼都是一個字典中的字
也就是說我們可以用 fcrackzip 搭配字典檔去暴力嘗試
在 Unix 系統下,通常會內建字典檔,可以在 /usr/share/dict/words/usr/dict/words 下找到

註:
如果是在 macOS 下使用這份 code ,編號 22, 92, 104, 121, 133 的 zip 會找不到密碼

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
import subprocess
from zipfile import ZipFile

crack = "fcrackzip -u -D -p \"/usr/share/dict/words\" \"{}\""
file = "all_the_zips/zip{}.zip"
check = "cat flag.txt"

for i in range(0, 140):
s = subprocess.check_output(crack.format(file.format(i)), stderr=subprocess.STDOUT, shell=True)
try:
pwd = s.split()[-1]
except EOFError:
continue
print("# {}: {}".format(i, pwd))
with ZipFile(file.format(i)) as zf:
zf.extractall(pwd=pwd)
s = subprocess.check_output(check, stderr=subprocess.STDOUT, shell=True).strip()
print(s)
if "tjctf" in s:
with open("flag.txt", "w") as f:
f.write(s)
exit()

Flag tjctf{sl4m_1_d0wn_s0_that_it5_heard}