Phar反序列化
本文最后更新于 36 天前,其中的信息可能已经有所发展或是发生改变。

来填坑了,差点就忘了,今天做题遇见了才想起来的

什么是Phar

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

同时对PHP版本有要求

PHP version >-5.3

Phar文件的结构

大致分为四个部分

1、Stub          //Phar文件头
2、manifest //压缩文件信息
3、contents //压缩文件内容
4、signature //签名

Sutb

其中Stub是Phar的文件标识,也可以理解为它就是Phar的文件头

Stub其实就是一个简单的PHP文件,对格式有要求的

xxx<?php xxx; __HALT_COMPILER();?>

前面的内容是不限制的,但在该PHP语句中,必须有__HALT_COMPILER(),没有这个,PHP就无法识别出它是Phar文件

manifest

用于存放文件的属性,权限等信息

这里也是反序列化的攻击点,因为这里以反序列化的形式存储了用户自定义的meta-data

contents

用于存放Phar文件的内容

signature

签名(可选参数),位于文件末尾,具体格式

从官方文档中不难看出,签证尾部的01代表md5加密,02代表sha1加密,04代表sha256加密,08代表sha512加密

更换签名的脚本

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

反序列化利用原理

就是因为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
  class TestObject {
   
  }
   
  $phar = new Phar("phar.phar"); //后缀名必须为phar
  $phar->startBuffering();//开启缓冲区
  $phar->setStub("<?php __HALT_COMPILER(); ?>"); //设置stub
   
  /*可选*/
  $o = new TestObject();
  $o -> data='hu3sky';
  $phar->setMetadata($o); //将自定义的meta-data存入manifest
   
  $phar->addFromString("test.txt", "test"); //添加要压缩的文件
  //签名自动计算
  $phar->stopBuffering();//关闭缓冲区
?>

注:文件上传时,不必要.phar后缀,文件上传不是难点!!(phar伪协议自动解析成.phar文件)

学都学了,那就一并整理一下绕过吧

比较重要的是,记得更改自己的php.ini将 phar.readonly 那一行设置为 Off,将前面的分号去掉,分号在这里起着注释符的作用

绕过方式

更改文件格式

利用Phar反序列化的第一步就是需要将Phar文件上传到服务器,若服务器存在防护,那就需要更改文件格式

比如只允许上传gif文件

PHP通过Stub里的__HALT_COMPILER();来识别这个文件是Phar文件,对于其他无限制。

故 对文件后缀、文件名进行更改,其实质仍然是Phar文件,所以不用担心文件后缀的问题

绕过正则phar

if (preg_match("/^php|^file|^phar|^dict|^zip/i",$filename){
  die();
}

可以通过各种协议绕过

1、使用filter伪协议来进行绕过
php://filter/read=convert.base64-encode/resource=phar://test.phar

2、使用bzip2协议来进行绕过
compress.bzip2://phar:///test.phar/test.txt

3、使用zlib协议进行绕过
compress.zlib://phar:///home/sx/test.phar/test.txt

绕过__HALT_COMPILER检测

可以通过前面加上图片头绕过

$phar->setStub("GIF89a<?php __HALT_COMPILER();?>");

也可将Phar文件的内容写到压缩包的注释中,压缩为zip文件

<?php
$a = serialize($a);
$zip = new ZipArchive();
$res = $zip->open('phar.zip',ZipArchive::CREATE);
$zip->addFromString('flag.txt', 'flag is here');
$zip->setArchiveComment($a);
$zip->close();
?>

或者是将生成的Phar文件进行gzip压缩,压缩命令

gzip test.phar
//gzip 文件名.phar
压缩后同样也可以进行反序列化

还有签名计算那个,暂时还没弄

暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇