打开靶场
![](https://i-blog.csdnimg.cn/direct/171990997e06456285c9267103f8a1fe.png)
查看源代码
![](https://i-blog.csdnimg.cn/direct/09676c961b334e95a8361538215dce00.png)
// 为 ID 为 calc 的表单的 submit 事件绑定一个处理函数
$('#calc').submit(function(){
// 使用 jQuery 的 $.ajax 方法发起一个 AJAX 请求
$.ajax({
// 请求的 URL,拼接了一个参数 num,其值是 ID 为 content 的输入框的值并进行了 URI 编码
url:"calc.php?num="+encodeURIComponent($("#content").val()),
// 请求的类型为 GET
type:'GET',
// 请求成功时的回调函数
success:function(data){
// 将返回的数据插入到 ID 为 result 的元素中,以一个带有成功提示样式的 HTML 结构呈现
$("#result").html(`<div class="alert alert-success">
<strong>答案:</strong>${data}
</div>`);
},
// 请求失败时的回调函数
error:function(){
// 弹出一个警告框提示请求失败
alert("这啥?算不来!");
}
});
// 阻止表单的默认提交行为
return false;
});
这段代码是用 jQuery 编写的,其主要功能是当 ID 为 calc
的表单被提交时,阻止表单的默认提交行为,然后通过 AJAX(异步的 JavaScript 和 XML)向 calc.php
发送一个 GET 请求。请求的参数 num
是 ID 为 content
的输入框中的值,并且对该值进行了 URI 编码处理。如果请求成功,会将返回的数据显示在 ID 为 result
的元素中,以一个带有成功提示样式的 HTML 结构呈现;如果请求失败,会弹出一个警告框提示 "这啥?算不来!"。
思路
注释<!--I've set up WAF to ensure security.-->,我以设置waf确保安全。说明要waf绕过。源代码里并没有给出过滤的规则,发现提到了calc.php文件,这个文件负责处理传进来的参数,所以我们尝试访问它。
WAF
WAF 即 Web 应用防火墙(Web Application Firewall)
- 防范常见攻击
- SQL 注入防护:通过对请求中的 SQL 语句进行分析,检测是否存在恶意的 SQL 注入代码,防止攻击者通过构造恶意的 SQL 语句来获取、篡改或删除数据库中的数据。
- 跨站脚本攻击(XSS)防护:识别请求中是否包含恶意的脚本代码,当用户访问受影响的页面时,这些脚本可能会在用户的浏览器中执行,从而窃取用户的敏感信息。
- 跨站请求伪造(CSRF)防护:验证请求的来源,确保请求是由合法的用户发起的,防止攻击者通过诱导用户在已登录的网站上执行恶意操作。
- 访问控制:可以根据 IP 地址、地理位置、用户代理等条件对访问进行控制。例如,禁止来自特定 IP 段的访问,或者只允许特定地区的用户访问某些资源。
- 流量监控和日志记录:对 Web 应用的访问流量进行实时监控,记录所有的请求和响应信息。这些日志可以用于安全审计、故障排查和攻击溯源。
![](https://i-blog.csdnimg.cn/direct/5ae6894800444310a44a0f5cdf005178.png)
php代码审计
1.错误报告设置:
error_reporting(0);
这行代码将 PHP 的错误报告级别设置为 0,意味着关闭所有的错误报告,这样在代码执行过程中出现的错误不会显示给用户。
2.参数检查与源码显示:
if(!isset($_GET['num'])){
show_source(__FILE__);
}
检查是否通过 GET 请求传递了 num
参数。如果没有传递,使用 show_source
函数显示当前 PHP 文件的源代码。
3.输入过滤与执行:
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.';');
}
如果传递了 num
参数,将其赋值给变量 $str
。
然后定义了一个黑名单数组 $blacklist
,包含了一些特殊字符。
通过 foreach
循环遍历黑名单,
使用 preg_match
函数检查 $str
中是否包含黑名单中的字符,
如果包含则终止程序并输出提示信息what are you want to do?。
如果 $str
不包含黑名单中的字符,使用 eval
函数执行 echo $str;
代码 ,将 $str
的内容输出。
函数
foreach
循环主要用于遍历数组或对象,为数组或对象中的每个元素执行一次循环体中的代码。
foreach
循环有两种基本语法形式:形式一:只获取数组的值
foreach ($array as $value) { // 循环体,使用 $value 进行操作 }
这里的
$array
是要遍历的数组,$value
是每次循环时从数组中取出的当前元素的值。形式二:同时获取数组的键和值
foreach ($array as $key => $value) { // 循环体,使用 $key 和 $value 进行操作 }
在这种形式中,
$key
是当前元素的键,$value
是当前元素的值。执行
foreach ($blacklist as $blackitem)
时,具体步骤如下:
- 从
$blacklist
数组中取出第一个元素。- 将该元素的值赋给变量
$blackitem
。- 执行循环体中的代码。
- 重复步骤 1 - 3,直到遍历完
$blacklist
数组中的所有元素。preg_match
用于执行正则表达式匹配的函数。
语法:preg_match(pattern, subject[, matches[, flags = 0[, offset = 0]]])
pattern :要匹配的正则表达式模式。
subject :要进行匹配操作的目标字符串。
matches :可选参数,用于存储匹配结果的数组。如果匹配成功, matches[0] 将包含完整的匹配文本, matches[1] 等将包含正则表达式中捕获组匹配的内容。
flags :可选参数,用于指定匹配的标志,常用的有 PREG_OFFSET_CAPTURE ,会使 matches 数组中的每个元素成为一个包含匹配文本和其在 subject 中偏移量的数组。
offset :可选参数,指定从 subject 字符串的哪个位置开始匹配,默认为0。
eval()
作用是把字符串作为 PHP 代码来执行。
eval(string $code);
$code
:这是一个必需的参数,代表要被执行的 PHP 代码字符串。该字符串必须是合法的 PHP 代码,并且通常需要以分号;
结尾,否则可能会导致语法错误。- 函数返回值:如果代码字符串执行过程中没有错误,
eval()
函数返回NULL
;如果执行过程中出现错误,则返回false
。
代码注入风险 :由于 eval
函数会执行任意的 PHP 代码,攻击者可以通过构造恶意的 num
参数来执行任意代码,例如执行系统命令、读取敏感文件等。虽然代码中设置了黑名单,但攻击者仍然可能通过绕过黑名单的方式注入恶意代码。
RCE
即远程命令 / 代码执行,是一种严重的网络安全漏洞。
RCE 漏洞通常源于应用程序对用户输入的验证和过滤不严格,使得攻击者可以通过构造恶意输入,绕过应用程序的安全机制,将恶意命令或代码注入到目标系统并执行。常见的触发方式有以下几种:
- 代码注入 :当应用程序使用动态代码执行函数(如 PHP 的
eval()
、Python 的exec()
等)处理用户输入时,如果没有对输入进行严格的验证和过滤,攻击者就可以注入恶意代码并让系统执行。- 命令注入:应用程序在执行系统命令时,如果将用户输入直接拼接到命令中,而没有进行适当的处理,攻击者就可以构造恶意输入来执行额外的命令。
做题步骤
1.waf绕过
经过简单的测试,会发现如果输字符字符会直接WAF禁止,用php字符串解析特性,在num
前面加上空格
或者+号。
calc.php?num=system('ls');
![](https://i-blog.csdnimg.cn/direct/d9a0cafdafea4b459c3b849ba82539a5.png)
calc.php? num=system('ls');
![](https://i-blog.csdnimg.cn/direct/dd70ab11c9f64056b5ce70ec6dc592e6.png)
服务器会认为传入的参数是 空格num ,而不是 num 。当 空格num 参数传入到后端,被 PHP 代码处理时,会被去除多余空格及特殊字符:如空格、制表符、回车换行符以及某些特殊字符等。这样一来仍然是 num 参数了。
php参数的字符串解析特性:
在php中传参时,PHP需要将所有参数转换为有效的变量名,因此在解析查询字符串时,它会做两件事:删除空白符和将某些字符转换为下划线(包括空格)
2.构造命令查看
显示用var_dump()或print_r()
都行,
当前目录用scandir
,
屏蔽的/
可以用chr(47)
calc.php? num=print_r(scandir(chr(47)))
print_r()
函数用于以人类可读的格式输出变量。对于数组和对象,它会递归地显示其结构和元素;对于其他类型的变量,它会直接显示其值。
chr()
函数把 ASCII 码值转换为对应的字符。码值 47 对应的字符是斜杠/
scandir()
用于列出指定目录中的文件和目录
![](https://i-blog.csdnimg.cn/direct/144b1c01d9454c0088640a55792af911.png)
发现疑似文件f1agg
查看文件用file_get_content()
或者highlight_file()
都行
? num=file_get_contents(chr(47).chr(102).chr(49).chr(97).chr(103).chr(103));
其中chr(47).chr(102).chr(49).chr(97).chr(103).chr(103)分别是 '/' 'f' '1' 'a' 'g' 'g' 的 ASCII 值转字符,'.' 用作字符串连接。每一个 chr() 函数返回的结果由于是字符,所以自带了一对引号,不需要额外再加。
![](https://i-blog.csdnimg.cn/direct/34fc63b1074b4e01b84ef598e7c20cc1.png)
![](https://i-blog.csdnimg.cn/direct/27b0a7b86c2045a087f6ac9fabb6dd6f.png)
highligh_file
函数会读取指定文件的内容,将其中的关键字用黄色背景的 <span>
标签包裹,实现高亮显示,并将结果输出。
页面源码高亮
![](https://i-blog.csdnimg.cn/direct/c04e73d9359e41d1b7c094490eeb5ccc.png)