漏洞文件:
/phpcms/modules/block/block_admin.php
public function public_view() {
$id = isset($_GET['id']) && intval($_GET['id']) ? intval($_GET['id']) : exit('0');
if (!$data = $this->db->get_one(array('id'=>$id))) {
showmessage(L('nofound'));
}
if ($data['type'] == 1) {
exit('<script type="text/javascript">parent.showblock('.$id.', ÿcf4 .str_replace("", '', $_POST['data']).'ÿ/script>');
} elseif ($data['type'] == 2) {
extract($data);
unset($data);
$title = isset($_POST['title']) ? $_POST['title'] : '';
$url = isset($_POST['url']) ? $_POST['url'] : '';
$thumb = isset($_POST['thumb']) ? $_POST['thumb'] : '';
$desc = isset($_POST['desc']) ? $_POST['desc'] : '';
$template = isset($_POST['template']) && trim($_POST['template']) ? trim($_POST['template']) : '';
$data = array();
foreach ($title as $key=>$v) {
if (empty($v) || !isset($url[$key]) ||empty($url[$key])) continue;
$data[$key] = array('title'=>$v, 'url'=>$url[$key], 'thumb'=>$thumb[$key], 'desc'=>str_replace(array(chr(13), chr(43)), array('<br />', ' '), $desc[$key]));
}
$tpl = pc_base::load_sys_class('template_cache');
echo $template;
$str = $tpl->template_parse(new_stripslashes($template));
$filepath = CACHE_PATH.'caches_template'.DIRECTORY_SEPARATOR.'block'.DIRECTORY_SEPARATOR.'tmp_'.$id.'.php';
$dir = dirname($filepath);
if(!is_dir($dir)) {
@mkdir($dir, 0777, true);
}
if (@file_put_contents($filepath,$str)) {
ob_start();
include $filepath;
$html = ob_get_contents();
ob_clean();
@unlink($filepath);
}
exit('<script type="text/javascript">parent.showblock('.$id.', ÿcf4 .str_replace("", '', $html).'ÿ/script>');
}
}
首先可以看见最后有一个file_put,$filepath是生成的php文件所以不用担心了,然后看str的内容由来。
$str = $tpl->template_parse(new_stripslashes($template));
这里的$template是post传入的内容,先跟入new_strip
function new_stripslashes($string) {
if(!is_array($string)) return stripslashes($string);
foreach($string as $key => $val) $string[$key] = new_stripslashes($val);
return $string;
}
简单的理解就是处理内容的字符串然后接着看下一个函数
public function template_parse($str) {
$str = preg_replace ( "/\template+(.+)\/", "<?php include template(\1); ?>", $str );
$str = preg_replace ( "/\include+(.+)\/", "<?php include \1; ?>", $str );
$str = preg_replace ( "/\php+(.+)\/", "<?php \1?>", $str );
$str = preg_replace ( "/\if+(.+?)\/", "<?php if(\1) { ?>", $str );
$str = preg_replace ( "/\else\/", "<?php } else { ?>", $str );
$str = preg_replace ( "/\elseif+(.+?)\/", "<?php } elseif (\1) { ?>", $str );
$str = preg_replace ( "/\\/", "<?php } ?>", $str );
//for Ñ-»·
$str = preg_replace("/\for+(.+?)\/","<?php for(\1) { ?>",$str);
$str = preg_replace("/\\/","<?php } ?>",$str);
//++ --
$str = preg_replace("/\+(.+?)\/","<?php ++\1; ?>",$str);
$str = preg_replace("/\-(.+?)\/","<?php ++\1; ?>",$str);
$str = preg_replace("/\(.+?)++\/","<?php \1++; ?>",$str);
$str = preg_replace("/\(.+?)--\/","<?php \1--; ?>",$str);
$str = preg_replace ( "/\loop+(S+)+(S+)\/", "<?php $n=1;if(is_array(\1)) foreach(\1 AS \2) { ?>", $str );
$str = preg_replace ( "/\loop+(S+)+(S+)+(S+)\/", "<?php $n=1; if(is_array(\1)) foreach(\1 AS \2 => \3) { ?>", $str );
$str = preg_replace ( "/\\/", "<?php $n++;}unset($n); ?>", $str );
$str = preg_replace ( "/\([a-zA-Z_f-][a-zA-Z0-9_f-:]*(([^{}]*)))\/", "<?php echo \1;?>", $str );
$str = preg_replace ( "/\\$([a-zA-Z_f-][a-zA-Z0-9_f-:]*(([^{}]*)))\/", "<?php echo \1;?>", $str );
$str = preg_replace ( "/\(\$[a-zA-Z_f-][a-zA-Z0-9_f-]*)\/", "<?php echo \1;?>", $str );
$str = preg_replace_callback("/\(\$[a-zA-Z0-9_[]ÿ$f-]+)\/s", array($this, 'addquote'),$str);
$str = preg_replace ( "/\([A-Z_f-][A-Z0-9_f-]*)\/s", "<?php echo \1;?>", $str );
$str = preg_replace_callback("/\pc:(+)+([^}]+)\/i", array($this, 'pc_tag_callback'), $str);
$str = preg_replace_callback("/\\/i", array($this, 'end_pc_tag'), $str);
$str = "<?php defined('IN_PHPCMS') or exit('No permission resources.'); ?>" . $str;
return $str;
}
这个就稍微有点意思了!是正则替换str中的内容。 |