| 关键词: 27 value 审计 return 版本 array 漏洞 where 语句 一下 |
声明 由于传播、利用此文所提供的信息而造成的任何直接或者间接的后果及损失,均由使用者本人负责,雷神众测以及文章作者不为此承担任何责任。 雷神众测拥有对此文章的修改和解释权。如欲转载或传播此文章,必须保证此文章的完整性,包括版权声明等全部内容。未经雷神众测允许,不得任意修改或者增减此文章内容,不得以任何方式将其用于商业目的。 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)--+" ![]() 该漏洞已提交厂商修复 " |
| 本文出处: https://www.toutiao.com/a6854710884447552013/ |
|
声明:文章版权归原作者所有 部分文章转自互联网 如有侵权请联系
[邮箱地址] 删除
|