介绍
文件上传漏洞是指当 WEB 服务对用户上传到其文件系统而没有进行充分验证其名称、类型、内容、大小等内容时产生的,如果没有执行这些限制攻击者可能上传具有危险的文件甚至是远程代码执行的服务器端脚本文件,当然这其中最关键是服务器如何处理、解释文件,如果服务器的处理逻辑不够安全则可能会导致严重后果。
原因
服务器配置不当
开源编辑器上传漏洞
本地文件上传限制被绕过
过滤不严格被绕过
文件解析漏洞导致文件执行
文件路径截断
影响
文件上传漏洞的影响一般取决于两个关键因素:
网站没有正确验证文件的一些信息 eg : 大小、类型、内容
文件上传成功后有哪些限制
比如:
服务器对某些类型文件 (.php .jsp) 配置为允许执行,在这种情况下,攻击者可能上传充当 WEB SHELL 的服务器端代码文件
如果文件名没有进行验证。攻击者可能上传同名文件来覆盖一些关键文件
如果对文件大小没有限制还可能导致拒绝服务攻击,攻击者可以利用此漏洞填满磁盘空间
WEB 服务器如何处理对静态文件的请求
在我们研究如何利用文件上传漏洞之前,重要的是您对服务器如何处理静态文件请求有一个基本的了解。
从历史上看,网站几乎完全由静态文件组成,这些文件会在用户请求时提供给他们。因此,每个请求的路径可以与服务器文件系统上的目录和文件层次结构 1:1 映射。如今,网站越来越动态,请求的路径通常与文件系统没有直接关系。尽管如此,Web 服务器仍然处理对一些静态文件的请求,包括样式表、图像等。
处理这些静态文件的过程在很大程度上仍然是相同的。在某些时候,服务器解析请求中的路径以识别文件扩展名。然后它使用它来确定所请求文件的类型,通常是通过将其与扩展名和 MIME 类型之间的预配置映射列表进行比较。接下来发生的事情取决于文件类型和服务器的配置。
如果此文件类型是不可执行的,例如图像或静态 HTML 页面,则服务器可能只是在 HTTP 响应中将文件的内容发送给客户端。
如果文件类型是可执行的,比如PHP文件,并且服务器被配置为执行这种类型的文件,它会在运行脚本之前根据HTTP请求中的头部和参数分配变量。生成的输出然后可以在 HTTP 响应中发送到客户端。
如果文件类型是可执行的,但服务器没有配置为执行这种类型的文件,它通常会响应一个错误。但是,在某些情况下,文件的内容可能仍以纯文本形式提供给客户端。此类错误配置偶尔会被利用来泄露源代码和其他敏感信息
攻击
1. 有缺陷的文件类型验证
服务器通过 Content-Type 来对上传的文件类型验证
2. 上传至其他目录
用户正常文件上传的目录可能具有严格的限制,而其他目录则没有,我们可以将文件上传到其他目录上,服务器可能执行我们上传的脚本
3. 黑名单
服务器可能会将具有潜在威胁的文件扩展名列入黑名单,这时候我们可以通过测试来找到一些替代的文件扩展名来绕过黑名单限制
4. 覆盖服务器配置
服务器通常不会执行文件,除非将他们配置为执行文件,我们可以对配置文件修改,来实现对文件的执行
1. .htaccess
htaccess文件(或者"分布式配置文件")提供了针对目录改变配置的方法, 即,在一个特定的文档目录中放置一个包含一个或多个指令的文件, 以作用于此目录及其所有子目录。作为用户,所能使用的命令受到限制。管理员可以通过Apache的AllowOverride指令来设置。
概述来说,htaccess文件是Apache服务器中的一个配置文件,它负责相关目录下的网页配置。通过htaccess文件,可以帮我们实现:网页301重定向、自定义404错误页面、改变文件扩展名、允许/阻止特定的用户或者目录的访问、禁止目录列表、配置默认文档等功能。
启用.htaccess,需要修改httpd.conf,启用AllowOverride,并可以用AllowOverride限制特定命令的使用。如果需要使用.htaccess以外的其他文件名,可以用AccessFileName指令来改变。例如,需要使用.config ,则可以在服务器配置文件中按以下方法配置:AccessFileName .config 。
笼统地说,.htaccess可以帮我们实现包括:文件夹密码保护、用户自动重定向、自定义错误页面、改变你的文件扩展名、封禁特定IP地址的用户、只允许特定IP地址的用户、禁止目录列表,以及使用其他文件作为index文件等一些功能
一般.htaccess
可以用来留后门和针对黑名单绕过。在上传网站的根目录下,上传一个.htaccess
文件即可。
绕过方法:
针对黑名单绕过
创建一个txt文件,写入
另存为
.htaccess
名称,保存类型为所有文件,即可将png
文件解析为php
文件。留后门
在
.htaccess
内写入php
解析规则,类似于把文件名包含s
的解析成php
文件利用.htaccess进行文件包含
使用#注释使得.htaccess能够成功解析
5. 混淆文件扩展名
大小写扩展名
双写扩展名
特殊后缀名
提供多个扩展, 根据用于解析文件名的算法,以下文件可能被解释为 PHP 文件或 JPG 图像:
exploit.php.jpg
添加尾随字符, 一些组件会去除或忽略尾随的空格、点等:
exploit.php.
尝试对点、正斜杠和反斜杠使用 URL 编码(或双重 URL 编码)。如果在验证文件扩展名时该值未被解码,但稍后在服务器端被解码,这也可以让您上传本来会被阻止的恶意文件:
exploit%2Ephp
在文件扩展名前添加分号或 URL 编码的空字节字符。如果验证是用 PHP 或 Java 等高级语言编写的,但服务器使用 C/C++ 中的低级函数处理文件,例如,这可能会导致文件名末尾的差异:
exploit.asp;.jpg
或exploit.asp%00.jpg
尝试使用多字节 unicode 字符,这些字符在 unicode 转换或规范化后可能会转换为空字节和点。 如果文件名被解析为 UTF-8 字符串,则 xC0 x2E、xC4 xAE 或 xC0 xAE 等序列可能会被转换为 x2E,但在用于路径之前会被转换为 ASCII 字符。
6. 文件内容验证有缺陷
1. 文件头信息检测
与隐式信任Content-Type
请求中指定的内容不同,更安全的服务器会尝试验证文件内容是否确实符合预期。
在图像上传功能的情况下,服务器可能会尝试验证图像的某些固有属性,例如尺寸。例如,如果您尝试上传一个 PHP 脚本,它根本就没有任何维度。因此,服务器可以推断它不可能是图片,并据此拒绝上传。
同样,某些文件类型可能始终在其页眉或页脚中包含特定的字节序列。这些可以像指纹或签名一样用于确定内容是否与预期类型匹配。例如,JPEG 文件总是以字节开头FF D8 FF
。
这是验证文件类型的更可靠的方法,但即使这样也不是万无一失的。使用 ExifTool 等特殊工具,可以轻松创建在其元数据中包含恶意代码的多语言 JPEG 文件。
2. 判断 <? php
绕过
<?
:绕过
php
:
7. 利用文件上传竞争条件
文件上传的位置和最终存储位置不在一个目录中
服务器接收文件后,不再验证直接转移目录,我们可以使用爆破进行不断访问
服务器接收文件后,在进行验证,如果没有通过则删除
攻击者需要先上传一个WebShell脚本1.php,1.php的内容为生成一个新的WebShell脚本shell.php,1.php写入如下代码
当1.php上传完成后,客户端立即访问1.php,则会在服务端当前目录下自动生成shell.php,这时攻击者就利用了时间差完成了WebShell的上传
8. 基于 URL 的文件上传中的竞争条件
允许您通过提供 URL 上传文件的函数中可能会出现类似的竞争条件。在这种情况下,服务器必须通过 Internet 获取文件并创建本地副本,然后才能执行任何验证。
由于文件是使用 HTTP 加载的,开发人员无法使用其框架的内置机制来安全验证文件。相反,他们可能会手动创建自己的进程来临时存储和验证文件,这可能不太安全。
例如,如果文件被加载到一个随机名称的临时目录中,理论上,攻击者应该不可能利用任何竞争条件。如果他们不知道目录的名称,他们将无法请求该文件以触发其执行。另一方面,如果随机目录名称是使用伪随机函数(如 PHP 的)生成的uniqid()
,则它可能会被暴力破解。
为了使此类攻击更容易,您可以尝试延长处理文件所花费的时间,从而延长暴力破解目录名称的时间。一种方法是上传更大的文件。如果它以块的形式处理,您可以通过创建一个恶意文件来利用这一点,该恶意文件的开头是有效负载,后跟大量任意填充字节
9. 无需远程代码执行即可利用文件上传漏洞
1. 上传恶意客户端脚本
虽然您可能无法在服务器上执行脚本,但您仍然可以上传脚本以进行客户端攻击。例如,如果您可以上传 HTML 文件或 SVG 图像,则可以使用<script>
标签来创建存储的 XSS负载。
2. 利用上传文件解析漏洞
10. 使用 PUT 上传文件
值得注意的是,某些 Web 服务器可能配置为支持PUT
请求。如果没有适当的防御措施,这可以提供一种上传恶意文件的替代方法,即使上传功能无法通过 Web 界面使用。
11. 多文件上传
本意为上传两个或多个文件去突破。上传点支持多文件上传,但是却只对第一个文件做了过滤。
利用方式:
在存在双文件上传漏洞的页面中,查看上传的页面。F12找到上传的post表单,action属性是指定上传检测页面,一般是写的绝对路径,比如:
xxx.asp/xxx.php
补全url:
https://www.xxx.com/xxx.php(asp)
构造本地post提交表单
利用时只需要修改action的值为指定上传页面即可
第一个文件上传允许的文件类型(
.jpg
.png
.gif
等),第二个上传文件是一句话木马或者WebShell脚本。这样就可以突破上传限制,成功上传木马到服务器。
12. WEB 容器解析漏洞
1. 目录解析
形式:
www.xxx.com/xxx.asp/xxx.jpg
原理:服务器会默认把
.asp
和.asp
目录下的文件都解析成asp文件
2. 文件解析
形式:
www.xxx.com/xxx.asp;.jpg
原理:服务器默认不解析
;
后面的内容,因此xxx.asp;jpg
被解析为xxx.asp
文件了
3. IIS 目录解析漏洞和 分号解析漏洞
将一句话木马的文件名 backlion.php,改成 backlion.php.abc(奇怪的不被解析的后缀名都 行)。首先, 服务器验证文件扩展名的时候,验证的是.abc,只要该扩展名符合服务器端黑白名单觃则,即可上传。
4. NGINX 漏洞
空字节漏洞: xxx.jpg%00.php 这样的文件名会被解析为php代码运行
MGINX 解析漏洞
Nginx默认是以CGI的方式支持PHP解析的,普遍的做法是在Nginx配置文件中通过 正则匹配设置SCRIPT_FILENAME。当访问
www.xxx.com/phpinfo.jpg/1.php
这个 URL时,$fastcgi_script_name会被设置为“phpinfo.jpg/1.php”,然后构造成 SCRIPT_FILENAME传递给PHP CGI。原因是开启了 fix_pathinfo 这个选项,会触发 在PHP中的如下逻辑: PHP会认为SCRIPT_FILENAME是phpinfo.jpg,而1.php是PATH_INFO,所以就会 将phpinfo.jpg作为PHP文件来解析了。
5. Apache 解析漏洞
服务器代码中限制了某些后缀的文件不允许上传,但是有些Apache是允许解析其它后缀的,例如在httpd.conf中如果配置有如下代码,则能够解析php和phtml文件
在Apache的解析顺序中,是从右到左开始解析文件后缀的,如果最右侧的扩展名不可识别,就继续往左判断,直到遇到可以解析的文件后缀为止。因此,例如上传的文件名为1.php.xxxx,因为后缀xxxx不可解析,所以向左解析后缀php。
防御
设置扩展名白名单
确保文件名不包含任何可能被解释为目录或遍历序列的子字符串
重命名上传文件
在完成验证之前,不要将文件上传到服务器的永久文件系统
尽可能使用已建立的框架来处理文件上传,而不是自己尝试编写验证机制
参考
最后更新于
这有帮助吗?