phpコード監査(一)phpBug#69892

13667 ワード

phpbug #69892
Description:
------------
var_dump([0 => 0] === [0x100000000 => 0]); // bool(true)

タイトルコード:
# Challenge


$users = array(
        "0:9b5c3d2b64b8f74e56edec71462bd97a" ,
        "1:4eb5fb1501102508a86971773849d266",
        "2:facabd94d57fc9f1e655ef9ce891e86e",
        "3:ce3924f011fe323df3a6a95222b0c909",
        "4:7f6618422e6a7ca2e939bd83abde402c",
        "5:06e2b745f3124f7d670f78eabaa94809",
        "6:8e39a6e40900bb0824a8e150c0d0d59f",
        "7:d035e1a80bbb377ce1edce42728849f2",
        "8:0927d64a71a9d0078c274fc5f4f10821",
        "9:e2e23d64a642ee82c7a270c6c76df142",
        "10:70298593dd7ada576aff61b6750b9118"
);

$valid_user = false;

$input = $_COOKIE['user'];
$input[1] = md5($input[1]);

foreach ($users as $user)
{
        $user = explode(":", $user);
        if ($input === $user) {
                $uid = $input[0] + 0;
                $valid_user = true;
        }
}

if (!$valid_user) {
        die("not a valid user
"
); } if ($uid == 0) { echo "Hello Admin How can I serve you today?
"
; echo "SECRETS ....
"
; } else { echo "Welcome back user
"
; }
  • まずテーマの論理
  • を分析します
  • 第1部
  • 
    
    $users = array(
            "0:9b5c3d2b64b8f74e56edec71462bd97a" ,
           ······
    );
    
    $valid_user = false;
    
    

    MD 5ハッシュ値を定義したユーザーパスワードのリストでvalid_userをfalseに初期化
  • 第2部
  • $input = $_COOKIE['user'];
    $input[1] = md5($input[1]);
    

    クッキー方式で1つの入力を受け入れ、受け入れた入力を配列に変換してチェックし、配列の2番目のパスワード項目をmd 5に変換する
  • 第3部
  • foreach ($users as $user)
    {
            $user = explode(":", $user);
            if ($input === $user) {
                    $uid = $input[0] + 0;
                    $valid_user = true;
            }
    }
    

    配列内を巡回して使用する入力したユーザーとパスワードをチェックし、一致した場合、入力したアカウントをuidに割り当て、値0を追加して数値データ型に強制的に変換します.それ以外は、フラグ$valid_userはtrueに設定され、このセクションはログインを検証するセクションです.
  • 第4部
  • if (!$valid_user) {
            die("not a valid user
    "
    ); } if ($uid == 0) { echo "Hello Admin How can I serve you today?
    "
    ; echo "SECRETS ....
    "
    ; } else { echo "Welcome back user
    "
    ; }

    この部分の主な役割はuidに基づいて管理者かどうかを判断することであり、uidが0であれば管理者ログインと確認し、そうでなければuserログインである.
    問題を解く構想.
    私は第1歩の汎読コードが構想を整理した後に逆プッシュの方法を採用して問題を解決することに慣れていますまず管理者の身分でログインしてuid==0(ここでは弱いことに注意してください)に成功して、uidはどのように0になることができて、コードの第3部分のuidアカウントまで実際に入ったアカウントに等しい(検証した入ったアカウントだけがuidに値を与えることができます)、では、アカウント0を使ってログインして検証に合格すればいいので、次に検証に合格する方法を解決します.転送されたアカウントパスワードはusers配列と一致し、配列中のmd 5値を復号すると、ユーザ5のみが復号できることが分かった.06 e 2 b 745 f 3124 f 7 d 670 f 78 eabaa 94809復号後hund.現在、ユーザー0を使用してログインできませんが、ユーザー5を使用してログインできます.
    cookie:user[0]=5;user[1]=hund;
    

    次の問題は、user[0]=5をuser[0]=0にする方法である.これはphpbug#69892に用いられる.簡単に言えば、脆弱性の利用はキー名user[4294967296]であり、効果的にはuser[0]=0に等しいが、user[0]=5であり、その値は5であり、user[4294967296]=5であり、彼の値は実際には空になっていることに注意しなければならない.でも後ろには
    $uid = $input[0] + 0;
    

    もともとここでinput[0]の値は空で、後+0がintタイプに強制的に変換されるとuidは0になります.比較の際、inputとuserの2つの配列で使用される"=="を比較すると、input[0]の値を設定するのではなく、input[4294967296]で代用し、比較の際に使用されるinput[4294967296]とinput[1]でリスト内のユーザと比較することができ、uidはinput[0]+0で得られるので、その制限を完全に迂回することができる.phpBug#69892の詳細については、やはり関連資料を参照してください.ここでは、1つの利用方法しか示していません.