漏洞详情:
if($operation == 'uc' && is_writeable('./config.inc.php') && $isfounder) {
$ucdbpassnew = $settingsnew['uc']['dbpass'] == '********' ? UC_DBPW : $settingsnew['uc']['dbpass'];
if($settingsnew['uc']['connect']) {
$uc_dblink = @mysql_connect($settingsnew['uc']['dbhost'], $settingsnew['uc']['dbuser'], $ucdbpassnew, 1);
if(!$uc_dblink) {
cpmsg('uc_database_connect_error', '', 'error');
} else {
mysql_close($uc_dblink);
}
}
$fp = fopen('./config.inc.php', 'r');
$configfile = fread($fp, filesize('./config.inc.php'));
$configfile = trim($configfile);
$configfile = substr($configfile, -2) == '?>' ? substr($configfile, 0, -2) : $configfile;
fclose($fp);
$connect = '';
if($settingsnew['uc']['connect']) {
require './config.inc.php';
$connect = 'mysql';
$samelink = ($dbhost == $settingsnew['uc']['dbhost'] && $dbuser == $settingsnew['uc']['dbuser'] && $dbpw == $ucdbpassnew);
$samecharset = !($dbcharset == 'gbk' && UC_DBCHARSET == 'latin1' || $dbcharset == 'latin1' && UC_DBCHARSET == 'gbk');
$configfile = insertconfig($configfile, "/define/ ('UC_DBHOST',/s*'.*?'/);/i", "define('UC_DBHOST', '".$settingsnew['uc'] ['dbhost']."');");//正则表示从'到')中的被替换,而')可以被任意提交,from oldjun.com
$configfile = insertconfig($configfile, "/define/('UC_DBUSER',/s*'.*?'/);/i", "define('UC_DBUSER', '".$settingsnew['uc']['dbuser']."');");
$configfile = insertconfig($configfile, "/define/('UC_DBPW',/s*'.*?'/);/i", "define('UC_DBPW', '".$ucdbpassnew."');");
$configfile = insertconfig($configfile, "/define/('UC_DBNAME',/s*'.*?'/);/i", "define('UC_DBNAME', '".$settingsnew['uc']['dbname']."');");
$configfile = insertconfig($configfile, "/define/('UC_DBTABLEPRE',/s*'.*?'/);/i", "define('UC_DBTABLEPRE', '`".$settingsnew['uc']['dbname'].'`.'.$settingsnew['uc']['dbtablepre']."');");
//$configfile = insertconfig($configfile, "/define/('UC_LINK',/s*'?.*?'?/);/i", "define('UC_LINK', ".($samelink && $samecharset ? 'TRUE' : 'FALSE').");");
}
$configfile = insertconfig($configfile, "/define/('UC_CONNECT',/s*'.*?'/);/i", "define('UC_CONNECT', '$connect');");
$configfile = insertconfig($configfile, "/define/('UC_KEY',/s*'.*?'/);/i", "define('UC_KEY', '".$settingsnew['uc']['key']."');");
$configfile = insertconfig($configfile, "/define/('UC_API',/s*'.*?'/);/i", "define('UC_API', '".$settingsnew['uc']['api']."');");
$configfile = insertconfig($configfile, "/define/('UC_IP',/s*'.*?'/);/i", "define('UC_IP', '".$settingsnew['uc']['ip']."');");
$configfile = insertconfig($configfile, "/define/('UC_APPID',/s*'?.*?'?/);/i", "define('UC_APPID', '".$settingsnew['uc']['appid']."');");
$fp = fopen('./config.inc.php', 'w');
if(!($fp = @fopen('./config.inc.php', 'w'))) {
cpmsg('uc_config_write_error', '', 'error');
}
@fwrite($fp, trim($configfile));
@fclose($fp);
}
settings.inc.php对提交的数据缺乏有效过滤,导致可以写入')污染配置文件的数据,而insertconfig函数的正则匹配无法正确匹配到最后,导致可以经过2次输入可以成功绕过daddslashes把shell写进配置文件。
function insertconfig($s, $find, $replace) {
if(preg_match($find, $s)) {
$s = preg_replace($find, $replace, $s); //正则匹配替换数据
} else {
$s .= "/r/n".$replace;
}
return $s;
}