IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> PHP知识库 -> 文件包含介绍以及代码分析 -> 正文阅读

[PHP知识库]文件包含介绍以及代码分析

0x01 文件包含介绍

文件包含漏洞是代码注入的一种,就是用户注入一段能控制的脚本或代码,并让服务端执行

0x02 文件包含函数

php文件包含主要由下面4种函数来完成的

  • include()
  • include_once()
  • require()
  • require_once
    当使用这4种函数包含一个新文件时,文件将作为php代码执行,php内核并不会在意被包含文件时什么类型,即使包含的时txt文件,图片文件。远程URL,也都将作为PHP代码执行

区别
require()的使用方法如:require(“xxx.php”)。这个函数通常放在PHP程序最前面,php程序执行前面,PHP程序再执行前,就会先读入require()所指定引入的文件,使他变成php程序网页的一部分

incloude()使用方法如:include(“xx.php”)。这个函数一般是放在流程控制的处理部分中。php程序网页再读到include()的文件时,才将它读进来,这种方式可以把程序执行时的流程简单化

require一个文件存在错误时,程序会中断执行,并显示致命错误
include一个文件存在错误时,那么程序不会中断,而是继续执行,并显示一个警告错误

require_once()、include_once()和require()、include()的区别是:当执行的问价被包含过 一次后,不会再次包含

0x03 文件包含影响函数

allow_url_include:是否允许远程包含文件
allow_url_include=On的情况下,它可以直接包含远程文件,当存在include( v a r ) 且 ( var)且( var)var)可控的情况下,可以直接控制$var变量来执行PHP代码。
allow_url_include再5.2.0以后默认配置为Off
allow_url_fopen:是否允许打开远程文件
allow_url_fopen默认配置是On

0x04 从源码审计看远程文件包含

<?php

/*

bWAPP, or a buggy web application, is a free and open source deliberately insecure web application.
It helps security enthusiasts, developers and students to discover and to prevent web vulnerabilities.
bWAPP covers all major known web vulnerabilities, including all risks from the OWASP Top 10 project!
It is for security-testing and educational purposes only.

Enjoy!

Malik Mesellem
Twitter: @MME_IT

bWAPP is licensed under a Creative Commons Attribution-NonCommercial-NoDerivatives 4.0 International License (http://creativecommons.org/licenses/by-nc-nd/4.0/). Copyright ? 2014 MME BVBA. All rights reserved.

*/

include("security.php");
include("security_level_check.php");
include("functions_external.php");
include("selections.php");

$language = "";

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;
    }
}
?>
<!DOCTYPE html>
<html>
    
<head>
        
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">

<!--<link rel="stylesheet" type="text/css" href="https://fonts.googleapis.com/css?family=Architects+Daughter">-->
<link rel="stylesheet" type="text/css" href="stylesheets/stylesheet.css" media="screen" />
<link rel="shortcut icon" href="images/favicon.ico" type="image/x-icon" />

<!--<script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script>-->
<script src="js/html5.js"></script>

<title>bWAPP - Missing Functional Level Access Control</title>

</head>

<body>
    
<header>

<h1>bWAPP</h1>

<h2>an extremely buggy web app !</h2>

</header>    

<div id="menu">
      
    <table>
        
        <tr>
            
            <td><a href="portal.php">Bugs</a></td>
            <td><a href="password_change.php">Change Password</a></td>
            <td><a href="user_extra.php">Create User</a></td>
            <td><a href="security_level_set.php">Set Security Level</a></td>
            <td><a href="reset.php" onclick="return confirm('All settings will be cleared. Are you sure?');">Reset</a></td>            
            <td><a href="credits.php">Credits</a></td>
            <td><a href="http://itsecgames.blogspot.com" target="_blank">Blog</a></td>
            <td><a href="logout.php" onclick="return confirm('Are you sure you want to leave?');">Logout</a></td>
            <td>
                <font color="red">
                    Welcome <?php
                    if(isset($_SESSION["login"])) {
                        if(isset($_SESSION["login"])) {
                            echo ucwords($_SESSION["login"]);
                         };
                    }
                    ?>
                </font>
            </td>
            
        </tr>
        
    </table>   
   
</div> 

<div id="main">

    <h1>Remote & Local File Inclusion (RFI/LFI)</h1>

    <form action="<?php echo($_SERVER["SCRIPT_NAME"]);?>" method="GET">

        Select a language:

        <select name="language">

<?php

if($_COOKIE["security_level"] == "1" || $_COOKIE["security_level"] == "2")
{

?>
            <option value="lang_en">English</option>
            <option value="lang_fr">Fran?ais</option>
            <option value="lang_nl">Nederlands</option>

<?php
}
else
{
?>
            <option value="lang_en.php">English</option>
            <option value="lang_fr.php">Fran?ais</option>
            <option value="lang_nl.php">Nederlands</option>

<?php
}

?>
        </select>

        <button type="submit" name="action" value="go">Go</button>        

    </form>

    <br />
<?php
    
if(isset($_GET["language"]))
{
    if($_COOKIE["security_level"] == "2")
    {
         if(in_array($language, $available_languages)){
             include($language);
         }

    } else
    {

        include($language);

    }

}

?>

</div>
    
<div id="side">
    <a href="http://twitter.com/MME_IT" target="blank_" class="button"><img src="./images/twitter.png"></a>
    <a href="http://be.linkedin.com/in/malikmesellem" target="blank_" class="button"><img src="./images/linkedin.png"></a>
    <a href="http://www.facebook.com/pages/MME-IT-Audits-Security/104153019664877" target="blank_" class="button"><img src="./images/facebook.png"></a>
    <a href="http://itsecgames.blogspot.com" target="blank_" class="button"><img src="./images/blogger.png"></a>
</div>     
    
<div id="disclaimer">
          
    <p>bWAPP is licensed under <a rel="license" href="http://creativecommons.org/licenses/by-nc-nd/4.0/" target="_blank"><img style="vertical-align:middle" src="./images/cc.png"></a> &copy; 2014 MME BVBA / Follow <a href="http://twitter.com/MME_IT" target="_blank">@MME_IT</a> on Twitter and ask for our cheat sheet, containing all solutions! / Need an exclusive <a href="http://www.mmebvba.com" target="_blank">training</a>?</p>
   
</div>
    
<div id="bee">
    <img src="./images/bee_1.png">
</div>

<div id="security_level">
    <form action="<?php echo($_SERVER["SCRIPT_NAME"]);?>" method="POST">
        
        <label>Set your security level:</label><br />
        
        <select name="security_level">
            <option value="0">low</option>
            <option value="1">medium</option>
            <option value="2">high</option>
        </select>
        <button type="submit" name="form_security_level" value="submit">Set</button>
        <font size="4">Current: <b><?php echo $security_level?></b></font>
    </form>   
    
</div>
    
<div id="bug">

    <form action="<?php echo($_SERVER["SCRIPT_NAME"]);?>" method="POST">
        
        <label>Choose your bug:</label><br />
        
        <select name="bug">
   
<?php

// Lists the options from the array 'bugs' (bugs.txt)
foreach ($bugs as $key => $value)
{
    
   $bug = explode(",", trim($value));
   
   // Debugging
   // echo "key: " . $key;
   // echo " value: " . $bug[0];
   // echo " filename: " . $bug[1] . "<br />";
   
   echo "<option value='$key'>$bug[0]</option>";
 
}
?>
        </select>
        <button type="submit" name="form_bug" value="submit">Hack</button>
    </form>
</div> 
</body>
</html>

上面是bWAPP的源码:直接定位到文件包含函数include($language),靶机上文件包含分为low、medium、high三个等级
在这里插入图片描述

当等级为low时,security_level等于0

在这里插入图片描述
从上图可以看出当security=0时,$language值就等于get方式传入的值,

在这里插入图片描述
经过一系列跳转来到147行,if(isset( G E T [ " l a n g u a g e " ] ) ) 条 件 为 真 , 进 入 158 行 执 行 i n c l u d e ( ) 函 数 , 可 以 看 出 全 程 没 有 过 滤 这 样 _GET["language"]))条件为真,进入158行执行include()函数,可以看出全程没有过滤 这样 G?ET["language"]))158include()language参数可控,可以直接进行文件包含

当等级为medium时,security_level等于1时

在这里插入图片描述
中级时他会在传入的$language后面拼接一个.php后缀,然后在147行进行if判断后,执行158行的文件包含
例如传入的是$language=./1.txt文件
执行include()时为include(./1.txt.php)造成无法包含成功

解决办法 1 %00截断

php内核是C语言实现的,因此C语言中的一些字符串处理函数。在连接字符串时,0字节(\x00)将作为字符串结束符。所以只要在1.txt后面加入一个0字节,就能截断$language变量后的字符串
即$language=./1.txt%00这样就能把添加的代码34行拼接的 **".php"**截断了

利用条件
  • magic_quotes_gpc=off
  • php小于5.3.4
    从利用条件来看可知利用比较局限
防御

在一般的应用 中,0字节是用户不需要的,可以完全禁用0字节

<?php
function getVar($name){
  value =isset(GET[name] ? GET[$name] : null; 
  if(is_string($value)){
    value= str_replace(“\0, ‘ ‘ , value);  
  }
}
?>

可以看到这里对“\0"进行了一个简单过滤

解决方法2 构造长目录截断(我尝试没有成功,可以自行尝试一下)

如果使用php5.3.4以上,或者过滤了"\0",大佬说可以利用操作系统对目录最大长度的限制,可以不需要0字节而达到截断的目的

目录字符串在windows下256字节,在linux下4096字节达到最大值,最大值长度以后的字符串将被丢弃
所以可以利用【./】构造超长目录,这样就可以把后面拼接的".php"给去掉了,但是我在bWAPP上调试时发现没用,这里我用的是win10+phpstudy搭建环境来尝试的

当等级为high时,security_level=2

在这里插入图片描述
可以看到他定义一个数组变量 $available_languages,里面存放了lang_en.php、lang_fr.php、和lang_nl.php三个值,并且将GET传参得到的language的值后面拼接了“.php”后重新赋值给$language,
然后执行如下if判断
在这里插入图片描述
此时security_level==2会执行149的if判断,判断$language的值是否在数组$available_languages中,如果在,执行include()包含,如果不在直接跳到160行外,不进行文件包含操作

0x05 利用伪协议进行文件包含

文件包含除了本地文件包含和远程文件包含还可以结合伪协议进行使用,关于伪协议的介绍以及使用我会单独写一篇文章的

  PHP知识库 最新文章
Laravel 下实现 Google 2fa 验证
UUCTF WP
DASCTF10月 web
XAMPP任意命令执行提升权限漏洞(CVE-2020-
[GYCTF2020]Easyphp
iwebsec靶场 代码执行关卡通关笔记
多个线程同步执行,多个线程依次执行,多个
php 没事记录下常用方法 (TP5.1)
php之jwt
2021-09-18
上一篇文章      下一篇文章      查看所有文章
加:2021-08-06 09:23:16  更:2021-08-06 09:25:23 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年4日历 -2024/4/28 9:02:45-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码