文件下载漏洞
概述
文件下载功能在很多web系统上都会出现,一般我们当点击下载链接,便会向后台发送一个下载请求,一般这个请求会包含一个需要下载的文件名称,后台在收到请求后 会开始执行下载代码,将该文件名对应的文件response给浏览器,从而完成下载。 如果后台在收到请求的文件名后,将其直接拼进下载文件的路径中而不对其进行安全判断的话,则可能会引发不安全的文件下载漏洞。
此时如果 攻击者提交的不是一个程序预期的的文件名,而是一个精心构造的路径(比如…/…/…/etc/passwd),则很有可能会直接将该指定的文件下载下来。 从而导致后台敏感信息(密码文件、源代码等)被下载。
所以,在设计文件下载功能时,如果下载的目标文件是由前端传进来的,则一定要对传进来的文件进行安全考虑
测试
存在图片地址和图片下载的链接地址 ,
图片地址:https://www.bihuoedu.com/vul/unsafedownload/download/kb.png
图片下载的链接地址:https://www.bihuoedu.com/vul/unsafedownload/execdownload.php?filename=kb.png
因为execdownload.php在unsafedownload目录下,此图片下载地址为unsafedownload目录的下一级,故下载execdownload.php时要返回上一级,再下载,为../execdownload.php
下载文件,就可以查看execdownload.php的内容了
文件上传漏洞
概述
文件上传功能在web应用系统很常见,比如很多网站注册的时候需要上传头像、上传附件等等。当用户点击上传按钮后,后台会对上传的文件进行判断 比如是否是指定的类型、后缀名、大小等等,然后将其按照设计的格式进行重命名后存储在指定的目录。 如果说后台对上传的文件没有进行任何的安全判断或者判断条件不够严谨,则攻击着可能会上传一些恶意的文件,比如一句话木马,从而导致后台服务器被webshell。
所以,在设计文件上传功能时,一定要对传进来的文件进行严格的安全考虑。比如:
–验证文件类型、后缀名、大小;
–验证文件的上传方式;
–对文件进行一定复杂的重命名;
–不要暴露文件上传后的路径;
–等等…
Content-Type限制(内容类型)
一般是指网页中存在的 Content-Type,用于定义网络文件的类型和网页的编码,决定浏览器将以什么形式、什么编码读取这个文件,这就是经常看到一些 PHP 网页点击的结果却是下载一个文件或一张图片的原因。Content-Type 标头告诉客户端实际返回的内容的内容类型。
MIME type限制了上传的文件,可将类型改为image/jpeg
上传成功
连接成功
getimagesize()函数绕过
可上传图片木马,输入copy /b 2.jpg + 1.php 3.jpg
合成3.jpg
上传3.jpg并连接
但没有执行代码,没有解析图片
所以可以借助文件包含执行图片代码(借助文件包含的url)
https://www.bihuoedu.com/vul/fileinclude/fi_local.php?filename=file1.php&submit=%E6%8F%90%E4%BA%A4%E6%9F%A5%E8%AF%A2
,再将图片地址包含进去
常见绕过方式
类型 | 方式 |
---|---|
对后缀的限制 | 可上传php,asp,cer,.htaccess,aspx等 ,在后缀后面可加空格,或截断等 |
客户端js检测上传文件后缀 | 通过burp抓包更改响应后缀 |
apache解析顺序 | 从右到左开始解析后缀,若最右侧的扩展名不可识别,则继续向左判断,直到遇到可以解析的文件后缀为止,如1.php.xxx会被解析为1.php |
不长见类型后缀 | 可尝试上传一些罕见后缀,如1.phtml |
Content-Type限制 | 此值通过客户端传递,可修改为 相应的类型,如图片类型为image/jpeg |
getimagesize() | 可将图片和webshell合成一个图片文件,如cat image.png webshell.php > image.php (linux) |
截断绕过 | php<5.3.4时,magic_quotes_gpc为off状态,00代表结束符,会把后面的所以字符删去。如上传1.php%00.jpg时,%00会把包括.jpg之后的文件名截断,之后就会保存为1.php |
条件竞争 | 一些网站上传文件先允任意上传文件,之后再检测,若检查有webshelll脚本,则删除。这里就存在检查和删除之间的时间差,可以利用这个时间差完成条件竞争的上传漏洞攻击(快速上传) |
*文件上传修复建议:*通过白名单的方式判断文件后缀是否合法,对上传文件重命名,如rand(1,99).date("YmdHis").".jpg"
。