文件包含漏洞介绍

1.文件包含漏洞介绍

1.1 文件包含漏洞解释

​ 文件包含漏洞就是使用函数去包含任意文件的时候,当包含的文件来源过滤不严谨的时候,当存在包含恶意文件后,就可以通过这个恶意的文件来达到相应的目的

1.2 文件包含漏洞原理

​ 其实原理就是由于在代码开发的过程中,有时候会遇到相同的代码,不想重复输入,就将代码单独写在一个文件里面,当遇到的时候就直接调用该文件进行运行,而这种方式就会导致客户端可以调用其他的恶意文件,通过恶意文件造成文件包含漏洞

​ 但是前提也是当文件包含的代码文件被当作一个变量来使用,并且能够被用户传入参数,如果没有对该变量做相应的安全防护,就可能会引发出文件包含漏洞

1.3 漏洞成因分析

​ 我们先直接来看一个简单的例子,include.php的网页代码如下:

复制代码
<?php
	include $_GET['test'];
?>

​ 在创建一个phpinfo.php页面,代码如下:

复制代码
<?php
	phpinfo();
?>

​ 利用文件包含,我们通过include函数来执行phpinfo.php页面,成功解析

​ 将phpinfo.php文件后缀改为txt后进行访问,依然可以解析:

​ 可以看出,include()函数并不在意被包含的文件是什么类型,只要有php代码,都会被解析出来。

​ 在文件上传漏洞的学习中,我们上传了一个jpg格式的一句话木马,如果网站有文件包含漏洞,jpg文件就可以被当作php文件解析,所以这就是文件上传漏洞通常配合文件包含漏洞使用

1.4 文件包含的函数

1.4.1 常见的文件包含函数

PHP:include()、include_once()、require()、require_once()

JSP/Servlet:ava.io.file()、java.io.filereader()

ASP:include file、include virtual

1.4.2 PHP函数区别:

​ 文件包含漏洞在PHP中是比较多的,像JSP、ASP这方面的漏洞是比较少的,但这并不是说就不存在。

include:当使用该函数包含文件时,只有代码执行到include()函数时才将文件包含进来,发生错误时给出一个警告,继续向下执行。如果包含文件不存在,程序继续执行

include_once:和include类似,不同处在于include_once会检查这个文件是否已经被导入,如果已经导入,下文便不会再导入,后面once理解就是只导入一次

require:包含并运行指定的文件,包含文件发生错误时,函数会输出错误信息,程序直接终止执行

require_once:和require类似,不同处在于require_once只导入一次

1.5文件包含漏洞特征

​ 其实文件包含在URL中能够明显的看出来,但是不代表含有这些特征就一定有文件包含漏洞。只不过有些特征可以进行判断是存在文件包含的,但是能不能利用是另一方面

​ 比如:

复制代码
http://www.xxx.com/index.php/?name=x.php
http://www.xxx.com/index.php/?file=index2.html

1.6 文件包含漏洞分类

1.6.1 本地文件包含漏洞

​ 本地文件包含,通过意思就能够理解,就是在条件允许的情况下,所谓的条件允许也就是安全防护没做到位,通过这个条件对文件路径加载文件,就形成了本地文件包含,简称为LFI

1.6.1.1 本地文件包含漏洞案例

​ 例如php代码:

复制代码
<?php
	$filename=$_GET[name];
	include($filename);
?>

​ 在我网站根目录下面有一个index.php,通过文件包含进行执行,就形成了本地文件包含,若这个name参数能够被用户控制,那么就形成了本地文件包含漏洞。

1.6.2 远程文件包含漏洞

​ 远程文件包含漏洞导致的原因和本地文件包含漏洞造成的原因是一样的,只不过远程文件包含漏洞是利用外部的服务器中的文件进行执行,就形成了远程文件包含漏洞

​ 但是前提是需要再php.ini中的配置选项中allow_url_fopen和allow_url_include(默认为off)都为ON,简称为LFI

1.6.2.1 远程文件包含漏洞案例

​ 准备两台虚拟机,一台做网站服务器,另外一台做攻击者主机

​ 网站服务器:http://192.168.119.133

​ 攻击者主机:10.1.248.209

​ 网站服务器php代码:

复制代码
<?php
	$filename=$_GET[name];
	include($filename);
?>

​ 攻击者主机php代码:

复制代码
<?php phpinfo();?>

攻击者访问服务器网站,并把主机上的文件进行远程文件包含

1.7 文件包含漏洞危害

​ 读取WEB服务器上的配置文件以及WEB服务器上的敏感文件,并且若和webshell联动,并将恶意代码执行将造成更大的危害,通常来说远程文件包含漏洞危害更大。

1.8 文件包含漏洞特点

1.8.1 无视文件扩展名

​ 在PHP中当使用上面的一些函数的时候,这个文件就会被当作PHP代码进行执行,PHP内核并不会在意包含的文件是什么类型的,也就是说当发过来的是.png的文件也会被当作PHP执行。

1.8.1.1 无视文件扩展名案例

​ 例如这里将原来含有代码的php文件后缀名修改为jpg的时候,依旧执行了php代码

1.8.2 无条件解析PHP代码

​ 文件包含漏洞在读取源码的时候,若遇到符合PHP语法规范的代码,将会无条件执行

.../当前文件的上一级(父)目录

file_get_contents() 读取文件原始内容,PHP标签会被解析执行,适用场景为读取纯文本文件(如.txt)

2. 文件包含漏洞利用方式

想要成功利用文件包含漏洞,需要满足一下两个基本条件:

  1. include()等函数通过动态变量的方式引入需要包含的文件
  2. 用户能够控制该动态变量

Windows下的敏感文件路径

复制代码
C:\windows\my.ini	\\安装mysql时会将root密码写入该文件
C:\windows\system32\config\sam	存放windows管理员登录密码
C:\windows\system32\inetsrv\MetaBase.xml	\\存放iis配置文件
C:\tomcat5.0\conf\resin.conf	\\tomcat存放密码的位置
C:\boot.ini	\\查看系统版本
C:\windows\php.ini

Linux敏感文件绝对路径

复制代码
/etc/passwd   /etc/shadow     //密码存放文件/etc/passwd   /etc/shadow     //密码存放文件/etc/passwd   /etc/shadow     //密码存放文件/etc/passwd		//用户账号
/usr/local/app/apache2/conf/httpd.conf	//apache2默认配置文件
/usr/local/app/appache2/conf/extra/httpd-vhosts.conf	//虚拟网站设置
/usr/local/app/php5/lib/php.ini		//php相关设置
/etc/httpd/conf/httpd.conf		//apache配置文件
/etc/my.cnf		//mysql配置文件
/etc/sysconfig/iptables		//查看防火墙策略
/etc/sysconfig/network-scripts/ifcfg-eth0  //查看IP
/etc/redhat-release	//系统版本
/etc/rc.local   //有时可以读出来apache的路径
/etc/passwd   /etc/shadow     //密码存放文件

2.1伪协议

php伪协议介绍

file:// #访问本地文件系统

http:// #访问HTTPs网址

ftp:// #访问ftp URL

php:// #访问输入输出流

zlib:// #压缩流

data:// #数据

ssh2:// #security shell2

expect:// #处理交互式的流

glob:// #查找匹配的文件路径

​ 文件系统是PHP使用的默认封装协议,展现了本地文件系统。file://这个伪协议可以展示"本地文件系统",当存在某个用户可控制、并得以访问执行的输入点时,我们可以尝试输入file://去试图获取本地磁盘文件

​ 以DVWA的文件包含漏洞为例,获取存在C盘跟目录下的password.txt文件

​ 注意:file://这个伪协议后需要跟文件的绝对路径。以上两种方式效果一样,但是前面的是以电脑本地文件路径访问,后面的是浏览器访问本地文件的方式

​ 通过前面的介绍应该就可以了解到,远程文件包含漏洞是能够执行攻击者自定义的php代码的。在这里,利用php伪协议可以使得本地文件包含也有机会执行自定义的php代码。

​ 可以通过伪协议data://和php://input实现。具体实现方式如下:

复制代码
?page=data:text/plain,<?php php代码 ?>
?page=data:text/plain;base64,PD9waHAgcGhwaW5mbygpPz4=
"PD9waHAgcGhwaW5mbygpPz4="是通过base64加密的<?php phpinfo();?>
复制代码
?page=php://input
POST提交:<?php php代码 ?>

php://filter

php://filter是一种元封装器,设计用于数据流打开时的筛选过滤应用。类似readfile()、file()和file_get_contents()

php://filter/read/write=\<读/写链的筛选列表\>/resource=<要过滤的数据流>

php://filter参数:

名称 描述
resource=<要过滤的数据流> 这个参数是必须的。它指定了你要筛选过滤的数据流
read=<读链的筛选列表> 该参数可选。可以设定一个或多个过滤器名称,以管道符( | )分隔
write=<写链的筛选列表> 该参数可选。可以设定一个或多个过滤器名称,以管道符( | )分隔
<; 两个链的筛选列表> 任何没有以read=或write=作前缀的筛选器列表会视情况应用于读或写链

可以通过伪协议 php://filter 或者实现。具体的实现方式如下:(伪协议都需要allow_url_fopen和allow_url_include为on)

转换过滤器base64 convert.base64-encode:加密

从服务器读取php文件源代码

复制代码
?page=php://filter/read=convert.base64-encode/resource=file1.php

常见代码一

常见代码二

常见代码三------%00截断

包含日志文件

​ 有时候网站存在文件包含漏洞,但是却没有文件上传点。这个时候我们还可以通过利用Apache的日志文件来生成一句话木马。

​ 日志会记录客户端请求及服务器响应的信息,访问http://www.xx.com/时,也会被记录在日志里,也可以插入到User-Agent,但是请求的信息有可能被url编码之后记录日志,这里可以通过burp来发送请求包来防止被编码,通过相对路径找到日志文件,利用包含漏洞执行。

Apache日志文件存放位置

apache存在两个日志文件,access.log是记录登录等信息的日志文件,而error.log是错误文件。

Windows系统:

​ apache安装目录/logs/access.log或者error.log

Linux系统:

​ /var/log/apache/access.log或者error.log

​ /var/log/apache2/access.log或者error.log

​ /etc/httpd/logs/access_log或者error.log

Nginx日志文件存放位置

​ nginx存在两个文件日志文件,access.log是记录登录等信息的日志文件,而error.log是错误文件。

windows系统:

​ nginx安装目录/logs/access.log或者error.log

Linux系统:

​ /var/log/nginx/access.log或者error.log

IIS日志文件存放位置

iis6.0版本

​ C:\windows\system32\LogFiles

iis7.5版本

​ %SystemDrive%\inetpub\logs\LogFiles

3、文件包含漏洞防御

  1. 在php代码中禁止0字节(\0),防止攻击者截断攻击。把版本更新到最新版本

    目的:

    复制代码
    include '/home/wwwrun/' . $page . '.php' ;

    为了安全起见,开发人员通常以路径拼接的方式包含文件。当攻击者尝试提交:

    复制代码
    ?page=../../etc/passwd 

    这时候代码相当于:

    复制代码
    include '/home/wwwrun/../../etc/passwd.php';

    被包含的文件实际上是"/etc/passwd.php",但这个文件其实是不存在的。这时候攻击者可以在最后加上一个 0 字节,就能截断page变量之后的字符串:

    复制代码
    ../../etc/passwd\0

    通过web输入,只需urlencode编码,就能绕过拼接限制实现文件包含:

    复制代码
    ?page=../../etc/passwd%00
  2. 在PHP中配置open_basedir,限制PHP仅能打开某个文件夹的文件,使攻击者无法通过.../等方式遍历服务器文件。

  3. 过滤.(点)/ (斜杠)\(反斜杠)

  4. 尽量避免包含动态的变量,尤其是用户可以控制的变量,可以通过枚举实现,比如:

攻击者可以在最后加上一个 0 字节,就能截断page变量之后的字符串:

复制代码
../../etc/passwd\0

通过web输入,只需urlencode编码,就能绕过拼接限制实现文件包含:

复制代码
?page=../../etc/passwd%00
  1. 在PHP中配置open_basedir,限制PHP仅能打开某个文件夹的文件,使攻击者无法通过.../等方式遍历服务器文件。

    外链图片转存中...(img-wVAsYK3T-1785657375858)

  2. 过滤.(点)/ (斜杠)\(反斜杠)

  3. 尽量避免包含动态的变量,尤其是用户可以控制的变量,可以通过枚举实现,比如:

相关推荐
一只小菜鸡..5 小时前
南京大学 操作系统 (JYY) 学习笔记:CPU 的局限、GPU 与 AI 时代的算力革命
人工智能·笔记·学习
所愿ღ6 小时前
SSM框架-Spring3
java·开发语言·笔记·spring
影视飓风TIM7 小时前
C++ STL 完整入门笔记[8]:deque 底层原理深度剖析
开发语言·c++·笔记
凉、介7 小时前
ARMv8-A 指令学习
linux·笔记·学习·嵌入式·arm·指令
星恒随风7 小时前
Linux 基础指令(三):grep、压缩打包、系统信息与 Shell 运行原理
linux·笔记·学习
库玛西8 小时前
快速幂算法全景总结图:从“愚公移山”到“细胞分裂”
c语言·c++·笔记·算法
是江迪呀8 小时前
关于记笔记的批评和自我批评
笔记·aigc·ai编程
不会代码的小猴8 小时前
电机学笔记
笔记
程序员老陆9 小时前
FFmpeg 硬解在 Linux 上:从“能跑”到“跑满 GPU”的实战笔记
linux·笔记·ffmpeg