漏洞描述
1.文件上传漏洞
文件上传漏洞介绍
文件上传漏洞是指用户上传了一个可执行的脚本文件,并通过此脚本文件获得了执行服务器端命令的能力。"文件上传" 本身没有问题,有问题的是文件上传后,服务器怎么处理、解释文件。如果服务器的处理逻辑做的不够安全,则会导致严重的后果。这种攻击方式是最为直接和有效的,所以我们需要思考的是如何绕过检测和过滤。
文件上传漏洞危害
上传文件是web脚本语言,服务器的web容器解释并执行了用户上传的脚本,导致代码执行。上传文件是病毒或者木马时,主要用于诱骗用户或者管理员下载执行或者直接 自劢运行;上传文件是Flash的策略文件 crossdomain.xml,黑客用以控制Flash在该域 下的行为(其他通过类似方式控制策略文件的情况类似);上传文件是病毒、木马文件,黑客用以诱骗用户或者管理员下载执行;上传文件是钓鱼图片或为包含了脚本的图片,在某些版本的浏览器中会被作为脚本执行,被用于钓鱼和欺诈。 除此之外,还有一些不常见的利用方法,比如将上传文件作为一个入口,溢 出服务器的后台处理程序,如图片解析模块;或者上传一个合法的文本文件,其内容包含了PHP脚本,再通过"本地文件包含漏洞(Local File Include)"执行此脚本。
文件上传漏洞满足条件
上传的后门文件,需要能被脚本语言解析执行。
说明一:对方服务器运行的PHP环境,你不能上传一个JAVA的后门代码。
说明二:你上传文件的目录可以被脚本语言解析执行,如果你上传的目录没有执行权限也不行
说明三:一般文件上传后会返回你一个地址,如果无妨链接到也不能构成文件上传漏洞。
还有例外情况,非脚本文件也能被成功解析。比如:上传了一个图片,如果对方中间件上存在一些漏洞的话,配合这些漏洞可以实现图片文件按照脚本文件解析。
2.文件包含
一种代码处理方法,函数如include,require等,参数是文件名。
3.文件包含漏洞(以PHP为例)
文件包含漏洞的产生原因是在通过 PHP 的函数引入文件时,由于传入的文件名没有经过合理的校验,从而操作了预想之外的文件,就可能导致意外的文件泄露甚至恶意的代码注入。
include() 当使用该函数包含文件时,只有代码执行到 include() 函数时才将文件包含进来,发生错误时只给出一个警告,继续向下执行。
include_once() 功能和 include() 相同,区别在于当重复调用同一文件时,程序只调用一次。
require() 只要程序一执行就会立即调用文件,发生错误的时候会输出错误信息,并且终止脚本的运行
require_once() 它的功能与 require() 相同,区别在于当重复调用同一文件时,程序只调用一次。
当使用这四个函数包含一个新文件时,该文件将作为 PHP 代码执行,php 内核并不在意该被包含的文件是什么类型。所以如果被包含的是 txt 文件、图片文件、远程 url、也都将作为 PHP 代码执行。这一特性,在实施攻击时非常有用。
一、 文件上传
1. Low等级
查看源码

可以看到,服务器对上传文件的类型、内容没有做任何的检查、过滤,存在明显的文件上传漏洞,生成上传路径后,服务器会检查是否上传成功并返回相应提示信息。
本地上传
编写木马

上传文件

上传成功
将显示出来的路径与url进行拼接,测试上传文件

直接访问测试上传成功
(2) Medium等级
查看源码

可以看到这里对上传的文件做了一个简单的前段验证,验证文件的后缀名是否为jpeg,png,同时对文件的大小做出了限制。
本地上传
对于上述验证,有多种绕过方法比如:%00截断、修改后缀等等以下是修改后缀
对此可以将low中上传的1.php文件改为1.png进行上传,然后用burpsuite进行抓包,修改后缀为php上传;
方法一:
先用burpsuite进行抓包

修改文件格式类型

修改类型为image/jepg并放包重新上传

上传成功
方法二:
修改文件名(00截断)

抓包并修改参数

将70改为00,放包重新上传

上传成功
- High等级
查看源码

可以看到这里又添加了一个getimagesize(string filename)函数,它会通过读取文件头,返回图片的长、宽等信息,如果没有相关的图片文件头,函数会报错。这里读取文件名中最后一个"."后的字符串,期望通过文件名来限制文件类型,因此要求上传文件名形式必须是".jpg"、".jpeg" 、"*.png"之一。同时,getimagesize函数更是限制了上传文件的文件头必须为图像类型。
本地文件上传
使用终端将木马文件添加到图片文件的后面

使用记事本打开查看木马程序

可以看见木马程序在最后
重新上传文件

上传成功,查看上传信息

4 、 Impossible等级
查看源码

机制:
可以看到,Impossible级别的代码对上传文件进行了重命名(为md5值,导致%00截断无法绕过过滤规则),加入Anti-CSRF token防护CSRF攻击,同时对文件的内容作了严格的检查,导致攻击者无法上传含有恶意脚本的文件。
修复、防御本地上传的方法:
1.文件类型验证:在接受用户上传的文件之前,进行严格的文件类型验证,以确保只允许合法的文件类型上传。这可以通过文件扩展名、MIME 类型或文件头部信息进行验证。
2.文件大小限制:限制用户上传的文件大小,防止恶意用户上传过大的文件导致服务器资源耗尽或拒绝服务攻击。
3.隔离上传文件:将用户上传的文件保存在与应用程序代码和系统文件隔离的位置,避免直接访问上传文件的路径。
4.权限控制:确保上传文件的存储目录具有适当的权限设置,限制对上传文件的访问和执行权限。
5.病毒扫描:对上传的文件进行病毒扫描,确保上传的文件不包含恶意代码。
6.安全编程实践:使用安全的编程语言和框架,避免直接将上传文件内容作为可执行代码执行。
7.安全配置:确保服务器和应用程序的安全配置,包括限制文件上传的大小、类型和数量等。
8.持续监控:定期审查和监控文件上传功能,及时发现潜在的安全问题并采取相应的措施。
二、 文件包含
- Low等级

图中 file1.php、file2.php、file3.php 是服务器希望用户点击,服务器包含相应的文件,返回结果。服务器包含文件时无论文件后缀是否是php,均当做php文件来执行。当文件内容为php,返回正常执行结果;当文件内容不是php,则原封不动打印文件内容。
查看核心代码:page未做任何过滤。

点击File 1.php

发现URL可以被利用,开始尝试
(1)本地文件包含
构造url
http://192.168.241.133/DVWA/vulnerabilities/fi/?page=/etc/shaow ,其中/etc/shaow为linux的系统路径。

同时得到了文件的绝对路径为:
C:\phpstudy\PHPTutorial\WWW\DVWA\vulnerabilities\fi\index.php

构造绝对路径url

构造url(相对路径):因为文件位于fi文件夹下,距离根目录还有2层,所以可以使用../../进行跨目录读取。 "..\"代表上一层目录,".\"代表下一层目录。
http://192.168.241.133/DVWA/vulnerabilities/fi/?page=..\..\php.ini

显示出php.ini的内容,说明成功读取。

(2)远程文件包含
尝试查看和执行服务端本来就有的脚本文件
当服务器的php配置中,allow_url_fopen和allow_url_include打开时,服务器会允许包含远程服务器上的文件。在远程服务器上上传一个phpinfo.txt文件。这里我们自己编辑文件存放在windown10系统。

构造url
http://192.168.241.133/DVWA/phpinfo.php
http://192.168.241.133/DVWA/vulnerabilities/fi/?page=..\..\phpinfo.php


为了增加隐蔽性,可以百度一个在线编码工具,对url进行编码:
http://192.168.241.133/DVWA/vulnerabilities/fi/?page=C:\phpstudy\PHPTutorial\WWW\DVWA\phpinfo.php
同样可成功执行。
同样也可以用于访问其他


成功执行。
Medium等级
查看核心代码

str_replace()函数对"http://"、"https://"、"../"、"..\"都进行了过滤删除。
但str_replace()可以用双写绕过。且规则里绕过"../"、"..\",则用绝对路径的方式包含文件不受此规则限制。(本文由于phpinfo.txt文件在本地,无http://或https://,故为
方法一:绝对路径

http://192.168.241.133/DVWA/vulnerabilities/fi/?page=C:\\phpstudy\\PHPTutorial\\WWW\\DVWA\\php.ini)

获取成功
方法二:改变大小写
http://192.168.241.133/DVWA/vulnerabilities/fi/?page=hTTp://192.168.241.133/phpinfo.php)

获取成功
方法三:复写

获取成功
High等级
查看核心代码

这里使用fnmatch()函数对page参数进行过滤,要求page必须以"file"开头,服务器才会包含相应的文件。
file协议:本地文件传输协议)主要用于访问本地计算机中的文件。基本格式为:file:///文件路径。
故利用file协议,构造url:
(1)本地文件包含:

本地文件成功
(2)远程文件包含:
发现远程文件执行也需要file开头的,发现file协议只能执行本地文件,需要结合文件上传漏洞,然后进行本地文件执行。先使用文件上传,上传木马。

这里上传了带了木马的png图片。

Impossible等级
查看核心代码

发现page参数只能是:include.php、file1.php、file2.php、file3.php文件,否则就会输出错误提示。
机制:
1.禁止包含任何本地或远程的文件:在Impossible等级下,Web应用程序将不允许包含本地或远程的任何文件,包括本地文件系统、网络共享和远程服务器等。这样可以防止攻击者使用恶意文件替换Web应用程序的关键文件,或者通过包含远程文件来执行恶意代码。
2.随机生成文件名和路径:在Impossible等级下,Web应用程序会随机生成文件名和路径,而不是从用户输入中获取。这样可以防止攻击者使用特定的文件名或路径来绕过过滤和验证机制,进而执行恶意代码。
3.禁止上传文件:在Impossible等级下,Web应用程序将禁止用户上传任何文件,以防止攻击者上传恶意文件到服务器上,并通过包含漏洞来执行它们。
4.设置严格的文件访问权限:在Impossible等级下,Web应用程序将设置严格的文件访问权限,只允许访问必要的文件和目录,并禁止访问其他敏感文件。这样可以防止攻击者通过包含漏洞来访问敏感文件和目录,进而执行恶意代码。
修复和防御文件包含的方法:
1.输入验证和过滤:对用户输入的文件名或路径进行严格的验证和过滤,只允许合法的、预期的文件被包含。
2.文件路径处理:避免直接使用用户提供的文件路径,而是使用固定的、可信任的路径或白名单机制来引用文件。
3.限制文件系统访问权限:确保应用程序运行的上下文只有最小必要的权限,并限制对系统文件和目录的访问。
4.安全编程实践:使用安全的编程语言和框架,并遵循最佳实践,如避免使用动态文件包含函数。
5.安全配置:确保服务器和应用程序的安全配置,包括禁用不必要的服务、限制文件系统访问等。
6.更新和补丁管理:及时更新应用程序和相关组件,以修复已知的漏洞,并及时应用安全补丁。