PHP文件包含
文章目录
PHP文件包含相关
文件包含
开发人员一般都把重复使用的函数放在单个文件中,需要使用的时候再调用,这调用的过程一般称为文件包含
PHP的文件包含函数
|
|
Include()
生成warning
,错误后继续执行
require()
生成error
,错误后不继续执行
_once
就是当已经文件包含后就不再包含同文件
举个例子
所有实验要在php.ini
中设置
allow_url_fopen=On
(是否允许打开远程文件)
allow_url_include=On
(是否允许include/require远程文件)
设置display_error=Off
(关闭警告提示)
此时,我们访问的当前目录下的文件,如果不限制参数,我们可以读取其他其他路径下的文件,这里有个绝对路径和相对路径的概念
绝对路径:绝对路径是指文件在硬盘上真正存在的路径 例如
/var/www/html/test/a.php
相对路径:就是相对于自己的目标文件位置 如 ./a.php,只要两个文件相对的路径不变,那么实际就是对的
他们的效果是一样的
文件包含漏洞原理
开发人员都希望代码灵活,所以通常会将包含文件设置为变量,如果这些变量没经过严格过滤或定义,可以被用户控制,包含了恶意文件或敏感路径,这就造成了文件包含漏洞
文件包含漏洞利用的前提条件:
(1)web 应用采用include
等文件包含函数,并且需要包含的文件路径是通过用户传输参数的方式引入;
(2)用户能够控制包含文件的参数,被包含的文件可被当前页面访问;
无限制本地包含漏洞
通过目录遍历漏洞可以获取到系统中其他文件的内容:
有限制本地文件包含
|
|
常见的利用目录
Windows:
|
|
Linux:
|
|
日志默认路径
|
|
web 中间件默认配置
|
|
远程文件包含
我们可以利用PHP的文件包含这个特性去访问另一台服务器文件
PHP
的配置文件allow_url_fopen
和allow_url_include
设置为ON
include/require
等包含函数可以加载远程文件,如果远程文件没经过严格的过滤,导致了执行恶意文件的代码,这就是远程文件包含漏洞。
有限制远程文件包含
?绕过
#绕过 %23
空格绕过 %3f
文件包含+文件改写+GETSHELL
设置一个极端的场景用户可以通过修改参数来更新自己的信息保存在另一个文件里(这种场景谁敢这么写怕不是没吃过毒打……)
发现成功执行了phpinfo()这个函数,这样,我们可以修改相对应的文件进行getshell,接下来就简单介绍一下利用代码执行函数和命令执行函数来getshell
上传文件包含获取 webshell 的条件:
(1)攻击者需要知道文件存放的物理路径; (2)对上传文件所在目录拥有可执行权限; (3)存在文件包含漏洞;
一句话木马的原理是调用了PHP的代码执行函数,常见的一句话菜刀马,就是调用了eval函数、assert函数。
|
|
session文件包含
大致了解了文件改写和一句话木马,现在讲一下文件包含中稍微有点难的session文件包含漏洞,其实上边文件改写就是session包含的一个翻版
利用条件:
(1)session的存储位置可以获取
(2)通过phpinfo获取到session存储位置
通过猜测默认的session存放位置进行尝试。如linux
下默认存储在/var/lib/php/session
目录下
Session.php
中的内容可以被控制,传入恶意代码。
此php会将获取到的GET
型session
变量的值存入到session
中。
当访问http://192.168.43.167/session.php?session=aaaa
后,会在/var/lib/php/session
目录下存储session
的值。session
的文件名为sess_+sessionid
,sessionid
可以通过开发者模式获取
所以文件是sess_v49q30h3c0jcornf4j8osule26
回到服务器查看
发现成功写入,接下来利用和上边一样的方法来执行恶意代码
PHP伪协议
php://input(写木马)
php://input
是个可以访问请求的原始数据的只读流。 POST 请求的情况下,最好使用php://input
来代替 $HTTP_RAW_POST_DATA
,因为它不依赖于特定的php.ini
指令。 而且,这样的情况下 $HTTP_RAW_POST_DATA
默认没有填充, 比激活always_populate_raw_post_data
潜在需要更少的内存。enctype=”multipart/form-data”
的时候php://input
是无效的。 ——php.net
简单说就是获取post数据。
还可以将文件包含变成命令执行
php://filter (读文件)
php://filter
是一种元封装器, 设计用于数据流打开时的筛选过滤应用。 这对于一体式(all-in-one)的文件函数非常有用,类似readfile()、file()和file_get_contents()
,在数据流内容读取之前没有机会应用其他过滤器。 ——php.net
简单说经常利用它进行base64编码,在CTF中,经常出现,我们利用
|
|
使用base64解码
zip://,bzip2://,zlib://(上传)
zlib://
的功能类似gzopen()
,但是 其数据流还能被fread()
和其他文件系统函数使用。 自PHP 4.3.0后这个不建议被使用,因为会和其他带“:”字符的文件名混淆;请使用compress.zlib://
作为替代。compress.zlib://、 compress.bzip2:// 和 gzopen()、bzopen()
是相等的。并且可以在不支持 fopencookie
的系统中使用。ZIP扩展注册了zip://
封装器。 自PHP7.2.0和libzip1.2.0+
起,加密归档开始支持密码,允许数据流中使用密码。 字节流上下文(stream contexts)中使用 ‘password’ 选项设置密码。 ——php.net
简单说就是直接访问压缩包里的文件。将phpinfo.txt
压缩成zip
,实战中可以改后缀为jpg
绕过上传限制。
data://伪协议
数据流封装器,和php://
相似都是利用了流的概念,将原本的include
的文件流重定向到了用户可控制的输入流中,简单来说就是执行文件的包含方法包含了你的输入流,通过你输入payload
来实现目的;如果php.ini
里的allow_url_include=On(PHP < 5.3.0)
,就可以造成任意代码执行
经过测试PHP版本5.2,5.3,5.5,7.0;data://
协议是是受限于allow_url_fopen
的
phar://伪协议
这个参数是就是php解压缩包的一个函数,不管后缀是什么,都会当做压缩包来解压。
用法:?file=phar://
压缩包/内部文件phar://xxx.png/shell.php
步骤: 写一个一句话木马文件shell.php,然后用zip协议压缩为shell.zip,然后将后缀改为png等其他格式。
注意:PHP > =5.3.0 压缩包需要是zip协议压缩,rar不行,将木马文件压缩后,改为其他任意格式的文件都可以正常使用。
这个可以参考初识phar反序列化
伪协议在CTF中的骚操作
不过一般现在这种文件包含漏洞和伪协议在CTF中都配合源码审计反序列化,文件上传绕过一起考,反序列化这里可以参考最通俗易懂的PHP反序列化原理分析
PHP反序列化漏洞总结:PHP反序列化漏洞总结(一) 、PHP反序列化漏洞总结(二)
文件包含+PHP伪协议利用绕过WAF
|
|
文件包含漏洞防御
在功能设计上尽量不要将文件包含函数对应的文件放在前端进行选择和操作
黑名单过滤
|
|
白名单过滤
|
|