第四届上海大学生信息安全比赛----- web3
这道是源码题,
源码:
源码很简单,我觉得考得主要是细心
直接看第一个if,
判断是否上传了一个文件,然后进去判断是否POST了一个名为file的参数,如果有上传这个参数,那么$filename就等于这个POST上去的值,否则就等于上传上去的文件名
然后下面判断$filename是否是一个array ,
如果是,就对$filename 进行 explode ,切割成一个数组
否则,。。。没有判断(这就是第一个考点)
$ext = end($filename)
如果$filename 不是array,那么$ext 就等于上传的文件的后缀
那么如果是数组呢,那么就等于POST上去的一个值。值可控,也就是说$ext可控了
继续判断$ext是否和$filename[count($filename)-1]的值相等
如果count($filename)为2,那么就是判断
$ext === $filename[1]
这里就有一个问题了,那么end($filename),到底是哪一个 (我觉得这里也是一个考点)
测试一下
可以很简单地绕过。
然后下面新生成一个文件,后缀我们可以控制为php
然后将刚才上传的文件,保存进去
下面在POST一个参数hehe,
首先将这个文件的内容读取出来,判断前6位是否等于 @<?php
然后判断上传的文件不能和新生成的文件名一样,这个随便就可以过
成功了就包含这个php文件
可怕的是下面有一个unlink() ,将刚才生成的文件全部删除了,但是这个绕过去也很简单
首先想到的是,资源竞争。
开多线程,如果这个文件刚生成,还没有执行到unlink()的时候,被另外一个线程访问到,那么就会执行这个文件,如果这个文件的代码再生成了一个文件,那么这个文件就不会被删除了。事实证明是可以的。
还有一种方法,我们控制后缀为 php/.
那么生成的文件就会一直保存着,不会被删除
(这种方法,我不是很理解,我没有想到可以这样子来绕过unlink(),学习姿势了)
两种方法都来试一下
第一种方法,资源竞争,这个比较耗时间,但是容易想到
第二种,
修改file[0]为php/. 就可以了
做到这里,全部完成了,读取flag的话,修改一下里面内容,就可以读到