kuzushikiのぺーじ

セキュリティに関することを書きたいですね

GitHub Twitter

SarCTF 2020 write up

SarCTF 2020に参加しました!

(team: score_gazer)

6137点を入れ、順位は98位 / 418チーム(0点は除く)でした

FireShot Capture 017 - SarCTF - sarctf tk

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

開くとシャーロックホームズっぽい写真と文章

holmes

なにもなさそうなので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種類

以下のようなアルゴリズムのスクリプトを作る

  1. それぞれの拡張子で解凍できるか確認し、できなかったら別の拡張子で試す

  2. 全ての拡張子で解凍に失敗したらその中身を表示させる

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つの投稿が引っかかった

一番古い投稿に添付されている画像リンクをボットに送信 (なぜかブラウザではメッセージを送信できなかったので、わざわざアプリをダウンロードした)

telegtram

フラグゲット 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}

感想

シャーロック・ホームズをモチーフにした問題が多く、 セキュリティの技術よりもひらめきを求められている気がしました。

これはこれで面白かったです。