文件上传漏洞学习总结
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了文件上传漏洞学习总结相关的知识,希望对你有一定的参考价值。
一、定义
文件上传功能本身是一个再正常不过的功能,但是由于开发人员代码编写不严谨,对用户输入/上传文件未做严格的校验,当恶意人员上传恶意文件后,导致站点执行了该文件,最终对站点造成破坏,常见的危害如上传MU马文件导致站点被控制。本文为笔者学习中的笔记,框架如下:
二、产生原因
产生此类漏洞的原因是多种多样的,总结归类为以下几类:
1、 站点前后端对用户上传文件校验不严
2、 使用的组件存在上传漏洞
3、 旧版本中间件解析漏洞
三、漏洞存在条件
漏洞存在且可以利用,通常需要满足以下条件:
1、 网站存在文件上传功能点,且可以上传动态文件,如ASP、php、JSP等文件;
2、 动态文件可以被网站解析;
3、 可以访问到该上传的文件;或者网站存在文件包含功能点,该文件可以被文件包含访问
四、安全检测与防护点
1、 网站前端
在网站前端,也就是客户端,通常可以通过javascript对用户输入的信息进行过滤,但严格意义上讲这中过滤意义不大,可以比较容易的绕过。
2、 网络中间传输
在网络传输过程中通常会有WAF等安全设备的检测防护,这类设备通常具备成熟的特征库,可以过滤掉大部分的恶意请求。
3、 服务器后端服务
服务端通过安全编码进行过滤防护是比较彻底的,基本可以解决文件上传漏洞的问题。
五、漏洞测试
1、 直接上传动态文件,如.asp,.aspx,.jsp,.php等文件
通过直接上传动态文件,观察响应情况,判断是否有相关过滤。
2、 文件头绕过
大多数文件都有其特定的文件头,通常可以作为检测的一个点,这时可以尝试修改文件头,伪装文件属性。常见图片文件头标识(16进制表示):
1).JPEG/JFIF/JPG - 文件头标识 (2 bytes): 0xff, 0xd8,0xff - 文件结束标识
2).PNG - 文件头标识
3).GIF - 文件头标识
4).BMP - 文件头标识
如下为jpg格式文件,查看16进制:
通过BURP抓包看到的如下:
在实际测试中可以尝试修改文件头为图片,测试是否可以绕过。
3、 文件类型绕过
通过HTTP向服务器提交文件时通常会在协议头中携带Content-type字段,用来在客户端与服务端之间传输文件格式进行标记。如下为jpg图片:
如下为PHP/ASP/JSP文件类型:
Application/octet-stream表明为字节流文件。
常见的类型还包括:
使用POST方法提交表单时:application/x-www-form-urlencoded
GIF文件时:image/gif
JPEG文件时:image/jpeg
PNG文件时:image/png
在测试过程中可以修改Content-Type进行尝试。
4、 文件后缀名绕过
一些程序配置了不允许上传文件的后缀名黑名单,可以尝试修改后缀进行绕过,linux文件系统区分大小写,windows系统不区分大小写。常见的扩展名绕过如下:
Asp:asa cer cdx
Aspx: ashx asmx ascx
Php: .php/php1/php2/php3/php…n/phps/pht/phtm/phtml等,将上传文件的后缀进行替换测试
Jsp: jspx jspf
可以尝试的技巧包括双写文件后缀、大写文件后缀等。
5、 文件解析测试
a. %00截断
方法一: 首先将马制作为jpeg格式,上传截包后,将文件名1.jpeg修改为1.php jpeg,注意中间有一个空格,然后跳转到hex十六进制中,将空格%20修改为00,再将报文发送出去:
方法二:上传截包后,在文件名1.jpeg后增加1.php%00jpeg,然后选中%00后,右键选择URL-decode,最后发送报文出去。
b. apache解析漏洞( CVE-2017-15715 ):
apache是从右向左开始判断解析,如果为不可识别解析,就再往左判断。如1.php.rar文件,rar这个后缀是apache不可识别解析的,apache就会把1.php.rar解析为php文件。
c. IIS目录解析、文件解析、畸形解析漏洞
漏洞比较早了,就不记录了,可以遇到老版本就直接百度查询。
6、 图片马测试
部分场景下可以尝试使用图片马尝试绕过,即将图片和小马合成,然后进行上传:
查看生成的图片后面添加上了PHP小马:
上传文件,使用BURP截包,同时可以修改后缀名为动态文件名:
六、安全编码
以JAVA SpringMVC框架为例:
1、 编码注意事项
1)、对用户输入、前台带入的信息默认不可信,在服务端均进行校验;
2)、白名单比黑名单可靠;
3)、文件上传在服务端需要关注上传的文件名、文件的Content-Type、文件的后缀名,文件的保存路径、文件存储名字是否可猜测;
4)、文件名还要预防存入数据库中,程序再根据文件名进行数据库查找导致SQL注入,防止文件名直接输出导致XSS等。
2、 安全编码示例:
@RequestMapping("/upload1")
public String upload1(@RequestParam("file") CommonsMultipartFile file, HttpServletRequest request) throws IOException
//1、定义白名单,后缀名白名单以及ContentType白名单
String suffix[] = "jpg","jpeg","bmp","jfif","png","gif";
String allContentType[] = "image/gif","image/jpeg","image/png";
boolean flagType = false ;
boolean flagContent = false;
//2、取出文件名
String uploadFileName = file.getOriginalFilename();
//3、取出文件后缀名,不要用indexOf("."),使用lastIndexOf
String fileType = uploadFileName.substring(uploadFileName.lastIndexOf(".")+1);
//4、取出ContentType
String contentType = file.getContentType();
if(uploadFileName.isEmpty())
return "redirect:/index.jsp";
System.out.println("上传文件名:" + uploadFileName);
//5、进行文件后缀判断
//使用equalsIgnoreCase或者先使用toLowerCase转换为小写,再使用equals进行比较
for (int i = 0; i < suffix.length; i++)
if(fileType.equalsIgnoreCase(suffix[i]))
flagType = true;
break;
if(flagType)
System.out.println("上传文件后缀合法!");
else
System.out.println("上传文件后缀不合法!");
//返回上传页面
return "redirect:/index.jsp";
//6、进行文件内容判断
//使用equalsIgnoreCase或者先使用toLowerCase转换为小写,再使用equals进行比较
//还可以获取文件的图片大小等信息
for (int i = 0; i < allContentType.length; i++)
if(contentType.equalsIgnoreCase(allContentType[i]))
flagContent = true;
break;
if(flagContent)
System.out.println("上传文件content-type匹配正确!");
else
System.out.println("上传文件content-type匹配失败,上传文件不合法!");
//返回上传页面
return "redirect:/index.jsp";
String path =request.getServletContext().getRealPath("/upload");
File realPath = new File(path);
if(!realPath.exists())
realPath.mkdir();
System.out.println("上传文件保存地址:" + realPath);
//7、文件名中加入时间戳
long TimeStampes =System.currentTimeMillis();
InputStream inputStream = file.getInputStream();
OutputStream outputStream = new FileOutputStream(new File(realPath,TimeStampes+uploadFileName));
int len = 0;
byte[] buffer = new byte[1024];
while ((len =inputStream.read(buffer)) != -1)
outputStream.write(buffer,0,len);
outputStream.flush();
outputStream.close();
inputStream.close();
return "redirect:/index.jsp";
3、 审计要点
1)、从前台的功能点,通过接口找到后台的功能实现点,再进一步查看是否进行了安全相关的过滤;
2)、直接从代码入手,全局进行关键字查找,常见的关键字如CommonsMultipartFile、commons-fileupload、transferTo、Files.copy、indexOf、getRealPath、MultipartFile、FileUtils、equals等。
以上是关于文件上传漏洞学习总结的主要内容,如果未能解决你的问题,请参考以下文章
七夕咱一起验证漏洞✨ IIS7/7.5对文件名畸形解析导致远程代码执行❤️