文件包含漏洞详解

目录

文件包含及文件包含漏洞

PHP中常见包含文件函数

include()

include_once()

require()

require_once()

文件包含漏洞原理

常见漏洞代码

文件包含漏洞危害

文件包含漏洞的分类

文件包含利用

1.上传图片马,包含图片马GetShell

2.读取网站源码及配置文件

php://filter

php://input

data:text/plain

zip://伪协议

file://伪协议

Phar协议

更多伪协议

3.包含日志文件GetShell

4.包含session文件GetShell

 %00截断

漏洞挖掘

修复办法

1.PHP 中使用open_basedir 配置限制访问在指定的区域。

2.过滤 . / \  ../../../ 

3.过滤伪协议 

4.禁止服务器远程文件包含。

5.包含的参数值,不要用户可控。

6.设置白名单


什么是文件包含

程序开发人员一般会把重复使用的函数写到单个文件中,需要使用某个函数时直接调用此文件,而无需再次编写,这种文件调用的过程一般被称为文件包含。

文件包含漏洞

开发人员为了使代码更灵活,会将被包含的文件设置为变量,用来进行动态调用,从而导致客户端可以恶意调用一个恶意文件,造成文件包含漏洞。

即在文件包含的路径是攻击者可控的情况下,攻击者可以通过控制参数变量从而能包含本不在开发者意愿之内的文件。

PHP中常见包含文件函数

include()

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

include_once()

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

require()

        require()与include()的区别在于require()执行如果发生错误,函数会输出错误信息,并终止脚本的运行。

require_once()

        功能与require()函数相同。区别在于当重复调用同一文件时,程序只调用一次。

重点:include()与require()函数的区别

        当处理一个不存在或者无法包含的文件时,对于include()会抛出错误,然后继续执行下面的PHP代码。require()会直接抛出致命错误,后面的代码无法继续执行。

        如果出现语法错误,两个不会继续执行,如果是找不到文件,include()会继续执行,require()会终止执行。

文件包含漏洞详解_第1张图片文件包含漏洞详解_第2张图片

文件包含漏洞详解_第3张图片文件包含漏洞详解_第4张图片 

文件包含漏洞原理

        文件包含漏洞产生的原因是在通过引入文件时,包含的文件名,用户可控,由于传入的文件名没有经过合理的校验,或者校验被绕过。

常见漏洞代码

文件包含漏洞详解_第5张图片文件包含漏洞详解_第6张图片

文件包含漏洞危害

1. 配合文件上传漏洞 GetShell
2.可以执行任意脚本代码(php://input)(即时没有文件上传也能执行脚本代码)
3.网站源码文件及配置文件泄露(PHP://filter/read=convert.base64-encode/resource=Test.php)(即时没有文件上传也能读取)
4.远程包含GetShell
5.控制整个网站甚至是服务器

文件包含漏洞的分类

        1)本地文件包含:包含服务器端的文件

         当被包含的文件在服务器本地时,就形成了本地文件包含漏洞。

        本地文件包含就是通过浏览器包含 Web 服务器上的文件,这种漏洞时因为浏览器包含文件时没有进行严格的过滤允许遍历目录的字符注入浏览器并执行。

        2)远程文件包含:包含远程 url 的文件(allow_url_fopen  allow_url_include)

           远程文件包含就是允许攻击者包含一个远程的文件,一般是在远程服务器上预先设置好的脚本,此漏洞是因为浏览器对用户的输入没有进行检查,导致不同程度的信息泄露,拒绝服务攻击甚至在目标服务器上执行代码。

           本地文件包含和远程文件包含造成漏洞的原因是一样的。当 php.ini 中的配置选项 allow_url_fopen (是否运行通过一个url进行包含)和 allow_url_include 为ON的话,则包含的文件可以是第三方服务器中的软件,这样就形成了远程文件包含漏洞。

文件包含漏洞详解_第7张图片文件包含漏洞详解_第8张图片文件包含漏洞详解_第9张图片文件包含漏洞详解_第10张图片文件包含漏洞详解_第11张图片文件包含漏洞详解_第12张图片

文件包含利用

        1.上传图片马,包含图片马GetShell

        2.读取网站源码及配置文件


    

文件包含漏洞详解_第13张图片

php://filter

                        php://filter

利用条件:只是读取,所以只需要开启 allow_url_fopen , 对于 allow_url_include 不做要求。
实现效果:将文件种的数据进行 base64 加密之后输出
        index.php?file=php://filter/read=convert.base64-encode/resource=Test.php

        不支持多 / 

文件包含漏洞详解_第14张图片

';
        echo 'Input again';
    }

?>

文件包含漏洞详解_第15张图片

 php://input

                    php://input
需要开启 allow_url_include=on,对于 allow_url_fopen 不做要求。

接受post请求

php://input 是个可以访问请求的原始数据的只读流。 POST 请求的情况下,最好使用 php://input 来代替 $HTTP_RAW_POST_DATA,因为它不依赖于特定的 php.ini 指令。 而且,这样的情况下 $HTTP_RAW_POST_DATA 默认没有填充, 比激活 always_populate_raw_post_data 潜在需要更少的内存。 enctype="multipart/form-data" 的时候 php://input 是无效的。 

文件包含漏洞详解_第16张图片文件包含漏洞详解_第17张图片文件包含漏洞详解_第18张图片文件包含漏洞详解_第19张图片文件包含漏洞详解_第20张图片文件包含漏洞详解_第21张图片

 data:text/plain

                data:text/plain

条件:allow_url_fopen 参数与 allow_url_include 都需要开启。
i
用法:i
    1) ?file=data:text/plain,
    2) ?file=data:text/plain;base64,编码后的 php 代码
       注意:base64加密之后的代码,不能有+号,否则会和 url 中的+编码冲突。

       注:测试发现plain改为plan也可输出正确结果。i

文件包含漏洞详解_第22张图片文件包含漏洞详解_第23张图片文件包含漏洞详解_第24张图片文件包含漏洞详解_第25张图片 

 zip://伪协议

                    zip://伪协议
    
使用条件:使用 zip 协议,需要将 # 编码为%23 ,所以需要PHP的版本 >= 5.3.0,要是因为版本的问题无法将 # 编码为 %23 ,可以手动更改。

用法: ?file=zip://[压缩文件路径 + 压缩文件名]#[压缩文件内的子文件名]
       注:既可以用相对路径,也可以用绝对路径。
       file=zip://./1.zip%231.txt
       file=zip://c:\PHPstudy\WWW\Test\1.zip%231.txt
    

文件包含漏洞详解_第26张图片文件包含漏洞详解_第27张图片文件包含漏洞详解_第28张图片文件包含漏洞详解_第29张图片 文件包含漏洞详解_第30张图片

file://伪协议

                         file://伪协议

file://可以用来访问本地文件系统,且不受 allow_url_fopen 与 allow_url_include 的影响。

用法:?file=file://文件绝对路径 
     支持多 / 如?file=file:///文件绝对路径
     不支持文件相对路径

文件包含漏洞详解_第31张图片文件包含漏洞详解_第32张图片 

 Phar协议

                            Phar协议

用法:?file=phar://压缩包/内部文件 phar://xxx.png/shell.php

注意:PHP >= 5.3.0 压缩包需要是zip协议压缩,rar不行 ,将木马文件压缩后,改为其任意格式的文件都可以正常使用。

步骤:写一个一句话木马文件 sehll.php ,然后用zip协议压缩为 shell.zip ,然后将后缀改为 png 等其他格式。

文件包含漏洞详解_第33张图片文件包含漏洞详解_第34张图片文件包含漏洞详解_第35张图片 文件包含漏洞详解_第36张图片

更多伪协议

PHP官方的伪协议解释

        3.包含日志文件GetShell

1.首先 找到日志文件存放位置
2.让日志文件插入 PHP 代码
3.包含日志文件

httpd.conf 文件注释 ' CustomLog "logs/access.log" common ' 后出现 access.log 文件。

文件包含漏洞详解_第37张图片文件包含漏洞详解_第38张图片文件包含漏洞详解_第39张图片

 文件包含漏洞详解_第40张图片文件包含漏洞详解_第41张图片文件包含漏洞详解_第42张图片

 文件包含漏洞详解_第43张图片文件包含漏洞详解_第44张图片文件包含漏洞详解_第45张图片

小结:只有日志中记录内容为正确的可执行文件格式时才能执行。
    例如:
                可执行
                不可执行
              不可执行
             不可执行

        4.包含session文件GetShell

                            Session包含

利用条件:session的存储位置可以获取。
        通过 phpinfo() 的信息可以获取到 session 的存储位置。
        通过 phpinfo() 的信息,获取到 session.save_path

使用前提:1)要知道 session 的存储位置
         2)有一个可控的 session 参数位置
         3)要有一个文件包含点

文件包含漏洞详解_第46张图片文件包含漏洞详解_第47张图片文件包含漏洞详解_第48张图片文件包含漏洞详解_第49张图片文件包含漏洞详解_第50张图片文件包含漏洞详解_第51张图片文件包含漏洞详解_第52张图片文件包含漏洞详解_第53张图片

 %00截断

                                %00截断

    1) /etc/passwd%00
    2)需要 magic_quotes_gpc=off
    3)PHP < 5.3.4 有效

  ";
  }
  $file_name = $_GET['file'].".jpg" ;
  echo $file_name."
"; include $file_name ; ?>

文件包含漏洞详解_第54张图片文件包含漏洞详解_第55张图片文件包含漏洞详解_第56张图片文件包含漏洞详解_第57张图片文件包含漏洞详解_第58张图片

漏洞挖掘

        1.没有同用的挖掘办法(Google 搜索 include...file=...)

        2.特定的CMS,特定的版可能存在漏洞(include , require)

        3.Web 漏洞扫描器扫描,常见的 Web 漏洞扫描器都支持可以检测。

        4.手工挖掘,看参数,filename=xxx,是否可以包含其他文件。

修复办法

        1.PHP 中使用open_basedir 配置限制访问在指定的区域。

文件包含漏洞详解_第59张图片文件包含漏洞详解_第60张图片

        2.过滤 . / \  ../../../ 

1) 利用 str_replace() 函数。
2)利用 preg_replace() 函数。

        3.过滤伪协议 

        4.禁止服务器远程文件包含。

        5.包含的参数值,不要用户可控。

         6.设置白名单

你可能感兴趣的:(php)