文件包含

PHP常用的文件包含函数有四种,区别如下:

1
2
3
4
require():找不到被包含的文件会产生致命错误,并停止脚本运行
include():找不到被包含的文件只会产生警告,脚本继续执行
require_once()与require()类似:唯一的区别是如果该文件的代码已经被包含,则不会再次包含
include_once()与include()类似:唯一的区别是如果该文件的代码已经被包含,则不会再次包含

以这四个函数包含文件时,不论文件什么类型都会直接作为php文件解析。

分类

  • 本地文件包含漏洞(LFI)

能够打开并包含本地文件的漏洞,我们称为本地文件包含漏洞(LFI)

(1)使用绝对路径

(2)使用相对路径进行读取

1
2
./表示当前位置路径
../表示上一级路径位置

(3)一些常见的敏感目录信息路径

Windows系统:

1
2
3
4
5
6
C:\boot.ini 										//查看系统版本
C:\windows\system32\inetsrv\MetaBase.xml //IIS配置文件
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配置信息

Linux/Unix系统:

1
2
3
4
5
6
7
8
/etc/password 												//账户信息
/etc/shadow //账户密码信息
/usr/local/app/apache2/conf/httpd.conf //Apache2默认配置文件
/usr/local/app/apache2/conf/extra/httpd-vhost.conf //虚拟网站配置
/usr/local/app/php5/lib/php.ini //PHP相关配置
/etc/httpd/conf/httpd.conf //Apache配置文件
/etc/my.conf //mysql配置文件

  • 远程文件包含(RFI)

需要再php.ini中配置

1
2
allow_url_fopen = On			//一直默认
allow_url_include = On //php5.2之后默认

包含方式

  • php伪协议

1.file://协议
2.php://协议
1
2
3
4
5
6
7
8
php://filter用于读取源码并进行base64编码输出
eg: ?file=php://filter/read=convert.base64-encode/resource=flag.php
如果不写可选参数2(read或write),那么网页会自动匹配一个合适的read或write
3是过滤器。主要有四种:字符串过滤器,转换过滤器,压缩过滤器,加密过滤器。filter里可以用一或多个过滤器(中间用|隔开)

php://input用于执行php代码。 php代码写在POST

phar://路径 //php版本>=5.3.0
字符串过滤器
  • string.rot13(对字符串执行ROT13编码转换)
  • string.toupper(将字符串转化为大写)
  • string.tolower(将字符串转化为小写)
  • string.strip_tags(自 PHP 7.3.0 起废弃,从字符串中去除 HTML 和 PHP 标记)
转换过滤器

注:转换过滤器是 PHP 5.0.0 添加的

  • convert.base64-encode convert.base64-decode(将字符串进行base64编码加解密)
3.ZIP://协议

和phar相似,但是只能加绝对路径,并将#编码成%23,之后填压缩包里的文件

4.data://协议
1
2
eg:	?file=data:text/plain,<?php system();?>
?file=data:text/plain;base64,xxxxxx //xxxxxx的base解码为php代码
  • 包含session

    //session文件路径已知,且其中内容部分可控

1、包含日志

2、SSH log

  • 包含environ

//在user-agent中插入php代码,代码会写入environ中,之后再包含

  • 包含临时文件

//在temp目录下,在临时文件被删除前竞争时间包含

绕过方式

一、本地文件包含绕过

  • 空字符绕过(%00)

//存在PHP小于5.3.4版本,并且关闭PHP魔术引导。

  • 超长字符绕过(可以使用”./“or”.”填充)

//在Windows中目录长度不可以超过256字节,linux中目录长度不可以超过4096字节。超过的部分会被丢弃。

二、远程文件包含绕过

  • 空字符绕过
  • 超长字符绕过(远程文件包含好像只能使用”./“)
  • ?绕过(query)
  • #绕过(用#的编码%23)
  • 空格绕过(用空格的编码%20)