- A+
在系统、程序运行的过程中,内存中的变量数据随着运行的结束,自动销毁,而想保存内存中的数据,就应运而生了一种序列化与反序列化的技术,用来将内存中的数据保存到文件中。
在php中利用serialize函数,将要处理的数据进行序列化,利用unserialize函数,将处理过的序列化数据进行反序列化输出。
其中的魔术方法__sleep()与__wakeup()在序列化与反序列化的过程中,可能导致某些漏洞,举某个ctf比赛中的例子
通过show_source函数把当前目录与获取到的变量file结合,将文件内容显示出来,上述代码的突破点就在于绕过__wakeup函数。可利用的方法为CVE-2016-7124,表示对象属性个数的值大于真实的属性个数时就会跳过__wakeup的执行,下面引入php序列化的一些基础知识,大佬可以跳过
上图为序列化后的数据,每个开头字母所代表的含义,简单叙述一下,此ctf题的payload,和上图对照以便理解,O:5:”SoFun”:2:{S:7:”\00*\00file”;s:8:”flag.php”;}
其中O代表类,5代表长度为5,2代表类中声明了两个变量,S代表字符串,7代表长度,受保护的成员在成员名前面加上'*'。这些前缀值在任一侧都有空字节,形成\00*\00。对于php序列化的过程,O:与O:+都可代表类(在经典SugarCRM中绕过preg_ macth的检查,详情可看参考链接)。
phar扩展提供了一种将整个PHP应用程序放入名为“phar”(PHP Archive)的单个文件中的方法,以便于分发和安装。通过php官方手册可以得知,phar文件会包含meta-data的序列化数据,当我们可以控制序列化数据,可以配合魔术方法,达到漏洞利用
既然要利用phar,那咱们本地生成一个demo,看看phar文件中有哪些结构和内容,demo代码下图所示:
通过php官方手册可得知,stub为phar文件中的一个标志:<?php __HALT_COMPILER();
addFromString以字符串的形式添加一个文件到 phar 档案,setMetadata,Sets phar archive meta-data,根据之前所述会序列化meta-data数据,将生成的文件通过16进制查看,可以找到序列化数据
通过分析phar文件及生成过程,发现phar的标志是通过stub识别,也就是如果可以将phar文件变为gif,txt等类型文件,只要存在stub,就可以被识别成phar文件。通过setstub函数,在stub标志之前加入GIF89a文件头,可绕过很多上传机制。
在此简单做个测试,本地搭建一个只允许上传.gif 或 .jpeg 文件,文件大小必须小于 20 kb的模拟后台(测试代码为最后一个参考链接)
upload.php
upload.html
evil.php
show.php
利用过程如下:
攻击效果图如下:
参考paper中解析phar文件受影响函数,如下图:
参考链接:
https://bugs.php.net/bug.php?id=72663
https://paper.seebug.org/39/
https://i.blackhat.com/us-18/Thu-August-9/us-18-Thomas-Its-A-PHP-Unserialization-Vulnerability-Jim-But-Not-As-We-Know-It-wp.pdf
https://paper.seebug.org/680/
http://www.w3school.com.cn/php/php_file_upload.asp