Java后台Linux软链接文件下载检验

Posted 木字旁

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java后台Linux软链接文件下载检验相关的知识,希望对你有一定的参考价值。

  最近项目的测试哥们提了一个linux系统软链接攻击的问题,项目中导出服务器上某个文件的时,通过软连接漏洞可以获取到其他文件的信息。

  具体过程自己写了个下载的Demo模拟了一下:

  下载的servlet和html如下,下载/opt/temp/a.txt,国际惯例,内容是hello world,文件大小12kb。

  
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Download File</title>
<script type="text/javascript">
    function download() {
        window.open("download.do");
    }
</script>
</head>
<body>
    <input type="button" value="Download" onclick="download()" />
</body>
</html>
View Code
  
package com.dj.servlet;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.net.URLEncoder;

import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.tomcat.util.http.fileupload.IOUtils;

/**
 * @author DU
 *
 */
@WebServlet("/download.do")
public class DownloadDemoServlet extends HttpServlet
{
  private static final long serialVersionUID = 1L;

  public DownloadDemoServlet()
  {
    super();
  }

  protected void doGet(HttpServletRequest request, HttpServletResponse response)
      throws ServletException, IOException
  {
    String fileName = "a.txt";
    response.setHeader("content-disposition", "attachment;filename=" + URLEncoder.encode(fileName, "UTF-8"));
    String filePath = "/opt/temp/" + fileName;
    FileInputStream is = new FileInputStream(new File(filePath));
    ServletOutputStream os = response.getOutputStream();
    IOUtils.copy(is, os);
    os.close();
    is.close();
  }

  protected void doPost(HttpServletRequest request, HttpServletResponse response)
      throws ServletException, IOException
  {
    doGet(request, response);
  }

}
View Code

  这样下载下来的文件没有任何问题,接下来就涉及软链接的问题,在服务器上/home目录下有一个npp.7.3.3.Installer.x64.exe的文件,当然这是个notepad++的安装文件,我自己放进去的。先将/opt/temp/a.txt删除掉,然后用xshell执行命令ln -s /home/npp.7.3.3.Installer.x64.exe /opt/temp/a.txt 创建.exe的软链接文件为a.txt,关于软链接文件这里不细表,可以自行百度,可以理解为类似windows的快捷方式,创建成功之后是这样的,注意这时候文件大小已经是2.84M了。

  

  然后再次点击下载,这个时候下载下来的是这样的:

 

  

  是的,下载软链接会直接下载软链接指向的源文件,如果是敏感文件的话就很不好了。当然,笔者依然处于菜鸟阶段,还不是很清楚恶意攻击者可以通过怎样的手段达到创建出这个软链接。

  接下来就是如何规避这个问题了:

  第一种方式是通过对比文件的绝对路径和规整化路径,如果是源文件的话这两个路径应该是一样的,否则就是链接文件。

  
    // 对比绝对路径和规整化路径
    String absolutePath = file.getAbsolutePath();
    String canonicalPath = file.getCanonicalPath();
    if (!absolutePath.equals(canonicalPath))
    {
      response.getWriter().append("Download Failed!");
      return;
    }
View Code

  第二种方式可以直接通过jdk1.7开始出现的java.nio.file.Files类提供的接口判断。

   

  

  
    // 直接通过java.nio.file包中提供的接口判断
    Path path = Paths.get(filePath);
    boolean isSymbolicLink = Files.isSymbolicLink(path);
    if (isSymbolicLink)
    {
      response.getWriter().append("Download Failed!");
      return;
    }
View Code

 如图,校验成功!

 

以上是关于Java后台Linux软链接文件下载检验的主要内容,如果未能解决你的问题,请参考以下文章

2-18 Linux中的连接文件 --- 软链接

Linux文件系统中硬链接和软链接的区别

linux中的软连接的文件前缀

Linux中硬链接文件和软链接文件有啥区别?

Linux中硬链接和软链接的区别与联系!

linux软链接(符号链接)