码农知识堂 - 1000bd
  •   Python
  •   PHP
  •   JS/TS
  •   JAVA
  •   C/C++
  •   C#
  •   GO
  •   Kotlin
  •   Swift
  • phar反序列化


    序列化和反序列化的区别?

    可参考:【精选】什么是反序列化?反序列化的过程,原理-CSDN博客

    通俗的说序列化将对象转化为了字符串,包含了对象的所有数据信息,
    反序列化时再根据这些信息还原对象

    序列化:就是将对象转化成字节序列的过程。

    反序列化:就是讲字节序列转化成对象的过程。

    对象序列化成的字节序列会包含对象的类型信息、对象的数据等,说白了就是包含了描述这个对象的所有信息,能根据这些信息“复刻”出一个和原来一模一样的对象。

    那么为什么要去进行序列化呢?

    有以下两个原因

    1. 持久化:对象是存储在JVM中的堆区的,但是如果JVM停止运行了,对象也不存在了。序列化可以将对象转化成字节序列,可以写进硬盘文件中实现持久化。在新开启的JVM中可以读取字节序列进行反序列化成对象。
    2. 网络传输:网络直接传输数据,但是无法直接传输对象,可在传输前序列化,传输完成后反序列化成对象。所以所有可在网络上传输的对象都必须是可序列化的。

    什么是phar?

    Phar是PHP的压缩文档,是PHP中类似于JAR的一种打包文件。它可以把多个文件存放至同一个文件中,无需解压,PHP就可以进行访问并执行内部语句。

    phar扩展提供了一种将整个PHP应用程序放入.phar文件中的方法,以方便移动、安装。

    .phar文件的最大特点是将几个文件组合成一个文件的便捷方式,.phar文件提供了一种将完整的PHP程序分布在一个文件中并从该文件中运行的方法

    可以将phar文件类比为一个压缩文件

    借用kali_Ma_笔记,渗透测试,安全-CSDN博客的解释就是

    php序列化和反序列化过程

    执行结果:

    反序列化结果:

    php的序列化将对象转化为了字符串,包含了对象的所有数据信息,
    反序列化时再根据这些信息还原对象

    phar文件格式:

    1.stub                       //phar文件头
    2.manifest                //压缩文件信息
    3.contents                //压缩文件内容
    4.signature               //签名

     stub:

    Stub是Phar的文件标识,也可以理解为它就是Phar的文件头
    这个Stub其实就是一个简单的PHP文件,它的格式具有一定的要求,具体如下

    xxx xxx; __HALT_COMPILER();?>

    前面的内容是不限制的,可以是任意字符,包括留空

    php闭合符与最后一个分号之间不能有多于一个的空格符。另外php闭合符也可省略

    但在该PHP语句中,必须有 __HALT_COMPILER() ,没有这个,PHP就无法识别出它是Phar文件

    manifest:

    用于存放文件的属性、权限等信息。
    这里也是反序列化的攻击点,因为这里以序列化的形式存储了用户自定义的 Meta-data

    contents:

    用于存放Phar文件的内容

    signature:

    位于文件末尾

    签证尾部的01代表md5加密,02代表sha1加密,04代表sha256加密,08代表sha512加密

    当我们修改文件的内容时,签名就会变得无效,这个时候需要更换一个新的签名

    更换签名的脚本

    1. from hashlib import sha1
    2. with open('test.phar', 'rb') as file:
    3. f = file.read()
    4. s = f[:-28] # 获取要签名的数据
    5. h = f[-8:] # 获取签名类型和GBMB标识
    6. newf = s + sha1(s).digest() + h # 数据 + 签名 + (类型 + GBMB)
    7. with open('newtest.phar', 'wb') as file:
    8. file.write(newf) # 写入新文件

    PHP反序列化:

    Phar之所以能反序列化,是因为Phar文件会以序列化的形式存储用户自定义的meta-data,PHP使用phar_parse_metadata在解析meta数据时,会调用php_var_unserialize进行反序列化操作

    利用条件:

    1、phar文件能够上传至服务器
    //即要求存在file_get_contents()、fopen()这种函数

    2、要有可利用的魔术方法
    //利用魔术方法作为"跳板"

    3、文件操作函数的参数可控,且:、/、phar等特殊字符没有被过滤
    //一般利用姿势是上传Phar文件后通过伪协议Phar来实现反序列化,伪协议Phar格式是`Phar://`这种,如果这几个特殊字符被过滤就无法实现反序列化

    4、php.ini中的phar.readonly选项,需要为Off(默认是on)。

    Phar属于伪协议,伪协议使用较多的是一些文件操作函数,如fopen()、copy()、file_exists()等,具体如下图,也就是下面的函数如果参数可控可以造成Phar反序列化

    phar的生成

    需要去检查一下php.ini中的phar.readonly选项,如果是On,需要修改为Off。

    还需要下列代码生成

    1. class test{
    2. public $name="qwq";
    3. function __destruct()
    4. {
    5. echo $this->name;
    6. }
    7. }
    8. $a = new test();
    9. $a->name="phpinfo();";
    10. $phartest=new phar('phartest.phar',0);//后缀名必须为phar
    11. $phartest->startBuffering();//开始缓冲 Phar 写操作
    12. $phartest->setMetadata($a);//自定义的meta-data存入manifest
    13. $phartest->setStub("");//设置stub,stub是一个简单的php文件。PHP通过stub识别一个文件为PHAR文件,可以利用这点绕过文件上传检测
    14. $phartest->addFromString("test.txt","test");//添加要压缩的文件
    15. $phartest->stopBuffering();//停止缓冲对 Phar 归档的写入请求,并将更改保存到磁盘
    16. ?>

    绕过方式:

    当环境限制了phar不能出现在前面的字符里。可以使用compress.bzip2://和compress.zlib://等绕过

    compress.bzip://phar:///test.phar/test.txt
    compress.bzip2://phar:///test.phar/test.txt
    compress.zlib://phar:///home/sx/test.phar/test.txt

    也可以利用其它协议

    php://filter/read=convert.base64-encode/resource=phar://phar.phar

    GIF格式验证可以通过在文件头部添加GIF89a绕过

    1、$phar->setStub(“GIF89a”.""); //设置stub
    2、生成一个phar.phar,修改后缀名为phar.gif

    如:

    更改文件格式

    我们利用Phar反序列化的第一步就是需要上传Phar文件到服务器,而如果服务端存在防护,比如这种

    $_FILES["file"]["type"]=="image/gif"
    

    要求文件格式只能为gif,这个时候我们该怎么办呢?
    因为PHP识别Phar文件的方式是通过Stub里的__HALT_COMPILER();来识别这个文件是Phar文件,对于其他是无限制的,也就意味着我们即使对文件后缀和文件名进行更改,其实质仍然是Phar文件。
    示例代码

    1. class Test {
    2. public $name;
    3. function __construct(){
    4. echo "I am".$this->name.".";
    5. }
    6. }
    7. $obj = new Test();
    8. $obj -> name = "quan9i";
    9. $phar = new Phar('test.phar');
    10. $phar -> startBuffering(); //开始缓冲 Phar 写操作
    11. $phar -> setStub('GIF89a'); //设置stub,添加gif文件头
    12. $phar ->addFromString('test.txt','test'); //要压缩的文件
    13. $phar -> setMetadata($obj); //将自定义meta-data存入manifest
    14. $phar -> stopBuffering(); 停止缓冲对 Phar 归档的写入请求,并将更改保存到磁盘
    15. ?>

    绕过__HALT_COMPILER();检测

    PHP通过__HALT_COMPILER来识别Phar文件,那么出于安全考虑,即为了防止Phar反序列化的出现,可能就会对这个进行过滤

    示例代码如下

    1. if (preg_match("/HALT_COMPILER/i",$Phar){
    2. die();
    3. }

    这里的话绕过思路有两个
    1、将Phar文件的内容写到压缩包注释中,压缩为zip文件,示例代码如下

    1. $a = serialize($a);
    2. $zip = new ZipArchive();
    3. $res = $zip->open('phar.zip',ZipArchive::CREATE);
    4. $zip->addFromString('flag.txt', 'flag is here');
    5. $zip->setArchiveComment($a);
    6. $zip->close();
    7. ?>

    2、将生成的Phar文件进行gzip压缩,压缩命令如下

    gzip test.phar

    压缩后同样也可以进行反序列化


    相关链接见:

    https://www.cnblogs.com/CoLo/p/16786627.html#:~:text=Phar%E5%8F%8D%E5%BA%8F%E5%88%97%E5%8C%96%20Phar%E4%B9%8B%E6%89%80%E4%BB%A5%E8%83%BD%E5%8F%8D%E5%BA%8F%E5%88%97%E5%8C%96%EF%BC%8C%E6%98%AF%E5%9B%A0%E4%B8%BAPhar%E6%96%87%E4%BB%B6%E4%BC%9A%E4%BB%A5%E5%BA%8F%E5%88%97%E5%8C%96%E7%9A%84%E5%BD%A2%E5%BC%8F%E5%AD%98%E5%82%A8%E7%94%A8%E6%88%B7%E8%87%AA%E5%AE%9A%E4%B9%89%E7%9A%84%20meta-data%2CPHP%E4%BD%BF%E7%94%A8,phar_parse_metadata%20%E5%9C%A8%E8%A7%A3%E6%9E%90meta%E6%95%B0%E6%8D%AE%E6%97%B6%EF%BC%8C%E4%BC%9A%E8%B0%83%E7%94%A8%20php_var_unserialize%20%E8%BF%9B%E8%A1%8C%E5%8F%8D%E5%BA%8F%E5%88%97%E5%8C%96%E6%93%8D%E4%BD%9C%E3%80%82

    phar反序列化+两道CTF例题_ctf phar反序列化_Z3eyOnd的博客-CSDN博客

    https://www.cnblogs.com/CoLo/p/16786627.html#:~:text=Phar%E5%8F%8D%E5%BA%8F%E5%88%97%E5%8C%96%20Phar%E4%B9%8B%E6%89%80%E4%BB%A5%E8%83%BD%E5%8F%8D%E5%BA%8F%E5%88%97%E5%8C%96%EF%BC%8C%E6%98%AF%E5%9B%A0%E4%B8%BAPhar%E6%96%87%E4%BB%B6%E4%BC%9A%E4%BB%A5%E5%BA%8F%E5%88%97%E5%8C%96%E7%9A%84%E5%BD%A2%E5%BC%8F%E5%AD%98%E5%82%A8%E7%94%A8%E6%88%B7%E8%87%AA%E5%AE%9A%E4%B9%89%E7%9A%84%20meta-data%2CPHP%E4%BD%BF%E7%94%A8,phar_parse_metadata%20%E5%9C%A8%E8%A7%A3%E6%9E%90meta%E6%95%B0%E6%8D%AE%E6%97%B6%EF%BC%8C%E4%BC%9A%E8%B0%83%E7%94%A8%20php_var_unserialize%20%E8%BF%9B%E8%A1%8C%E5%8F%8D%E5%BA%8F%E5%88%97%E5%8C%96%E6%93%8D%E4%BD%9C%E3%80%82

     PHP Phar反序列化浅学习 - 跳跳糖

  • 相关阅读:
    流量调度、微服务可寻址性和注册中心
    《洛谷深入浅出进阶篇》P3397 地毯————二维差分
    HBase 开发:使用Java操作HBase 第2关:添加数据
    大厂年薪几十万,但是5-8年外包程序员,年薪是多少你知道吗?
    C语言--程序环境和预处理(宏)
    OSG嵌入QT的简明总结2
    网络中的一些基本概念
    对指针的深入理解
    微信、支付宝、百度(drawImage及canvasGetImageData、支付宝(getImageData))踩坑,uni-app 获取图片底色像素值
    测试管理并不好做,做好以下几点可直上云霄!
  • 原文地址:https://blog.csdn.net/m0_75178803/article/details/134061681
  • 最新文章
  • 攻防演习之三天拿下官网站群
    数据安全治理学习——前期安全规划和安全管理体系建设
    企业安全 | 企业内一次钓鱼演练准备过程
    内网渗透测试 | Kerberos协议及其部分攻击手法
    0day的产生 | 不懂代码的"代码审计"
    安装scrcpy-client模块av模块异常,环境问题解决方案
    leetcode hot100【LeetCode 279. 完全平方数】java实现
    OpenWrt下安装Mosquitto
    AnatoMask论文汇总
    【AI日记】24.11.01 LangChain、openai api和github copilot
  • 热门文章
  • 十款代码表白小特效 一个比一个浪漫 赶紧收藏起来吧!!!
    奉劝各位学弟学妹们,该打造你的技术影响力了!
    五年了,我在 CSDN 的两个一百万。
    Java俄罗斯方块,老程序员花了一个周末,连接中学年代!
    面试官都震惊,你这网络基础可以啊!
    你真的会用百度吗?我不信 — 那些不为人知的搜索引擎语法
    心情不好的时候,用 Python 画棵樱花树送给自己吧
    通宵一晚做出来的一款类似CS的第一人称射击游戏Demo!原来做游戏也不是很难,连憨憨学妹都学会了!
    13 万字 C 语言从入门到精通保姆级教程2021 年版
    10行代码集2000张美女图,Python爬虫120例,再上征途
Copyright © 2022 侵权请联系2656653265@qq.com    京ICP备2022015340号-1
正则表达式工具 cron表达式工具 密码生成工具

京公网安备 11010502049817号