这道是源码题,

源码:

源码很简单,我觉得考得主要是细心

直接看第一个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的话,修改一下里面内容,就可以读到

 

 

版权声明:本文为nienie原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://www.cnblogs.com/nienie/p/9929227.html