这两天突然看到 https://blog.ripstech.com/2020/sql-injection-impresscms/,想着复现一下,记录一下学习过程。

漏洞分析

漏洞复现

首先我们先下载安装一下这个 cms,然后直接访问:

http://127.0.0.1:81/admin.php/modules/system' and sleep(2) and '1

这个 url,会发现延迟了三秒,没错这个漏洞就是这么简单。更深的用法我们就不讨论了。

漏洞分析

打开 cms 的文件: \htdocs\libraries\icms\module\Handler.php,找到 service 函数:

static public function service($inAdmin = FALSE) {
        if ($inAdmin || ... ) {
            $url_arr = explode('/', strstr($_SERVER['PHP_SELF'], '/modules/'));
            if (isset($url_arr[2])) {

                //关键点
                $module = icms::handler("icms_module")->getByDirname($url_arr[2], TRUE);

我们首先访问 admin.php 会执行到这个函数,然后 inAdmin 会设置成 true,到第四行获取了 PHP_SELF 并以 /modules/ 分割,然后讲 /modules/ 后的内容带入 getByDirname,跟进该函数:

public function getByDirname($dirname, $loadConfig = FALSE) {
        if (!empty($this->_cachedModule[$dirname]) &&
            $this->_cachedModule[$dirname]->getVar('dirname') == $dirname
        ) {
            ...
        } else {
            $sql = "SELECT * FROM " . $this->db->prefix('modules') . " WHERE dirname = '" . trim($dirname) . "'";
            //执行sql

可以看到这里直接带入了 $sql 没有任何过滤。

扩展思考

之前我也审计到过一个此类的漏洞,这里顺便分享一下:

然后下面的代码:

//此处的 $uri 就是 PHP_SELF
$tmp = strtolower(substr($uri,-4));
if(in_array($tmp,array('.jpg','.gif','.png','jpeg')) && substr($uri,0,11) == 'res/_cache/'){
    $tmp = substr($uri,11);
    $tmp = explode("/",$tmp);
    get_one($tmp[0]);

当文件名是 .jpg 结尾并且 uri 前十一位是 res/_cache/ 时进入,最后用 / 分割 uri 并带入 sql 语句。

很容易就可以 payload

index.php/res/_cache/a'-sleep(3)-'/test/test.jpg

此外还有一个点,但是暂时没有见到过案例,比如:

<?php
print_r($_SERVER['REQUEST_URI']);
?>

这样的代码,然后我们用 bp/test/test.php 修改成:/abc'd/../test/test.php

当然,不管是 PHP_SELF 还是 REQUEST_URI 我们直接 echo 出来都会造成 反射的 XSS

实际上我们访问的依然是 test.php,但是 REQUEST_URI 输出的却是 /abc'd/../test/test.php

当然,$_SERVER 里还有很多好玩的,期待师傅们挖掘出来教我QAQ

点击收藏 | 0 关注 | 1
  • 动动手指,沙发就是你的了!
登录 后跟帖