目录

Web安全之文件包含漏洞


1. 文件包含漏洞介绍

文件包含,就是在一个文件中引用另一个文件,这就是文件包含。而文件包含漏洞就是指引用的文件被攻击者控制,然后攻击者使其包含恶意文件实现攻击。

文件包含有两种方式:本地文件包含(LFI)和远程文件包含(RFI)。而区别就和名字一样,本地文件包含只能包含服务器本地的文件,远程文件包含可以包含其他服务器的文件。


2. 漏洞危害

  • 敏感文件读取:可以读取一些敏感文件,如网站配置文件等。

  • 暴露绝对路径:在php中,若包含的文件不存在,可能会爆出网站的绝对路径。

  • 包含木马:可以包含木马文件,直接getshell。


3. 漏洞利用

在文件包含漏洞中,由于各个语言的文件包含语法不一致,所以利用方式也各不相同,需根据实际情况进行相应的利用。

3.1 PHP文件包含

基础知识

  • PHP的文件包含相当于将被包含的文件代码拷贝到当前文件中。

  • 被包含的文件内容只要符合PHP语法规范,任何扩展名都可以。但是如果文件内容不符合PHP语法规范,那么PHP就会将文件内容原样输出在页面上。

  • 文件包含相关函数

    • include():找不到被包含的文件时会产生警告(E_WARNING),脚本将继续执行。

    • include_once():与include()类似,唯一区别是如果被包含的文件已被包含,则不会再次包含,相当于有且只包含一次。

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

    • require_once():与require()类似,唯一区别是如果被包含的文件已被包含,则不会再次包含,相当于有且只包含一次。

  • PHP配置选项

  • allow_url_include:该选项控制是否允许通过url的方式包含文件,也就是是否允许远程包含,默认值为Off,不允许远程包含。

  • PHP支持协议:可用以下协议进行文件包含。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    
    file://
    http://
    ftp://
    php://
    zlib://
    data://
    ssh2://
    expect://
    glob://
    

利用方式

  • 绝对路径暴露:当被包含的文件不存在时,PHP会抛警告在页面上,有可能暴露网站绝对路径。

  • 读取敏感文件:可通过漏洞读取敏感文件,例如读取/etc/passwd

  • 包含远程木马:可以直接包含一句话木马,或者包含一个写入一句话木马的文件。

  • 绕过WAF:将木马写入图片中并包含图片。

绕过方式

  • 包含日志文件:当只能进行本地包含,且没有地方上传文件时,可以包含日志文件来实现攻击。

    • 可包含的日志:容器日志、数据库日志等。

    • 利用条件:日志的绝对路径。

    • 容器日志就拿Apache举例。当访问网站时,Apache会将请求路径写入access.log文件中,如果在请求路径中写入一句话木马,再包含日志,即可实现攻击。需要注意的是,在浏览器访问网站时,会将特殊字符转义,如<会转义成%3C,而日志中也会根据转过来的转义数据进行存储,所以需要抓包直接发送未转义的数据。

    • 数据库日志就拿MySQL举例,当开启了日志功能后,在网站请求能查询数据库的请求,请求中包含恶意数据,再包含日志,即可实现攻击。

  • %00截断绕过:当magic_quotes_gpc选项为Off状态,且php版本<5.3.4,可尝试此方式

3.2 JSP/Servlet文件包含(未实验)

基础知识

  • JSP分为静态包含和动态包含

    • 静态包含:在JSP中,include指令为静态包含,它只允许包含一个已经存在于服务器中的文件,而且不能使用变量来控制包含某个文件。这就意味着使用include指令将不存在文件包含漏洞

      1
      
      <%@ include file="a.txt" %>
      
    • 动态包含:与静态包含正好相反,它可以包含一个动态页面,也就是用变量指定包含的文件名。动态包含<jsp:include/>的标签就存在文件包含漏洞

      1
      2
      3
      4
      
      <%
          String pages = request.getParameter("page");		// 获取page变量
      %>
      <jsp:include page="<%=pages%>"></jsp:include>    		// 包含获取的page变量,产生漏洞
      
  • 如果动态包含<jsp:include/>标签包含一个非JSP文件扩展名的文件时,即使其内容符合JSP语法规范,也只会读取其源码,而不会当成JSP代码执行。

漏洞点

  • 上面所提到的JSP文件中的动态包含。

  • Servlet中的RequestDispatcher接口:使用request对象的getRequestDispatcher方法生成新文件。该方法接收一个模板参数,若此参数可控,攻击者则可以提供恶意文件名实现攻击。

  • RequestDispatcher接口的forward方法:该方法将跳转到参数所指向的文件,若参数可控,也可实现文件包含攻击。

利用方式

  • 读取敏感文件,如网站根目录下的WEB-INF/web.xml

  • 包含JSP木马


4. 防御

  • 严格判断包含中的参数,做好限制与过滤

  • 路径限制:限制被包含的文件只能在某一目录中,一定要禁止目录跳转字符,如:../

  • 白名单限制:判断被包含的文件是否在白名单内,只允许对白名单内的文件进行包含

  • 做好网站配置,例如php的allow_url_include选项,如不使用就将其设置为Off



参考书籍
《Web安全深度剖析》 张炳帅 著,电子工业出版社,ISBN: 9787121255816,豆瓣链接