目录穿越, 也被称为目录遍历/directory traversal/path traversal)是通过使用 …/ 等目录控制序列或者文件的绝对路径来访问存储在文件系统上的任意文件和目录,特别是应用程序源代码、配置文件、重要的系统文件等。
low
观察url会发现参数directory=documents, 是一个目录, 页面列出了docments下的所有文件信息, 这为目录遍历创造了条件
medium
if(isset($_GET["directory"]))
{
$directory = $_GET["directory"];
switch($_COOKIE["security_level"])
{
case "0" :
show_directory($directory);
// echo "
" . $_GET['page'];
break;
case "1" :
$directory_traversal_error = directory_traversal_check_2($directory);
if(!$directory_traversal_error)
{
show_directory($directory);
}
else
{
echo $directory_traversal_error;
}
break;
case "2" :
$directory_traversal_error = directory_traversal_check_3($directory, $base_path = "./documents");
if(!$directory_traversal_error)
{
show_directory($directory);
}
else
{
echo $directory_traversal_error;
}
break;
default :
show_directory($directory);
break;
}
}
?>
function directory_traversal_check_1($data)
{
// Not bulletproof
$directory_traversal_error = "";
// Searches for special characters in the GET parameter
if(strpos($data, "../") !== false ||
strpos($data, "..\\") !== false ||
strpos($data, "/..") !== false ||
strpos($data, "\..") !== false)
{
$directory_traversal_error = "Directory Traversal detected!";
}
/*
else
{
echo "Good path!";
}
*/
return $directory_traversal_error;
}
function directory_traversal_check_2($data)
{
// Not bulletproof
$directory_traversal_error = "";
// Searches for special characters in the GET parameter
if(strpos($data, "../") !== false ||
strpos($data, "..\\") !== false ||
strpos($data, "/..") !== false ||
strpos($data, "\..") !== false ||
strpos($data, ".") !== false)
{
$directory_traversal_error = "Directory Traversal detected!";
}
/*
else
{
echo "Good path!";
}
*/
return $directory_traversal_error;
}
function directory_traversal_check_3($user_path,$base_path = "")
{
$directory_traversal_error = "";
$real_base_path = realpath($base_path);
// echo "base path: " . $base_path . " real base path: " . $real_base_path . "
";
$real_user_path = realpath($user_path);
// echo "user path: " . $user_path . " real user path: " . $real_user_path . "
";
// int strpos ( string $haystack , mixed $needle [, int $offset = 0 ] )
// URL: http://php.net/manual/en/function.strpos.php
if(strpos($real_user_path, $real_base_path) === false)
{
$directory_traversal_error = "An error occurred, please try again.";
}
/*
else
{
echo "Good path!";
}
*/
return $directory_traversal_error;
}
// Searches for special characters in the GET parameter
if(strpos($data, "../") !== false ||
strpos($data, "..\\") !== false ||
strpos($data, "/..") !== false ||
strpos($data, "\..") !== false ||
strpos($data, ".") !== false)
{
$directory_traversal_error = "Directory Traversal detected!";
}
限制了../
的使用
在Linux下可以使用绝对路径/etc/apt
high
使用了realpath
函数,做了绝对的防护
realpath() 函数返回绝对路径
该函数删除所有符号连接(比如 ‘/./’, ‘/…/’ 以及多余的 ‘/’),并返回绝对路径
medium
function directory_traversal_check_2($data)
{
// Not bulletproof
$directory_traversal_error = "";
// Searches for special characters in the GET parameter
if(strpos($data, "../") !== false ||
strpos($data, "..\\") !== false ||
strpos($data, "/..") !== false ||
strpos($data, "\..") !== false ||
strpos($data, ".") !== false)
{
$directory_traversal_error = "Directory Traversal detected!";
}
/*
else
{
echo "Good path!";
}
*/
return $directory_traversal_error;
}
过滤了../
,..\\
,/..
,\..
,.
high
function directory_traversal_check_3($user_path,$base_path = "")
{
$directory_traversal_error = "";
$real_base_path = realpath($base_path);
// echo "base path: " . $base_path . " real base path: " . $real_base_path . "
";
$real_user_path = realpath($user_path);
// echo "user path: " . $user_path . " real user path: " . $real_user_path . "
";
// int strpos ( string $haystack , mixed $needle [, int $offset = 0 ] )
// URL: http://php.net/manual/en/function.strpos.php
if(strpos($real_user_path, $real_base_path) === false)
{
$directory_traversal_error = "An error occurred, please try again.";
}
/*
else
{
echo "Good path!";
}
*/
return $directory_traversal_error;
}
同样使用了realpath
函数
尝试抓包修改一下host
为localhost
可以看到, 链接地址会随着host地址改变, localhost可以代表攻击者的服务器地址, 攻击者可以在自己的服务器上同样构造这样的目录和文件http://xxx/bWAPP/portal.php
,用户点击后会受到攻击
medium&high
{
?>
<p>Click <a href="portal.php">here</a> to go back to the portal.</p>
}
与上一关一样, 也是通过修改http头中的host
地址来更改url
本地/远程文件包含
low
远程包含需要两个条件:
- php.ini中allow_url_include和allow_url_fopen的开启
- 所包含的远程文件后缀不能与目标服务器语言相同. (比如目标服务器是php解析的, 远程服务器的文件不能是php)
和本地包含原理类似, 直接在可控参数language
处写上远程服务器文件的地址
medium
high
if(isset($_GET["language"]))
{
switch($_COOKIE["security_level"])
{
case "0" :
$language = $_GET["language"];
break;
case "1" :
$language = $_GET["language"] . ".php";
break;
case "2" :
$available_languages = array("lang_en.php", "lang_fr.php", "lang_nl.php");
$language = $_GET["language"] . ".php";
// $language = rlfi_check_1($language);
break;
default :
$language = $_GET["language"];
break;
}
}
$available_languages = array("lang_en.php", "lang_fr.php", "lang_nl.php");
采用了白名单, 只能执行白名单中的php"lang_en.php", "lang_fr.php", "lang_nl.php"
那么可以通过修改http头的User-Agent
来实现
Mozilla/5.0 (iPhone; CPU iPhone OS 6_0 like Mac OS X) AppleWebKit/536.26 (KHTML, like Gecko) Version/6.0 Mobile/10A403 Safari/8536.25
限制文件夹访问
提示经过授权后才能访问这个目录中的文件
点击的话会发现要下载(看了教程才知道这里与题无关,仅仅是因为我安装了一个下载的插件。。)
switch($_COOKIE["security_level"])
{
case "0" :
// Deletes the '.htaccesss' file
if(file_exists($directory . "/.htaccess"))
{
unlink($directory . "/.htaccess");
}
$dp = opendir($directory);
while($line = readdir($dp))
{
if($line != "." && $line != "..")
{
echo " . $directory . "/" . $line . "\" target=\"_blank\">" . $line . "
";
}
}
break;
case "1" :
// Creates the '.htaccess' file
$fp = fopen($directory . "/.htaccess", "w");
fputs($fp, "Deny from all", 200);
fclose($fp);
$dp = opendir($directory);
while($line = readdir($dp))
{
if($line != "." && $line != ".." && $line != ".htaccess")
{
echo " . $directory . "/" . $line . "\">" . $line . "
";
}
}
break;
case "2" :
// Creates the '.htaccess' file
$fp = fopen($directory . "/.htaccess", "w");
fputs($fp, "deny from all", 200);
fclose($fp);
$dp = opendir($directory);
while($line = readdir($dp))
{
if($line != "." && $line != ".." && $line != ".htaccess")
{
echo " . $directory . "/" . $line . "\">" . $line . "
";
}
}
break;
default :
// Deletes the '.htaccesss' file
if(file_exists($directory . "/.htaccess"))
{
unlink($directory . "/.htaccess");
}
$dp = opendir($directory);
while($line = readdir($dp))
{
if($line != "." && $line != "..")
{
echo " . $directory . "/" . $line . "\" target=\"_blank\">" . $line . "
";
}
}
break;
}
学习一下htaccess
文件
概述来说,htaccess文件是Apache服务器中的一个配置文件,它负责相关目录下的网页配置。通过htaccess文件,可以帮我们实现:网页301重定向、自定义404错误页面、改变文件扩展名、允许/阻止特定的用户或者目录的访问、禁止目录列表、配置默认文档等功能
case "0" :
// Deletes the '.htaccesss' file
if(file_exists($directory . "/.htaccess"))
{
unlink($directory . "/.htaccess");
}
$dp = opendir($directory);
while($line = readdir($dp))
{
if($line != "." && $line != "..")
{
echo " . $directory . "/" . $line . "\" target=\"_blank\">" . $line . "
";
}
}
break;
比对low和medium的源码发现,在low中会将.htaccesss
这个文件删除;而在medium中会新建这个文件并写入deny from all
,而deny from all
的作用是写入的文件的目录下的所有内容都不能被访问
但不知道为啥我的low级别不是访问而是直接下载。。
服务端请求伪造(Server Side Request Forgery, SSRF)指的是攻击者在未能取得服务器所有权限时,利用服务器漏洞以服务器的身份发送一条构造好的请求给服务器所在内网。SSRF攻击通常针对外部网络无法直接访问的内部系统
SSRF可以对外网、服务器所在内网、本地进行端口扫描,攻击运行在内网或本地的应用,或者利用File协议读取本地文件。内网服务防御相对外网服务来说一般会较弱,甚至部分内网服务为了运维方便并没有对内网的访问设置权限验证,所以存在SSRF时,通常会造成较大的危害
三个链接代表三种不同类型的SSRF利用方式, 文件在evil
下
具体操作看大佬SSRF学习之路
XXE -“xml external entity injection"即xml外部实体注入漏洞”
概括一下就是"攻击者通过向服务器注入指定的xml实体内容,从而让服务器按照指定的配置进行执行,导致问题"
也就是说服务端接收和解析了来自用户端的xml数据,而又没有做严格的安全控制,从而导致xml外部实体注入
大佬文章
浅谈XML实体注入漏洞
抓包看看
看到xxe-1.php页面以POST方式向xxe-2.php页面传输了XML数据
那么可以自己增加一个恶意外部实体然后在原本的XML数据中进行实体调用,来进行XXE攻击
]>
<reset><login>&test;login><secret>Any bugs?secret>reset>
// If the security level is MEDIUM or HIGH
else
{
// Disables XML external entities. Doesn't work with older PHP versions!
// libxml_disable_entity_loader(true);
$xml = simplexml_load_string($body);
// Debugging
// print_r($xml);
$login = $_SESSION["login"];
$secret = $xml->secret;
DTD-实体
实体是用于定义引用普通文本或特殊字符的快捷方式的变量
实体引用是对实体的引用
实体可以在内部或外部进行声明
外部实体
Disables XML external entities
禁用了引用外部DTD实体