12.路径遍历漏洞一
转载自https://github.com/cokepluscarbon/
12.1 任意文件下载
这是开发人员在实现下载功能的时候很容易引入的一个漏洞。我曾经利用该漏洞渗透两个系统,纯手工,前后不到十分钟就把两个操作系统的root权限擒下了。这应该高度引起开发人员的注意,而实际上,却没几开发人员有意识去避免这些漏洞的产生。
以下这段代码用于实现文件下载,当然,这段代码是有严重漏洞的。(希望你的系统中没有类似的实现)
String fileName = request.getParameter("fileName");
File file = new File("C://download/" + fileName);
int len = 0;
byte[] buffer = new byte[1024 * 4];
InputStream input = new FileInputStream(file);
while ((len = input.read(buffer)) != -1) {
response.getOutputStream().write(buffer, 0, len);
}
response.getOutputStream().flush();
input.close();
代码思路也很简单:先从请求中获取fileName参数,然后将它拼接到C://download/中。
HTTP请求:http://example.com/download?fileName=users.xls
对应系统文件路径:C://download/users.xls
貌似从代码看来,文件的路径已经被限定在了C://downlaod/目录下,好像没有什么漏洞吧?
而实际上真如此吗?下载的文件真的被限定在C://download/目录下了吗?
假如C盘下有个github.pdf文件,我是否可以通过这样的参数获得该PDF文件?
HTTP请求:http://example.com/download?fileName=../github.pdf
对应系统文件路径:C://download/../github.pdf
12.2 意料之外
以上论述的关键在于,我们是否可以通过C://download/../github.pdf来获取C://github.pdf这个文件?
File file = new File("C://download/../github.pdf");
System.out.println(file.getPath());
System.out.println(file.getAbsolutePath());
System.out.println(file.getCanonicalPath());
System.out.println(file.exists());
/** 输出结果 **/
// C:\download\..\github.pdf
// C:\download\..\github.pdf
// C:\github.pdf
// true
而实际上,我们不得不承认,C:\download\..\github.pdf跟C:\github.pdf这个路径是一致的。所以,我们可以通过..来返回上一层目录,从而实现任意文件下载。
12.3 抽象路径 vs 规范路径
也许你会怀疑这是Java的Bug,其实不然,所有的操作系统和大多数的开发语言都允许这样的路径存在(你可以尝试在linux中执行 cd /root/abc/../../试试)。在Java中,我们称这种路径为“抽象路径”。
抽象路径,分为绝对路径和相对路径。
抽象路径:与平台无关的路径,允许./和../的存在。
绝对路径:抽象路径的一种,绝对路径名是完整的,不需要其他信息来定位文件或文件夹。
相对路径:抽象路径的一种,相对于当前工作目录的路径。允许./和../。相对路径名是不完整的,需要借助当前工作路径来定位文件或文件夹。
规范路径:与系统相关的且唯一的路径。不允许./和../的存在。指定文件或文件夹的规范路径有且只有一个。
在Java中,可以使用java.io.File.getCanonicalPath()获取文件或文件夹的规范路径。
File file1 = new File("C://download/../github.pdf");
File file2 = new File("C://download/../download/../github.pdf");
System.out.println(file1.getAbsolutePath()); // C:\download\..\github.pdf
System.out.println(file1.getCanonicalPath()); // C:\githug.pdf
System.out.println(file2.getAbsolutePath()); // C:\download\..\download\..\github.pdf
System.out.println(file2.getCanonicalPath()); // c:\github.pdf
从而得知,同一个文件或目录可以有N个抽象路径表示,但是规范路径有且只有一个。
12.4 上传文件漏洞
综上所述,12.1实现的下载功能是存在任意文件下载漏洞的。同样的道理,对于上传功能如果没有对文件名进行过滤的话,那么可以将文件上传到操作系统的任意路径,这是非常危险的,开发时一定要非常注意!
12.5 参考资料
- https://www.owasp.org/index.php/Path_Traversal
- https://www.owasp.org/index.php/File_System#Path_traversal
- https://www.owasp.org/index.php/Resource_Injection
- https://www.owasp.org/index.php/Relative_Path_Traversal
- https://www.owasp.org/index.php/Path_Manipulation
- https://www.owasp.org/index.php/Testing_for_Path_Traversal_(OWASP-AZ-001)
- http://www.ehow.com/info_12181467_abstract-path-name-java.html
- http://docs.oracle.com/javase/7/docs/api/java/io/File.html

浙公网安备 33010602011771号