web-dev-qa-db-ja.com

PHPセッションの脆弱性

PHPセッションを使用して、CTFの課題を解決しようとしています。目標は、check.phpエコー$_PASSWORDを作成することです。

ファイル自体にアクセスできないため、編集できません。

私が提案する解決策は:

  1. セッションを20秒間ロックする必要があるため、eat.phpをその時間だけ実行する必要があります。
  2. 同時に、check.phpを実行して$timeを設定し、セッションがロック解除されるのを待つ必要があります。
  3. 次に、セッションのロックを解除する必要があります。つまり、eat.phpを停止する必要があります。
  4. check.phpは実行を継続し、次の式:$time+20!=$_SESSION['time']はfalse、PHPは$_PASSWORDをエコーし​​ます。

私の提案は可能ですか?もしそうなら、どのように実装しますか?この問題を解決するための他の指示についても聞きたいです。

get.php:

<?php
setcookie('id',uniqid());
?>

eat.php:

<?php
$cookie=$_POST['cookie'];
session_save_path('/home/mawekl/timetravel/');
session_start();
echo 'You ate: '.htmlspecialchars($cookie);
echo "\n<br>";
$_SESSION['cookie']=$cookie;
$_SESSION['time']=time();
?> 

check.php:

<?php
$cookie=$_COOKIE['id'];
$time=time();
session_save_path('/home/mawekl/timetravel/');
session_start();
if ($cookie!=$_SESSION['cookie'])
    die('Wrong cookie');
if ($time+20!=$_SESSION['time'])
    die('You must eat cookie after 20 seconds from now, but you ate it '.($time-$_SESSION['time']).' seconds ago');
echo $_PASSWORD;
?> 
7
Roee H

もちろん私は解決策を知らないので間違っているかもしれませんが、これが私の分析です。

_get.php_は、ランダムなid Cookie値を作成できるため、完全に無視できます。

必要な情報がすべて揃っていない場合があります。サーバーはApacheなどを実行していますか?使用したPHPバージョンが使用されましたか?チャレンジの説明はありますか?(それらはしばしばあいまいなヒントを含んでいます)?

現状では、これにアプローチする現実的な方法は2つだけです。その_$_SESSION['time']_変数にデータを注入するか、_check.php_を$time=time();の後で_$time+20!=$_SESSION['time']_の前に一時停止します。

PHPのインジェクションの脆弱性を探したところ、CVE-2006-3016(PHP 5.1)しか見つかりませんでしたが、詳細はほとんど含まれておらず、非常に古いPHPバージョンを実行する必要があります。昨年誰かも セッションインジェクションの脆弱性を報告 ですが、適用できないようです。この方法はあまり実行可能ではないようです。

これは一時停止のトリックを残します。私はこのようなことを考えていました:

  1. たくさんの接続を開いて、_eat.php_に大きな_$_POST['cookie']_値を要求し、すべてのセッションの書き込みに多くの時間をかけるようにします。
  2. ステップ1が完了するまでハングする_check.php_を要求します。正確に20秒かかるまで、ステップ1で行われた要求の量を変化させます。

_check.php_をスリープ状態にして、一連の_eat.php_リクエストをバックグラウンドで実行する必要があるため、サーバーはマルチスレッドを実行する必要があります。

これの問題は、各_eat.php_が同じセッションに書き込む必要があるか、または_check.php_でまったくブロックされないことです(_check.php_をセッションにロックしているスレッドがないため)読み込もうとします)。ただし、連続する_eat.php_の完了ごとに_$_SESSION['time']_の値がより新しいものに更新される場合、古い時間の値はありません。したがって、これも機能しません。 (PHPブロック(anyセッションがまだ書き込まれている場合)であれば機能する可能性があり、別のセッションが_eat.php_を実行しても_check.php_がハングしたままになりますが、これはありそうにないため、可能性については調べていません。)

つまり、より多くの情報が必要であり、おそらくチャレンジ環境へのアクセスさえ必要です。私の観点からは、別の脆弱性なしでは不可能に思えます(たとえば、偽のNTPアップデートを送信する)。

あなたの質問に答えるために

はい、提案されたソリューションはおそらく機能します。ただ1つの問題:実際にどうやってこれを実現させるのですか? ;)

1
Luc