目录遍历攻击

原文地址:https://en.wikipedia.org/wiki/Directory_traversal_attack

目录遍历攻击

一次目录遍历攻击(directory traversal attack)通常利用了“服务器安全认证缺失”或者“用户提供输入的文件处理操作”,使得服务器端文件操作接口执行了带有“遍历父文件目录”意图的恶意输入字符。
这种攻击的目的通常是利用服务器相关(存在安全漏洞的)应用服务,来恶意的获取服务器上本不可访问的文件访问权限。该攻击利用了程序自身安全的缺失(对于程序本身的意图而言是合法的),因此存在目录遍历缺陷的程序往往本身没有什么逻辑缺陷。
目录遍历攻击也被称为“…/攻击”、“目录爬寻”以及“回溯攻击”。甚至有些形式的目录遍历攻击是公认的标准化缺陷。

示例

一个典型的易受攻击的PHP应用案例如下代码所示:

<?php
$template = 'red.php';
if (isset($_COOKIE['TEMPLATE']))
   $template = $_COOKIE['TEMPLATE'];
include ("/home/users/phpguru/templates/" . $template);
?>

译者注:如果有读者看不懂php代码,可以看下面这段nodejs代码,与原文示例中的php代码效果完全一致:

var http=require("http");
var fs=require("fs");
var server=http.createServer(function(req,res){
	var $template="red.php";
	if(req.headers.cookie){
		req.headers.cookie.split(";").forEach(function(index,i){
			var map=index.split("=");
			if(map[0]=="TEMPLATE"){
				$template=map[1];
			}
		});
	}
	var stream=fs.createReadStream("/home/users/phpguru/templates/"+$template);
	stream.pipe(res);
});

一个针对这个系统的目录遍历攻击即可像如下示例一样发送HTTP请求:

GET /vulnerable.php HTTP/1.0
Cookie: TEMPLATE=../../../../../../../../../etc/passwd

译者注:/etc/passwd是某些Unix系统的密码存储文件


进而服务器会发回如下响应:

HTTP/1.0 200 OK
Content-Type: text/html
Server: Apache

root:fi3sED95ibqR6:0:1:System Operator:/:/bin/ksh 
daemon:*:1:1::/tmp: 
phpguru:f8fk3j1OIf31.:182:100:Developer:/home/users/phpguru/:/bin/csh

正如上例所示,重复的“…/”字符跟在“/home/users/phpguru/templates/”后面,造成了服务器遍历到了跟目录,并最终访问了Unix密码文件“/etc/passwd”。
为了说明攻击者如何尝试获取服务器密码数据,我们在上例中使用了Unix的“/etc/passwd”公共文件来展示目录遍历攻击(directory traversal)。
不过值得庆幸的是,在较新版本的Unix系统中,“passwd”文件不再包含哈希密码。在新版Unix中,密码被存放在隐藏文件中,这样未授权的用户将无法再轻易查看。尽管如此,目录遍历攻击仍然是遍历服务器账号信息的有效手段,如今的许多账号服务器也确实仍存在类似的安全漏洞。

目录遍历攻击的多样性

本小节我们列出了一些已知的目录遍历攻击字符串组合:

1.Unix目录遍历攻击

通用的类Unix系统的目录遍历攻击字符串形如“…/”。

2.Windows操作系统目录遍历攻击

对于微软的Windows操作系统以及DOS系统的目录结构,攻击者可以使用“…/”或者“…\”字符串。
在这种操作系统中,每个磁盘分区有一个独立的根目录(比如我们会把个人电脑分区成“C盘”、“D盘”等等),并且在所有磁盘分区之上没有更高级的根目录。这意味着Windows系统上的目录遍历攻击会被隔离在单个磁盘分区之内(C盘被攻击,D盘不受影响)。
目录遍历攻击是诸多微软的漏洞之一。

3.URI编码形式的目录遍历攻击

标准化缺陷
一些网络应用会通过查询危险的字符串,例如:

  • …\
  • …/
    来防止目录遍历攻击。然而,服务器检查的字符串往往会被URI编码。因此这类系统将无法避免如下形式的目录遍历攻击:
  • %2e%2e%2f:解码为…/
  • %2e%2e/:解码为…/
  • …%2f:解码为…/
  • %2e%2e%5c:解码为…\

4.Unicode/UTF-8编码形式的目录遍历攻击

标准化缺陷
UTF-8编码被Bruce Scheneier和Jeffery Streifling标记为一种易受攻击的资源。
当微软向他们的Web服务增加Unicode支持时,一种新的编码方式——“…/”被引入,也正是这一举动最终引入了目录遍历攻击。
许多带百分号的编码方式,例如:

  • %c1%1c
  • %c0%af
    被转换成“/”或“\”字符。
    百分号编码字符被微软提供的Web服务解码成相应的8字节字符。正式由于Windows和DOS使用基于ASCII的8字节标准编码方式,这个行为在历史上一度被认为是正确的。
    然而,UTF-8本身的源头并非标准化。许多字符串甚至根本就没有对应的编解码字符。微软通过其他一些方式,最终没有使用标准化的编解码方式。许多奇怪的百分号编码形式,例如“%c0%9v”也被引入。

5.Zip/归档文件目录遍历攻击

形如zip这样的归档文件格式也允许目录遍历攻击:就像回溯文件系统一样,在归档文件中的任何文件也会被重写。我们可以编写出查看归档文件内部文件路径的代码来。

几种可能的防御手段

一个用来防御目录遍历攻击的算法应该包含以下几点:
1.针对URI请求的服务功能不应该导致文件系统被操作。举例来说,在继续执行下一步操作之前,在用户代码中执行嗅探钩子。
2.当确实需要提供一个操作文件或目录的URI请求服务时,在访问文件时先生成完整的文件路径(如果相应参数存在的话),并且将路径内的所有的字符都标准化(举例来说,将%20转换成空格)。
3.程序应当设置一个“文档根节点”,以这个确信的、标准化的路径为基准,来确定一个最顶层的目录路径N。并且规定在该目录上层的所有目录或文件不可访问。
4.通过程序来检查客户端请求拼接解码后的目录路径字符串的头部是否和程序规定的“文档根节点”N的头部相同。
5.如果相同,则允许本次文件操作。
6.如果不同,返回一个错误,因为该请求需要访问的文件目录范围已经超出了Web程序服务的文件范围。
7.请注意对文件后缀名进行硬编码,并不能限定所有请求都操作硬编码后缀的文件,例如如下代码:

<?php
include($_GET['file'] . '.html');

客户端只要使用形如“\0”(即NULL,表明字符串已经结束。类似的结束符还有很多,详见https://en.wikipedia.org/wiki/Null_character#Representation)的字符来结尾,就能使程序忽略$_GET[php specific]后的所有内容。

熬夜不易,请作者喝杯酒!

  • 6
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值