buuctf9
[安洵杯 2019]easy_serialize_php
1 |
|
extract():e
函数从数组中将变量导入到当前的符号表。
该函数使用数组键名作为变量名,使用数组键值作为变量值。针对数组中的每个元素,将在当前符号表中创建对应的一个变量。
该函数返回成功设置的变量数目。
1 |
|
大致清楚代码逻辑后,我们先看看phpinfo里面提供了啥信息:
flag所在文件名~大概是要读取文件源码
前两天在学序列化的知识的时候有看到一个phar的似乎跟文件有关,然后这里也是允许?会不会有点搞头?继续往下看看
好的没有搞头,因为:根据文件结构我们来自己构建一个phar文件,php内置了一个Phar类来处理相关操作。
注意:要将php.ini中的phar.readonly
选项设置为Off
,否则无法生成phar文件。
本地测试抓包传一下值吧
需要解决的问题如下:
1.对于传入的img_path会进行加密处理,那么传入到unserialize内容中以后就无法被反序列化了
2.这里还有一个extract()函数,但是他会被filter过滤内容,所以这里要想想如何绕过,让反序列化执行我们的文件读取类。
好的想不出来,看wp发现
PHP反序列化的对象逃逸
这题和我在隔壁文档演示的又有点不太一样,这里我们获得文本的点在于 :base64_decode($userinfo[‘img’])所以此时我们需要含有flag的字符串编码被序列化内容舍弃掉,如何舍弃呢?就是让前面的内容被过滤,那么序列化的字符串就会往下读取字符
这里有个误区:后面读取文件的而是序列化内的img值,所以我们需要丢掉的是本来有的img值!也就是说我们传入的值要在程序本来自带的img的前面
flag文件base64加密后为:
1 | ZDBnM19mMWFnLnBocA== |
救命 遇到大坑了,我们利用的是flag等字符会被转化为空来吃掉后面的字符,但是如果我们传入的数据时:
1 | _SESSION[user]=flagflagflagflagflagflag&_SESSION[img]=Z3Vlc3RfaW1nLnBuZw==&_SESSION[function]=a";s:3:"img";s:4:"aaaa";s:3:"img";s:4:"aaaa";} |
这样子的话吃掉就是img,虽然多构造几个flag也能把function的48字符给吃掉,但是就无法传入img值也就是打开我们的flag:
//a:3:{s:4:”user”;s:24:””;s:3:”img”;s:20:”Z3Vlc3RfaW1nLnBuZw==”;s:8:”function”;s:46:”a”;s:3:”img”;s:4:”aaaa”;s:3:”img”;s:4:”aaaa”;}”;}
像这个有46的出现就报错了~所以要吃掉它呀!!!!!!就要和img互换位置,所以真正的payload为:
1 | _SESSION[user]=flagflagflagflagflagflag&_SESSION[function]=a";s:3:"img";s:20:"ZDBnM19mMWFnLnBocA==";s:2:"dd";s:1:"a";} |
1 | a:3:{s:4:"user";s:24:"";s:8:"function";s:59:a";s:3:"img";s:20:"ZDBnM19mMWFnLnBocA==";s:2:"dd";s:1:"a";}";s:3:"img";s:20:"Z3Vlc3RfaW1nLnBuZw==";} |
调试代码:
1 | <?php |
小结
这题不算难,但是坑不少,主要是细心问题,多调试很有用!!
[0CTF 2016]piapiapia
www.zip源码泄露打开审计一下:
本地运行的时候需要注意 mysql要全部更改为mysqli(版本不同)
在本地运行调试了一下,发现有登录注册还有一个更新页面,登录注册页面没啥大问题,在更新页面可以上传文件并且将会被序列化,在序列化之前还会
针对我们传入的内容进行一下反序列化操作后使用了filter进行过滤:
1 | a:4:{s:5:"phone";s:11:"15559564603";s:5:"email";s:12:"10452@qq.com";s:8:"nickname";s:3:"123";s:5:"photo";s:39:"upload/d41d8cd98f00b204e9800998ecf8427e";} |
这里需要做的就是让123”以后的内容被丢弃掉,和上一题差不多,然后这里如何吃字符呢?filter里面只有where替换为hacker能吃,所以就要输入很多个where
由于都有长度限制,并且只有nickname能全输出英文,所以需要绕过strlen函数,如何绕过呢?传入数组就行了接下来直接构造一下payload吧:
1 | nickname[]=wherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewhere";}s:5:"photo";s:10:"config.php";} |
解释一下 由于我们传入的数组,所以序列化的过程中也是数组,所以s前面需要有个中括号和分号,才能达到闭合的效果
我们下载源码后,发现config里面有个flag,所以推测flag在这里
小结:
连续做了两题这个,感觉更加得心应手一些了总结一下就是:
1.filter在序列化之后,并且filter的是序列化后的内容
2.看看filter哪些可以吃字符
3.构造好闭合语句
4.让不要的字符被丢弃