下載
下載源碼: https://gitee.com/hnaoyun/PbootCMS
版本V3.0.1 ,更新時間為20200709
安裝教程如下
安裝后去 https://www.pbootcms.com/freesn/獲取授權碼
代碼分析
依然是先查看apps\home\controller\ParserController.php中的parserIfLabel方法的兩個if標簽的過濾項
if (preg_match_all('/([\w]+)([\/\*\<\>\%\w\s\\\\]+)?\(/i', $matches[1][$i], $matches2)) {
foreach ($matches2[1] as $value) {
if (function_exists($value) && ! in_array($value, $white_fun)) {
$danger = true;
break;
}
}
}
if (preg_match('/(\$_GET\[)|(\$_POST\[)|(\$_REQUEST\[)|(\$_COOKIE\[)|(\$_SESSION\[)|(file_put_contents)|(file_get_contents)|(fwrite)|(phpinfo)|(base64)|(`)|(shell_exec)|(eval)|(assert)|(system)|(exec)|(passthru)|(pcntl_exec)|(popen)|(proc_open)|(print_r)|(print)|(urldecode)|(chr)|(include)|(request)|(__FILE__)|(__DIR__)|(copy)|(call_user_)|(preg_replace)|(array_map)|(array_reverse)|(getallheaders)|(get_headers)|(decode_string)|(htmlspecialchars)/i', $matches[1][$i]))
關於第一處的判斷,我們依然可以使用在函數名和括號之間插入控制字符的方法來繞過該處校驗,對於第二處,可以看到在黑名單中相較於上個分析版本(2.0.9)添加了getallheaders的黑名單判斷,於是該處我們需要尋找新的方法來實現代碼執行的目的,這讓我想到了array_filter函數
通過該函數我們可以實現執行php代碼,例如array_filter(['whoami'],'system');
那么接下來我們需要思考如何繞過黑名單中對system的檢測,在這里我們依然可以將system放到header頭中,這里可以使用session_id(session_start())的方法來取到session的值,我們可以將session的值置為system,就可以成功的調用system函數來執行命令了,通過上面的思路寫出利用payload使用的時候卻發生了如下問題
該處的冒號被替換成了@
符號,通過查看github更新記錄可以發現如下代碼段
該處使用了正則來替換我們輸入的if標簽,為了繞過該處正則的替換我們可以使用反斜杠來進行繞過,例如{pboot\:if}{/pboot\:if},該處的反斜杠會被寫入數據庫,而在程序調用該段數據並渲染到前台的模板時會調用到stripcslashes函數,進而刪除反斜杠,代碼位於core\function\handle.php中,如圖
通過上面的分析,我們易得如下payload
漏洞利用
來到后台站點信息處
插入如下代碼並保存
而后來到前台首頁,訪問前台首頁抓取數據包,將cookie中session的配置項改為system,如圖
可以看到成功執行了system("whoami");