cyask会将参数设置写入cache,写cache的时候从数据库取出未过滤的数据直接写文件,导致可以拿webshell
分析:
admin/setting_manage.php文件: <?php admin_footer(); exit(); } elseif($admin_action=='setting_edit') { if(isset($_POST['edit_submit'])) { $query=$dblink->query("SELECT * FROM {$tablepre}set WHERE T in('str','num')"); while($row=$dblink->fetch_array($query)) { $dblink->query("UPDATE {$tablepre}set SET V='".$_POST[$row[K]]."' WHERE K='".$row[K]."'"); //将设置写入数据库,未过滤by unknownman } create_cache('variable');//写cache by unknownman header("location:admin.php?admin_action=var_setting"); } else { $query=$dblink->query("SELECT * FROM {$tablepre}set WHERE T in('str','num') order by T"); admin_header(); ?> create_cache函数位于include/global.func.php: function create_cache($cachename) { global $dblink,$tablepre; $prefix='cache_'; $cachedata = ''; if($cachename=='variable') { $query = $dblink->query("SELECT * FROM {$tablepre}set WHERE T in ('str','num')");//从数据库取出设置 by unknownman $cachedata.=""; while($row = $dblink->fetch_array($query)) { if($row['T']=='str') { $cachedata.="\$".$row['K']." = '".$row['V']."';\n"; //字符串未过滤 by unknownman } elseif($row['T']=='num') { $cachedata.="\$".$row['K']." = ".intval($row['V']).";\n"; //数值参数简单过滤 by unknownman } } } elseif($cachename=='style') { $query = $dblink->query("SELECT templateid,name,tpldir,styledir FROM {$tablepre}tpl ORDER BY templateid"); $num=$dblink->num_rows($query); $cachedata.="\$_DCACHE['style'] = array("."\n"; $i=1; while($row = $dblink->fetch_array($query)) { $cachedata.=$row['templateid']." => array("."\n"; foreach($row as $key => $val) { //$val=addslashes($val); if($key=='styledir') $cachedata .= "'$key' => '$val'"."\n"; else $cachedata .= "'$key' => '$val',"."\n"; } if($i==$num) $cachedata .=")\n"; else $cachedata .="),\n"; $i++; } $cachedata .=");\n"; } else { exit('cachename error !'); } $dir = CYASK_ROOT.'./askdata/cache/'; if(!is_dir($dir)) { @mkdir($dir, 0777); } if(@$fp = fopen("$dir$prefix$cachename.php", 'w')) //写php文件 by unknownman { fwrite($fp, "<?php\n//Cyask cache file\n//Created on ".date("Y-m-d H:i:s")."\n\n$cachedata?>");//写的php文件本身也未安全设置,任何人都能访问 by unknownman fclose($fp); } else { exit('Can not write to cache files, please check directory ./askdata/ and ./askdata/cache/ .'); } }
阅读全文……