前言:

重新认知梳理一下知识,再打牢一下基础.,也方便以后复习

用了很多别的师傅总结过了的东西,我会附上链接,如有侵权什么的,请师傅们联系我删除,感谢师傅们QAQ

之前和小伙伴也分享过,但是现在感觉又有点生疏了,上次面试,直接拉胯。

php反序列化前奏:

反序列化的结果:

O:1:"A":3:{s:3:"one";s:1:"a";s:6:" A two";s:1:"1";s:8:" * three";i:11;}

前面表示实例化对象A 对象名的长度为1,对象有3个属性,大括号里面的就是具体的属性,例如 one属性 为字符 长度为3,而属性后面跟着的是属性值

不同字母的意义:


    a - array 数组型
    b - boolean 布尔型
    d - double 浮点型
    i - integer 整数型
    o - common object 共同对象
    r - objec reference 对象引用
    s - non-escaped binary string 非转义的二进制字符串
    S - escaped binary string 转义的二进制字符串
    C - custom object 自定义对象
    O - class 对象
    N - null 空
    R - pointer reference 指针引用
    U - unicode string Unicode 编码的字符串

这里举例了php中的三种变量,三种变量在序列化的结果不一样,使用的方法也不一样

public  本例中得到的结果是 s:3:"one"

private  s:6:" A two" //其实是有不可见符 s:6:"\00A\00two" 或着 %00 
值得注意的是:无法通过$obj->属性名(或方法名) 来调用pravite类型的方法或属性

protected    s:8:" * three" //也是有不可见符 s:8:"\00*\00three" 或着 %00

一个小Trick
这里因为题目环境是php7+,对类型不敏感,所以本地pop链用public类型就可以绕过//2020网鼎杯青龙组AreUSerialz

魔法函数:
__construct()//当一个对象创建时被调用
__destruct() //当一个对象销毁时被调用
__toString() //当一个对象被当作一个字符串使用
__sleep()//在对象在被序列化之前运行
__wakeup()//将在反序列化之后立即被调用(通过序列化对象元素个数不符来绕过)
__get()//获得一个类的不存在变量时调用
__set()//设置一个类的不存在成员变量时调用
__invoke()//调用函数的方式调用一个对象时的回应方法
__call()//当调用一个对象中的不能用的方法的时候就会执行这个函数
当序列化字符串中表示对象属性个数的值大于真实的属性个数时会跳过__wakeup执行

几种特殊的反序列化类型

session反序列化

原理:如果php反序列化session数据时所使用的的引擎与序列化时的引擎不同,就会造成数据解析时出现错误。这时如果反序列化session的值可以控制,就可以构造恶意数据利用脚本中的漏洞函数点进行攻击

php session序列化引擎:

php: 
    name|s:1:"a";
    

php_binary:
    names:1:"a";
    

php_serialize(php>5.5.4):
    a:1:{s:4:"name";s:1:"a";}
    

例如:

php_serialize与php

  • Php引擎下,会将 | 作为key和value分隔符
  • 如果:php_serialize引擎传入:
    $_SESSION['aa']='|O:6:"m0n1ca":0:{}';
  • 得到 a:1:{s:2:“aa”;s:18:“|O:6:“m0n1ca”:0:{}”;}
  • 在php引擎下解析时,会将a:1:{s:2:“aa”;s:18:” 当成key
  • 将 O:6:“m0n1ca”:0:{} 作为value 这时就会逃逸出这个新的类 m0n1ca

题目练习:http://www.m0n1ca.top/index.php/bestphps-revengephp_session

phar反序列化

原理:phar的本质是一种压缩文件,其中每个被压缩文件的权限、属性等信息都放在这部分。这部分还会以序列化的形式存储用户自定义的meta-data,我们可以控制这里的meta-data写入我们构造好的pop链,再上传phar后phar协议解析,达到攻击目的。

生成phar文件

<?php
    class TestObject {
    }

    @unlink("phar.phar");
    $phar = new Phar("phar.phar"); //后缀名必须为phar
    $phar->startBuffering();
    $phar->setStub("<?php __HALT_COMPILER(); ?>"); //设置stub //在此可以添加任意文件头绕过例如:图片头GIF89a
    $o = new TestObject();
    $phar->setMetadata($o); //将自定义的meta-data存入manifest
    $phar->addFromString("test.txt", "test"); //添加要压缩的文件
    //签名自动计算
    $phar->stopBuffering();
?>

注意:phar.readonly选项设置为Off
phar反序列化有几点限制:

phar文件要能够上传到服务器端。
要有可用的魔术方法作为“跳板”。
文件操作函数的参数可控,且:、/、phar等特殊字符没有被过滤。

受影响的函数:

C0mRaDe师傅总结了其他受影响的函数:参考

exif

  • exif_thumbnail
  • exif_imagetype

gd

  • imageloadfont
  • imagecreatefrom***

hash

  • hash_hmac_file
  • hash_file
  • hash_update_file
  • md5_file
  • sha1_file

file / url

  • get_meta_tags
  • get_headers

standard

  • getimagesize
  • getimagesizefromstring

zip

<?php
$zip = new ZipArchive();
$res = $zip->open('c.zip');
$zip->extractTo('phar://test.phar/test');

限制phar://不能出现在头几个字符 绕过方法:

compress.bzip2://phar://
compress.zlib://phar://
或着其他协议
php://filter/read=convert.base64-encode/resource=phar://
php://filter/resource=phar://phar.phar
原生类反序列化

原生类中可以利用到的魔术方法:

Error / Exception :: xss   
	值得注意的是Error 仅使用与php7,而Exception适用于5和7
SimpleXMLElement :: xxe(用于做一个xml的对象)
GlobIterator ::遍历目录 可以配合SimpleXMLElement进行读取
soapclient  :: ssrf 配合 crlf
DirectoryIterator   /   FilesystemIterator ::也可以造成目录遍历
SplFileObject ::读取文件


利用的方法:
以bjd2 xss之光为例 参考

参考:

https://xi4or0uji.github.io/2019/06/27/php%E5%8F%8D%E5%BA%8F%E5%88%97%E5%8C%96%E7%94%B1%E6%B5%85%E5%88%B0%E6%B7%B1/#%E5%8E%9F%E7%94%9F%E7%B1%BB%E9%AD%94%E5%B9%BB%E5%87%BD%E6%95%B0

https://coomrade.github.io/2018/10/26/%E5%8F%8D%E5%BA%8F%E5%88%97%E5%8C%96%E6%94%BB%E5%87%BB%E9%9D%A2%E6%8B%93%E5%B1%95%E6%8F%90%E9%AB%98%E7%AF%87/

https://xz.aliyun.com/t/2715

https://xz.aliyun.com/t/6454#toc-0

分类: web安全

0 条评论

发表评论

电子邮件地址不会被公开。 必填项已用*标注