Pass-01
- 在Pass-01上传php文件,根据下图提示,是在前段限制了上传文件的类型。
- 查看前端代码,发现有checkFile()函数,再次印证了是在前段限制了上传文件的类型。
- 先将test.php文件改成test.jpg图片文件上传,同时抓包再将test.jpg改回test.php。即可成功上传。
- 测试一下成功上传的文件,文件成功执行。
Pass-02
- Pass-02没有做前端限制,后在后端做了Content-Type限制。
MediaType,即是Internet Media Type,互联网媒体类型;也叫做MIME类型,在Http协议消息头中,使用Content-Type来表示具体请求中的媒体类型信息。
- 常见的媒体格式类型如下:
text/html : HTML格式
text/plain :纯文本格式
text/xml : XML格式
image/gif :gif图片格式
image/jpeg :jpg图片格式
image/png:png图片格式
- 以application开头的媒体格式类型:
application/xhtml+xml :XHTML格式
application/xml: XML数据格式 application/atom+xml :Atom XML聚合格式
application/json: JSON数据格式 application/pdf:pdf格式 application/msword :
Word文档格式 application/octet-stream : 二进制流数据(如常见的文件下载)
application/x-www-form-urlencoded : 中默认的encType,form表单数据被编码为key/value格式发送到服务器(表单默认的提交数据的格式)
- 另外一种常见的媒体格式是上传文件之时使用的:
multipart/form-data : 需要在表单中进行文件上传时,就需要使用该格式
- 上传php文件,同时抓包,将application/octet-stream改为Content-Type: image/jpeg即可成功上传。
Pass-03
- 由提示可知,黑名单限制上传.asp|.aspx|.php|.jsp后缀文件!但是会存在一种场景:由于后端Apache的httpd.conf配置不当,可通过上传畸形后缀文件,绕过并执行。
- 上图中,意为:.php、.phtml后缀的文件都能以php文件执行。
- 所以,上传xx.phtml文件既可以绕过黑名单限制,又能以php文件执行。
- 成功上传:
- 成功执行:
Pass-04
- 由提示可知,大量的黑名单限制上传,但没有限制htaccess的上传。突破点就放在htaccess上吧。
- htaccess文件(或者”分布式配置文件”),全称是Hypertext Access(超文本入口)。提供了针对目录改变配置的方法,即在一个特定的文档目录中放置一个包含一个或多个指令的文件, 以作用于此目录及其所有子目录。
- 但,要黑类似于本Pass的站点,需要给他们的运维Call一下,让他把Apache的httpd.conf做一下不当的配置:AllowOverride None该为AllowOverride All。
- 先上传htaccess文件:
- 在上传task文件:
- 成功执行解析:
Pass-05
- 天呐!就连htaccess也给限制了,咋弄?!
- Look!!!源码中好像没有“转换为小写”语句:
$file_ext = strtolower($file_ext);
直接上传Php、phP、PHP既绕过了限制,又成功上传了文件,访问如下:
- 注意!注意!!!此方法暂且在环境:Windows下实现,其他环境下暂未实现。
Pass-06
此Pass同样是黑名单过滤,对提交的文件竟然做文件名“小写转换”了,BUT没有了:
$file_ext = trim($file_ext);
So,用空格改变后缀,绕过:
- 成功上传并访问被解析:
- 注意!注意!!!此方法暂且在环境:Windows下实现,其他环境下暂未实现。
Pass-07
- 相比于Pass-06代码,加上了首尾去空,但是却少了尾部去点:
$file_name = deldot($file_name);
上传test.php. 进行绕过,因为这是利用Windows特性——自动去掉后缀名中最后的”.” 。成功上传:
- 访问之,被解析:
- 注意!注意!!!此方法暂且在环境:Windows下实现,其他环境下暂未实现。
Pass-08
- 本Pass除了有黑名单处理,BUT没有对后缀名进行去”::$DATA”处理,也是利用windows特性。你不去除,我就加上:
- 访问一下:
- 由此说明,从代码层面没有对后缀做去除:: D A T A 处 理 , 而 在 操 作 系 统 层 面 对 文 件 储 存 时 W i n d o w s 系 统 对 上 传 的 文 件 做 了 去 除 : : DATA处理,而在操作系统层面对文件储存时Windows系统对上传的文件做了去除:: DATA处理,而在操作系统层面对文件储存时Windows系统对上传的文件做了去除::DATA处理。
Pass-09
- 黑名单过滤的类型齐全,并且又进行了大小写经过转换、去除了文件名末尾的点、去除了文件名尾空格、还去除了::$DATA。BUT,办法还是有的。这里的代码逻辑是先删除文件名末尾的点,再进行首尾去空。都只进行一次。SO可以构造点空格点进行绕过,也就是后缀名改为test.php. .(即:[点+空格+点])也是利用了Windows的特性。
- 访问之,被解析:
- 注意!注意!!!此方法暂且在环境:Windows下实现,其他环境下暂未实现。
Pass-10
- 同样是过滤的一大堆黑名单。
- BUT!通过查看源码可以发现:这里是将问题后缀名替换为空。于是可以利用双写绕过。
$file_name = str_ireplace($deny_ext,"", $file_name);
意思是:在上传的文件名的后缀中连续字符如果能和黑名单中的任何一个能匹配上,就会将匹配上的字符替换为空。
- 所以就可以以此为基准构造后缀名,如:test1.phjspp、test.pphphp,被替换为空后都是 .php。如下图所示:
- 成功上传的文件被成功解析:
Pass-11
- Pass-11提示:“本pass上传路径可控!”。看看源码,又是白名单限制。
- 可以发现,这里与之前代码相比,使用了白名单,只允许上传jpg、png、gif三种格式文件。但是在进行move_uploaded_file前。利用 G E T [ ‘ s a v a p a t h ‘ ] {}_G\!ET[`sava_path`] GET[‘savapath‘]和随机时间函数进行拼接,拼接成文件存储路径。SO,构造文件存储路径利用了_GET传入:
$img_path = $_GET['save_path']."/".rand(10, 99).date("YmdHis").".".$file_ext;
导致服务器最终存储的文件名可控。所以可以利用这个点进行绕过。
- 这里利用的是%00截断。即move_uploaded_file函数的底层实现类似于C语言,遇到0x00会截断
- 上传的文件会以文件名“phpinfo.php”存储。
- 截断条件:1、php.ini的magic_quotes_gpc为OFF状态,2、php版本小于5.3.4
Pass-12
- 通过分析代码发现本Pass与Pass-11基本相似,只不过构造文件存储路径利用了_POST传入:
$img_path = $_POST['save_path']."/".rand(10, 99).date("YmdHis").".".$file_ext;
- So,漏洞利用原理与Pass-11一样,只不过位置有变:
- 上传的文件会以文件名“info.php”存储。
Pass-13
- 由源码可知,上传的文件会经过通过读文件的前2个字节判断文件类型。话不多说,造图片马,通过cmd命令操作:
copy tupian.jpg/b+shell.php/a tuma.jpg
其中/b代表二进制文件binary,放在图片后面,/a代表文字文件ascii。
- 上传构造好的图片:
- 但访问使其成功解析是个问题。So,需要配合php的文件包含漏洞。
- 另外,按照正常的URL访问上传的文件,是可以正常的图片解析的:
Pass-14
- 也是上传图片马,但根据提示可知,后端会通过getimagesize()函数对图片属性校验。
$info = getimagesize($filename);
- getimagesize()函数用于获取图像大小及相关信息,通过校验则返回一个数组。将测定任何 GIF,JPG,PNG,SWF,SWC,PSD,TIFF,BMP,IFF,JP2,JPX,JB2,JPC,XBM 或 WBMP 图像文件的大小并返回图像的尺寸以及文件类型及图片高度与宽度。
- 所以,要想通过此种校验,让getimagesize()成功获取图像相关属性,同Pass-13的方法亦能满足。
- 注意:上传的jpg文件,会以jpeg格式存储:
Pass-15
- 又是上传图片马,但根据提示可知,后端会通过exif_imagetype()读取一个图像的第1个字节并检查其签名。
$image_type = exif_imagetype($filename);
- exif_imagetype()可用来避免调用其它 exif 函数用到了不支持的文件类型上或和 $_SERVER[‘HTTP_ACCEPT’] 结合使用来检查浏览器是否可以显示某个指定的图像。
- 所以,要想通过此种校验,让exif_imagetype()成功读取图像的第1个字节并检查其签名,同Pass-13的方法亦能满足。方法同Pass-13,就不在此赘述了。
Pass-16
- 由代码知,过刀顺序为:判断文件类型Content-Type:
$filetype = $_FILES['upload_file']['type'];
$fileext= substr(strrchr($filename,"."),1);
jpg:
$im = imagecreatefromjpeg($target_path);
png:
$im = imagecreatefrompng($target_path);
gif:
$im = imagecreatefromgif($target_path);
Pass-17
- 此Pass要从代码说起,上传的文件得先让move_uploaded_file函数过一刀,即:将上传文件临时保存。然后再进行判断:是否符合白名单,符合就重命名等。看似较为严格的文件上传条件,但存在不妥,问题在于move_uploaded_file。
- 这里就要引入“条件竞选”的概念了。由于move_uploaded_file函数将上传的php文件会在后端临时保存极短的时间就删除。所以要抢在上传的php文件删除之前访问文件,并使文件如愿解析执行。So,这样如此的抢时间的现象就是条件竞选。
- 因此,在具体操作是要用到BurpSuite的Intruder模块。首先,将上传的PHP文件抓包,然后Send to Intruder。目的在于不停的向目标上传PHP文件,同时也不停的访问临时保存时的PHP文件,让“上传”动作和“访问”动作时间间隔越小越好。
- (1)先设置持续上传PHP文件操作:
- (2)再设置持续访问所上传的PHP文件操作:
- 先后执行“文件上传”和“上传文件访问”操作“Start attrak”
Pass-18
- 和Pass-17原理一样,都是利用条件竞争原理。Pass-17是和move_uploaded_file函数竞争保留之间。而此Pass是和renameFile函数作条件竞争。上传的函数不仅要满足合法上传条件,还要分别过以下三刀:
第一刀:
$ret = $this->checkFileExists();
第二刀:
$ret = $this->move();
第三刀:
$ret = $this->renameFile();
- 突破点就在“第三刀”,与其在重命名前竞争。
- 所以,同样一边持续上传图片马,一边持续访问为来得及重命名的图片马(此时需要配合文件包含漏洞)。方法:前面已提到(见“Pass-13&17”)。
Pass-19
- 此Pass可以上传随意文件,但你在“保存名称”中要守规矩。
- 如何绕过,还得从代码说起。其中有一个move_uploaded_file函数。但是它有个毛病:会忽视文件名末尾的 /. So可以构造 cmd.php/. 来绕过。
- 检验一下:
Pass-20
- 有代码知,第5-6行先进行了一个Content-Type判断。
$allow_type = array('image/jpeg','image/png','image/gif');
if(!in_array($_FILES['upload_file']['type'],$allow_type)){
- 10-13行,如果save_name是字符串的话就通过explode函数,将post进去的save_name转成小写后按’.'打散成数组。
$file = empty($_POST['save_name']) ? $_FILES['upload_file']['name'] : $_POST['save_name'];
if (!is_array($file)) {
$file = explode('.', strtolower($file));
- 第20行,由于后面filename构成的过程中由于 f i l e [ c o u n t ( file[count( file[count(file) - 1]的作用,导致$file[1] = NULL,所以构造文件名后相当于直接就是xx.php/.,
$file_name = reset($file) . '.' . $file[count($file) - 1];
- 具体操练如下: