picoCTF 2021 writeup

今回はyarakashikosenで参加しました(何もやらかしてないです)

チームでの総得点は1950で398位(今回は母数が多いので母数は無視)

個人では1010(多分)獲得しました。

以下解けた問題のwriteupを書いていきたいと思います。

Genaral skills

Obedient Cat (5pt)

配布ファイル : flag

$cat flag 

flag : picoCTF{s4n1ty_v3r1f13d_1a94e0f9}

Wave a flag (10pt)

配布ファイル : warm

$chmod +x warm 

$./warm -h

flag : picoCTF{b1scu1ts_4nd_gr4vy_616f7182}

Nice netcat... (15pt)

nc mercury.picoctf.net 7449

確かこれにアクセスすると数字をたくさん得ました。

112はord("p")なのでフラグのASCII codeな気がします。直してみます

solve.py

num=[112,105,99,111,67,84,70,123,103,48,48,100,95,107,49,116,116,121,33,95,110,49,99,51,95,107,49,116,116,121,33,95,102,50,100,55,99,97,102,97,125,10]

for i in num:
    print(chr(i),end="")

flag : picoCTF{g00d_k1tty!_n1c3_k1tty!_f2d7cafa}

Static ain't always noise(20pt)

配布ファイル : ltdis.sh, static

$ chmod +x ltdis.sh

$ chmod +x static

$ sh ltdis.sh static

$ rg pico 

flag : picoCTF{d15a5m_t34s3r_f5aeda17}

これよく分からないまま解けてしまった。

Tab, Tab, Attack(20pt)

配布ファイル : Addadshashanammu.zip

$ unzip Addadshashanammu.zip

$ cd Addadshashanammu/Almurbalarammi/Ashalmimilkala/Assurnabitashpi/Maelkashishi/Onnissiralis/Ularradallaku

(補完されたから一発で行けた)

$ chmod +x fang-of-haynekhtnamet

$ ./fang-of-haynekhtnamet

flag : picoCTF{l3v3l_up!_t4k3_4_r35t!_6f332f10}

Magikarp Ground Mission(30pt)

f:id:Bigdrea6:20210401082737p:plain

途中でちょっと無駄なことしてますが、やることはこれだけです。

flag : picoCTF{xxsh_0ut_0f_\/\/4t3r_3ca613a1}(このままでよかったか忘れた)

 

genral skillsは1問だけ解けなかった。チームメイトが解いてくれました。

Crypto

Mod 26(10pt)

暗号化されたフラグ : cvpbPGS{arkg_gvzr_V'yy_gel_2_ebhaqf_bs_ebg13_jdJBFOXJ}

ぱっと見た感じシーザー暗号です。

cyberchefに投げました。rot13でフラグゲット

flag : picoCTF{next_time_I'll_try_2_rounds_of_rot13_wqWOSBKW}

Mind your  Ps and Qs(20pt)

配布ファイル : value

問題文にあるとおり、Nが小さいと(ツールを使うと)簡単に素因数分解できます。

factordb.com素因数分解しましょう。

solve.py

import gmpy2,binascii

n = 1584586296183412107468474423529992275940096154074798537916936609523894209759157543
e = 65537
p = 2434792384523484381583634042478415057961
q = 650809615742055581459820253356987396346063
c = 964354128913912393938480857590969826308054462950561875638492039363373779803642185

d = gmpy2.invert(e,(p-1)*(q-1))

m = pow(c,d,n)
print("\n")
print("m="+str(m))

flag = binascii.unhexlify(format(m, 'x')).decode()

print("FLAG: {}".format(flag))

flag : picoCTF{sma11_N_n0_g0od_73918962}

New Caeser (60pt)

配布ファイル : new_caeser.py

暗号化されたフラグ : ihjghbjgjhfbhbfcfjflfjiifdfgffihfeigidfligigffihfjfhfhfhigfjfffjfeihihfdieieih

まず問題文を読んで注意すべきことは、このフラグは中身だけということですね。

ソースを読むと、assertからkeyはa~pの内の一文字であることが分かります。

次に、b16_encode, shiftを見てその逆のことをするソルバを書きます。

ここで、keyの半分総当り的なことをすることになりますが、暗号化されたフラグが79文字なので、もとのフラグは39文字であることにも注意します。

solve.py(コード汚くてごめんなさい)

import string

for i in range(16):
    key=chr(97+i)
    print("key=",key)
    print()
    alf = string.ascii_lowercase[:16]
    flag="ihjghbjgjhfbhbfcfjflfjiifdfgffihfeigidfligigffihfjfhfhfhigfjfffjfeihihfdieieih"

    def shift(kari,t2):
        kari=ord(kari)-97
        t2=ord(t2)-97
        t1=16+kari-t2

        if t1<0:
            t1=32+kari-t2
            return t1
        elif t1>15:
            t1=kari-t2
            return t1
        else:
            return t1

    t1=[]
    for i,c in enumerate(flag):
        t1.append(shift(c,key[i%len(key)]))

    print("flag=",end="")
    for i in range(0,len(t1),2):
        bin_f="{0:04b}".format(t1[i])
        bin_b="{0:04b}".format(t1[i+1])
        bin=bin_f+bin_b
        print(chr(int(bin,2)),end='')
    print()

key=cのとき、それっぽい内容になりました。文字数も一致していたので正解だと思いました。

flag : picoCTF{et_tu?_0797f143e2da9dd3e7555d7372ee1bbe}

Mini RSA (70pt)

配布ファイル : ciphertext

問題文の通り調べます。rsa small e的な感じで

いろんなwriteiupがあります。コードを拝借しました。

solve.py

c, nは長いのでここに書くのはやめます。

import gmpy2, binascii
# c=
# n=
e = 3

me = c + n

m,result = gmpy2.iroot(me,e)
i=1

while (result != True):
    i+=1
    me=c+(n*i)
    m,result=gmpy2.iroot(me,e)
    print("count: ",i)
    print("c+(n*{})={}".format(i,me))

print("m: ",m)
print(binascii.unhexlify(format(m, 'x')).decode())

flag : picoCTF{e_sh0u1d_b3_lArg3r_60ef2420}

 

cryptoはいつものことだけどこう既出の問題しかとけてないので、既出じゃないやつとかもコードを読んでしっかり解けるようにしたい。(数学もやらなきゃね)

Web

Scavenger Hunt(50pt)

url : http://mercury.picoctf.net:5080/

この問題フラグは5つのパートに別れています。それぞれのファイルを見に行って集めるという形でした。

・part 1 : index.html

developer toolで見ました。末尾にフラグが有ります。

picoCTF{t

・part 2 : mycss.css

同じです。

h4ts_4_l0

・part 3 : robots.txt

myjs.jsにヒントがあったみたいですが、気づかずとりあえず訪れるとありました。

t_0f_pl4c

・part 4 : .htaccess

ここから知らないものだったので時間がかかりました。robots.txtに書いてあったヒントを理解できなかったので、変な解き方をした気がします(多分)。

$dirb http://mercury.picoctf.net:5080

結果は既出のpart1,3そしてそれに加えて.htaccessでした。

訪れるとフラグを得ます。

3s_2_lO0k

・part 5 : .DS_Store

.htaccessのヒントをもとに調べるとこれを見つけました。

訪れると最後のパートをゲットします。

_35844447}

flag : picoCTF{th4ts_4_l0t_0f_pl4c3s_2_lO0k_35844447}

 

webはこの1問だけです。チームメイトには申し訳ない。

Rev

Transformation(20pt)

配布ファイル : enc

配布コード : ''.join([chr( (ord(flag[i]) << 8) + ord(flag[i + 1])) for i in range(0, len(flag), 2)])

encにはコードによって暗号化?されたフラグがあります。

全部コード書けばよかったんですが、なぜか半分人力でやりました。

まず、encをすべてASCII codeに戻します。コードからencの1文字はフラグの2文字で構成されていることは分かります。なので逆のことをしていけばいいです。

encの頭4文字は"picoCTF{"なので触れなくていいと思います。

まずフラグの1文字目を適当にord("適当な文字")<<8をして対応するencのASCII codeに近づけます。そして、encと1文字目の差が2文字目のASCII codeなのでこれでフラグが分かります。残りすべてこれをしていけばいいです。

flag : picoCTF{16_bits_inst34d_of_8_75d4898b}

 

revもこの1問だけです。revをしたいと思っているのでこの結果を踏まえてもっと精進したいと思います。解けなすぎた

Forensics

なんで得点の主成分がこれなんだ...

infomation(10pt)

配布ファイル : cat.jpg

file形式はjpgだったので、exiftoolを使って見てみます。

Licenseがbase64ぽいです。

License : cGljb0NURnt0aGVfbTN0YWRhdGFfMXNfbW9kaWZpZWR9

デコードするとフラグを得ました。

flag : picoCTF{the_m3tadata_1s_modified}

Matryoshka doll(30pt)

配布ファイル : dolls.png

file形式はpngでした。exifにめぼしい情報はありません。

binwalkで見ると違うpngを発見しました。

$ binwalk -e dolls.png

$ cd _dolls.png.extracted/base_images

またbinwalkで見ていきます。2_cから3_c。そして4_c

4_c.pngからはflag,txtを手に入れれました。

$ cat flag.txt

flag : picoCTF{4cf7ac000c3fb0fa96fb92722ffb2a32}

この中身ってなんか意味あるのかな。

tunn3l v1s10n(40pt)

配布ファイル :tunn3l_v1s10n

file形式はdata

$ hexdump -C tunn3l_v1s10n | head

bmpっぽい。手元に違うbmpがあったので見比べてヘッダの修正

00000000  42 4d 8e 26 2c 00 00 00  00 00 ba d0 00 00 ba d0  |BM.&,...........| #修正前
-------------------------------------------------------------------------------------
00000000  42 4d 8e 26 2c 00 00 00  00 00 36 00 00 00 28 00  |BM.&,.....6...(.| #修正後

 この状態で得られたbmpはこちら

f:id:Bigdrea6:20210401104527p:plain

まだなようです。

そこで、高さを編集しました。とりあえず幅の1134に合わせました。

すると

f:id:Bigdrea6:20210401112009p:plain

フラグを手に入れました

flag : picoCTF{qu1t3_a_v13w_2020}

解いてる最中tunnel visionを「てめえ頭かてえよ。違う見方しろよ」って意味かと思ってたんですが単純に視野がせまいということだったんですね。

Weird 

picoGymになかったので問題名は自分のフォルダにつけてた名前です。

配布ファイル : weird.docm

問題の横にあるヒントを読むと、使うべきツールが示してあります。

インストールしましょう

$ oleva -c weird.dcom

base64っぽいものが見えました。(ホントはpythonのコード読むべきだろうけど)

decodeするとフラグを手に入れます

flag : picoCTF{m4cr0s_r_d4ng3r0us}

Wireshark doo dooo do doo...(50pt)

配布ファイル : shark1.pcapng

まずはstringsで見てみます。

$ strings shark1.pcapng | grep pico

何もないです。そんな簡単じゃねえよという問題の意思を感じます。

wiresharkで開いて適当にtcp streamを眺めていたら、明らかにフラグっぽいものを見つけます。

HTTP/1.1 200 OK
Date: Mon, 10 Aug 2020 01:51:45 GMT
...

Gur synt vf cvpbPGS{c33xno00_1_f33_h_qrnqorrs}

(tcp.stream eq 5より)

原型はとどめているのでシーザーでしょう。

rot13でフラグを手に入れました。

flag : picoCTF{p33kab00_1_s33_u_deadbeef}

MacroHard WeakEdge(60pt)

配布ファイル : Forensics is fun.pptm

関係ないけど、個人的にファイル名に空白使うの嫌だ。

macroとあるので、weirdと同じかと思い、olevatoolを使ってみる。

$ oleva -c Forensics_is_fun.pptm

結果は

olevba 0.56 on Python 3.8.6 - http://decalage.info/python/oletools
...
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
Sub not_flag()
    Dim not_flag As String
    not_flag = "sorry_but_this_isn't_it"
End Sub

 違うよう。ここで結構詰まって時間を溶かしてしまった。

初心にかえる。ワードやパワポの別の形はzipなので、やってみる。

$ unzip Forensics_is_fun.zip

$tree

ppt/slideMastersにhiddenというファイルが。怪しい

$ cat hidden

パット見では気づかなかったが、base64のよう。decodeしてみる。

フラグを手に入れた。

flag : picoCTF{D1d_u_kn0w_ppts_r_z1p5}

weirdの時に、誘導で解いたから気づかなかったが、macro(vbaProject.bin)はこの方法でも見つけれたのでこれをしていればすっと行けたのかなと思う

Trivial Flag Transfer Protocol(90pt)

配布ファイル : tftp.pcapng

tftpと言われているので、絞って見るといろんなデータがある。

手元に持ってくる。 File -> Export Objects -> tftp... -> save all

ファイルは以下の6つ

instructions.txt, picture(1~3).bmp, plan, program.deb

picture1~3はいずれもbmpだった。2がちょっと変だったけど、firefoxで見ればちゃんと見れた。

program.debは開くとsteghideというものが見える。つまり、これで1~3になにか隠したということが分かる。

instructions.txt, planはどちらもテキストファイル。開くとよくわからない文字。とりあえず、rot13してみる。なんか読めそう。

GSGCQBRFAGRAPELCGBHEGENSSVPFBJRZHFGQVFTHVFRBHESYNTGENAFSRE.SVTHERBHGNJNLGBUVQRGURSYNTNAQVJVYYPURPXONPXSBEGURCYNA

TFTP DOESNT ENCRYPT OUR TRAFFIC SO WE MUST DISGUISE OUR FLAG TRANSFER.FIGURE OUT AWAY TO HIDE THE FLAG AND I WILL CHECK BACK FOR THE PLAN (rot13)

 instructions.txt

 VHFRQGURCEBTENZNAQUVQVGJVGU-QHRQVYVTRAPR.PURPXBHGGURCUBGBF

I USED THE PROGRAM AND HID IT WITH-DUE DILIGENCE .CHECK OUT THE PHOTOS (rot13)

 plan

自分で区切ってしまったことで、変な区切りになってしまい"due diligence"がよくわからなくなっていた。しかし、改めて見直すとWITH-DUEDILIGENCEである。passがこれと言っていることが分かった。1~3にやっていく。

$ steghide --extract -sf picture3.bmp

flag.txtが出てきた。

$ cat flag.txt

フラグを手にいれた。

flag : picoCTF{h1dd3n_1n_pLa1n_51GHT_18375919}

Disk, disk, sleuth!(110pt)

配布ファイル : dds1-alpine.flag.img.gz

とりあえず解凍

$ gzip -d dds1-alpine.flag.img.gz

srch_stringsを使う。

$ srch_strings dds1-alpine.flag.img | grep pico

flag : picoCTF{f0r3ns1c4t0r_n30phyt3_dcbf5942}

Milkslap(120pt)

url : http://mercury.picoctf.net:48380/

マウスポインターの動きに合わせて写真が動くサイト。

とりあえず、この写真を手元に持っていく。(これ競技中、結構途中で通信切れたけど、人多かったからかな?)

$ wget http://mercury.picoctf.net:48380/concat_v.png

exiftも何もなさそう。知ってるstegoのツールを順番に使っていった。

(stegsolve.jarとか、binwalkもとりあえずしてみた)

正解はzstegでした

$ zsteg -a concat_v.png

フラグを手に入れました

flag : picoCTF{imag3_m4n1pul4t10n_sl4p5}

Disk, disk, sleuth! II(130pt)

配布ファイル : dds2-alpine.flag.img.gz

先程と同様にとりあえず解凍

$ gzip -d dds2-alpine.flag.img.gz

srch_stringsを使うけど何もなさそう。

このファイル形式でwriteupを探していると適している記事を見つけた。

qiita.com

やって行きましょう

$ fls -o 2048 -r dds2-alpine.flag.img

down-at-the-bottom.txtが怪しそうです。

$ fls -o 2048 -r dds2-alpine.flag.img | grep down-at-the-bottom.txt

+ r/r 18291: down-at-the-bottom.txt

icatで抽出します。

$ icat -o 2048 -r dds2-alpine.flag.img 18291 > down-at-the-bottom.txt

$ cat down-at-the-bottom.txt

見にくいですが、フラグを手に入れました。

flag : picoCTF{f0r3ns1c4t0r_n0v1c3_ff27f139}

 

forensicsは10/13解いたので、この分野は全完したかった(waveとhiddenはきつそうだけど)。wire twoもほぼ解けてたから、解きたかった。