概述
悟空軟件長期為企業(yè)提供企業(yè)管理軟件(CRM/HRM/OA/ERP等)的研發(fā)、實(shí)施、營銷、咨詢、培訓(xùn)、服務(wù)于一體的信息化服務(wù)。悟空軟件以高科技為起點(diǎn),以技術(shù)為核心、以完善的售后服務(wù)為后盾,秉承穩(wěn)固與發(fā)展、求實(shí)與創(chuàng)新的精神,已為國內(nèi)外上千家企業(yè)提供服務(wù)。
聽說很厲害,搜索了下存在的舊版本漏洞,看看是否還存在這樣的漏洞,舊漏洞如下:
按照已有的方向先排查一波。
安裝
下載完包后,解壓放到環(huán)境的根目錄。
訪問url
點(diǎn)擊同意,進(jìn)行下一步安裝。
安裝完成,使用安裝過程功的賬號(hào)密碼,登錄到工作臺(tái)。
sql注入
進(jìn)入到管理操作區(qū),找到項(xiàng)目管理,在所有請(qǐng)求中有一個(gè)myTask請(qǐng)求,
使用burpsuite抓取到改請(qǐng)求,發(fā)送到重放模塊,接著修改構(gòu)建傳遞的參數(shù),第一個(gè)將url部分mytask修改成dateList,將body部分的{"search":"","sort_field":2,"completed_task":true,"owner_user_id":[],"time_type":"","label_id":[]}修改改成{"start_time":"123","stop_time":"12"}此時(shí)點(diǎn)擊一次go,看是否有正確相應(yīng)。
接著,將請(qǐng)求保存到一個(gè)文本中,命名為post.txt。
接著上sqlmap跑一下這個(gè)請(qǐng)求包。
代碼分析:
publicfunctiondateList() { $param=$this->param; $taskModel=model('Task'); $userInfo=$this->userInfo; $param['user_id']=$userInfo['id']; $data=$taskModel->getDateList($param); returnresultArray(['data'=>$data]); }
此方法中的getDateList讀取數(shù)據(jù)庫,看方法邏輯:
publicfunctiongetDateList($param) { $start_time=$param['start_time']; $stop_time=$param['stop_time']; $user_id=$param['user_id']; //$date_list=dateList($start_time,$stop_time,1); $where=[]; $where['ishidden']=0; $where['is_archive']=0; $where['status']=1; $where['pid']=0; $str=','.$user_id.','; $whereStr='(create_user_id='.$user_id.'or(owner_user_idlike"%'.$str.'%")or(main_user_id='.$user_id.'))'; $whereDate='(stop_time>0andstop_timebetween'.$start_time.'and'.$stop_time.')or(update_timebetween'.$start_time.'and'.$stop_time.')'; $list=db('task') ->where($where) ->where($whereStr) ->where($whereDate) ->field('task_id,name,priority,start_time,stop_time,priority,update_time') ->select(); return$list?:[]; }
再此方法中接受的參數(shù)有start_time、stop_time、user_id三個(gè)參數(shù),其實(shí)這三個(gè)參數(shù)都沒有加過濾,直接字符串拼接。所以都存在SQL注入點(diǎn),只不過sqlmap在start_time的時(shí)候,就跑出結(jié)果了,后面不驗(yàn)證罷了。
需要提醒的是,再最新版本中,這個(gè)url需要構(gòu)造出來,而不是點(diǎn)解控制臺(tái)中哪個(gè)url。項(xiàng)目方把這個(gè)功能模塊去掉了,但是代碼并沒有刪除。簡單驗(yàn)證如下圖:
所以,前臺(tái)的vue打包程序中,沒有這個(gè)路由了。只能通過后期的構(gòu)建,才能復(fù)現(xiàn)出這個(gè)漏洞。
任意文件上傳
在平臺(tái)所有文件上傳點(diǎn)上,選取上傳用戶圖像的功能點(diǎn)。
使用burpsuite抓包,如下:
將用戶名和圖片內(nèi)容分別替換成php后綴的文件,和PHP代碼如:此時(shí)返回的數(shù)據(jù)是錯(cuò)誤的,不過沒關(guān)系,文件已經(jīng)生成了。如下圖所示:
嘗試了很多次,生的文件比較多。此時(shí)從瀏覽器上訪問任意一個(gè)文件路徑,效果如下:
當(dāng)寫入一句話的時(shí)候,也是可以用蟻劍連接的。
代碼分析:通過抓包,訪問的url/index.php/admin/users/updateImg可以看到該方法如下:
publicfunctionupdateImg() { $fileModel=model('File'); $param=$this->param; $userInfo=$this->userInfo; //處理圖片 header('Access-Control-Allow-Origin:*'); header('Access-Control-Allow-Methods:POST'); header("Access-Control-Allow-Headers:Origin,X-Requested-With,Content-Type,Accept"); $param['file']=request()->file('file'); $resImg=$fileModel->updateByField($param['file'],'User',$param['id'],'img','thumb_img',150,150); if(!$resImg){ returnresultArray(['error'=>$fileModel->getError()]); } returnresultArray(['data'=>'上傳成功']); }
在方法里,有個(gè)updateByField的方法,這個(gè)是上傳文件的調(diào)用,方法體如下:
publicfunctionupdateByField($file,$module,$module_id,$field,$thumb_field='',$x='150',$y='150') { if(empty($module)||empty($module_id)||empty($field)){ $this->error='參數(shù)錯(cuò)誤'; returnfalse; } $info=$file->move(FILE_PATH.'public'.DS.'uploads');//驗(yàn)證規(guī)則 $fileInfo=$info->getInfo();//附件數(shù)據(jù)
在這個(gè)方法中,有個(gè)文件管理類file,其中的move方法做了文件的上傳操作,如下:
publicfunctionmove($path,$savename=true,$replace=true) { //文件上傳失敗,捕獲錯(cuò)誤代碼 if(!empty($this->info['error'])){ $this->error($this->info['error']); returnfalse; } //檢測合法性 if(!$this->isValid()){ $this->error='uploadillegalfiles'; returnfalse; } //驗(yàn)證上傳 if(!$this->check()){ returnfalse; } $path=rtrim($path,DS).DS; //文件保存命名規(guī)則 $saveName=$this->buildSaveName($savename); $filename=$path.$saveName; //檢測目錄 if(false===$this->checkPath(dirname($filename))){ returnfalse; } //不覆蓋同名文件 if(!$replace&&is_file($filename)){ $this->error=['hasthesamefilename:{:filename}',['filename'=>$filename]]; returnfalse; } /*移動(dòng)文件*/ if($this->isTest){ rename($this->filename,$filename); }elseif(!move_uploaded_file($this->filename,$filename)){ $this->error='uploadwriteerror'; returnfalse; } //返回File對(duì)象實(shí)例 $file=newself($filename); $file->setSaveName($saveName)->setUploadInfo($this->info); return$file; }
到此,方法體中的move_uploaded_file算是保存完了構(gòu)建的PHP文件,需要注意的是,這里的命名規(guī)則,代碼里用了時(shí)間的隨機(jī)數(shù),
switch($this->rule){ case'date': $savename=date('Ymd').DS.md5(microtime(true)); break;
也就是說,前端可以猜到具體的文件夾,但是具體的文件名,需要后期做個(gè)碰撞的腳本,才可以獲取到。因?yàn)槭前缀袑徲?jì),這一步就暫時(shí)省略掉了。
總結(jié)
老版本種存在的問題,最新版本也是存在的,只不過需要后期數(shù)據(jù)的加工,沒有之前版本來的那么容易。所以做程序要用心,做安全更是如此。
審核編輯:劉清
-
SQL
+關(guān)注
關(guān)注
1文章
762瀏覽量
44123 -
CRM
+關(guān)注
關(guān)注
1文章
145瀏覽量
21122 -
數(shù)據(jù)庫
+關(guān)注
關(guān)注
7文章
3798瀏覽量
64370 -
HRM
+關(guān)注
關(guān)注
0文章
10瀏覽量
8980
原文標(biāo)題:悟空crm漏洞新用
文章出處:【微信號(hào):Tide安全團(tuán)隊(duì),微信公眾號(hào):Tide安全團(tuán)隊(duì)】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論