提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
文章目录
Web93
还是老样子,先看代码:
php
<?php
include("flag.php");
highlight_file(__FILE__);
if(isset($_GET['num'])){
$num = $_GET['num'];
if($num==4476){
die("no no no!");
}
if(preg_match("/[a-z]/i", $num)){
die("no no no!");
}
if(intval($num,0)==4476){
echo $flag;
}else{
echo intval($num,0);
}
}
这个代码的作用很明显
preg_match("/[a-z]/i", $num)
:过滤所有的字母,不分大小写;这说明之前的八进制,十六进制等方式是不是就不管用了?if(intval($num, 0)===4476)
: 这是第二个关键点,也是漏洞所在- intval(num, 0) 函数会尝试将 num 转换为一个整数
- 0x 开头会被识别为十六进制。
- 0b 开头会被识别为二进制。
- 0 开头会被识别为八进制。
既然不给出现字母,那我们直接纯数字不就好了:
第一个payload肯定是八进制:?num=010574
有关这个函数intval(str,int)
的讲解:
- PHP 的 intval 函数会从字符串的开始部分提取有效数值,直到遇到非数字字符就停止了
- payload:
?num=4476.1
所以payload:

bash
# payload
?num=010574 # 进制绕过
?num=4476.1 # 小数点取整
--
Web94
php
<?php
include("flag.php");
highlight_file(__FILE__);
if(isset($_GET['num'])){
$num = $_GET['num'];
if($num==="4476"){
die("no no no!");
}
if(preg_match("/[a-z]/i", $num)){
die("no no no!");
}
if(!strpos($num, "0")){
die("no no no!");
}
if(intval($num,0)===4476){
echo $flag;
}
}
代码分析:
-
if($num==="4476")
:这是一个严格比较。它检查你的输入是否值和类型都等于字符串 "4476"。为了绕过它,你不能直接输入 ?num=4476。 -
if(preg_match("/[a-z]/i", $num))
:这个过滤器使用正则表达式来检查你的输入中是否包含任何字母(不区分大小写)。这限制了你不能使用类似"0x117c"
这样的十六进制表示,因为其中包含了字母 c。 -
if(!strpos($num, "0"))
:strpos() 函数查找字符串中第一次出现 "0" 的位置。- 如果找到了,它会返回一个非布尔 false 的值(即 0 或更大),!strpos() 的结果就是 false。
- 如果没找到 "0",它会返回布尔 false,!strpos() 的结果就是 true,从而触发 die()。这意味着你的输入中必须包含数字 0,但开头不能是0。
-
if(intval($num, 0)===4476)
:这是触发漏洞的核心条件。intval() 函数会根据第二个参数 0(自动识别进制)将你的输入转换为一个整数。为了获取 flag,转换后的值必须严格等于 4476。
漏洞利用
要成功获取 flag,你需要找到一个输入,它能同时满足所有四个条件:
- 不等于字符串 "4476"。
- 不包含任何字母。
- 开头不能为0,必须包含数字 0。
- 被 intval() 转换为整数后,等于 4476。
这答案不是呼之欲出了吗,八进制出来吧:
在8进制010574的基础上,增加一个空格即可绕过 Payload:?num=%20010574
bash
# payload
?num= 010574
?num=+010574
# 小数点取整
?num=4476.0
# 也可以使用换行,0是为了匹配strpos() 函数函数
?num=4476%0a0
Web95
php
<?php
include("flag.php");
highlight_file(__FILE__);
if(isset($_GET['num'])){
$num = $_GET['num'];
if($num==4476){
die("no no no!");
}
if(preg_match("/[a-z]|\./i", $num)){
die("no no no!!");
}
if(!strpos($num, "0")){
die("no no no!!!");
}
if(intval($num,0)===4476){
echo $flag;
}
}
老样子,先分析代码:
preg_match("/[a-z]|\./i"
:增加了个条件
- 多了对
.
的过滤,说明小数点取整的方法不可取 - payload:
4476%0a0
则被过滤了- 在弱类型比较中,PHP 会解析 "4476\n0",发现它以数字开头,因此将其转换为 4476
那payload也没有太大的区别:
bash
# payload
?num= 010574
?num=+010574

Web96(新题型)
php
<?php
highlight_file(__FILE__);
if(isset($_GET['u'])){
if($_GET['u']=='flag.php'){
die("no no no");
}else{
highlight_file($_GET['u']);
}
}
代码分析我相信大家都看得懂,所以这里就不赘述了,直接说说解题思路:
- 要绕过这个限制并读取 flag.php 的内容,就要让你的输入字符串不等于 flag.php,但最终指向的仍然是 flag.php 文件
所以我尝试了一下几种办法:
-
大小写绕过:如果文件系统不区分大小写(例如 Windows),你可以尝试使用大小写混合的字符串。
-
Payload:?u=FlAg.pHp
-
解释:
FlAg.pHp
不等于 flag.php,所以可以绕过第一层检查。如果服务器文件系统不区分大小写,highlight_file() 依然能找到并读取 flag.php。
-
-
URL 编码:你可以对部分字符进行 URL 编码。
-
Payload:?u=fl%61g.php
-
解释:
fl%61g.php
在 URL 传输过程中不会被解析,但在 PHP 内部,%61
会被解码为 a,最终文件路径仍然是 flag.php。
-
-
路径绕过:你可以使用相对路径或目录跳转来绕过。
-
Payload:?u=./flag.php 或 ?u=.../html/flag.php
-
解释:./ 表示当前目录。./flag.php 不等于 flag.php,但它指向同一个文件。如果 flag.php 在 /html 目录下,.../html/flag.php 也可以绕过。
-
-
PHP 伪协议 :利用
php://filter
伪协议对文件进行编码,这样就不会直接匹配到flag.php
。-
Payload:?u=php://filter/read=convert.base64-encode/resource=flag.php
-
解释:这个 Payload 会告诉 PHP 读取 flag.php 的内容,并用 Base64 编码,然后输出。编码后的字符串不会是 flag.php,但你可以将输出结果解码来获取 flag。
-
这里尝试了下,只有路径绕过和PHP伪协议才能得到flag:

bash
# payload
?u=./flag.php
?u=php://filter/read=convert.base64-encode/resource=flag.php
好了,得到flag的过程暂时到此为止。接下来要是想更深入了解一点的话,可以往下看。
PHP伪协议绕过的解释:
php://filter
协议之所以能绕过 if($_GET['u']=='flag.php')
的检查,是因为它的工作原理和 PHP 内部的文件处理机制:
- 处理流程:
-
PHP 识别到
php://filter
协议,知道它是一个过滤器。 -
它接收到你的请求参数
$_GET['u']
,其值是完整的字符串php://filter/read=convert.base64-encode/resource=flag.php
。 -
这个字符串不等于 flag.php,所以它顺利通过了 if($_GET['u']=='flag.php') 的检查。
-
然后,highlight_file() 函数被调用,并传入了完整的
php://filter
路径。 -
highlight_file()
内部会向这个路径发起一个文件读取请求。 -
PHP 的文件系统层接收到这个请求后,会启动 php://filter 过滤器。
-
过滤器会按照请求中的指令工作:它会去读取
resource=flag.php
指定的文件内容,然后用convert.base64-encode
对文件内容进行 Base64 编码。 -
最终,highlight_file() 收到的是编码后的数据流,而不是 flag.php 的原始内容。
-
highlight_file()
随后将这串 Base64 编码的文本高亮显示到页面上。
总结
此次PHP特性,也是让我遇到了很多新的方法,多学习多总结。