文件上传漏洞
文件上传的功能在web 应用系统很常见,很多网站都会会允许用户上传头像、附件、视频等。
然而向用户提供的功能越多,web 应用受到攻击的风险越大。
用户点击上传按钮后,后台会对上传的文件进行判断是否为指定的类型、后缀名、大小等等,然后将其按设计的格式重命名存储在指定的目录。
如果后台对上传的文件没有进行任何安全判断或判断条件不够严谨,攻击者就可能上传一些恶意文件。比如上传一句话木马。
原理
在web 应用程序中进行文件上传是通过将表单设为 multipart/form-date( 是http请求中的multipart/form-data,它会将表单的数据处理为一条消息,以标签为单元,用分隔符分开),同时加入文件域,通过 http 协议将文件内容发送到服务器,服务器端读取这个分段(multipart)的数据信息,并将文件的内容提取出来保存。
在文件保存时,服务器端会读取文件的原始文件名,并得出文件的拓展名,而后会为文件起一个名字(防止存储的文件名重复),并加上原始文件的拓展名保存在服务器上。
危害
攻击者可以利用上传的恶意脚本控制整个网站,甚至控制服务器。
这个恶意脚本文件,又被称为 webshell ,也可将 webshell 脚本称为一种网页后门。
webshell
是以 asp、php、jsp或 cgi 等网页文件形式存在的一种命令执行环境,也称之为一种网页后门。
webshell 脚本具有强大的功能,比如查看服务器目录、服务器中的文件,执行系统命令等。
攻击者入侵一个网站后,会将这些上传的网页后门文件与网站服务器目录下正常的网页文件混在一起,然后通过浏览器访问这些后门,得到命令执行环境,达到控制网站的目的。
webshell 后门的隐蔽性高,可以轻松穿越防火墙,访问 webshell 时不会留下系统日志,只会在网站的web 日志中留下一些数据提交记录。。
攻击者将 webshell 隐藏在正常文件中并修改文件时间增强隐蔽性,也可以采用一些函数对 webshell 进行编码规避检测来提高隐蔽性。
文件上传漏洞的绕过方式
JS检测绕过
例如这一段在前端的源代码中会有一段JavaScript 代码对上传的文件形式进行验证。
在选择文件时,会调用 js 中的函数,如果上传文件不符合要求,就会弹窗提示。
可以通过关闭浏览器的 JavaScript 功能来进行绕过。
也可以先上传一个不允许的文件 .php ,用 burp 抓包,再修改文件后缀,点击 forword 放包,就上传文件成功。
文件后缀绕过
服务端会通过函数获取文件后缀,判断是否符合要求,如果不符合,则不允许上传。
若上传文件后缀被限制,可尝试:
大小写:.Php .pHp .phP
空格:1.php 改为 1. php ("."后面又个空格)
双写后缀:1.phphpp (后端代码会把后缀名替换为空字符)
文件类型绕过
客户端上传文件时,通过 burpsuite抓包。
如果上传一个 .php格式的文件,数据包中 Content-Type 的值是 application/octet-stream。
上传 jpj 格式的文件时,数据包中 Content-Type 的值是 image/jpeg 。
如果服务端代码通过 Content-Type 的值来判断文件的类型,那么就存在被绕过的可能。
检测Content-Type的值的也叫 MIME类型
因为 Content-Type 的值是通过客户端传递的,可以任意修改。
所以如果上传一个 php 文件时,在 burp 中将 Content-Type 的值 application/octet-stream 改为 image/jpeg,就可以绕过服务端的检测。
在PHP中还存在一种类似的文件上传漏洞,PHP函数 getimagesize() 可以获取图片的宽、高等信息。
如果上传的不是图片文件,getimagesize() 函数就获取不到信息,文件就不允许上传。
这里就可以将一个图片和一个 webshell 合并为一个文件,此时可以通过 getimagesize() 函数,就可以达到上传文件的目的。
文件截断绕过
截断类型:PHP %00截断
截断原理:00代表结束符,会把00后面的所有字符删除。
截断条件:PHP版本小于5.3.4,PHP的配置文件中的 magic_quotes_gpc 为 off 状态。
00截断绕过上传限制适用的场景:
后端先获取文件的文件名,比如网站允许上传后缀名为 .jpg,上传文件1.php\00.jpg。
再根据文件名得到文件的实际后缀 .jpg
通过后缀的白名单校验后,最终在保存文件时00截断就会产生作用,导致后端实际保存的文件为 1.php
文件上传修复
验证文件类型、后缀名、大小,即进行白名单验证;
上传后在指定的目录进行存储,防止目录解析漏洞;
验证文件的上传方式;
对文件进行一定复杂的重命名;
不暴露文件上传后的路径。