一瞬ディレクトリトラバーサルに見えますが、たとえば/hash?file=../../flag
にアクセスしてもフラグのハッシュ値しか得られません。ハッシュ値から元のデータを復元するのは一般に不可能です。
今回の想定解はOSコマンドインジェクションでした。
execCommand(`md5sum "texts/${filename}"`)
Node.jsのchild_process.exec
はコマンドをシェル経由で実行するので、シェルスクリプトの文法がそのまま使えます。たとえば、filename
を";cat "/flag
にすれば、実行されるコマンドはmd5sum "texts/";cat "/flag"
となり、フラグを入手できます。しかし、今回は"
がバリデーションで弾かれてしまうので不可能です。そこで、文字列の中で使える特殊記号を利用します。具体的には$(command)
や`command`
です。
/hash?file=$(cat%20/flag)
にアクセスすると、実行されるコマンドはmd5sum "$(cat /flag)"
となりますが、このコマンドはフラグと同じ名前のファイルを読もうとしてエラーになります。さらに、レスポンスにエラーメッセージが含まれているので、そこからフラグを入手できます。
攻撃者にとって、エラーメッセージは情報の宝庫です。webサービスを開発する際は、不必要なエラーメッセージを返さないようにしましょう。