一.文件包含漏洞
1.文件包含
开发人员将可重复使用的内容写到单个文件中,使用时直接调用此文件,无需再次编写,这种调用文件的过程一般被称为文件包含。这样编写代码能减少代码冗余,降低代码后期维护难度,保证网站整体风格统一,比如:导航栏、底部栏等。
2.文件包含漏洞
开发人员希望代码更加灵活,有时会将包含的文件设置为变量,用来动态调用,由于这种灵活性,可能导致攻击者调用恶意文件,造成文件包含漏洞。
3.漏洞危害
- 配合文件上传漏洞GetShell
- 网站源码文件以及配置文件泄露
- 远程包含GetShell
- 敏感信息泄露
4.文件包含相关函数
几乎所有脚本语言都会提供文件包含的功能,但文件包含漏洞在PHP Web应用中居多,而在JSP、ASP程序中却非常少,甚至没有。PHP中提供了四个文件包含的函数,分别是 include() 、include_once() 、 require() 和 require_once() 。
- include:出现错误时,会抛出一个警告,程序继续运行。
- include_once:出现错误时,会抛出警告,且仅包含一次。
- require:出现错误时,会直接报错并退出程序执行。
- require_once:出错时直接退出;且仅包含一次。
PHP 文件包含的特性:
-
只要被包含文件的文件内容符合PHP语法,不管文件类型是什么,该文件都会被php解释器去解析执行;如果文件内容不符合PHP语法,就会将该文件内容读取出来。
5.漏洞利用思路
- 包含一些敏感的配置文件,获取目标敏感信息
- 配合图片马getshell
- 包含临时文件getshell
- 包含session文件getshell
- 包含日志文件getshell(Apache等)
- 利用php伪协议进行攻击
二.文件包含漏洞类型
1.本地文件包含
基本概念
仅能够对服务器本地的文件进行包含,由于服务器上的文件并不是攻击者所能够控制的,因此该情况下,更多的会包含一些固定的系统配置文件,从而读取系统敏感信息。很多时候本地文件包含漏洞会结合网站的文件上传功能,从而形成更大的威力。
- 简单来说:当包含的文件在服务器本地时,就形成了本地文件包含。
利用方式
- 上传图片马,包含图片马GetShell
- 读取网站源码以及配置文件
- 包含日志文件GetShell
读取敏感信息
利用格式:http://example.com/file.php?file=flag.txt
-
利用file伪协议读取系统信息
http://example.com/file.php?file=file://c:/windows/win.ini
Windows常见敏感文件:
文件 | 说明 |
---|---|
C:\boot.ini | 查看系统版本 |
C:\windows\system32\inetsrv\MetaBase.xml | iis配置文件 |
C:\windows\repair\same | 存储windows系 统初次安装密码 |
C:\ProgramFiles\mysql\my.ini | mysql配置信息 |
C:\ProgramFiles\mysql\data\mysql\user.MYD | mysql root密码 |
C:\windows\win.ini | 系统信息,常用 于注入木马 |
Linux常见敏感文件:
文件 | 说明 |
---|---|
/etc/passwd | 账户信息 |
/etc/shadow | 账户密码文件 |
/etc/apache2/apache2.conf | Apache2默认配置文件 |
/etc/my.conf | mysql配置文件 |
/etc/php/5.6/apache2/php.ini | php相关配置 |
/etc/httpd/conf/httpd.conf | apache配置信息 |
2.远程文件包含
如果应用程序的配置还允许包含远程的其它服务器上的文件,恶意攻击者就有可能构造恶意的脚本然后通过包含并予以执行,进而获取WEB应用的敏感数据或控制权,这种方式称为远程文件包含。
-
简单来说:当包含的文件在远程服务器上时,就形成了远程文件包含。
-
利用前提:
- allow_url_fopen=On (默认开启)
- allow_url_include=On (默认关闭)
- PS:可在 \phpstudy\PHPTutorial\php\php-5.2.17\php.ini 中配置。
-
漏洞利用:
-
攻击者在自己的服务器上随意写一个文件 phpinfo.php内容为:
<?php phpinfo();?>
-
然后在目标网站上包含该文件
PS:如果远程文件包含一句话木马时,不要做成.php文件,一般做成.txt文件。因为本地php解释器和远程服务器的php解释器可能会造成冲突从而导致不解析。并且后缀为 .php 的文件,在包含时,显示的是远程服务器的信息,而不是本地的信息。如上方 phpinfo.php 显示的是远程服务器(kali)的php信息。
所以我们在远程服务器(kali)的 /var/www/html 目录下,创建一个名为 shell.txt 的文件,文件内容为:<?php eval($_POST["cmd"]);?>
-
然后通过远程文件包含来包含该文件(记得开启kali的apache服务)
-
三.PHP伪协议
PHP带有很多内置URL风格的封装协议,用于类似 fopen() 、copy() 、 file_exists() 和 filesize() 文件系统函数。
具体协议请参照:PHP:支持的协议和封装协议
-
1.file://
-
作用:用于访问本地文件系统,常用来读取本地文件。
-
格式:file://文件的绝对路径和文件名
-
示例:
-
绝对路径:http://127.0.0.1/include.php?file=file://c:/windows/win.ini
-
相对路径:http://127.0.0.1/include.php?file=./phpinfo.txt
- ./:表示当前目录
-
2.php://input
-
介绍:php://input 可以访问请求的原始数据的只读流,将post请求的数据当作php代码执行,如果存在文件包含漏洞,可将 php://input作为文件名传入,同时在post中设置想要注入的代码,php执行时就会将post的内容作为php代码执行。
-
前提条件:
- allow_url_fopen=On (默认开启)
- allow_url_include=On (默认关闭)
-
示例:
-
将 php://input作为文件名传入,同时在post中设置想要注入的代码
-
如果要写文件,则可以把php代码换成以下内容:
<?php fputs(fopen('shell.php','w'),'<?php @eval($_POST["a"])?>');?>
- PS:这段代码的意思为打开shell.php执行写入的操作,写入的内容为一句话木马。
-
3.php://filter
-
介绍:php://filter是一种元封装器,设计用于数据流打开时的筛选过滤。主要用来查看源码。
-
用法:php://filter/read=convert.base64-encode/resource=filepath
-
表示以base64编码的方式进行读取指定路径的文件。
-
参数说明:
参数 | 描述 |
---|---|
resource=<要过滤的数据流> | 这个参数是必须的。它指定了你要筛选过滤的数据流。 |
read=<读链的筛选列表> | 该参数可选。可以设定一个或多个过滤器名称,以管道符(|)分隔。 |
write=<写链的筛选列表> | 该参数可选。可以设定一个或多个过滤器名称,以管道符(|)分隔。 |
其他过滤器:
-
字符串过滤器
string.rot13 进行rot13转换
string.toupper 将字符全部大写
string.tolower 将字符全部小写
string.strip_tags 去除空字符、HTML 和 PHP 标记后的结果 -
转换过滤器
convert.base64-encode base64 编码
convert.base64-decode base64 解码
convert.quoted-printable-encode quoted-printable 编码(也是另一种将二进制进行编码的方案)
convert.quoted-printable-decode quoted-printable 解码
convert.iconv 实现任意两种编码之间的转换 -
压缩过滤器
zlib.deflate 压缩过滤器
zlib.inflate 解压过滤器
bzip2.compress 压缩过滤器
bzip2.decompress 解压过滤器 -
加密过滤器
mcrypt.* 加密过滤器
mdecrypt.* 解密过滤器
4.phar://
-
作用:属于压缩流,可以访问压缩文件中的子文件,不需要指定后缀名,可修改为任意后缀,比如:jpg png gif xxx 等等。
- PS:可以使用相对路径也可以使用绝对路径。
-
示例:
-
相对路径:
-
绝对路径:
-
5.zip://
-
作用:属于压缩流,可以访问压缩文件中的子文件,可以不需要指定后缀名,可修改为任意后缀。比如:jpg png gif xxx 等等。
- 优点:可以绕过包含的固定后缀。
- 缺点:需要知道文件的绝对路径。
-
格式:zip://[压缩文件绝对路径]%23[压缩文件内的子文件名](#编码为%23)
-
示例:
-
压缩 phpinfo.txt 为 phpinfo.zip ,压缩包重命名为 phpinfo.jpg
-
6.http:// https://
-
作用:访问远程文件或资源,常用于远程包含。
-
前提条件:
- allow_url_fopen=On (默认开启)
- allow_url_include=On (默认关闭)
-
使用示例:
-
检测是否存在远程文件包含
-
远程文件包含利用
-
7.data://
-
介绍:数据流封装器,以传递相应格式的数据。
-
前提条件:
- allow_url_fopen=On (默认开启)
- allow_url_include=On (默认关闭)
-
作用:自PHP>=5.2.0起,可以使用data://数据流封装器,已传递相应格式的数据,通常可以用来执行PHP代码。
-
格式:
data://text/plain,[php代码]
data://text/plain;base64,[base64编码的php代码] -
示例:
-
php代码:
-
base64编码的php代码:
- PS:file=data://text/plain;base64,PD9waHAgcGhwaW5mbygpOz8+ 在URL中加号要改成%2B
-
四.防御方案
- 设置白名单:代码在进行文件包含时,如果文件名可以确定,可以设置白名单对传入的参数进行比较。
- 路径限制:限制被包含的文件只能在某一文件夹内,PHP配置文件中有open_basedir选项可以设置用户需要执行的文件目录,如果设置目录的话,PHP仅仅在该目录内搜索文件。
- 关闭危险配置:PHP配置中的allow_url_include选项如果打开,PHP会通过Include/Require进行远程文件包含,由于远程文件的不可信任性及不确定性,在开发中禁止打开此选项,PHP默认是关闭的。
- 过滤危险字符:严格检查用户输入,参数中不允许出现 ../ 之类的目录跳转符。
- 尽量不要使用动态包含,可以在需要包含的页面固定写好,例如:include('head.php')。