原理
文件包含漏洞产生的原因是在通过引入文件时,包含的文件名,用户可控,由于传入的文件名没有经过合理的校验,或者校验被绕过。
常用函数
PHP中常见包含文件函数
include()
当使用该函数包含文件时,只有代码执行到include()函数时才将文件包含进来,发生错误
时之给出一个警告错误,继续向下执行。
include once()
功能与include()相同,区别在于当重复调用同一文件时,程序只调用一次
require
require()与include()的区别在于require()执行如果发生错误,函数会输出致命错误,并终止脚本的运行。
require once ()
功能与require()相同,区别在于当重复调用同一文件时,程序只调用一次。
file_get_contents() 读取文件 需要echo.
Fopen() 用读形式打开 是资源类型
区别
include:包含的文件不存在,程序会继续执行
require:包含文件不存在,程序停止执行
如果出现语法错误,两个不会继续执行,如果是找不到这个文件,include继续执行,require停止执行)
绕过
.html绕过
? %23
本地包含需开启
allow_url_include = On
远程包含需开启
allow_url_fopen = On allow_url_include = On
读取本地文件
开启 allow_url_fopen
讲文件中的数据进行base64加密
Windows系统:
c:\boot..ini/查看系统版本
c:\windows\system32 inetsrv\MetaBase.xml /IlS配置文件
c:windows\repair\sam /存储Windows系统初次安装的密码
c:\ProgramFiles\mysql\my.ini /MySQL配置
c:\ProgramFiles\mysql\data\mysql\user.MYD /MySQL root
c:\windows\php.ini /php配置信息
协议
开启allow_url_fopen = On
php://fileter
php://filter/read=convert.base64-encode/resource=路径(可以是相当路径)
以base64编码显示
开启allow_url_include = On
php://input
php语句
开启allow_url_include = On allow_url_fopen = On
data:text/plain,php语句 可用编码 data:text/plain;base64,php语句
php版本大于5.3.0皆适用
zip://压缩包绝对路径#压缩包里的文件
压缩包后缀可任意更改,只要它是个压缩包就行
file://路径(绝对路径)
phar协议
%00截断
php版本小于5.3.4 gpc未开启
路径长度截断
php版本小于5.2.8
/etc/passwd.////./././././././/.[]/////////......
linux需要文件名长于4096,windows需要长于256
中间件日志
包含日志文件GetShell
1.首先找到日志文件存放位置(httpd.ini设置,默认开启)
CustomLog "logs/access.log" common
让日志文件插入PHP代码
3.包含日志文件
中间件/logs/access.log
session会话文件包含
需要代码审计
<?php session_start(); $ctfs=$_GET['se']; $_SESSION["username"]=$ctfs; ?> ?se=php语句 需要bp抓包(否则会被转义) ../../tmp/tmp
漏洞挖掘
参数=文件 !!! 可能存在sql注入 /文件包含
没有通用的挖掘办法(Google搜索include..file=..) 特定的CMS,特定的版本可能存在漏洞(include,require) Web漏洞扫描器扫描,常见的web漏洞扫描器都支持可以检测。 手工挖掘,看参数,filename=xxx,是否可以包含其他文件
防御方法
PHP中使用open basedir配置限制访问在指定的区域 过滤.(点)/(正斜杠)\(反斜杠) 禁止服务器远程文件包含(allow_url_fopen,allow_url_include,off) 包含的参数值,不要用户可控
