文件包含漏洞可以分为LFI(Local File Inclusion,本地文件包含)和RFI(Remote File Inclusion,远程文件包含)两种。而区分二者最简单的办法就是通过查看php.ini中是否开启了allow_url_include。如果开启就有可能包含远程文件。
远程文件包含需要php.ini中allow_url_fopen = On(是否允许打开远程文件) allow_url_include = On(是否允许include/require远程文件)。在php.ini中,allow_url_fopen默认一直是On,而从php5.2之后就默认为allow_url_includ为Off。
以PHP为例,常用的文件包含函数有以下四种:
include(),require(),include_once(),require_once()
区别如下:
require(),找不到被包含的文件时会产生致命错误,并停止脚本运行。
include(),找不到被包含的文件时只会产生警告,脚本将继续运行。
include_once()与include()类似,唯一区别是如果该文件中的代码已经被包含,则不会再次包含。
require_once()与require()类似,唯一区别是如果该文件中的代码已经被包含,则不会再次包含。
Windows系统敏感信息:
C:\boot.ini //查看系统版本
C:\windows\system32\inetsrv\MetaBase.xml //IIS配置文件
C:\windows\repair\sam //windows初次安装的密码
C:\program Files\mysql\my.ini //Mysql配置信息
C:\program Files\mysql\data\mysql\user.MYD //Mysql root
C:\windows\php.ini //php配置信息
......
Linux系统敏感信息:
/etc/passwd //linux用户信息
/usr/local/app/apache2/conf/httpd.conf //apache2配置文件
/usr/local/app/php5/lib/php.ini //php配置文件
/etc/httpd/conf/httpd.conf //apache配置文件
/etc/my.cnf //Mysql配置文件
......
文件上传漏洞在绕过内容检测的时候,会制作图片马上传,但是图片马在上传之后,又不能解析。如果网站同时存在文件包含漏洞,利用文件包含无视后缀名,只要被包含的文件内容符合PHP语法规范,任何扩展名都可以被PHP解析的特点来解析上传的图片马。
制作图片马的方式有很多,常见的有两种:
参数/b指定以二进制格式复制、合并文件,用于图像类/声音类文件
参数/a指定以ASCII格式复制、合并文件,用于txt等文档类文件
只有文件包含漏洞,且目标服务器本地无shell文件可利用,又可以远程文件包含时,可以在攻击机本地新建一个一句话木马文件(比如:shell.txt,不要以.php的文件存在,因为php文件在操作机本地会被解析),然后远程包含攻击机本地新建的木马文件,从而Getshell。
接受 POST 数据
执行shell命令
写入shell文件
’);?>
读取index.php文件并用base64加密
php://filter/read=convert.base64-encode/resource=index.php
读取index.php并用rot13加密
php://filter/read=string.toupper|string.rot13/resource=index.php
将数据以rot13加密写入index.php
php://filter/write=string.rot13/resource=index.php
php版本大于等于php5.3.0
绝对路径
phar://D:/phpStudy/WWW/fileinclude/test.zip/phpinfo.txt
相对路径(test.zip在当前目录下)
phar://test.zip/phpinfo.txt
php版本大于等于php5.3.0
使用zip协议,需要指定绝对路径,同时将#编码为%23,之后填上压缩包内的文件
zip://D:\phpStudy\WWW\fileinclude\test.zip%23phpinfo.txt
压缩包内存在子文件夹
zip://D:\phpStudy\WWW\fileinclude\test.zip%23test\phpinfo.txt
data://text/plain,
http://ip/include/include.php?page=data://text/plain,
data://text/plain;base64,
http://ip/include/include.php?page=data://text/plain;base64,PD9waHAgcGhwaW5mbygpPz4=
当我们的目标站点没有上传功能时,并且也不能远程文件包含时,就可以考虑包含日志文件或者其它可以记录客户端输入的文件。原理非常简单,当我们访问网站时,服务器日志会记录我们的行为,当我们的访问链接中含义恶意代码时,也会被记录到日志中,从而通过包含日志可以进行getshell。
但是整个过程最难就是获取日志文件的存放路径。
日志默认路径
(1) apache+Linux日志默认路径
/etc/httpd/logs/access_log 或者 /var/log/httpd/access_log
(2) apache+win2003日志默认路径
apache\logs\access.log
apache\logs\error.log
(3) IIS6.0+win2003默认日志文件
C:\WINDOWS\system32\Logfiles
(4) IIS7.0+win2003
默认日志文件
%SystemDrive%\inetpub\logs\LogFiles
(5) nginx 日志文件
日志文件在用户安装目录logs目录下
以我的安装路径为例/usr/local/nginx,
那我的日志目录就是在/usr/local/nginx/logs里
原理:apache服务器会在日志文件中记录每次的操作,攻击者想办法使php代码被记录在日志文件中,然后对日志进行文件包含,以此来执行php代码.
注意:直接在URL地址栏中写代码的话,日志记录的是URL编码后的内容,用文件包含是无法执行的.因此要抓包写php代码,这样日志中记录的就是php代码,可以用文件包含执行.
缺点就是必须要知道绝对路径和日志名,可以通过phpinfo来查看.
SSH:Secure Shell 为远程登录会话提供安全性的协议.通常用windows远程连接linux虚拟机执行命令.
需要注意默认不支持连接root用户,但是可以su root切换到root用户.
ssh连接格式:ssh 用户名@ip地址
ssh在连接时会有ssh日志记录ssh连接的记录,ssh日志保存在/var/log/auth.log文件中.因此可以在ssh连接时写入php代码,使代码被记录在日志中,然后包含ssh日志来执行.
用法:ssh ""@linux的ip地址 此时这串连接命令就被记录在ssh日志中,可以用文件包含执行代码.
注意windows中连接的话一定要用双引号.
前提:代码中有类似$_SESSION['name']的语句.能向session中写入恶意代码.
利用phpinfo可以看到session的存储路径,sessionid可以抓包获取,session文件名为sess+sessionid.
抓包向session中写入恶意代码,包含路径+文件名即可执行代码.
open_basedir是php.ini中的一个配置项,默认为空.
设置open_basedir=目录,使服务器只能访问指定目录及其子目录.如果文件包含一个open_basedir之外的文件就会报错,通常用来防御非法目录或文件操作.
godzilla工具
godzilla:哥斯拉,基于java的一款webshell管理工具,可以绕过open_basedir.
命令执行绕过
php中系统命令不受open_basedir的限制,在有命令执行漏洞的情况下可以绕过open_basedir操作文件.
ini.set()配合chdir()
ini.set()函数作用是临时修改php.ini文件,chdir()作用是切换文件指针所指向的目录.
这种方法的底层原理较为复杂,但poc是固定的,可以直接用.
glob协议
glob协议用来查找相匹配的文件,不受open_basedir的限制,可以用来遍历目录.
后期还会补充......
参考:
WEB安全梳理-文件包含 - FreeBuf网络安全行业门户
文件包含 - FreeBuf网络安全行业门户