ctfshow web入门 php特性 89-95

89 - 95 利用 intval() 函数漏洞,php 弱语言特点绕过正则表达式获取flag

重点

  了解 intval()、grep_match() 函数缺点

  了解变量类型转换(php弱语言特点

  了解正则表达式

  了解 == 与 === 区别

 

web 89

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

要求:1、$num 不允许出现数字

     2、intval($num) 非0 ,要求 $num 不能是 非数字开头的且数字不能全为0 的字符串 

                

     3、 存在 die() 函数,在 preg_match() 正则匹配成功时执行,后续程序将忽略不执行,因此需要对 preg_match() 正则匹配绕过

知识点

  1、intval()

    intval() 是变量类型转化函数,php有8种变量类型

    其中 intval() 函数

      转化 string(非数字开头的且数字不能全为0的字符串)、array(空)、bool(false)、NULL 类型变量时,值为 0

      转化 bool(true)、array(非空)、object 类型变量时,值为 1

      转化 int、float、string(数字开头的字符串)类型变量时,值为其整数部分的数字

  2、preg_match()

    正则表达式

    可以匹配 int、float、str、bool

    不能匹配 array、object、NULL

 

payload

num[]=1    //将 num 类型改变成array

理论上 num=['w'] ,也符合本题,至少在我本地环境中,是可以成功获取flag的

 

web90

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

要求:num 值不能之间等于4476,需经过 intval() 函数转换过后的 数值、类型 与4476相同

知识点

  1、intval() 函数参数

intval($var,$base)
// $var 指定转化成 int 的数量值,$base 转化所用的进制
如果 $base 为 0 ,则通过 $var 的格式决定
    若字符串包含 0x,则使用 16 进制
    若字符串包含 0,则使用 8 进制
    其余默认十进制

  2、比较运算符

    === 表示全等运算符,要求值相同,类型相同

    == 表示等于运算符,要求值相同(会进行临时的类型转化弱比较

      由于 == 会临时转换数据类型,因此 === 操作比 == 操作快

  3、php 弱语言特性

    当执行关系运算符 == 时,要求运算符两边的数据类型必须一致,因此会被临时强制转化成整形

    如:123q 被转换成 123,123.4qwer 被转换成 123

payload

num=4476q    //十进制,利用弱比较           
num=010574    //八进制,intval() 参数特点
num=0x117c    // 十六进制,intval() 参数特点

 

web91

show_source(__FILE__);
include('flag.php');
$a=$_GET['cmd'];
if(preg_match('/^php$/im', $a)){
    if(preg_match('/^php$/i', $a)){
        echo 'hacker';
    }
    else{
        echo $flag;
    }
}
else{
    echo 'nonononono';
}

要求:以 php 作为开头结尾(不区分大小写、且多行匹配),且不能以 php 作为开头结尾(不区分大小写)

知识点

  1、正则表达式

    i 不区分大小写

    m 多行匹配

    ^ 定位符,字符串开始位置

    $ 定位符,字符串结尾位置

 

payload

num=%0aphp  //突破口在于多行匹配
       //利用 %0a 使参数为两行,php 在第二行既处于开头又处于结尾,第二个正则将第一行和第二行一起匹配,这时php处于结尾而不处于开头

 

web92

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

与 90 相似,90 为强比较,92为弱比较。同样采用 intval() 函数,第二位参数为0,payload 参考90

 

payload

num=010574    //八进制
num=0x117c    // 十六进制

 

web93

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

在 92 的基础上,屏蔽字母,也就是屏蔽十六进制,根据 intval($var,0)  特性,可采用八进制

payload

num=010574    //八进制

 

web94

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

要求:变量不能为4476,不能有字母,第一位不能是0、不能不出现0

知识点

  strpos() 函数查找字符串在另一字符串中第一次出现的位置

  查找成功,返回其位置,int 类型

  查找失败,返回 false,bool 类型

payload

num=4476.0    //利用 float 类型转换 int 类型
num=4476%0    //利用 str 类型 转换 int 类型(其余符号一样可行,不一定为%)

 

web95

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 采用弱比较,屏蔽 str 转 int

   第二个 if 禁用字母和小数点,屏蔽十六进制和 float 转 int

   第三个 if 禁止第一位为 0,且除第一位以外必须出现 0(看似屏蔽八进制,实则没有屏蔽)

payload

num=%09010574    //利用 %09 代替空格(起占位作用),4476 用八进制表示

 

posted @ 2023-03-04 17:06  kazie  阅读(105)  评论(0编辑  收藏  举报