picoCTF 2022 writeup (Reversing)
picoCTF 2022 の Rev 問題の Writeup.
難易度 medium のみ
unpackme
- upx とついた名前のファイルが配布されたため, upx コマンドを用いてファイルの unpack を試みる
upx -d unpackme-upx -o out
- 出力として 64 bit の実行ファイルが渡された
- 実行してみると数値の入力を求められたため, objdump で main 関数などを調べる
objdump -d out -M intel
- cmp 命令で 0xb83cb (10 進法で 754635) と入力を比較していたため, それを入力として渡してあげるとフラグが表示された
unpackme.py
- python ファイルが渡される
- 実行するとパスワードを求められる
- プログラム内に
exec(plain.decode())
というコードがあり, 中身は byte コードであることが考えられる - 試しに print 関数を仕込んでみるとフラグが読めた
import base64 from cryptography.fernet import Fernet payload = b'gAAAAABkzWGSzE6VQNTzvRXOXekQeW4CY6NiRkzeImo9LuYBHAYw_hagTJLJL0c-kmNsjY33IUbU2IWlqxA3Fpp9S7RxNkiwMDZgLmRlI9-lGAEW-_i72RSDvylNR3QkpJW2JxubjLUC5VwoVgH62wxDuYu1rRD5KadwTADdABqsx2MkY6fKNTMCYY09Se6yjtRBftfTJUL-LKz2bwgXNd6O-WpbfXEMvCv3gNQ7sW4pgUnb-gDVZvrLNrug_1YFaIe3yKr0Awo0HIN3XMdZYpSE1c9P4G0sMQ==' key_str = 'correctstaplecorrectstaplecorrec' key_base64 = base64.b64encode(key_str.encode()) f = Fernet(key_base64) plain = f.decrypt(payload) print(plain.decode()) exec(plain.decode())
Safe Opener
- java ファイルが渡される
- 入力が Base64 でエンコードされたうえでハードコーディングされたキーと比較されている
- デコードしてフラグを獲得
patchme.py
- 渡された Python ファイルを調べると, パスワードの入力処理がある
- パスワードはエンコードなどもされないままハードコーディングされているため, それを入力すればフラグ獲得
Bbbbloat
- バイナリファイルが配布される
- ltrace を用いてデバッグ
ltrace bbbbloat
- scanf で数字を読み込むプログラム
- objdump で逆アセンブル
objdump -d bbbbloat -M intel > dumped.txt
- .text で scanf が呼び出されている付近のコードを眺めていると, 入力と比較を行っている箇所が見つかった
mov eax,DWORD PTR [rbp-0x40] cmp eax,0x86187
- ここで
[rbp-0x40]
には scanf で渡した値がそのまま数値として入るため, 0x86187 (549255) を入力してあげると分岐をクリアできそう - 入力するとフラグを獲得できた
bloat.py
- Python ファイルが渡される
- 中身を読むと a という変数に各種の文字を格納しそのインデックスを用いたアクセスを行うことで読みづらくしている
- arg133 という関数がパスワードの比較となっているため,
return True
を差し込んであげることでパスワードチェックを無条件で通過できるようにプログラムを書き換えてあげる - ファイルを実行するとフラグが獲得できた
GDB Test Drive
- 実行ファイルが渡される
- ltrace でデバッグ
ltrace gdbme
- 実行結果
sleep(100000
- sleep 関数が呼ばれている
- 問題名からおそらく gdb で sleep 関数の実行をスキップすれば良いと考えられる
gdb gdbme (gdb) break *main+94 (gdb) run (gdb) jump *main+104
- フラグが獲得できた
Fresh Java
- Java のクラスファイルが配布される
jadx
を用いて逆コンパイル
jadx KeygenMe.class
- コードを読むと一文字ずつ key があっているか検証しているので, 順に並べるとフラグになる
file-run1
- 64bit のバイナリファイルが渡される
- 実行するとフラグが出てきた (難易度 medium?)
- ちなみに
strings
でもフラグが確認できた
file-run2
- またバイナリファイルが渡される
- 引数を指定して実行するとフラグ獲得
./run Hello!
- また
strings
でも見つけられた