文件上传漏洞学习总结

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进制:

文件上传漏洞学习总结_JAVA代码审计_02

通过BURP抓包看到的如下:

文件上传漏洞学习总结_文件上传_03

在实际测试中可以尝试修改文件头为图片,测试是否可以绕过。

3、 文件类型绕过

        通过HTTP向服务器提交文件时通常会在协议头中携带Content-type字段,用来在客户端与服务端之间传输文件格式进行标记。如下为jpg图片:

文件上传漏洞学习总结_漏洞_04

如下为PHP/ASP/JSP文件类型:

文件上传漏洞学习总结_文件上传_05

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,再将报文发送出去:

文件上传漏洞学习总结_安全编码_06

方法二:上传截包后,在文件名1.jpeg后增加1.php%00jpeg,然后选中%00后,右键选择URL-decode,最后发送报文出去。

文件上传漏洞学习总结_JAVA代码审计_07

b.     apache解析漏洞( CVE-2017-15715 ):

        apache是从右向左开始判断解析,如果为不可识别解析,就再往左判断。如1.php.rar文件,rar这个后缀是apache不可识别解析的,apache就会把1.php.rar解析为php文件。

c.     IIS目录解析、文件解析、畸形解析漏洞

        漏洞比较早了,就不记录了,可以遇到老版本就直接百度查询。

6、 图片马测试

        部分场景下可以尝试使用图片马尝试绕过,即将图片和小马合成,然后进行上传:

文件上传漏洞学习总结_安全编码_08

        查看生成的图片后面添加上了PHP小马:

文件上传漏洞学习总结_漏洞_09

        上传文件,使用BURP截包,同时可以修改后缀名为动态文件名:

文件上传漏洞学习总结_漏洞_10

六、安全编码

以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对文件名畸形解析导致远程代码执行❤️

七夕咱一起验证漏洞✨ IIS7/7.5对文件名畸形解析导致远程代码执行❤️

上传突破学习笔记

文件上传漏洞,解析漏洞总结