博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Dedecms V5.7后台的两处getshell
阅读量:5734 次
发布时间:2019-06-18

本文共 4094 字,大约阅读时间需要 13 分钟。

在这个帖子里我把两个洞一起写出来。

第一个是常见的思路,把语句写入inc文件,然后在其他的include语句中,包含了恶意代码进而getshell。

漏洞代码在:/dede/sys_verifies.php 代码如下:

else if ($action == 'getfiles'){    if(!isset($refiles))    {        ShowMsg("你没进行任何操作!","sys_verifies.php"); exit(); } $cacheFiles = DEDEDATA.'/modifytmp.inc'; $fp = fopen($cacheFiles, 'w'); fwrite($fp, '<'.'?php'."\r\n"); fwrite($fp, '$tmpdir = "'.$tmpdir.'";'."\r\n"); $dirs = array(); $i = -1; $adminDir = preg_replace("#(.*)[\/\\\\]#", "", dirname(__FILE__)); foreach($refiles as $filename) { $filename = substr($filename,3,strlen($filename)-3); if(preg_match("#^dede/#i", $filename)) { $curdir = GetDirName( preg_replace("#^dede/#i", $adminDir.'/', $filename) ); } else { $curdir = GetDirName($filename); } if( !isset($dirs[$curdir]) ) { $dirs[$curdir] = TestIsFileDir($curdir); } $i++; fwrite($fp, '$files['.$i.'] = "'.$filename.'";'."\r\n"); } fwrite($fp, '$fileConut = '.$i.';'."\r\n"); fwrite($fp, '?'.'>'); fclose($fp); $dirinfos = ''; if($i > -1) { $dirinfos = ''; $dirinfos .= "本次升级需要在下面文件夹写入更新文件,请注意文件夹是否有写入权限:
\r\n"; foreach($dirs as $curdir) { $dirinfos .= $curdir['name']." 状态:".($curdir['writeable'] ? "[√正常]" : "[×不可写]")."
\r\n"; } $dirinfos .= "\r\n"; } $doneStr = "\r\n"; include(DEDEADMIN.'/templets/sys_verifies_getfiles.htm'); exit(); }

从这段代码里,可以得知会在/data目录下生成一个inc文件,并且这个inc文件的内容是我们可以控制的,因此只需要再找一个include了这个inc文件的地方,便可以完成攻击。

全局搜索了下这个文件,发现就在同一个php文件的下面,因此利用条件就全部齐了,可以开始构造写入的语句了。

观察逻辑,代码会先从url中获取一个refiles参数,并且refiles作为数组参数,被写入inc文件。而紧接的foreach语句其实重点就只是一个replace,只要绕过去就好了。最后的payload大概如下:

此时写入shell成功,触发shell:
);

 

任意代码执行了

 

 

第二个的思路比第一个稍微绕一点,但也只是绕的有限。

漏洞代码在/dede/sys_cache_up.php处 36行处:

else if($step == 2){    include_once(DEDEINC."/enums.func.php");    WriteEnumsCache();    //WriteAreaCache(); 已过期 ShowMsg("成功更新枚举缓存,准备更新调用缓存...", "sys_cache_up.php?dopost=ok&step=3&uparc=$uparc"); exit(); } 跟进WrtieEnumsCache(): function WriteEnumsCache($egroup='') { global $dsql; $egroups = array(); if($egroup=='') { $dsql->SetQuery("SELECT egroup FROM `#@__sys_enum` GROUP BY egroup "); } else { $dsql->SetQuery("SELECT egroup FROM `#@__sys_enum` WHERE egroup='$egroup' GROUP BY egroup "); } $dsql->Execute('enum'); while($nrow = $dsql->GetArray('enum')) { $egroups[] = $nrow['egroup']; } foreach($egroups as $egroup) { $cachefile = DEDEDATA.'/enums/'.$egroup.'.php'; $fp = fopen($cachefile,'w'); fwrite($fp,'<'."?php\r\nglobal \$em_{$egroup}s;\r\n\$em_{$egroup}s = array();\r\n"); $dsql->SetQuery("SELECT ename,evalue,issign FROM `#@__sys_enum` WHERE egroup='$egroup' ORDER BY disorder ASC, evalue ASC "); $dsql->Execute('enum'); $issign = -1; $tenum = false; //三级联动标识 while($nrow = $dsql->GetArray('enum')) { fwrite($fp,"\$em_{$egroup}s['{$nrow['evalue']}'] = '{$nrow['ename']}';\r\n"); if($issign==-1) $issign = $nrow['issign']; if($nrow['issign']==2) $tenum = true; } if ($tenum) $dsql->ExecuteNoneQuery("UPDATE `#@__stepselect` SET `issign`=2 WHERE egroup='$egroup'; "); fwrite($fp,'?'.'>'); fclose($fp); if(empty($issign)) WriteEnumsJs($egroup); } return '成功更新所有枚举缓存!'; }

可以看到有文件读写操作,但是文件内容是从数据库取值的,因此需要先往数据库里写入内容,同时,因为没有任何过滤,因此操作难度降低了许多。找到的写数据库的位置在:

dede/stepselect_main.php:

else if($action=='addenum_save'){    if(empty($ename) || empty($egroup))     {         Showmsg("类别名称或组名称不能为空!","-1"); exit(); } if($issign == 1 || $topvalue == 0) $enames = explode(',', $ename); foreach($enames as $ename){ $arr = $dsql->GetOne("SELECT * FROM `#@__sys_enum` WHERE egroup='$egroup' AND (evalue MOD 500)=0 ORDER BY disorder DESC "); if(!is_array($arr)) $disorder = $evalue = ($issign==1 ? 1 : 500); else $disorder = $evalue = $arr['disorder'] + ($issign==1 ? 1 : 500); $dsql->ExecuteNoneQuery("INSERT INTO `#@__sys_enum`(`ename`,`evalue`,`egroup`,`disorder`,`issign`) VALUES('$ename','$evalue','$egroup','$disorder','$issign'); "); } echo "INSERT INTO `#@__sys_enum`(`ename`,`evalue`,`egroup`,`disorder`,`issign`) VALUES('$ename','$evalue','$egroup','$disorder','$issign'); "; die(); WriteEnumsCache($egroup); ShowMsg("成功添加枚举分类!".$dsql->GetError(), $ENV_GOBACK_URL); exit(); }

因此传入如下url:

然后被写入了数据库,此时直接查询,便可以写入文件,写文件url如下:

转载于:https://www.cnblogs.com/WhiteHatKevil/p/10226726.html

你可能感兴趣的文章
oracle查看经常使用的系统信息
查看>>
Django_4_视图
查看>>
Linux的netstat命令使用
查看>>
lvm讲解,磁盘故障小案例
查看>>
大快网站:如何选择正确的hadoop版本
查看>>
经过这5大阶段,你离Java程序员就不远了!
查看>>
IntelliJ IDEA 连接数据库详细过程
查看>>
thymeleaf 学习笔记-基础篇
查看>>
PHP-X开发扩展
查看>>
android学习笔记——onSaveInstanceState的使用
查看>>
工作中如何做好技术积累
查看>>
怎么用sysLinux做U盘双PE+DOS??
查看>>
Spring Transactional
查看>>
shell脚本实例
查看>>
我的友情链接
查看>>
Windows Phone 7 隔离存储空间资源管理器
查看>>
Microsoft Excel 2000/2003修复工具
查看>>
apache安装报错undefined reference ssl
查看>>
关于爱情只有一句忠告
查看>>
CentOS LVM 新加硬盘,扩容逻辑卷步骤
查看>>