1漏洞代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<?php

class F{

public $filename='a.txt';

function __construct()

{

echo phpinfo();

}

}

$a = new F();

serialize($a);

$b = unserialize('O:1:"F":1:{s:9:"filenameF";s:8:"bcda.txt";}');
?>

这是一个简单的将变量序列化,然后反序列化。

运行结果就会显示php的基本信息

2、 漏洞原因

为什么这里会执行phpinfo()呢?

在理解这个之前先了解下php序列化:

序列化说通俗点就是把一个对象变成可以传输的字符串,这个有点类似于前端的json传输数据

我们再来看下将一个变量($test=hahaha)序列化后的样子吧

O:1:”S”:1:{s:4:”test”;s:7:”hahaha”;}

O:代表object
1:代表对象名字长度为一个字符
S:对象的名称
1:代表对象里面有一个变量
s:数据类型
4:变量名称的长度
test:变量名称
s:数据类型
7:变量值的长度
hahaha:变量值

反序列化就是把被序列化的字符串还原为对象,然后在接下来的代码中继续使用。

序列化和反序列化本来是为了方便数据的传输的,本身是没有问题的,而问题就出在,序列化和反序列化过程中调用的php魔法函数

常见的几个魔法函数:
__construct()当一个对象创建时被调用 在序列化之前执行函数里面的内容

__destruct()当一个对象销毁时被调用 在反序列化之后执行函数里面的内容

__toString()当一个对象被当作一个字符串使用 此函数在执行echo或者print或者字符串输出的函数时被调用

__sleep() 在对象在被序列化之前运行 在序列化之前执行函数里面的内容,且执行后序列化返回N;

__wakeup将在序列化之后立即被调用 在反序列化之前执行函数里面的内容

下面我们看一下php序列化造成的反射型xss

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
<?php
class S{

var $test = "pikachu";

function __destruct(){

echo $this->test;

}

}

if(isset($_POST['o'])){

$s = $_POST['o'];
$unser=new S();

if(!@$unser = unserialize($s)){

$html.="<p>input error</p>";

}else{

$html.="<p>ok</p>";

}



}

?>

这段代码利用的payload是

O:1:”S”:1:{s:4:”test”;s:29:”“;}

将这段payload反序列化后,test的值变成了,然后在反序列化后,将对象销毁,调用魔法函数__destruct(),输出到前端。

这个漏洞的威胁取决于魔法函数中的代码,严重的话可以造成任意代码执行。而且因为是php正常执行,因此不会任何异常。