**摘要:**文章详细阐述了文件上传漏洞的常见场景、危害以及webshell的概念。讨论了多种绕过验证的技巧,包括JS验证、MIME-Type验证、黑名单和白名单验证的绕过方法。此外,还提到了文件内容检测、竞争条件、脏字符和HPP漏洞等高级绕过技术。最后,文章强调了防护措施,如内容检测、白名单策略和及时更新软件来防止攻击。
目录
[三、 任意文件上传危害](#三、 任意文件上传危害)
[四、 Webshell 基础](#四、 Webshell 基础)
[1. 概念](#1. 概念)
[2. 利用手段](#2. 利用手段)
[3. 常见的一句话木马](#3. 常见的一句话木马)
[五、 上传木马所需条件](#五、 上传木马所需条件)
[六、 木马上传检测流程](#六、 木马上传检测流程)
[七、 上传绕过技术详解](#七、 上传绕过技术详解)
[1. 绕过 JS 验证](#1. 绕过 JS 验证)
[2. 绕过 MIME-Type 验证](#2. 绕过 MIME-Type 验证)
[1) 文件幻数(文件头)检测绕过:](#1) 文件幻数(文件头)检测绕过:)
[2) getimagesize()检测绕过](#2) getimagesize()检测绕过)
[3) exif_imagetype()检测绕过](#3) exif_imagetype()检测绕过)
一、任意文件上传漏洞
定义: 由于服务端对上传文件未作过滤或过滤机制不严(如文件后缀、MIME类型等),导致恶意用户可以上传脚本文件, 最终达到获取或控制网站权限的目的。
二、常见文件上传点
大部分的网站和应用系统都有上传功能,主要集中在以下场景:
-
用户交互: 用户头像上传、身份认证附件上传。
-
内容发布: 发表文章时的图片上传、视频上传。
-
办公协作: 内部系统的文档上传、表格导入。
三、 任意文件上传危害
-
权限夺取: 攻击者可获得网站控制权限(Webshell)。
-
数据安全: 查看、修改、删除网站数据库或敏感信息。
-
主机控制: 配合提权漏洞,攻击者可直接获得服务器系统主机权限。
四、 Webshell 基础
1. 概念
一种网页后门,以 asp、php、jsp 或 cgi 等网页文件形式存在的一种命令执行环境。
2. 利用手段
黑客在入侵后,通常将后门文件与正常的网页文件混在 Web 目录下。通过浏览器访问这些后门,即可得到命令执行环境,实现对服务器的控制。
3. 常见的一句话木马
-
PHP:
<?php @eval($_POST['pass']);?> -
ASP:
<%eval request("pass")%> -
ASPX:
<%@ Page Language="Jscript"%> <%eval(Request.Item["pass"],"unsafe");%>
五、 上传木马所需条件
核心原理: 利用文件上传漏洞,向服务端提交简短代码,配合本地客户端(如 中国菜刀、蚁剑、冰蝎 等)实现 Webshell 功能。
成功入侵的三个必要条件:
-
上传成功且未被杀: 木马顺利落地服务器,未被安全软件拦截。
-
路径已知: 明确木马在服务器上的存放位置。
-
若路径不明,可通过爆破/目录遍历获取。
-
利用程序报错(乱改URL、请求不存在路径)寻找泄露的绝对路径。
-
-
解析正常: 上传的木马能被服务器环境作为脚本正常运行。
六、 木马上传检测流程
-
客户端 JavaScript 前端检测: (最易绕过)。
-
服务端 MIME 类型检测: 检查请求包中的 Content-Type。
-
服务端目录路径检测: 验证文件存放路径。
-
服务端文件扩展名检测: 核心检测环节(黑白名单)。
-
服务端文件内容检测: 检查文件头、关键函数等。
注意: 木马上传成功后,返回包通常会告知存储路径(通常接复制图片链接)。若是一句话木马,直接连接工具即可控制服务器。
七、 上传绕过技术详解
1. 绕过 JS 验证
方法一: 利用 Burpsuite 截获响应包,剔除验证后缀的 JS 代码后再执行上传。

方法二: 使用浏览器审计工具(F12)直接修改或剔除前端 JS 验证逻辑。

2. 绕过 MIME-Type 验证
补充知识: MIME(Multipurpose Internet Mail Extensions)多用途互联网邮件扩展类型。是设定某种扩展名的文件用一种应用程序来打开的方式类型,当该扩展名文件被访问的时候,浏览器会自动使用指定应用程序来打开。多用于指定一些客户端自定义的文件名,以及一些媒体文件打开方式。
操作: 拦截请求包,将 Content-Type: text/php 等修改为 image/jpeg 等合法类型。

- 代码分析: 后端使用
$_FILES['upload_file']['type']获取类型,该方式仅检测请求包头部字段,极易伪造。
3、绕过黑名单验证
1)文件后缀名验证
基于文件后缀名验证介绍:
对于文件上传模块来说,尽量避免上传可执行的脚本文件。为了防止上传脚本需要设置对应的验证方式。最简单的就是设置文件后缀名验证。
基于文件后缀名验证方式的分类:
基于白名单验证:只针对白名单中有的后缀名,文件才能上传成功。
基于黑名单验证:只针对黑名单中没有的后缀名,文件才能上传成功。
简单来说就是我随便写一个不存在的后缀,例如:est.sfasdfklsd的文件进行上传 ,假如能够上传成功,说明该处设置了黑名单验证,如果不能上传成就说明该处设置了白名单验证。
基于黑名单验证代码分析
对于黑名单中的后缀名筛选。绕过黑名单可以通过寻找"漏网之鱼",寻找某些可以被作为脚本执行同时也不在黑名单中。

我们可以使用Burpsuite绕过黑名单验证,利用Burpsuite工具截断HTTP请求,利用Intruder模块进行枚举后缀名,寻找黑名单中没有过滤的后缀名。

2).htaccess文件(针对Apache)
.htaccess文件是Apache服务器中的一个配置文件,它负责相关目录下的网页配置。通过.htaccess文件,可以帮我们实现:网页301重定向、自定义404错误页面、改变文件扩展名、允许/阻止特定的用户或者目录的访问、禁止目录列表、配置默认文档等功能。
其中.htaccess文件对应的MIME-Type类型:
SetHandler application/x-httpd-php
设置当前目录所有文件都使用PHP解析,那么无论上传任何文件,只要文件内容符合PHP语言代码规范,就会被当作PHP执行。不符合则报错。
<FilesMatch "1.jpg">
SetHandler application/x-httpd-php
</FilesMatch>
前提:Apache中允许使用 .htaccess 的配置文件(默认是开启的)
在Apache中如果需要启动 .htaccess,必须在http.conf中设置 AllowOverride

注意:.htaccess 的配置文件一般是无法在桌面上创建的,这时候就可以使用Burp抓包来直接修改上传文件的后缀名。
3)大小写绕过
Windows系统下,对于文件名中的大小写不敏感。例如:test.php和TeSt.PHP是一样的。
Linux系统下,对于文件名中的大小写敏感。例如:test.php和 TesT.php就是不一样的。
4)user.ini文件绕过
先上传一个.user.ini文件【用户自定义的配置文件】,内容为:
auto_prepend_file=1.gif
再上传一个1.gif文件,内容为木马;
最后在浏览器访问一个在当前目录下的随意一个php文件(必须存在),就能间接的访问了该以1.gif命名的木马了。
注意:
这里在当前目录下必须存在php文件;
目标的php版本有要求,php要带nts版本;
允许上传 .ini 文件;
这里很多人会想,在真实环境岂不是很鸡肋,毕竟一个不允许上传php文件的路径怎么可能会存在php文件?这里其实我们可以直接使用burp把上传的路径给改了的,让它上传到一个有php文件的路径。
5)空格绕过
绕过原理:Windows系统下,对于文件名中空格会被作为空处理,程序中的检测代码却不能自动删除空格。从而绕过黑名单。
6).号绕过
绕过原理:Windows系统下,文件后缀名最后一个点会被自动去除。
7)特殊符号绕过
绕过原理:Windows系统下,如果上传的文件名中test.php::$DATA会在服务器上生成一个test.php的文件,其中内容和所上传文件内容相同,并被解析。
例如:
在Windows系统下新建一个文件名为 1.php::$DATA的文件,查看效果。但是在Window下新建的文件名中包含特殊符号不能成功新建。

8)路径拼接绕过
绕过原理:
在没有对上传的文件进行重命名的情况下,用户可以自定义文件名并在服务器中上传新建,就会造成对应的绕过黑名单。
例如:
用户新建 1.php.+空格+.
deldot删除最后一个点之后,不再进行删除,trim删除空格,那么最终上传的文件名为 1.php.。利用Windows自动去除最后一个点,导致成功上传1.php。
9)双写绕过
绕过原理
代码编写过程中,只对黑名单中的内容进行空替换,因为只替换一次所以造成双写绕过。
例如:
1.phphpp

4、白名单绕过(00截断)
00截断原理:
0x00是十六进制表示方法,是ascii码为0的字符,在有些函数处理时,会把这个字符当做结束符。
系统在对文件名的读取时,如果遇到0x00,就会认为读取已结束。
在PHP5.3之后的版本中完全修复了00截断。并且00截断受限与GPC,addslashes函数。

注意:一定要关闭GPC,否则无法成功。
1)GET型00截断
GET型提交的内容会被自动进行URL解码。

2)POST型00截断
在POST请求中,%00不会被自动解码,需要在16进制中进行修改00.

5、文件包含漏洞绕过
在PHP中,使用include、require、include_once、require_once函数包含的文件都会被当作PHP代码执行,无论文件的名称是什么,只要符合文件内容符合PHP代码规范,都会被当作PHP代码执行。
利用存在文件包含的PHP页面,包含上传的图片木马,从而触发木马。
6、文件内容检测绕过
1) 文件幻数(文件头)检测绕过:
通过正则匹配判断文件幻数(文件头)内容是否符合要求,一般为白名单检测,常见的文件头(文件头标志位)如下:
.JPEG .JPE .JPG :"JPGGraphicFile"(FFD8FFFE00)
.gif:"GIF89A"(474946383961)
.zip:"ZipCompressed"(504B0304)
.doc .xls .xlt .ppt .apr:"MSCompoundDocumentv1orLotusApproachAPRfile"(D0CF11E0A1B11AE1)
一般是在木马文件头部插入对应的文件头内容,比如GIF89A等,伪装成图片马。
图片马制作方法:
- 直接在木马文件的头部添加GIF89A等字母;
- 直接在图片文件中添加payload(易造成图片损坏);
- 使用cmd命令,copy tupian.jpg /b + muma.php /a muma.jpg
使用edjpgcom等工具制作;
2) getimagesize()检测绕过
getimagesize()函数会读取目标文件的16进制,验证目标文件16进制的头几个字符串是否符合图片的要求,通过此函数判断文件类型。故可以使用图片马进行绕过。
源码:

3) exif_imagetype()检测绕过
exif_imagetype()函数是用来读取文件的第一个字节并检查其签名,即通过文件头判断文件类型。所以与getimagesize()函数检测一样,可使用图片马进行绕过。

7、竞争条件绕过
文件上传过程介绍

竞争条件原理介绍
网站逻辑:
网站允许上传任意文件,临时保存在服务器,然后检测上传的文件是否符合上传的条件,符合就重命名该文件并保存,不符合就删除。
在删除之前,访问上传的php文件,从而执行上传文件中的php代码。
简单来说就是,不断(大量)上传文件,同时也不断(大量)尝试请求访问该文件**,利用时间差去赌服务器线程来不及删除文件然后成功访问并执行的可能性**,从而实现先木马上传。
例如,上传文件代码如下:
<?php fputs(fopen('shell.php','w'),'<?php phpinfo(); ?>'); ?>
该代码是生成一个名叫shell.php的PHP文件,内容是一句话木马。
源码:

上传逻辑
1.通过 move_uploaded_file(temp_file, upload_file)移动上传的文件;
2.上传完毕后通过in_array(file_ext,ext_arr)检查文件名后缀是否在白名单中;
3.若后缀合法,则对文件进行重命名(rename),上传完成;
4.若后缀非法,则删除文件。
8、脏字符绕过
脏字符参数填充的地方,from-data 后面 ,或者,内容脏字符绕,当然内容脏字符绕过还是需要考虑一下语言注释符常见如jsp<!--注释内容--> php /**/ ,当waf检测内容数据包过大时,可能会放行。
9、文件路径修改绕过
木马文件上传成功,但是不解析,看请求包是否存在有指定上传路径

利用../回溯,上传到根目录

成功链接木马

10、HPP漏洞绕过
1)HPP漏洞
HPP 是 HTTP Parameter Pollution 的缩写,意思即**" HTTP 参数污染 "**。这个漏洞由 S.di Paola 与 L. Caret Toni 在 2009 年的 OWASP 上首次公布。这也是一种注入型的漏洞,攻击者通过在HTTP请求中插入特定的参数来发起攻击。如果Web应用中存在这样的漏洞,可以被攻击者利用来进行客户端或者服务器端的攻击。通过 HPP 参数污染可以实现绕过 waf 来进行攻击。
2)漏洞原理
浏览器与服务器进行交互时,浏览器提交 GET/POST 请求参数,这些参数会以 "名称-值对" 的形式出现。通常在一个请求中,同样名称的参数只会出现一次,但是在 HTTP 协议中是允许同样名称的参数出现多次的。
GET /foo?par1=val1&par2=val2 HTTP/1.1
User-Agent: Mozilla/5.0
Host: Host
Accept: */*
如上面的 HTTP 请求,在跟服务器交互的过程中,HTTP 协议允许 GET/POST 请求多次传同一参数值。
但是不同的服务器处理方式会不一样,比如必应搜索引擎,如果输入了两次查询参数q,第二次输入的参数值将覆盖第一次输入的参数值:

但是对于谷歌搜索引擎,则会将两次输入的参数值进行拼接而没有覆盖:

从上面可以看到,如果同时提供2个搜索的关键字参数给 Google,那么 Google 会对2个参数都进行查询;但是必应则不一样,它只会处理后面一个参数。服务列表
下面这个表简单列举了一些常见的 Web 服务器对同样名称的参数出现多次的处理方式:

3)漏洞利用
在HPP中最典型的的例子就是 "双文件上传" 。
1、如下例子,可以看到 filename 参数写了两次,可能绕过一些上传限制:

2、也可以尝试直接多加一个 filename(HPP):

3、或者直接多个 Content-Disposition:

4、同时可以上传一个正常图片文件+一个木马文件尝试绕过:
------61234564788
Content-Disposition: form-data; name="FileName";
filename="1.png"
图片内容
------61234564788
Content-Disposition: form-data; name="FileName1";
filename="1.php"
木马内容
------61234564788--
八、防护措施
检测的重点放在文件内容检测
路径/扩展名检测一定要用白名单
不能有本地文件包含漏洞
随时注意更新Web应用软件
调整好格式输出
