douphp20190711代码审计及漏洞复现

douphp20190711代码审计及漏洞复现

下载链接http://down.douco.com/DouPHP_1.5_Release_20190711.rar

1.安装时参数控制不严谨getshell

1.1 审计过程

在审计的时候,直接使用了被动加主动扫描,安装douphp以及进行常规测试,在没有头绪的时候看了一下扫描日志,发现了代码执行,查看漏洞点在/install/index.php下161-173行,由于对传入的参数没有严格过滤,并且对于写入的参数进行双引号包裹,导致传入的参数会被直接当作函数执行

在这里插入图片描述

1.2 分析漏洞

首先检查data/install.lock文件是否存在,如果不存在进行下一步的操作

对于传入的参数进行了全局过滤,使用addslashes进行处理,但是,没有对其他参数进行过滤,将文件直接写入之后并且进行包含即可查看代码执行结果。

<?php
$dbpass   = "${@eval(phpinfo())};";
?>

直接写下如下代码也会产生如此漏洞

在新版中修复了这个问题,把单引号替换成双引号

在这里插入图片描述

但是一个安装漏洞一般都是比较鸡肋的,如果没有任意文件删除的话是没有任何作用的于是接下来开始了任意文件删除漏洞的挖掘

2.后台任意文件删除

看一下官方的更新日志

在这里插入图片描述

修正后台安全问题,查看更新代码

在这里插入图片描述

发现对于删除的文件名进行了正则过滤,继续向上查找被过滤的参数,从数据库的mobile_logo取出的value值

在这里插入图片描述

我们继续查看value值是否可控,查找相关对于这个 字段的操作。

这里面的act 操作参数为clear_logo,通过我们对于后台参数传递的观察,发现在admin/mobile.php下有一个删除logo操作,引起了我们的主意,查看传递参数,跟踪代码,发现时一个文件上传操作,尝试修改文件名称上传,但是后台的参数一直时logo.png 查看后台代码

核心代码在mobile.php下62-69行

在这里插入图片描述

查看代码时把post传递过来的键值和键名赋值,之后通过update传递进入数据库存储,并没有对文件名进行操作,于是查看数据包,进行修改

在这里插入图片描述

发现可以成功修改数据库内容,继续查看图片上传目录在 \m\theme\default\images目录下,直接构造payload“…/…/…/…/data/install.lock” 存入数据库,执行clrea_logo操作,成功删除data/install.lock文件,之后我们就可以勇敢上面的安装漏洞进行shell写入。

3.遇到的坑

3.1 对于文件上传进行审计

    function upload($file_field, $file_name = '') {
        if ($GLOBALS['dou']->check_read_write($this->full_file_dir) != 'write') {
            $GLOBALS['dou']->dou_msg($GLOBALS['_LANG']['file_dir_wrong']);
        }
        
        // 没有命名规则默认以时间作为文件名
        if (empty($file_name))
            $file_name = $GLOBALS['dou']->create_rand_string('number', 6, time()); // 设定当前时间为图片名称
        
        if (@ empty($_FILES[$file_field]['name']))
            $GLOBALS['dou']->dou_msg($GLOBALS['_LANG']['file_empty']);

        $name = explode(".", $_FILES[$file_field]["name"]); // 将上传前的文件以“.”分开取得文件类型
        $img_count = count($name); // 获得截取的数量
        $img_type = $name[$img_count - 1]; // 取得文件的类型
        if (stripos($this->file_type, $img_type) === false) {
            $GLOBALS['dou']->dou_msg($GLOBALS['_LANG']['file_support'] . $this->file_type . $GLOBALS['_LANG']['file_support_no'] . $img_type);
        }
        $full_file_name = $file_name . "." . $img_type; // 写入数据库的文件名
        $file_address = $this->full_file_dir . $full_file_name; // 上传后的文件名称
        $file_ok = move_uploaded_file($_FILES[$file_field]["tmp_name"], $file_address);
        if ($file_ok) {
            $img_size = $_FILES[$file_field]["size"];
            $img_size_kb = round($img_size / 1024);
            if ($img_size_kb > $this->file_size_max) {
                @unlink($file_address);
                $GLOBALS['dou']->dou_msg($GLOBALS['_LANG']['file_out_size'] . $this->file_size_max . "KB");
            } else {
                return $full_file_name;
            }
        } else {
            $GLOBALS['_LANG']['file_wrong'] = preg_replace('/d%/Ums', $this->file_size_max, $GLOBALS['_LANG']['file_wrong']);
            $GLOBALS['dou']->dou_msg($GLOBALS['_LANG']['file_wrong']);
        }
    }

对于upload函数进行审计,发现使用了白名单模式,只能对于图片文件进行写入,如果图片文件的后缀存在于白名单中,将获取的文件后缀直接当作文件的后缀,并且进行写入,通过%00截断等方式已经没有作用,如果没有文件包含等漏洞的话,是没有办法利用的

3.2对于账户登录的记录的ip是否可注入的猜测

我们登录到后台可以发现,系统对于操作的ip进行记录,这个ip在参数获取时如果方式不正确,可以造成伪造,并且http header参数不在get post cookie参数里,并没有经过全局过滤,那么这个时一个比较好的注入点,我们查看登录页面代码

在admin/login.php下77行get_ip()函数,跟进函数

    function get_ip() {
        static $ip;
        if (isset($_SERVER)) {
            if (isset($_SERVER["HTTP_X_FORWARDED_FOR"])) {
                $ip = $_SERVER["HTTP_X_FORWARDED_FOR"];
            } else if (isset($_SERVER["HTTP_CLIENT_IP"])) {
                $ip = $_SERVER["HTTP_CLIENT_IP"];
            } else {
                $ip = $_SERVER["REMOTE_ADDR"];
            }
        } else {
            if (getenv("HTTP_X_FORWARDED_FOR")) {
                $ip = getenv("HTTP_X_FORWARDED_FOR");
            } else if (getenv("HTTP_CLIENT_IP")) {
                $ip = getenv("HTTP_CLIENT_IP");
            } else {
                $ip = getenv("REMOTE_ADDR");
            }
        }
        
        if (preg_match('/^(([1-9]?[0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]).){3}([1-9]?[0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$/', $ip)) {
            return $ip;
        } else {
            return '127.0.0.1';
        }
    }

查看源代码,心中一喜,这上面两个参数都是可以伪造的,于是兴致冲冲的去伪造,但是发现后台并没有成功几率,ip反而变成了127.0.0.1 于是我们继续查看源码,发现下面有一个正则,对ip进行了匹配,,,,,

抱歉ip注入这个点我没看过,我只是一只菜狗。

4.总结

查看源代码,心中一喜,这上面两个参数都是可以伪造的,于是兴致冲冲的去伪造,但是发现后台并没有成功几率,ip反而变成了127.0.0.1 于是我们继续查看源码,发现下面有一个正则,对ip进行了匹配,,,,,

抱歉ip注入这个点我没看过,我只是一只菜狗。

4.总结

对于这个cms 只是找到了后台getshell 并且特征特别明显,删除文件并且重置的话这样对于实际操作中,一旦使用这种方式很难 如果操作不当,很容易就会被警察叔叔请去喝茶,该漏洞已经在新版cms中修复。由于个人水平比较差,还没有找到前台sql注入的方法,如果有前台sql注入,或者配合admin888或者信息泄露等等可以进入后台,对网站进行重装,getshell之后对数据进行修复,问题还是不大的。

发布了14 篇原创文章 · 获赞 0 · 访问量 13

猜你喜欢

转载自blog.csdn.net/qq_43645782/article/details/105468310