代码安全之上传文件

上传数据包

 

从数据包中可以看出,验证文件类型的参数有:Content-Type、Filename、Filedata。

客户端JS验证

原理介绍

通过JS验证上传文件类型是最不安全的做法,因为这个方式是最容易被绕过的。我们先来看下JS实现文件检测的代码如下:

 

客户端JS验证通常做法是验证上传文件的扩展名是否符合验证条件。

绕过姿势

1 通过firefox的F12修改js代码绕过验证

2 使用burp抓包直接提交,绕过js验证

服务端MIME类型检测

MIME类型介绍

不同的文件类型有不同的MIME头,常见的MIME头如下:

 

验证MIME头的测试代码

 

以上是一个简单的服务器上传验证代码,只要MIME头符合image/gif就允许上传。

绕过方式

使用Burp截取上传数据包,修改Content-Type的值,改为image/gif即可成功绕过上传webshell。

服务端文件扩展名检测

扩展验证测试代码

 

默认上传后的文件保存的名字是以获取到名字。

绕过技巧

1 使用大小写绕过(针对对大小写不敏感的系统如windows),如:PhP

2 使用黑名单外的脚本类型,如:php5

3 借助文件解析漏洞突破扩展名验证,如:test.jpg.xxx(apache解析漏洞)

4 借助系统特性突破扩展名验证,如:test.php_(在windows下下划线是空格,保存文件时下划线被吃掉剩下test.php)

5 双扩展名之间使用00截断,绕过验证上传恶意代码如:test.php%00.jpg

6 借助.htaccess文件上传恶意代码并解析。如:上传一个.htaccess文件,内容为AddTypeapplication/x-httpd-php .jpg,上传的jpg文件就可以当作php来解析

7 使用00截断,绕过后缀验证获取webshell(php<5.3.4+关闭GPC)

8 超长文件名截断上传(windows 258byte | linux 4096byte)

服务端文件内容检测

检测文件头

文件头简介

不同的图片文件都有不同文件头,如:

PNG: 文件头标识 (8 bytes) 89 50 4E 47 0D 0A 1A 0A

JPEG: 文件头标识 (2 bytes): 0xff, 0xd8 (SOI) (JPEG 文件标识)

GIF: 文件头标识 (6 bytes) 47 49 46 38 39(37) 61

绕过方式

绕过这个检测只需要在恶意脚本前加上允许上传文件的头标识就可以了。

文件内容检测

检测方式

使用正则对内容进行匹配,一旦匹配到恶意代码,就中断上传,提示用户重新上传。

绕过方式

通过fuzz,绕过正则上传。

安全建议

1 使用白名单限制可以上传的文件扩展

2 验证文件内容,使用正则匹配恶意代码限制上传

3 对上传后的文件统一随机命名,不允许用户控制扩展名

4 修复服务器可能存在的解析漏洞

5 严格限制可以修改服务器配置的文件上传如:.htaccess

posted @ 2019-03-18 12:26  Python研究者  阅读(672)  评论(0编辑  收藏  举报