0


php特性之intval学习小记

前言

文章同步我的个人博客http://www.quan9i.top/,欢迎大家访问。
php特性的intval是一个比较常见的漏洞,今天就来比较全面的学习这个函数,将其简单的利用方式总结一下

函数学习

学习函数最好的方式就是去学习官方的,这样学习得到的收获更多一些,这里我们先来看一下这个函数定义

intval — 获取变量的整数值

而它的具体格式和解释如下

intintval(var,base)//var指要转换成 integer 的数量值,base指转化所使用的进制 
Note: 
如果 base 是 0,通过检测 var 的格式来决定使用的进制: 
◦ 如果字符串包括了 "0x"(或 "0X") 的前缀,使用 16 进制 (hex);否则,  
◦ 如果字符串以 "0" 开始,使用 8 进制(octal);否则,  
◦ 将使用 10 进制 (decimal)。 

这里这个Note对我们来说就尤为重要了,没有声明base参数时,字符串首字母是0则视为8进制,是0X则视为16进制,具体可以看官方给出的例子

<?phpechointval(042);// 34echointval(0x1A);// 2?>

此时就可以看出它的一个利用方式了,当过滤某个数字时,我们可以利用它的进制转换来绕过。
此时再往下看

返回值 
成功时返回 var 的 integer 值,失败时返回 0。空的 array 返回 0,非空的 array 
返回 1。 

这时候就可以看出另一个利用方式了,如果是一个弱比较

a==b

我们输入

a[]=1

b[]=2

,此时这两个是不同的,但还都会返回1,此时也就实现了一种绕过,这是第二种绕过思路。
此时官方还给出了其他示例,我们再看

echointval(42);// 42echointval(4.2);// 4

我们可以发现小数点后的数字会直接舍去,所以这可以作为第三种,当过滤4的时候,我们可以输入4.2来绕过
然后呢,我们还发现例子里有

1e

这种格式的,

echointval(1e10);// 1410065408echointval('1e10');// 1

这个呢我们发现单引号传值的时候,它只识别字母前面的一部分,当我们进行get传参时,我们其实就是默认加单引号的,所以这又是一种绕过方式。
还有说一下这里不是必须是e,这里只要是字母就可以
在这里插入图片描述

实战

0X01

<?phpinclude("flag.php");highlight_file(__FILE__);if(isset($_GET['num'])){$num=$_GET['num'];if(preg_match("/[0-9]/",$num)){die("no no no!");}if(intval($num)){echo$flag;}}?>

看见这题我的思路就是用数组绕过,可能是因为之前md5()的时候强比较看习惯了,这里构造payload如下即可

num[]=1

在这里插入图片描述

0X02

include("flag.php");highlight_file(__FILE__);if(isset($_GET['num'])){$num=$_GET['num'];if($num==="4476"){die("no no no!");}if(intval($num,0)===4476){echo$flag;}else{echointval($num,0);}}

这关的话就是要求变量值不能为4476,但用过intval函数后为4476,这里的话我们首先需要知道intval的第二个参数为0时的意思是什么

intintval(var,base)
Note: 
如果 base 是 0,通过检测 var 的格式来决定使用的进制: 
◦ 如果字符串包括了 "0x"(或 "0X") 的前缀,使用 16 进制 (hex);否则,  
◦ 如果字符串以 "0" 开始,使用 8 进制(octal);否则,  
◦ 将使用 10 进制 (decimal)。 

此时的话我们再看一下在这个函数的运算
在这里插入图片描述
看到这里的话就可以看出payload就有多种构造方法了

num=4476e123//这里就跟上面那个单引号的1e10情况一样,此时只看字母前面的
num=4476.1//计算int值时,后面有小数点会直接舍去
num=0x117c//0x表明是十六进制数,117c是4476的十六进制数
num=010574//0表明是八进制数,10574是4476的八进制数

测试如下
在这里插入图片描述
执行结果如下
在这里插入图片描述

0X03

include("flag.php");highlight_file(__FILE__);if(isset($_GET['num'])){$num=$_GET['num'];if($num==4476){die("no no no!");}if(intval($num,0)==4476){echo$flag;}else{echointval($num,0);}}

这里的话就是从强比较换成了弱比较,用之前的解题payload即可

num=4476.1

0X04

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;}}?>

这道题的话看着几乎是防死了,多过滤了

.

,这就意味着小数点绕过行不通,此时我们看到这个i修饰符,想到那个m修饰符,此时就想起来有个换行符%0a,它对实际输出没影响,它还可以绕过上面的那些函数,因此我们这里构造如下语句,就实现了绕过,由于小数点不能用,这里就用八进制

num=%0a010574

在这里插入图片描述

标签: php 学习 web安全

本文转载自: https://blog.csdn.net/Reme_mber/article/details/124781330
版权归原作者 quan9i 所有, 如有侵权,请联系我们删除。

“php特性之intval学习小记”的评论:

还没有评论