boblog任意变量覆盖漏洞
漏洞代码如下:
// go.php
$q_url=$_server["request_uri"];
@list($relativepath, $rawurl)=@explode('/go.php/', $q_url);
$rewritedurl=$rawurl; // 来自$_server["request_uri"],可以任意提交的:)
...
$rewriterules[]="/component/([^/]+)/?/";
// 这个正则限制的不够细致,可以很轻易的绕过:)
...
$redirectto[]="page.php?pagealias=\1";
$i=0;
foreach ($rewriterules as $rule) {
if (preg_match($rule, $rewritedurl)) {
$tmp_rewritedurl=preg_replace($rule, '<'.$redirectto[$i].'<', $rewritedurl, 1);
$tmp_rewritedurl=@explode('<', $tmp_rewritedurl);
$rewritedurl=($tmp_rewritedurl[2]) ? false : $tmp_rewritedurl[1];
break;
}
$i+=1;
}
if ($rewritedurl==$rawurl || !$rewritedurl) {
...
$parsedurl=parse_url ($rewritedurl);
// 这里的$parsedurl['query']就是要利用的变量了:)
parse_str($parsedurl['query']);
// 通过这个地方可以覆盖任意变量
include(basename($parsedurl['path']));
// 通过上面的覆盖,可以利用这里包含本地文件,不过用了basename()函数处理:(
这个漏洞不是很复杂,关键说说利用,这里有两个利用点,一个覆盖,一个利用覆盖来包含,虽然用了basename()来限制,但是可以利用data://来执行命令.只是这种方式的利用是有限制的[php>5.2.0&allow_url_include=on].不过没关系,还有更好的利用方式
来看下global.php文件:
...
unregister_globals(); //when register_globals=on
...
function unregister_globals() { //when register_globals = 'on'
if (!ini_get('register_globals')) { //already off
return;
}
// variables that shouldn't be unset
$nounset = array('_get', '_post', '_cookie', '_request', '_server', '_env', '_files');
$input = array_merge($_get, $_post, $_cookie, $_server, $_env, $_files, isset($_session) && is_array($_session) ? $_session : array());
foreach ($input as $k => $v) {
if ($k=='globals') {
global $kgr;
$kgr=0;
kill_globals($input[$k]); //globals is recursive -,-
}
elseif (!in_array($k, $nounset) && isset($globals[$k])) {
$globals[$k]=null;
}
}
}
在这里取消了全局变量,但是我们可以通过go.php中的覆盖变量和包含文件来绕过unregister_globals()的限制,触发变量未初始化漏洞,这将导致xss、sql注射、命令执行等众多严重的安全问题。
上一篇: 电商运营经验贴:从用户拉新 商品选择入手