ctfshow刷题之php特性(web89--web97)

77 阅读2分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第1天,点击查看活动详情

web89

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

可以看出,传进的数不能是数字,而且可以被intval函数使用,那就是数组了。对于intval函数,空的数组返回0,非空数组返回1.得到flag

payload:

/?num[]

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

审一下代码,如果传的是4476就会输出no no no,如果经过intval函数之后的值是4476,那么就会输出flag,看一下intval函数的用法:

int intval ( mixed $var [, int $base = 10 ] )

如果 base 是 0,通过检测 var 的格式来决定使用的进制:

  • 如果字符串包括了 "0x" (或 "0X") 的前缀,使用 16 进制 (hex);否则,
  • 如果字符串以 "0" 开始,使用 8 进制(octal);否则,
  • 将使用 10 进制 (decimal)

所以将4476转换成16进制:0x117c

第一种payload:

http://59856415-74f4-4f45-8551-1cf70b4b2a1d.challenge.ctf.show/?num=0x117c

flag:

ctfshow{f2d7fe78-4f94-4bff-891a-a0ec1e741a0a}

第二种:因为intval返回字符串的整数部分。

/?num=4476.0

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

这里重点是正则匹配的模式:i:表示不区分大小写 m:多行匹配

审一下代码,传入cmd这个参数,然后进行多行的正则匹配,如果含有php就执行下面的代码,如果没有php就输出:no no no。接下来进行单行的匹配,如果单行有php就输出:hacker,如果没有,就输出flag。payload:

/?cmd=%0APhp

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

跟web90一样,用16进制就可以了。只不过这个是强等于,不过好像没影响。

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

先审一下代码,跟前面几个题大同小异,

第一个if:检测是否传入num这个变量。

第二个if: 如果num值为4476就输出:no no no

第三个if:进行正则匹配,如果num值中有字母,就输出:no no no

第四个if:如果经过Intval函数以后的值等于4476,就输出flag。

这个重点在于过滤了字母,就不能用十六进制了,但可以用八进制。

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

这个多了一个strpos函数,

if(!strpos($num, "0")

这个是说0不能在这个字符串的第一位,所以对于web93的payload我们在0前面加个空格,就行了。

payload:

/?num= 010574

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

相比web94过滤了.4476.0这个就不能用了。八进制那个payload还是能用。

web96

highlight_file(__FILE__);

if(isset($_GET['u'])){
    if($_GET['u']=='flag.php'){
        die("no no no");
    }else{
        highlight_file($_GET['u']);
    }


}

<?php

这个题涉及到php的相对路径和绝对路径

绝对路径是文件在目录中的确切的位置,例如C:\Windows\Boot

/ 以/开头通常代表从根目录开始 绝对路径

相对路径是以一个参照为基准,找到你所需要的文件

../ 代表上级目录 ../../代表上上级目录

./ 代表当前文件所在的目录 可以省略不写

payload:

/?u=./flag.php

web97

include("flag.php");
highlight_file(__FILE__);
if (isset($_POST['a']) and isset($_POST['b'])) {
if ($_POST['a'] != $_POST['b'])
if (md5($_POST['a']) === md5($_POST['b']))
echo $flag;
else
print 'Wrong.';
}
?>

这里需要传入两个值不同但是MD5加密后值相同的两个数。我们有两种方法

第一种:数组绕过

因为MD5对数组的返回值都是null

image.png

post传参,得到flag。

第二种:利用fastcoll工具生成两个MD5值相同的数。

问题:a[]=1怎么理解

解:a[]相当于创建一个空数组,a[]=1也就相当于a[0]="1"

见: m.php.cn/article/375…