云计算百科
云计算领域专业知识百科平台

三分钟看懂 PHP「路径跃迁」:用户输入如何意外走遍服务器目录?

三分钟看懂 PHP「路径跃迁」:用户输入如何意外走遍服务器目录?

文章目录

  • 三分钟看懂 PHP「路径跃迁」:用户输入如何意外走遍服务器目录?
    • 前言:
    • 什么是路径跃迁漏洞?
    • 路径跃迁漏洞复现与分析
    • 漏洞条件绕过与修复
      • 漏洞绕过
      • 漏洞修复

声明:本文所有操作均在本地封闭环境完成,未涉及任何真实生产系统;示例代码已做脱敏与范围限制,仅供学习交流。

前言:

此篇文章的以PHP语言来作为基础环境针对于PHP文件目录穿越漏洞读取进行研究并总结。

什么是路径跃迁漏洞?

目录穿越漏洞(Directory Traversal Vulnerability)是一种常见的安全漏洞,攻击者通过修改文件路径,绕过正常的文件访问限制,从而访问到系统中不应该公开的文件和目录。它也被称为路径穿越或目录遍历漏洞。

具体来说,攻击者可以利用这种漏洞在文件路径中使用“…/”(代表返回到上级目录)等特殊符号,绕过Web应用程序限制,访问文件系统上的敏感文件。例如,攻击者可能会试图访问系统配置文件、用户数据、数据库凭证等。

路径跃迁漏洞复现与分析

模拟漏洞复现场景,假设有一个PHP网站,它能读取当前目录的所有文件并且可以下载与删除。

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>文件列表</title>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css">
<style type="text/css">
ul {
liststyle: none;
padding: 0;
margin: 0;
}
li {
marginbottom: 10px;
}
i {
marginright: 10px;
}
a {
textdecoration: none;
color: #333;
}
</style>
</head>
<body>
<h1>当前目录下的文件列表</h1>
<ul>

</ul>
</body>
</html>

<?php
//获取 URL 参数 path,如果没有提供就默认为当前目录 ./。
$dir = $_GET['path'] ?? './';

//1.打开目录,读取文件列表 opendir
//2.循环读取文件列表 while readdir
//3.判断是文件还是文件夹 is_dir

// 构建函数:打开目录,循环读取目录下的文件和子目录
function filelist($dir){
if($dh = opendir($dir)){
//循环读取文件列表 while readdir
while(($file=readdir($dh) )!== false){
//判断是文件还是文件夹 is_dir
if(is_dir($file)){
echo "<li><i class='fa fa-folder'></i> <a href='?path=$file'>" . $file . '</a></li>';
}else{
echo '<li><i class="fa fa-file"></i> <a href="#">' . $file . '</a></li>';
}
}
}
}
// 调用函数列出目录内容。
filelist($dir);
//del($file) 函数:删除指定文件
function del($file){
if(!is_dir($file)){
unlink($file);
echo "<script>alert('删除成功')</script>";
}
}

if(isset($_GET['del'])){
del($_GET['del']);
}

//down($filepath) 函数:下载指定文件
function down($filepath){
$fileName = basename($filepath);
header("Content-Type: application/octet-stream");
header("Content-Disposition: attachment; filename=\\"" . $fileName . "\\"");
header("Content-Length: " . filesize($filepath));
readfile($filepath);
}

if(isset($_GET['down'])){
down($_GET['down']);
}
?>

分析上面代码,我们发现代码中由于开发的逻辑存在着目录穿越漏洞:用户可以访问服务器上任意目录和文件。

接下来我们来一步一步跟进复现漏洞与总结原理,通过web访问页面可以得知能读取我们当前代码所在目录的所有文件及文件夹并且可以通过点击按钮进行跳转如下图所示

通过分析代码,我们可以得知这是通过path进行传参来把需要读取的目录参数传递进去通过调用文件列表函数进行读取并显示。

我们代码当前所处在D:\\PhpstormProjects\\Basic PHP目录中,所以我们web页面就自然的显示当前目录下的所有文件

于是我们通过path传递参数"…/"看是否能读取上一级目录

http://localhost:63342/PhpstormProjects/Basic%20PHP/file-manage1.php?path=../

可以看到成功读取上一级的目录,于是我们继续套用递归…/读取上一级目录

http://localhost:63342/PhpstormProjects/Basic%20PHP/file-manage1.php?path=../../

可以发现依旧可以读取上一级目录,那么我们就发现了可以选择递归一直读取上一级的目录的规律。于是我们可以思考通过…/可以读取上一级目录的话,那么代码中没有设置黑名单或白名单来进行过滤的话,我们是否可以通过传入任意文件读取的参数来进行目录遍历或目录穿越呢?

实验是否能从D盘跳转到C盘下并读取C盘的文件目录

http://localhost:63342/PhpstormProjects/Basic%20PHP/file-manage1.php?path=c:\\windows

通过path传入c:\\windows参数,我们可以发现已经读取到了C盘Windows目录下的所有文件,则可以证实存在着目录穿越漏洞。

漏洞条件绕过与修复

漏洞绕过

在些许开发者的视角下,他们或许会用黑名单的方式将一些常用的文件读取参数加入黑名单中。例如以下代码

$black_filepath=array('../');
if(in_array($dir,$black_filepath)){
echo '<script>alert("禁止跨目录访问")</script>';
}else {
filelist($dir);
}

  • <font style="color:rgb(36, 41, 47);background-color:rgba(175, 184, 193, 0.2);">in_array($dir, $black_filepath)</font> 检查用户输入的目录 <font style="color:rgb(36, 41, 47);background-color:rgba(175, 184, 193, 0.2);">$dir</font> 是否包含 <font style="color:rgb(36, 41, 47);background-color:rgba(175, 184, 193, 0.2);">'../'</font>,即是否是试图进行目录穿越。
  • 如果 <font style="color:rgb(36, 41, 47);background-color:rgba(175, 184, 193, 0.2);">$dir</font> 是 <font style="color:rgb(36, 41, 47);background-color:rgba(175, 184, 193, 0.2);">'../'</font>,就会弹出一个警告框,提示 “禁止跨目录访问”。
  • 如果不是 <font style="color:rgb(36, 41, 47);background-color:rgba(175, 184, 193, 0.2);">'../'</font>,则继续执行 <font style="color:rgb(36, 41, 47);background-color:rgba(175, 184, 193, 0.2);">filelist($dir)</font> 函数,列出该目录下的文件。

我们继续访问环境中进行测试,在admin的目录下进行上一级跳转验证。

发现提示禁止跨目录访问,但通过代码审计,我们会发现黑名单的过滤参数中只有…/这一种所以想要绕过的话我们换一种方式就行了

可以发现我们换成…\\依旧可以进行跳转,当然如果黑名单中也有…\\的话我们还可以使用多种./…/、…/等这里就不一一例举了换汤不换药,所以这是一种在实战黑盒测试中的思路,但如果能进行白盒测试审计代码是最容易的。

漏洞修复

我们可以将代码放在phpstudy的环境下面,文件中有一个叫做php_ini的配置文件

我们可以通过open_base来限制可读取的目录,默认情况下是被注释掉的所有可以产生漏洞

我们取消注释,然后限制基础目录在D:\\phpstudy_pro\\WWW目录下面,注:改完配置文件后记得在phpstudy重启一下环境

于是继续触发漏洞,在未传参之前还是可以读取当前目录下面的所有文件

于是我们继续读取上一级的目录,通过path进行传参

可以发现已经无法读取上一级文件了,并且PHP也给出了报错提示:PHP 给你的脚本设置了 “访问禁区”——只允许你操作 **D:\\phpstudy_pro\\WWW** 这个文件夹里的内容,但你的代码在第 43 行尝试打开 <font style="color:rgba(0, 0, 0, 0.85);">../</font>(也就是 <font style="color:rgba(0, 0, 0, 0.85);">WWW</font> 的上一级文件夹 <font style="color:rgba(0, 0, 0, 0.85);">D:\\phpstudy_pro</font>),这个操作超出了 PHP 允许的范围,所以被拦截了,同时抛出警告告诉你 “操作不被允许”。

赞(0)
未经允许不得转载:网硕互联帮助中心 » 三分钟看懂 PHP「路径跃迁」:用户输入如何意外走遍服务器目录?
分享到: 更多 (0)

评论 抢沙发

评论前必须登录!