文件上传
将客户端数据以文件形式封装,通过网络协议发送到服务端,在服务端解析数据,最终在服务端硬盘上作为真实文件保存
文件上传检查方式
客户端JavaScript检测(检查文件扩展名)
服务端MIME类型检测(检查content-type内容)
服务端目录路径检测(检测跟文件path相关内容)
服务端文件扩展名检测(检测跟文件extension相关内容)
服务端文件内容检测(检测内容是否合法是否含有恶意代码)
绕过客户端检测
原理:通常上传页面里面含有专门检测文件上传的JavaScript代码,最常见的就是检测文件的扩展名是否合法
方法:在本地客户端禁用相关的js检测代码
绕过服务端检测
MIME类型
MIME type对照表
https://blog.csdn.net/u014744118/article/details/72779931
常见的MIME类型
超文本标记语言 | .html | text/html |
普通文本 | .txt | text/plain |
PDF文档 | application/pdf | |
Microsoft Word文件 | .word | application/msword |
PNG图像 | .png | image/png |
GIF图像 | .gif | image/gif |
MPEG文件 | .mpg .mpeg | video/mpeg |
AVI文件 | .avi | video/x-msvideo |
原理:检测图片类型文件上传过程中http包的Content-type字段的值,来判断文件上传内容是否合法。
方法:用Burpsuite截取数据包并修改文件的Content-type类型进行绕过
文件内容
文件幻数
原理:主要是检测文件内容开始处的文件幻数
图片渲染
方法:使用图像处理软件对一张图片进行代码注入,
攻击原理是:在不破坏文件本身的情况下找一个空白区进行代码填充,一般是图片的注释区
二次渲染
原理:把原本属于图像数据的部分提取出来,用自己的API或函数进行重新渲染,而非图像数据部分直接被隔离开了
方法:攻击文件加载器自身,可以通过溢出攻击对文件加载器进行攻击,上传自己的恶意文件后,服务器上的文件加载器会主动进行加载测试,加载测试时被溢出攻击执行shellcode
文件后缀
黑名单
黑名单策略:文件扩展名在黑名单中为不合法,一般有专门的黑名单列表,里面会包含常见的危险脚本文件
$deny_ext=array(".php",".php5",".php4",".php3",".php2",".html",".htm",".phtml",".pHp",".pHp5",".pHp4",".pHp3",".pHp2",".Html",".Htm",".pHtml",".jsp",".jspa",".jspx",".jsw",".jsv",".jspf",".jtml",".jSp",".jSpx",".jSpa",".jSw",".jSv",".jSpf",".jHtml",".asp",".aspx",".asa",".asax",".ascx",".ashx",".asmx",".cer",".aSp",".aSpx",".aSa",".aSax",".aScx",".aShx",".aSmx",".cEr",".sWf",".swf",".htaccess");
方法:
后缀大小写绕过(.Php)
在对后缀的判断中,如果只是通过对字符串进行单独的比较来判断是不是限制文件
空格绕过(.php )
黑名单没有对后缀名进行处理
点绕过(.php.)
利用Windows系统文件名特性,会自动去掉后缀最后的“.”
::$DATA绕过
如果黑名单没有对后缀名进行::$DATA处理,利用Windows下NTFS文件系统的一个特性
配合Apache解析漏洞
Apache解析文件时是从右往左判断,如果为不可识别解析再往左判断,如aa.php.owf.rar文件,AApache不可识别解析“.owf”和“。rar”两种后缀,会解析为.php文件
用.htaccess文件巧妙绕过黑名单
.htaccess全称是Hypertext Access(超文本入口)。htaccess文件也被称为分布式配置文件,是Apache特有的的针对目录改变配置的方法。通过在一个特定的文档目录中放置一个包含一个或多个指令的文件, 以作用于此目录及其所有子目录。该文件可以针对不同的目录采用不同的策略。 一般后端的黑名单不会过滤把.htaccess后缀写进去,那么我们可以先上传一个.htaccess文件上去,提前设置好让它把.jpg文件当做php文件来解析,这样后续只需要上传.jpg文件就可以了。
白名单
白名单策略:文件扩展名不在白名单中为不合法
方法:
%00截断
URL发送到服务端后被服务器解码,这时还没有传到验证函数,也就是说验证函数里接收的不是%00字符,而是解码后的0x00
0x00截断
系统对文件名进行读取时,如果遇到0x00,就会认为读取已经结束,但要注意的是文件的十六进制内容的00,而不是文件名中的00
参考博客:https://blog.csdn.net/weixin_64551911/article/details/124627363