本篇文章用于巩固对自己文件上传漏洞的学习总结,其中部分内容借鉴了以下博客。
链接: pikachu Unsafe Fileupload 不安全的文件上传(皮卡丘漏洞平台通关系列))
凡是存在文件上传的地方均有可能存在文件上传漏洞,关于上传文件操作的时候对方代码写的是否完整、是否安全,一旦疏忽了某个地方可能会造成文件上传漏洞。
网站Web应用都有一些文件上传功能,比如文档、图片、头像、视频上传,当上传功能的实现代码没有严格校验上传文件的后缀和文件类型,此时攻击者就可以上传一个webshell到一个Web可访问的目录上,并将恶意文件传递给如PHP解释器去执行,之后就可以在服务器上执行恶意代码,进行数据库执行、服务器文件管理,服务器命令执行等恶意操作。还有一部分是攻击者通过Web服务器的解析漏洞来突破Web应用程序的防护
文件可以自定义,可以成为Webshell,通过文件上传来上传后门,直接获取网站权限,属于高危漏洞。上传漏洞与SQL注入或者XSS相比,其风险更大。可以获取数据库信息,可以对服务器提权,获取内网权限。
1.黑盒查找
文件后台
进入网站后台不一定能获得网站权限,可以从后台获取网站权限
会员中心
通过图片上传
文件扫描
使用工具扫描出后台路径
2.白盒查找
通过代码分析到上传漏洞
查找文件上传功能
进入第一关有一个文件上传的按钮
先看一下直接上传php文件是个什么效果
如下图所示,刚选好文件,还没有点 “开始上传” 的时候,就弹出了提示 上传的文件不符合要求
客户端验证一般两种绕过方法
(1)浏览器禁用javascript
(2)burpsuite抓包改后缀
方法一、浏览器禁用javascript
firefox有个插件叫JS Switch可以很方便的控制启用和禁用JS(有时候好像有点迟钝,可以多试几次)
先禁用JS,然后上传文件muma.php,内容如下
禁用JS之后可以上传成功,回显了保存路径
方法二、burpsuite抓包改后缀
把muma.php文件名改muma.png,上传过程中burpsuite抓包
抓到上图所示的报文,右键 send to repeater
网页上 右键 查看网页源代码 可以在比较靠后的地方看到下图所示的代码
进入第二关,发现和上一关一样,也是一个上传界面
点击上传muma.php查看一下现象,发现没有弹窗,点“开始上传”之后会提示“上传的图片只能是jpg,jpeg,png格式的!”
关卡名字都透题了就直接来吧
说起来是两个思路,不过严格来说不能算两个思路,稍微有点殊途,很快同归
(1)上传muma.php,burpsuite抓包修改MIME type (好处是服务器上不会多一个没用的文件)
(2)上传muma.png,burpsuite抓包修改文件后缀 (好处是只要这个文件上传成功了,MIME type肯定是对的)
这里就不两个都演示了,反正最后请求报文都是一样的,用第二个方法来演示一下。
上传muma.png,burpsuite抓包
把filename改成muma.php,点forward,文件上传成功
关于MIME类型的介绍可以看这个网页链接: MIME类型,在HTTP request报文中MIME类型在Content-Type字段体现。
本关的防护代码如下图所示
$mime是一个包含合法MIME类型的数组,也就是MIME类型白名单;然后将这个白名单作为参数传入了upload_sick()函数进行服务器端的检测。
upload_sick()函数的定义如下,该函数不安全之处在于两点:
(1)仅检查了MIME类型,可以通过抓包修改绕过。
(2)保存文件的时候没有重命名文件,这样即使网页不回显文件保存路径,也有很大概率可以被攻击者猜测到。
整个关卡还有一处不安全,就是回显了文件保存路径。
成功上传webshell,并且知道文件保存路径后,攻击者就可以连接shell了。
和之前一样传一个muma.php,上传失败,提示和上一关有区别,多了个上传文件后缀名不能为空,由于上传的文件是有后缀名的,也许后端代码会删掉原本的后缀名并根据一些规则替换新的后缀名?或者这里只是迷惑操作?
传一个名为muma.png,实际内容是第一关中一句话木马的文件,发现服务器可以识别出这是个假图片:
上传名为“小白-正常图片.jpeg”的真的jpeg文件,回显如下,可见后端代码修改了文件名,但是把文件保存路径回显出来实在是个大胆的决定。。接下来就看看到底是不是艺高人胆大吧
这关的名字看起来是个函数,先用搜索引擎搜索一下试试:
getimagesize() 函数用于获取图像大小及相关信息,成功返回一个数组,失败则返回 FALSE 并产生一条 E_WARNING 级的错误信息。
getimagesize() 函数将测定任何 GIF,JPG,PNG,SWF,SWC,PSD,TIFF,BMP,IFF,JP2,JPX,JB2,JPC,XBM 或 WBMP 图像文件的大小并返回图像的尺寸以及文件类型及图片高度与宽度。
上传一张图片马(图片中间插入一句话木马),返回了文件保存路径
查看上述路径的图片,发现图片中仍保留着一句话木马,也就是说没有对图片内容进行检查和修改。
由于这关对文件后缀的检查是基于白名单的,所以这关后缀名绕过也行不通(这里偷了点懒,直接看代码了,黑盒状态下可以通过burpsuite爆破文件名后缀尝试绕过。
而从burpsuite截获的本关的request报文来看,本关也并不满足00截断的条件。
目前以我的知识面知道的本关的解法就是上传图片马并结合文件包含漏洞了。。如果哪位大神有其他思路,万望告知。(其实还可以利用Nginx解析漏洞,但是我这windows系统+phpstudy 8.1.1.2的环境似乎造不出这个漏洞来。相关知识点可搜索“Nginx解析漏洞”,以及这个链接: phpStudy nginx 解析漏洞通告)
图片马可以是基于真实图片的,也可以只是加个文件头。只加magic number就可以绕过的时候,直接加文件头的方式固然是更方便;但是普遍来说,还是在真实图片基础上制作图片马更保险。比如本关,直接加magic number是难以成功的,推测可能是因为getimagesize()函数检测的东西比较多,不仅仅是magic number。
这关是三关里面最安全的了,不能上传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行,修改文件名为随机值(本来是防止攻击者猜测文件路径的,但是由于网页上回显了文件保存路径,所以这个重命名的步骤显得没有什么卵用了。)