SarCTF 2020 write up
SarCTF 2020に参加しました!
(team: score_gazer)
6137点を入れ、順位は98位 / 418チーム(0点は除く)でした
write upを書いていきます
Doc. Holmes
ファイルが添付されてる
fileコマンド
root@kali:/media/sf_share/CTF/SarCTF 2020/DOC.HOLMES# file some.file
some.file: Microsoft Word 2007+
root@kali:/media/sf_share/CTF/SarCTF 2020/DOC.HOLMES# mv some.file some.docx
開くとシャーロックホームズっぽい写真と文章
なにもなさそうなのでbinwalk
してみる
root@kali:/media/sf_share/CTF/SarCTF 2020/DOC.HOLMES# binwalk -e some.docx
DECIMAL HEXADECIMAL DESCRIPTION
--------------------------------------------------------------------------------
0 0x0 Zip archive data, at least v2.0 to extract, compressed size: 359, uncompressed size: 1363, name: [Content_Types].xml
928 0x3A0 Zip archive data, at least v2.0 to extract, compressed size: 239, uncompressed size: 590, name: _rels/.rels
1728 0x6C0 Zip archive data, at least v2.0 to extract, compressed size: 2691, uncompressed size: 14624, name: word/document.xml
4466 0x1172 Zip archive data, at least v2.0 to extract, compressed size: 273, uncompressed size: 1081, name: word/_rels/document.xml.rels
5061 0x13C5 Zip archive data, at least v1.0 to extract, compressed size: 17283, uncompressed size: 17283, name: word/media/image1.jpg
22395 0x577B Zip archive data, at least v1.0 to extract, compressed size: 244243, uncompressed size: 244243, name: word/media/image3.jpg
266689 0x411C1 Zip archive data, at least v2.0 to extract, compressed size: 1786, uncompressed size: 8444, name: word/theme/theme1.xml
268526 0x418EE Zip archive data, at least v2.0 to extract, compressed size: 1152, uncompressed size: 3262, name: word/settings.xml
269725 0x41D9D Zip archive data, at least v2.0 to extract, compressed size: 3244, uncompressed size: 30615, name: word/styles.xml
273014 0x42A76 Zip archive data, at least v2.0 to extract, compressed size: 457, uncompressed size: 2269, name: word/webSettings.xml
273521 0x42C71 Zip archive data, at least v2.0 to extract, compressed size: 540, uncompressed size: 1966, name: word/fontTable.xml
274109 0x42EBD Zip archive data, at least v2.0 to extract, compressed size: 367, uncompressed size: 736, name: docProps/core.xml
274787 0x43163 Zip archive data, at least v2.0 to extract, compressed size: 502, uncompressed size: 1002, name: docProps/app.xml
276438 0x437D6 End of Zip archive, footer length: 22
すると/_some.docx.extracted/word/media
に3枚の画像が抽出される
3枚目にフラグが書いてある
FLAG{prominentplace}
Blogger
pcapngファイルが添付されてる
wiresharkで開くとUSBが使われてる
Leftover Capture Data
の値が毎回変わっており怪しいので調べてみる
どうやらUSBキーボードの入力らしい
まずLeftover Capture Data
の値をtsharkで取り出す
root@kali:/media/sf_share/CTF/SarCTF 2020/Blogger# tshark -r usb_here.pcapng -V | grep "Leftover Capture Data" | cut -d " " -f 4 > trim
対応表を参考にデータをキーに変換するpythonスクリプトを書く
FILE = "trim"
switcher = {
"04":"a", # or A
"05":"b", # or B
"06":"c", # or C
"07":"d", # or D
"08":"e", # or E
"09":"f", # or F
"0A":"g", # or G
"0B":"h", # or H
"0C":"i", # or I
"0D":"j", # or J
"0E":"k", # or K
"0F":"l", # or L
"10":"m", # or M
"11":"n", # or N
"12":"o", # or O
"13":"p", # or P
"14":"q", # or Q
"15":"r", # or R
"16":"s", # or S
"17":"t", # or T
"18":"u", # or U
"19":"v", # or V
"1A":"w", # or W
"1B":"x", # or X
"1C":"y", # or Y
"1D":"x", # or Z
"1E":"1", # or !
"1F":"2", # or @
"20":"3", # or #
"21":"4", # or $
"22":"5", # or %
"23":"6", # or ^
"24":"7", # or &
"25":"8", # or *
"26":"9", # or (
"27":"0", # or )
"2D":"-", # or _
"2E":"+", # or =
"2F":"[", # or {
"30":"]", # or }
"31":"\"", # or |
"33":";", # or :
"34":"'", # or "
"35":"`", # or ~
"36":",", # or <
"37":".", # or >
"38":"/" # or ?
}
with open(FILE) as f:
data = f.readlines()
for line in data:
byte = line[4:6].upper()
if byte in switcher:
print(switcher[byte], end="")
実行結果は以下の通り
root@kali:/media/sf_share/CTF/SarCTF 2020/Blogger# python3 solve.py
sherlock,john,andhenrythenvisitthehollowinthehopeoffindingthehound.ontheway,johnnoticeswhatseemstobeflag[like-a-b100dh0und]e
フラグはflag[like-a-b100dh0und]
の部分
一部のキーはシフトキーと同時に押されているので脳内変換
フラグゲット
FLAG{like_a_b100dh0und}
Deep dive
flag.txt
というファイルが添付されている
↓
fileコマンドで調べると実はtarファイル
↓
展開するとまたflag.txt
が出てくる
↓
実はzipファイル
↓
展開するとまたflag.txt
が出てくる
という流れの繰り返し
確認できた拡張子はzip
, gzip
, bz2
, tar
の4種類
以下のようなアルゴリズムのスクリプトを作る
-
それぞれの拡張子で解凍できるか確認し、できなかったら別の拡張子で試す
-
全ての拡張子で解凍に失敗したらその中身を表示させる
pythonによる実装は以下の通り
import zipfile
import tarfile
import gzip
import bz2
import os
import shutil
def unzip(data):
with zipfile.ZipFile(data) as f:
f.extractall()
def untar(data):
with tarfile.open(data) as f:
f.extractall()
def ungzip(data):
with gzip.open(data) as f:
dump = f.read()
with open("flag.txt", "wb") as f:
f.write(dump)
def unbz2(data):
with open(data, "rb") as f:
byte = f.read()
dump = bz2.decompress(byte)
with open("flag.txt", "wb") as f:
f.write(dump)
shutil.copy('original', 'flag.txt')
while True:
os.rename("flag.txt", "tmp")
try:
unzip("tmp")
except:
try:
untar("tmp")
except:
try:
ungzip("tmp")
except:
try:
unbz2("tmp")
except:
with open("tmp", encoding="utf_8") as f:
data = f.read()
print(data)
exit()
実行するとフラグがでてくる
root@kali:/media/sf_share/CTF/SarCTF 2020/Deep dive# python3 solve.py
FLAG{matri0sha256}
Layouts
RWtm7A5f
というちょっと変わった名前のファイルが添付されてる
fileコマンドで調べるとzip形式だと分かる
しかし、パスワードがかかっていて展開できない
ファイル名が怪しいので入れてみたら通った
おそらくこれを繰り返せば良さそう
pythonスクリプトは以下の通り
import zipfile
import os
import glob
def unzip(data, pwd):
with zipfile.ZipFile(data) as f:
f.extractall(pwd=pwd)
def get_name():
for name in glob.glob('./*'):
if ".py" not in name:
file_name = name[2:]
return file_name
while True:
data = get_name()
try:
unzip(data, data.encode("utf-8"))
except:
with open(data) as f:
r = f.read()
print(r)
exit()
os.remove(data)
するとflag
というファイルが抽出できる
fileコマンドで調べるとXZ形式だと分かるので展開
flags
というディレクトリが出てくる
中に沢山のフォルダが入っていたので、
とりあえず./flags
以下のファイルを抽出する
root@kali:/media/sf_share/CTF/SarCTF 2020/Layouts# find ./flags -type f -name "*"
./flags/101/9
./flags/102/11
./flags/103/8
./flags/110/16
./flags/112/18
./flags/117/12
./flags/120/13
./flags/122/6
./flags/123/5
./flags/125/21
./flags/49/19
./flags/49/20
./flags/51/10
./flags/52/14
./flags/52/7
./flags/53/17
./flags/78/3
./flags/83/1
./flags/84/4
./flags/89/2
./flags/95/15
cat
で中身を見ても何もなかった
ここで、ファイル名が1~21の連番になっていること、 さらにそのファイルが入っているフォルダ名がasciiコードの英数字の範囲にあることに気づく
先ほどの結果をdump
ファイルに保存してから、ファイル名で並べ替える
root@kali:/media/sf_share/CTF/SarCTF 2020/Layouts# sort -n -k 4 -t "/" dump| cut -d "/" -f 3
83
89
78
84
123
122
52
103
101
51
102
117
120
52
95
110
53
112
49
49
125
結果をdump2
として保存
asciiコードから文字に変換するpythonスクリプトを書く
FILE = "dump2"
with open(FILE) as f:
data = f.readlines()
i = 0
for line in data:
i += 1
print(chr(int(line,10)), end="")
実行結果は以下の通り
root@kali:/media/sf_share/CTF/SarCTF 2020/Layouts# python3 from_ascii.py
SYNT{z4ge3fux4_n5p11}
ROTっぽいのでcyberchefにかけてみる
フラグゲット
FLAG{m4tr3shk4_a5c11}
Sherlock team
問題にある画像をSNSで探してそのリンクをTelegramのbotに送信すればフラグを得られる
このCTFのトップページに、「VKのアカウント登録しといた方が良いよ」と書かれていたことを思い出し、VKを調査することにした
ハッシュタグ#SarCTF
で検索したところ、3つの投稿が引っかかった
一番古い投稿に添付されている画像リンクをボットに送信 (なぜかブラウザではメッセージを送信できなかったので、わざわざアプリをダウンロードした)
フラグゲット
FLAG{ShErL0cK_Teaaam}
正直VKとかTelegramのアカウントを登録する方が面倒だった
True Detective
Google formのリンクが張られてる
いくつかの質問に正確に答える必要があるみたいだ
ソースを"FLAG"で検索したら、以下の部分が引っかかった
var FB_PUBLIC_LOAD_DATA_ = [null,["Let's see how well you know London.",[[673760842,"What is the name of the store?",null,0,[[255559616,null,0,null,[[4,300,["(tesco|Testo)"]
,"1 - FLAG{08"]
]
]
]
,null,null,null,null,[["1cTysniECWio21dKH90wnnzNxlB4gKBJI7Bri1Q_K4moAtg",null,[740,385,0]
]
]
]
,[2014750817,"What is the name of this place?",null,0,[[1092335700,null,0,null,[[4,300,["(bridport|Bridport)"]
,"2 - c49c3d9a"]
]
]
]
,null,null,null,null,[["1sd8oiCWcjd1_HiCrOA2f1hrgkknzJvT_Y-tVgx5qjBanKw",null,[740,417,0]
]
]
]
,[771036932,"Very beautiful Park where Sherlock likes to walk. Where is it?",null,0,[[1600364512,null,0,null,[[4,300,["(finsbury|Finsbury)"]
,"3 - e8898343"]
]
]
]
,null,null,null,null,[["1-w_MvKBaer5I78ICXo70E94lH4vKSPmCRekszxbOblJRvA",null,[740,377,0]
]
]
]
,[302390155,"Every Englishman has been to this square at least once",null,0,[[661956933,null,0,null,[[4,300,["(euston|Euston)"]
,"4 - 7729747b"]
]
]
]
,null,null,null,null,[["1sGu1uvZD9tXdbS0ypGTsI05LDj8Bd1U03VV_vjDLI3bY6A",null,[740,385,0]
]
]
]
,[1070034509,"Which Embassy building is shown in the photo",null,0,[[2072641709,null,0,null,[[4,300,["(hungary|Hungary)"]
,"5 - cf1be8}"]
]
]
]
,null,null,null,null,[["174eoWKRoyVKEN21KJigFwwry_DncqoZfVECN_p6i85oWRw",null,[740,376,0]
]
]
]
]
,null,null,null,[0,0]
,null,null,"Task",48,[null,null,null,null,0]
,null,null,null,null,[2]
]
.
.
.
以下略
1 -
, 2-
と書いてあるところを全部繋げる
FLAG{08c49c3d9ae88983437729747bcf1be8}
点数の割にちょっと簡単すぎやしないか
Crossw0rd
パスワードの入力を求められる
IDAなどで逆アセンブルすると、1文字ずつ比較していることが分かるので、 何文字目の文字を何と比較してるかを調べる
手作業で抽出した
自動でやる方法誰か知ってたら教えて下さい
add rax, 7 cmp al, 35h ; '5'
add rax, 11h cmp al, 67h ; 'g'
add rax, 2 cmp al, 41h ; 'A'
add rax, 0Fh cmp al, 69h ; 'i'
add rax, 9 cmp al, 72h ; 'r'
add rax, 1 cmp al, 4Ch ; 'L'
add rax, 0Ah cmp al, 33h ; '3'
add rax, 12h cmp al, 7Dh ; '}'
add rax, 6 cmp al, 61h ; 'a'
add rax, 0 cmp al, 46h ; 'F'
add rax, 0Eh cmp al, 35h ; '5'
add rax, 10h cmp al, 6Eh ; 'n'
add rax, 3 cmp al, 47h ; 'G'
add rax, 0Bh cmp al, 76h ; 'v'
add rax, 5 cmp al, 33h ; '3'
add rax, 4 cmp al, 7Bh ; '{'
add rax, 0Ch cmp al, 33h ; '3'
add rax, 8 cmp al, 79h ; 'y'
add rax, 0Dh cmp al, 72h ; 'r'
整形してフラグを出力するスクリプトを書いた
FILE = 'data'
with open(FILE) as f:
r = f.readlines()
flag = ['?'] * len(r)
for line in r:
ind = line[13:].split(" ")[0]
if ind[-1] == 'h':
ind = ind[:-1]
c = line.split("\'")[1]
flag[int(ind,16)] = c
print("".join(flag))
フラグゲット
FLAG{3a5yr3v3r5ing}
Magic of numbers
SECCON CTF beginnersでいう「手計算えくすとりーむ」みたいな問題
サーバから式を受け取り、その計算結果を送り返すスクリプトを書いた
from pwn import *
io = remote('212.47.229.1', 33004)
for i in range(10):
io.recvuntil(b'[>] ')
eq = io.recvline().strip()
print(eq)
payload = str(eval(eq.decode())).encode()
io.recv()
io.sendline(payload)
print(payload)
io.interactive()
実行結果は以下の通り
root@kali:/media/sf_share/CTF/SarCTF 2020/Magic of numbers# python3 solve.py
[+] Opening connection to 212.47.229.1 on port 33004: Done
b'0 + 1'
b'1'
b'1 + 3'
b'4'
b'2 + 5'
b'7'
b'3 + 7'
b'10'
b'4 + 9'
b'13'
b'5 + 11'
b'16'
b'6 + 13'
b'19'
b'7 + 15'
b'22'
b'8 + 17'
b'25'
b'0.1 + 0.2'
b'0.30000000000000004'
[*] Switching to interactive mode
FLAG{MaGiC_0f_NuMbErS}
Find Moriarty
時間内にギリギリ解けなかった
後1分あればなあ…
圧縮ファイルが添付されてるので展開すると、
3枚の航空写真(png)と、PASS: IATA
と書かれたファイル(jpg)が出てくる
steganoの問題にpasswordが出てくるのでsteghide
の問題だと予想
次に、IATA
という言葉をググってみると、国際航空運送協会によって定義された世界中の多くの空港と大都市圏を指定する3文字のジオコードだと分かる
つまり3枚の航空写真がどこの空港の写真かを特定し、そのIATAを繋げたものをpasswordとしてsteghide
にかければいい
google画像検索にかけたらあっさり判明した
1枚目:ロンドン・ガトウィック空港 LGW
2枚目:ロンドン・ヒースロー空港 LHR
3枚目:ロンドン・スタンステッド空港 STN
問題は繋げる順番だが、6パターンしかないので総当たり
STNLHRLGW
がヒットした
root@kali:/media/sf_share/CTF/SarCTF 2020/Find Moriarty/airport# steghide extract -sf fly.jpg
Enter passphrase:
wrote extracted data to "key.txt".
抽出したkey.txt
にフラグが書かれている
FLAG{l375_fly_w17h_bu65}
感想
シャーロック・ホームズをモチーフにした問題が多く、 セキュリティの技術よりもひらめきを求められている気がしました。
これはこれで面白かったです。