PHP反序列化&POP链构造&魔术方法&原生类
序列化:对象转换为数组或字符串等格式
反序列化:将数组或字符串等格式转换成对象
serialize() //将一个对象转换成一个字符串
unserialize() //将字符串还原成一个对象
PHP反序列化漏洞:
原理:未对用户输入的序列化字符串进行检测,导致攻击者可以控制反序列化过程,从而导致代码执行,SQL注入,目录遍历等不可控后果。在反序列化的过程中自动触发了某些魔术方法。当进行反序列化的时候就有可能会触发对象中的一些魔术方法。
php中魔术方法:
触发:unserialize函数的变量可控,文件中存在可利用的类,类中有魔术方法:
__construct(): //构造函数,当对象new的时候会自动调用
__destruct()://析构函数当对象被销毁时会被自动调用
__wakeup(): //unserialize()时会被自动调用
__invoke(): //当尝试以调用函数的方法调用一个对象时,会被自动调用
__call(): //在对象上下文中调用不可访问的方法时触发
__callStatci(): //在静态上下文中调用不可访问的方法时触发
__get(): //用于从不可访问的属性读取数据
__set(): //用于将数据写入不可访问的属性
__isset(): //在不可访问的属性上调用isset()或empty()触发
__unset(): //在不可访问的属性上使用unset()时触发
__toString(): //把类当作字符串使用时触发
__sleep(): //serialize()函数会检查类中是否存在一个魔术方法__sleep() 如果存在,该方法会被优先调用
O:4:”info“:2:{s:5:“namea”;i:1:“9”;}
O:object 代表数组,i代表数组
4:对象长度
info:对象名称
2:该对象中变量的个数
s:变量数据类型,s代表string,i代表int
4:变量名长度
namea:变量名
上述是反序列化出来的格式
PHP原生类-获取&利用&配合其他:
内置的一个组件
参考:https://dar1in9s.github.io/2020/04/02/php%E5%8E%9F%E7%94%9F%E7%B1%BB%E7%9A%84%E5%88%A9%E7%94%A8/#Exception
生成序列化时记得开启SoapClient拓展:php.ini中启用php_soap.dll
脚本:
参考案例:https://www.anquanke.com/post/id/264823
<?php
$classes = get_declared_classes();
foreach ($classes as $class) {
$methods = get_class_methods($class);
foreach ($methods as $method) {
if (in_array($method, array(
'__destruct',
'__toString',
'__wakeup',
'__call',
'__callStatic',
'__get',
'__set',
'__isset',
'__unset',
'__invoke',
'__set_state'
))) {
print $class . '::' . $method . "\n";
}
}
}
PHP反序列化&原生类&漏洞绕过&公私有属性
对象变量属性:
public(公共的):在本类内部、外部类、子类都可以访问
protect(受保护的):只有本类或子类或父类中可以访问
private(私人的):只有本类内部可以使用
序列化数据显示:
private属性序列化的时候格式是%00类名%00成员名
protect属性序列化的时候格式是%00*%00成员名
<?php
header("Content-type: text/html; charset=utf-8");
/*public private protected说明
class test{
public $name="xiaodi";
private $age="29";
protected $sex="man";
}
$a=new test();
$a=serialize($a);
print_r($a);
*/