upload-labs靶场通关-01~10

文件上传漏洞通常发生在程序设计中,由于对用户上传文件的处理不当或存在缺陷,导致用户能够绕过校验限制,向服务器上传具有执行能力的动态脚本文件。这些文件可能包括木马程序、病毒、恶意脚本或WebShell等。尽管文件上传本身并非问题所在,但服务器对上传文件的处理和解释方式不当,可能会引发严重后果。

upload-labs靶场主要用于渗透测试和CTF比赛中的文件上传漏洞训练。它通过模拟真实的文件上传场景,帮助用户理解文件上传漏洞的原理、危害以及如何绕过各种检测机制。靶场包含20个关卡,每个关卡都有不同的挑战,从基本的文件类型检测到复杂的黑名单和白名单绕过,逐步提升难度,帮助用户逐步提升对文件上传漏洞的理解和实战能力‌。

Pass-01

  • 我们需要先确定上传上去的路径
  • 如何限制我们上传的问题

信息收集测试

1 使用info.php文件上传查看情况,结果有个弹窗提示无法上传,另外,这个时候我们没有拦截到任何发送到服务器端的请求,说明,此监测是客户端监测;

2.使用符合条件的文件上传,如下面,上传正确的图片后,页面上有反显,那么我们就能获取到访问图片的路径,因为我们不仅要上传文件上去,还要能访问。

3.通过chrome的开发者工具既能查看到图片访问的路径,这边上传上去的文件连名字都没有修改,那么我们要访问我们上传的文件路径就是http://ip:端口/Pass-01/upload/文件名

4.由于这个是客户端限制,我们可以直接通过bp向服务器端发送请求,在这之前我们要先拦截下正常的请求,这边image.png是上传的文件名字,而下面啊那些就是这个图片的信息,由于是图片,所以这边看上去像乱码。

分析

已知条件

  • 已经知道能访问的路径
  • 文件名没有修改

绕过方案:

把我们的info.php文件改成info.png,然后通过bp拦截,把文件名改成info.php,既能访问到这个文件,路径地址是:

http://ip:端口/upload/info.php

实施

1.修改文件名

2.开启bp的拦截

3.发起请求并拦截,第二部分是文件的内容

4.发送到repeat中,并修改文件名

5.访问地址

bash 复制代码
[http://ip](http://ip/):端口/upload/info.php

总结

文件要能上传,传完要能访问,还要能解析执行!

Pass-02

信息收集测试

1.使用info.php文件,异常提示文件类型不正确,并且有发送请求到服务端,说明是服务器端校验;

复制代码

2.如果是服务器端校验,那么我们就需要获取到服务器端的代码了,我们这边就假设我们已经能获取到服务器端的代码

ini 复制代码
```
$is_upload = false;
$msg = null;
if (isset($_POST['submit'])) {
    if (file_exists(UPLOAD_PATH)) {
        if (($_FILES['upload_file']['type'] == 'image/jpeg') || ($_FILES['upload_file']['type'] == 'image/png') || ($_FILES['upload_file']['type'] == 'image/gif')) {
            $temp_file = $_FILES['upload_file']['tmp_name'];
            $img_path = UPLOAD_PATH . '/' . $_FILES['upload_file']['name']            
            if (move_uploaded_file($temp_file, $img_path)) {
                $is_upload = true;
            } else {
                $msg = '上传出错!';
            }
        } else {
            $msg = '文件类型不正确,请重新上传!';
        }
    } else {
        $msg = UPLOAD_PATH.'文件夹不存在,请手工创建!';
    }
}
```

3.上传一个正常的页面,查看反显的路径,路径与Pass-01一样:http://ip:端口/Pass-01/upload/文件名

分析

这边的判断主要是根据请求过来的Content-Type的值进行判断是否图片,如果我们直接这个值改成其中一个"image/jpeg",其他的偶不变,既能绕过,注意这边的没有修改上传的文件名字。

已知条件:

  • 已经知道能访问的路径
  • 文件名没有修改
  • 文件校验的策略

绕过方案:

通过bp修改Content-Type的值为"image/jpeg"

实施

1.拦截请求或者让请求正常通过后,发送到repeat中;

2.在repeat中修改Content-Type,并发送请求;

3.验证,能正常访问:http://ip:端口/upload/info.php

总结

服务器端的校验主要根据具体的校验方案来进行突破,这边主要是对Content-Type校验的绕过方式。

Pass-03

信息收集测试

1.使用info.php文件,异常提示"提示:不允许上传.asp,.aspx,.php,.jsp后缀文件!",并且有发送请求到服务端,说明是服务器端校验;

2.正常图片,反显图片的名称与源文件不一致,说明文件名有做了修改;

3.查看源码:

ini 复制代码
```
$is_upload = false;
$msg = null;
if (isset($_POST['submit'])) {
    if (file_exists(UPLOAD_PATH)) {
        $deny_ext = array('.asp','.aspx','.php','.jsp');
        $file_name = trim($_FILES['upload_file']['name']);
        $file_name = deldot($file_name);//删除文件名末尾的点
        $file_ext = strrchr($file_name, '.');//获取文件扩展名
        $file_ext = strtolower($file_ext); //转换为小写
        $file_ext = str_ireplace('::$DATA', '', $file_ext);//去除字符串::$DATA
        $file_ext = trim($file_ext); //首尾去空
​
        if(!in_array($file_ext, $deny_ext)) {
            $temp_file = $_FILES['upload_file']['tmp_name'];
            $img_path = UPLOAD_PATH.'/'.date("YmdHis").rand(1000,9999).$file_ext;            
            if (move_uploaded_file($temp_file,$img_path)) {
                 $is_upload = true;
            } else {
                $msg = '上传出错!';
            }
        } else {
            $msg = '不允许上传.asp,.aspx,.php,.jsp后缀文件!';
        }
    } else {
        $msg = UPLOAD_PATH . 
        '文件夹不存在,请手工创建!';
    }
}
```

#### 分析与实施

分析代码,黑名单只有'.php',而apache识别为php脚本文件的扩展名有:.php、 .php3、.php4、 .php5,另外index.php.aaa也是能识别的,但是代码中会把.php删掉,所以使用php3|.php4| .php5。,所以,我把后缀改成php3上传既,并验证如下图,能正常访问

Apache HTTP服务器默认情况下支持解析以下常见的文件扩展名: ![image-20250424180334462]()

apache后缀识别原理:

复制代码
Apache对文件后缀名的识别是从后向前进行匹配的,以单个.作为分隔符。当遇到未知的文件后缀名时,会继续向前匹配,直到遇到可以识别的后缀名为止。

总结

这题主要让价了解apache解析成php脚本的扩展名有哪些,apache解析原理。

Pass-04

信息收集与分析

根据之前的经验,我们直接看源码

ini 复制代码
$is_upload = false;
$msg = null;
if (isset($_POST['submit'])) {
    if (file_exists(UPLOAD_PATH)) {
        $deny_ext = array(".php",".php5",".php4",".php3",".php2","php1",".html",".htm",".phtml",".pht",".pHp",".pHp5",".pHp4",".pHp3",".pHp2","pHp1",".Html",".Htm",".pHtml",".jsp",".jspa",".jspx",".jsw",".jsv",".jspf",".jtml",".jSp",".jSpx",".jSpa",".jSw",".jSv",".jSpf",".jHtml",".asp",".aspx",".asa",".asax",".ascx",".ashx",".asmx",".cer",".aSp",".aSpx",".aSa",".aSax",".aScx",".aShx",".aSmx",".cEr",".sWf",".swf");
        $file_name = trim($_FILES['upload_file']['name']);
        $file_name = deldot($file_name);//删除文件名末尾的点
        $file_ext = strrchr($file_name, '.');
        $file_ext = strtolower($file_ext); //转换为小写
        $file_ext = str_ireplace('::$DATA', '', $file_ext);//去除字符串::$DATA
        $file_ext = trim($file_ext); //收尾去空
​
        if (!in_array($file_ext, $deny_ext)) {
            $temp_file = $_FILES['upload_file']['tmp_name'];
            $img_path = UPLOAD_PATH.'/'.date("YmdHis").rand(1000,9999).$file_ext;
            if (move_uploaded_file($temp_file, $img_path)) {
                $is_upload = true;
            } else {
                $msg = '上传出错!';
            }
        } else {
            $msg = '此文件不允许上传!';
        }
    } else {
        $msg = UPLOAD_PATH . '文件夹不存在,请手工创建!';
    }
}
​

这回增加了更多的黑名单,03中的方法应该是不行了。我们可以利用apache中.htaccess文件的特性,把图片解析成php。其中.htaccess(Hypertext Access)是 Apache 服务器的一个分布式配置文件,可以覆盖主配置文件的设置,无需重启服务器即可生效(需要管理员级别权限修改的httpd.conf文件修改后需要重启Apach服务器)它主要用于目录级的配置,是 Web 安全、URL 重写和服务器优化的重要工具。

实施

  1. 新增一个文件.htaccess,添加下面代码,

    bash 复制代码
    <FilesMatch "loudong.jpg">
    SetHandler application/x-httpd-php
    </FilesMatch>  

2.然后在把info.php改成loudong.jpg文件

3.注意这边上传后的文件名没有改,我们就按照下面回显的路径去访问,访问地址是:http://ip:端口/upload/loudong.jpg,既能看到php的info信息

总结

此题主要的知识点是.htaccess文件。

Pass-05

信息收集与分析

查看了代码后,与04差不多,我们就试试使用04的代码测试下,得到下面的结果:

只能在分析下代码,与04差不多,黑名单中添加了".htaccess",但是没有转换成小写,那么我们PHP就能绕过。

ini 复制代码
$is_upload = false;
$msg = null;
if (isset($_POST['submit'])) {
    if (file_exists(UPLOAD_PATH)) {
        $deny_ext = array(".php",".php5",".php4",".php3",".php2",".html",".htm",".phtml",".pht",".pHp",".pHp5",".pHp4",".pHp3",".pHp2",".Html",".Htm",".pHtml",".jsp",".jspa",".jspx",".jsw",".jsv",".jspf",".jtml",".jSp",".jSpx",".jSpa",".jSw",".jSv",".jSpf",".jHtml",".asp",".aspx",".asa",".asax",".ascx",".ashx",".asmx",".cer",".aSp",".aSpx",".aSa",".aSax",".aScx",".aShx",".aSmx",".cEr",".sWf",".swf",".htaccess");
        $file_name = trim($_FILES['upload_file']['name']);
        $file_name = deldot($file_name);//删除文件名末尾的点
        $file_ext = strrchr($file_name, '.');
        $file_ext = str_ireplace('::$DATA', '', $file_ext);//去除字符串::$DATA
        $file_ext = trim($file_ext); //首尾去空
​
        if (!in_array($file_ext, $deny_ext)) {
            $temp_file = $_FILES['upload_file']['tmp_name'];
            $img_path = UPLOAD_PATH.'/'.date("YmdHis").rand(1000,9999).$file_ext;
            if (move_uploaded_file($temp_file, $img_path)) {
                $is_upload = true;
            } else {
                $msg = '上传出错!';
            }
        } else {
            $msg = '此文件类型不允许上传!';
        }
    } else {
        $msg = UPLOAD_PATH . '文件夹不存在,请手工创建!';
    }
}
​

实施

1.修改后缀php改成PHP并上传

2.访问对应的地址

总结

根据具体的代码制定绕过计划

Pass-06

信息收集与分析

与05比较,少了去掉收尾空格的代码片段。

ini 复制代码
$is_upload = false;
$msg = null;
if (isset($_POST['submit'])) {
    if (file_exists(UPLOAD_PATH)) {
        $deny_ext = array(".php",".php5",".php4",".php3",".php2",".html",".htm",".phtml",".pht",".pHp",".pHp5",".pHp4",".pHp3",".pHp2",".Html",".Htm",".pHtml",".jsp",".jspa",".jspx",".jsw",".jsv",".jspf",".jtml",".jSp",".jSpx",".jSpa",".jSw",".jSv",".jSpf",".jHtml",".asp",".aspx",".asa",".asax",".ascx",".ashx",".asmx",".cer",".aSp",".aSpx",".aSa",".aSax",".aScx",".aShx",".aSmx",".cEr",".sWf",".swf",".htaccess");
        $file_name = $_FILES['upload_file']['name'];
        $file_name = deldot($file_name);//删除文件名末尾的点
        $file_ext = strrchr($file_name, '.');
        $file_ext = strtolower($file_ext); //转换为小写
        $file_ext = str_ireplace('::$DATA', '', $file_ext);//去除字符串::$DATA
        
        if (!in_array($file_ext, $deny_ext)) {
            $temp_file = $_FILES['upload_file']['tmp_name'];
            $img_path = UPLOAD_PATH.'/'.date("YmdHis").rand(1000,9999).$file_ext;
            if (move_uploaded_file($temp_file,$img_path)) {
                $is_upload = true;
            } else {
                $msg = '上传出错!';
            }
        } else {
            $msg = '此文件不允许上传';
        }
    } else {
        $msg = UPLOAD_PATH . '文件夹不存在,请手工创建!';
    }
}
​

通过上传的时候通过bp添加空格,在校验文件名是否合格的时候,能绕过验证,并且系统保存末尾有空格的文件名称时,会自动把末尾的空格去掉。

实施

总结

保存的特性系统的特性,把末尾的空格去掉。

Pass-07

信息收集与分析

与06比较缺少了删除末尾的"."的代码段,如果我们再末尾添加一个.那么 <math xmlns="http://www.w3.org/1998/Math/MathML"> f i l e e x t = s t r r c h r ( file_ext = strrchr( </math>fileext=strrchr(file_name, '.'); 中返回的就是".",所以

ini 复制代码
is_upload = false;
$msg = null;
if (isset($_POST['submit'])) {
    if (file_exists(UPLOAD_PATH)) {
        $deny_ext = array(".php",".php5",".php4",".php3",".php2",".html",".htm",".phtml",".pht",".pHp",".pHp5",".pHp4",".pHp3",".pHp2",".Html",".Htm",".pHtml",".jsp",".jspa",".jspx",".jsw",".jsv",".jspf",".jtml",".jSp",".jSpx",".jSpa",".jSw",".jSv",".jSpf",".jHtml",".asp",".aspx",".asa",".asax",".ascx",".ashx",".asmx",".cer",".aSp",".aSpx",".aSa",".aSax",".aScx",".aShx",".aSmx",".cEr",".sWf",".swf",".htaccess");
        $file_name = trim($_FILES['upload_file']['name']);
        $file_ext = strrchr($file_name, '.');//返回最后一个.到字符串末尾的字符串片段
        $file_ext = strtolower($file_ext); //转换为小写
        $file_ext = str_ireplace('::$DATA', '', $file_ext);//去除字符串::$DATA
        $file_ext = trim($file_ext); //首尾去空
        
        if (!in_array($file_ext, $deny_ext)) {
            $temp_file = $_FILES['upload_file']['tmp_name'];
            $img_path = UPLOAD_PATH.'/'.$file_name;
            if (move_uploaded_file($temp_file, $img_path)) {
                $is_upload = true;
            } else {
                $msg = '上传出错!';
            }
        } else {
            $msg = '此文件类型不允许上传!';
        }
    } else {
        $msg = UPLOAD_PATH . '文件夹不存在,请手工创建!';
    }
}

实施

总结

针对操作系统在后面加.与空格,保存成文件后,都会自动把.与空格去掉

Pass-08

信息收集与分析

代码中缺少对":: <math xmlns="http://www.w3.org/1998/Math/MathML"> D A T A "的处理,在 W i n d o w s 中会把 : : DATA"的处理,在Windows中会把:: </math>DATA"的处理,在Windows中会把::DATA 之后的数据当成文件流处理,不会检测后 缀名,且保持:: <math xmlns="http://www.w3.org/1998/Math/MathML"> D A T A 之前的文件名,类似之前" . "与空格的功效,所以在 b p 中使用 r e p e a t 发送到服务器前把文件名中添加 : : DATA 之前的文件名,类似之前"."与空格的功效,所以在bp中使用repeat发送到服务器前把文件名中添加:: </math>DATA之前的文件名,类似之前"."与空格的功效,所以在bp中使用repeat发送到服务器前把文件名中添加::DATA即可。

ini 复制代码
$is_upload = false;
$msg = null;
if (isset($_POST['submit'])) {
    if (file_exists(UPLOAD_PATH)) {
        $deny_ext = array(".php",".php5",".php4",".php3",".php2",".html",".htm",".phtml",".pht",".pHp",".pHp5",".pHp4",".pHp3",".pHp2",".Html",".Htm",".pHtml",".jsp",".jspa",".jspx",".jsw",".jsv",".jspf",".jtml",".jSp",".jSpx",".jSpa",".jSw",".jSv",".jSpf",".jHtml",".asp",".aspx",".asa",".asax",".ascx",".ashx",".asmx",".cer",".aSp",".aSpx",".aSa",".aSax",".aScx",".aShx",".aSmx",".cEr",".sWf",".swf",".htaccess");
        $file_name = trim($_FILES['upload_file']['name']);
        $file_name = deldot($file_name);//删除文件名末尾的点
        $file_ext = strrchr($file_name, '.');
        $file_ext = strtolower($file_ext); //转换为小写
        $file_ext = trim($file_ext); //首尾去空
        
        if (!in_array($file_ext, $deny_ext)) {
            $temp_file = $_FILES['upload_file']['tmp_name'];
            $img_path = UPLOAD_PATH.'/'.date("YmdHis").rand(1000,9999).$file_ext;
            if (move_uploaded_file($temp_file, $img_path)) {
                $is_upload = true;
            } else {
                $msg = '上传出错!';
            }
        } else {
            $msg = '此文件类型不允许上传!';
        }
    } else {
        $msg = UPLOAD_PATH . '文件夹不存在,请手工创建!';
    }
}
​

实施

把请求发送到repeat中后,修改filename,添加::$DATA

访问地址http://IP:端口/upload/info.php

总结

在windows操作系统中添加::#DATA作为文件名末尾,操作系统会忽略。

Pass-09

信息收集与分析

代码:

ini 复制代码
$is_upload = false;
$msg = null;
if (isset($_POST['submit'])) {
    if (file_exists(UPLOAD_PATH)) {
        $deny_ext = array(".php",".php5",".php4",".php3",".php2",".html",".htm",".phtml",".pht",".pHp",".pHp5",".pHp4",".pHp3",".pHp2",".Html",".Htm",".pHtml",".jsp",".jspa",".jspx",".jsw",".jsv",".jspf",".jtml",".jSp",".jSpx",".jSpa",".jSw",".jSv",".jSpf",".jHtml",".asp",".aspx",".asa",".asax",".ascx",".ashx",".asmx",".cer",".aSp",".aSpx",".aSa",".aSax",".aScx",".aShx",".aSmx",".cEr",".sWf",".swf",".htaccess");
        $file_name = trim($_FILES['upload_file']['name']);
        $file_name = deldot($file_name);//删除文件名末尾的点
        $file_ext = strrchr($file_name, '.');
        $file_ext = strtolower($file_ext); //转换为小写
        $file_ext = str_ireplace('::$DATA', '', $file_ext);//去除字符串::$DATA
        $file_ext = trim($file_ext); //首尾去空
        
        if (!in_array($file_ext, $deny_ext)) {
            $temp_file = $_FILES['upload_file']['tmp_name'];
            $img_path = UPLOAD_PATH.'/'.$file_name;
            if (move_uploaded_file($temp_file, $img_path)) {
                $is_upload = true;
            } else {
                $msg = '上传出错!';
            }
        } else {
            $msg = '此文件类型不允许上传!';
        }
    } else {
        $msg = UPLOAD_PATH . '文件夹不存在,请手工创建!';
    }
}
​

根据代码的验证过程,只要 <math xmlns="http://www.w3.org/1998/Math/MathML"> f i l e e x t 中不是黑名单的字符串就行,由于" . "、 " 空格 " 、" : : file_ext中不是黑名单的字符串就行,由于"."、"空格"、":: </math>fileext中不是黑名单的字符串就行,由于"."、"空格"、"::DATA"三个保存时,对最终落地到操作系统的文件名没有影响,那么我们通过这个三个组合添加到我们的文件名后,由于"::$DATA"是整个替换,所以用不了,那么就剩"."与"空格"了

ini 复制代码
 $file_ext = str_ireplace('::$DATA', '', $file_ext);//去除字符串::$DATA

逐句分析:

ini 复制代码
$file_name = trim($_FILES['upload_file']['name']);

头尾去空格,那么我们文件名最后一个必须是"."

ini 复制代码
$file_name = deldot($file_name);//删除文件名末尾的点

deldot此函数删除末尾的点,一直删除到没有为止,如果有两个".",那么会删除两个,那么我们末尾的字符串是空格+.了:" ."

ini 复制代码
$file_ext = strtolower($file_ext); //转换为小写
$file_ext = str_ireplace('::$DATA', '', $file_ext);//去除字符串::$DATA
$file_ext = trim($file_ext); //首尾去空

前面两个对我们没有影响,最后一个取首位空格的函数,我们的倒数第二个空格又没有了,那么我们可以倒数三个在加上一个".",完成的文件名为:

info.php. .

实施

总结

需要对代码进行逐条分析,找到逻辑的漏洞。

Pass-10

信息收集与分析

代码:

ini 复制代码
$is_upload = false;
$msg = null;
if (isset($_POST['submit'])) {
    if (file_exists(UPLOAD_PATH)) {
        $deny_ext = array("php","php5","php4","php3","php2","html","htm","phtml","pht","jsp","jspa","jspx","jsw","jsv","jspf","jtml","asp","aspx","asa","asax","ascx","ashx","asmx","cer","swf","htaccess");
​
        $file_name = trim($_FILES['upload_file']['name']);
        $file_name = str_ireplace($deny_ext,"", $file_name);
        $temp_file = $_FILES['upload_file']['tmp_name'];
        $img_path = UPLOAD_PATH.'/'.$file_name;        
        if (move_uploaded_file($temp_file, $img_path)) {
            $is_upload = true;
        } else {
            $msg = '上传出错!';
        }
    } else {
        $msg = UPLOAD_PATH . '文件夹不存在,请手工创建!';
    }
}

这段代码的核心是 <math xmlns="http://www.w3.org/1998/Math/MathML"> f i l e n a m e = s t r i r e p l a c e ( file_name = str_ireplace( </math>filename=strireplace(deny_ext,"", $file_name);,它吧所有的黑名单中的关键字全部换成空格,文件都能上传,但是上传后,php的文件名被去掉了,那么也就无法运行了。

注意上面的代码知会执行一次,如果我们再php中插入一个php字符窜,那么一个php被替换成"",剩下的还是php,如pphphp、phphpp(这个不行,替换完会变成hpp),综上,只能是pphphp了。

实施

总结

根据具体的代码具体分析,分析出其中的逻辑漏洞。

相关推荐
用户962377954481 天前
DVWA 靶场实验报告 (High Level)
安全
数据智能老司机1 天前
用于进攻性网络安全的智能体 AI——在 n8n 中构建你的第一个 AI 工作流
人工智能·安全·agent
数据智能老司机1 天前
用于进攻性网络安全的智能体 AI——智能体 AI 入门
人工智能·安全·agent
用户962377954481 天前
DVWA 靶场实验报告 (Medium Level)
安全
red1giant_star1 天前
S2-067 漏洞复现:Struts2 S2-067 文件上传路径穿越漏洞
安全
用户962377954481 天前
DVWA Weak Session IDs High 的 Cookie dvwaSession 为什么刷新不出来?
安全
cipher3 天前
ERC-4626 通胀攻击:DeFi 金库的"捐款陷阱"
前端·后端·安全
一次旅行6 天前
网络安全总结
安全·web安全
red1giant_star6 天前
手把手教你用Vulhub复现ecshop collection_list-sqli漏洞(附完整POC)
安全
ZeroNews内网穿透6 天前
谷歌封杀OpenClaw背后:本地部署或是出路
运维·服务器·数据库·安全