路径遍历与文件读取漏洞以及其修复方案

来源:互联网 发布:电影字幕翻译软件 编辑:程序博客网 时间:2024/05/17 02:25

背景:

一些网站的业务需求,可能提供文件查看或下载功能,如果对用户查看或下载的文件不做限制,那么用户就能够查看和下载任意2文件,可以使源代码文件、敏感文件等。

路径遍历代码:

<?php$dir_path=$_REQUEST['path'];$filename=scandir($dir_path);foreach($filesnames as $name){echo $name."<br/>";}?>


路径遍历漏洞成因:

如果应用程序使用用户可控制的数据,以危险的方式访问位于引用程序服务器或其后端文件系统中的文件和目录,就会出现路径遍历漏洞。


文件读取代码:

<?php$filename=$_GET['m'];echo file_get_contest($filename);?>

<?php$filename=$_GET['m'];$fp=fopen($filename,"r") or die ("unable open!");echo fread($fp,filesize($filename));fclose($fp);?>

<?php$filename=$_GET['m'];readfile($filename);?>

文件读取漏洞成因

通过提交专门设计的输入,攻击者就可以在被访问的文件系统中读取或写入任意内容,往往能够使攻击者从服务器上获取敏感信息文件


$dir_path和$filename 没有经过校验或者不严格,用户可以控制这个变量读取任意文件(/etc/password..../index.php)


漏洞之所以会发生是因为攻击者可以将路径遍历序列放入文件名内,从当前位置向上回溯,从而浏览整个浏览器的的任何文件


给出一个典型攻击

http://127.0.0.1/path_traversal.php?path=..\

如果应用程序把file参数的值附加到目录名称之后,就得到以下

路径:D:\Program Files\phpstudy\WWW\..\

这个遍历序列立即从当前目录回溯到Web目录上一级目录,因此前

面的路径等同于以下路径:

D:\Program Files\phpstudy


漏洞过滤缺陷绕过:

提交大量的遍序列:几乎每一种文件系统都接收试图向上回溯到文件系统根目录的多余遍历序列:有助于避免误报警

分隔符:widows接收\和/作为目录的分割符,而UNIX接收/作为分隔符。但是一些WEB应用程序过滤两者之一。


漏洞挖掘:

使用编码,对遍历序列进行简单的URL编码(对输入的每一个斜线和点编码)

点 %2e

斜线%2f

反斜线%5c


双倍URL编码:有的网站waf会对想url进行一次解析进行过滤。这样双倍编码就变成了单次编码,在送给webserver再进行解析。完成目录宾律。

点 %u002

斜线%u2215

反斜线%u2216


16位Unicode编码
点 %u002

斜线 %u2215

反斜线 %u2216


尝试使用下面的超长UTF-8 Unicode编码:

点 %c0%2e、 %e0%40%ae、 %c0ae等

斜线 %c0%af、 %e0%80%af、 %c0%2f等

反斜线 %c0%5c、 %c0%80%5c等

这些表示法违反了Unicode表示法规则,却为许多Unicode解码器接受,特别是Windows平台的解码器。

如果程序尝试通过删除遍历序列来净化用户输入,但没有以递归的方式应用这种过滤,那么可以用一个序列替换另一个序列来避开过滤。.
例如:
....//
....\/
..../\
....\\


修复代码:

<?phpfunction checkstr($str,$find){$find_str=$find;$tmparray=explode($find_str,$str);if(count($tmparray)>1){return true;}else{return false;}}$hostdir=$_REQUEST['path'];if(!checkstr($hostdir,"..")&&!checkstr($jostdir,"../")){echo $hostdir;}else{echo "请勿提交非法字符";}?>


修复方案:

过滤.(点)等可能的恶意字符:这个试用于能够修改线上代码,最为推荐的方法

正则判断用户输入的参数的格式,看输入的格式是否合法:这个方法的匹配最为准确和细致,但是有很大难度,需要大量时间配置规则。

 php.ini 配置 open_basedir:这个参数值得的是用户只能访问的目录,作为不能修改线上代码时的备用方案。


文件读取修补方案:

<?php    $filename = $_REQUEST['file'];    switch($filename){           case "config":           echo file_get_contents("config.php");           break;           default:                   echo '请求错误';}?>





0 0