請(qǐng)遵守法律法規(guī),文章旨在提高安全軟件的應(yīng)變策略,嚴(yán)禁非法使用。
框架介紹:
本項(xiàng)目為dede自研系統(tǒng),其中所有功能點(diǎn)都由dede自開發(fā),訪問對(duì)應(yīng)PHP文件即可找到對(duì)應(yīng)功能點(diǎn)。
大部分文件都包含了/dede/config.php,該文件中檢測(cè)了用戶的登錄狀態(tài),且對(duì)于XSS進(jìn)行了過濾。
1.任意文件寫入
通過搜索 fwrite() 函數(shù),發(fā)現(xiàn)這里存在可疑寫入點(diǎn),而我們知道得知dede的路由可以通過直接訪問
我們可以看到這里代碼70行的變量 $configstr 是經(jīng)過序列化的 $faqs 變量傳入的,那么這里的 $faqs
這個(gè)數(shù)組是怎么傳入的。
直接訪問該文件發(fā)現(xiàn)如下功能點(diǎn),而這里的驗(yàn)證碼設(shè)置功能處正是傳入?yún)?shù)的地方。
這里抓包我們可以清楚的看到此處參數(shù)可控的地方。
但在代碼的第60行是存在過濾的,這里當(dāng)你 question 參數(shù)傳入單引號(hào)時(shí)會(huì)被正則替換為雙引號(hào)沒辦法
進(jìn)行閉合,而 quswer 參數(shù)則并沒有任何限制,反而幫我們刪除了反斜杠,所以這里 answer 參數(shù)處就存在繞過。
漏洞復(fù)現(xiàn):
2.目錄遍歷
搜索 read() 函數(shù),發(fā)現(xiàn)在危險(xiǎn)函數(shù)中存在參數(shù)可控的地方,我們進(jìn)入 select_images.php 文件。
漏洞復(fù)現(xiàn):
3.數(shù)據(jù)庫操作getshell(1)
在測(cè)試功能點(diǎn)模塊管理時(shí),發(fā)現(xiàn)一處可以操作數(shù)據(jù)庫的地方,我們點(diǎn)擊修改。
其實(shí)我們可以直接在刪除程序處輸入我們想要執(zhí)行的SQL語句進(jìn)行測(cè)試
這里傳入了兩個(gè)參數(shù) action 以及 hash。
這里通過uninstall執(zhí)行該處分支,然后通過上面?zhèn)魅氲膆ash參數(shù)值來定位文件, GetFileLists() 獲取
跟進(jìn) GetFileLists() 函數(shù)。
在該函數(shù)中首先包含了 modulescache.php 文件,并通過 $hash 返回xml文件內(nèi)容。
modulescache.php 文件內(nèi)容。
找到該xml,查看該xml內(nèi)容,該文件內(nèi)容中就是相應(yīng)模塊的配置信息。
回到上面代碼的的第425行,又執(zhí)行了 uninstallok 分支。該分支就是卸載模塊的分支,這里最重
要的是通過 GetSystemFile() 獲取文件內(nèi)容,這里傳入了另一個(gè)參數(shù) delSQL ,跟進(jìn)該函數(shù)
通過 GetHashFile() 函數(shù)獲取文件內(nèi)容。
這里的delsql內(nèi)容中正是刪除程序處的文件的base64內(nèi)容
最后在代碼518行執(zhí)行sql語句,所以我們可以通過Mysql日志文件來getshell,而這里需要網(wǎng)站的絕對(duì)
路徑,由于存在目錄遍歷,所以可以輕松獲取絕對(duì)路徑。
漏洞復(fù)現(xiàn):
最后訪問cyw.php,獲取到phpinfo信息。
4.任意文件寫入漏洞(2)
同樣的方法,在搜索危險(xiǎn)函數(shù) fwrite() 時(shí)發(fā)現(xiàn)在 article_string_mix.php 中存在可以控制寫入內(nèi)容
的地方。
在 article_string_mix.php 中 $allsource 寫入的內(nèi)容是可控的,但在代碼29-34行中存在危險(xiǎn)函數(shù)
過濾,但在過濾函數(shù)中過濾不嚴(yán)格導(dǎo)致繞過,實(shí)現(xiàn)代碼執(zhí)行。
漏洞復(fù)現(xiàn):
通過 preg_replace() 繞過危險(xiǎn)函數(shù)過濾,造成代碼執(zhí)行。
寫入downmix.data.php
訪問dede/article_template_rand.php文件,執(zhí)行phpinfo()。
5.任意文件寫入漏洞(3)
這里依舊是同樣的功能點(diǎn),所以大家看到這里其實(shí)也可以發(fā)現(xiàn),在dedecms中使用 fwrite() 函數(shù)寫入
配置文件的操作是很多的,在該系統(tǒng)中我們只需要觀察兩點(diǎn)即可,一寫入的位置為可解析的php文件,
二寫入的內(nèi)容我們是可控的即可。
在函數(shù) ReWriteConfig() 中,我們可以發(fā)現(xiàn)代碼的第38行和第42行都是用了 fwrite() 函數(shù),向上回
溯發(fā)現(xiàn)該處的值是從代碼31行的 sysconfig 表中拿到的,我們?nèi)タ纯丛摫碇械膬?nèi)容。
存儲(chǔ)了網(wǎng)站的配置信息,上面的代碼中可以看到type為 number 時(shí)會(huì)將 varname 字段
的值以及value字段的值寫入配置文件,如果類型不為type時(shí),這里會(huì)存在一個(gè)小小的過濾,這里的單引
號(hào)會(huì)被替換為空。
1.我們可以直接在type=number類型的字段中直接插入我們要執(zhí)行的代碼
2.通過反斜杠來轉(zhuǎn)義原本的單引號(hào),然后使我們的代碼逃逸出來
在 dopost 參數(shù)為 save 時(shí),我們可以發(fā)現(xiàn)這里接收了post傳入的參數(shù),并且將傳入的內(nèi)容寫入到了
sysconfig 表中。在代碼74行中執(zhí)行了上面分析的 ReWriteConfig() 函數(shù)。
漏洞復(fù)現(xiàn):
我們?cè)L問/dede/sys_info.php文件,發(fā)現(xiàn)該處功能點(diǎn)確實(shí)是配置系統(tǒng)參數(shù)處,所以我們直接在
type=number參數(shù)處插入我們的代碼。
第二種方法可以通過反斜杠轉(zhuǎn)義原有的單引號(hào),使我們的代碼逃逸出來。
這樣的話也可以造成代碼執(zhí)行,只不過方法不同。
6.數(shù)據(jù)庫操作getshell(2)
在測(cè)試系統(tǒng)功能點(diǎn)的時(shí)候,發(fā)現(xiàn)一處可以操作數(shù)據(jù)庫的地方,下面的功能可以執(zhí)行SQL語句。
漏洞分析:
這里執(zhí)行到query分支,108-111行這里存在過濾,這里過濾了drop關(guān)鍵字,116行執(zhí)行我們SQL語句。
漏洞復(fù)現(xiàn):
set global general_log = on;
set global general_log_file = 'D:/phpstudy_pro/WWW/www.dedecms12.com/uploads/shell.php';
7.文件上傳漏洞
該處具有前端限制,上傳 .jpg 后綴文件,結(jié)合brup抓包,發(fā)現(xiàn)處理上傳功能的文件為dede/archives_do.php
入口文件通過 config.php 會(huì)實(shí)現(xiàn)權(quán)限認(rèn)證和一些外部參數(shù)過濾注冊(cè)
我們這里上傳文件會(huì)帶有$_FILES參數(shù),上面通過全局分析得知會(huì)觸發(fā)uploadsafe.inc.php的過濾
在經(jīng)過過濾后,通過AdminUpload()實(shí)現(xiàn)最終文件上傳
include/helpers/upload.helper.php
最終實(shí)現(xiàn)文件上傳的AdminUpload()來自u(píng)pload.helper.php,傳入AdminUpload()的$ftype固定為imagelit,則一定會(huì)進(jìn)入對(duì)應(yīng)的檢測(cè)判斷,在檢測(cè)判斷代碼中,$sparr定義了一個(gè)MIME Type白名單,若上傳文件的MIME Type不在白名單中直接退出,MIME Type可控。
梳理一下,該功能點(diǎn),系統(tǒng)只做了兩個(gè)限制,MIMI Type為圖片類型,可控。但MIME Type為圖片類型時(shí)會(huì)通過getimagesize()檢測(cè),這里也可繞過,看是否可以利用保證Content-Type為圖片類型,構(gòu)造圖片的文件頭,繞過文件上傳的限制,并且會(huì)返回上傳文件名和路徑。
漏洞復(fù)現(xiàn):
進(jìn)入添加文檔,該功能可以發(fā)布文章,而且具有文件上傳的功能。
8.xss漏洞
測(cè)試發(fā)現(xiàn)還是黑盒好測(cè)一點(diǎn),在dedecms后臺(tái)還是存在很多xss的,本次是在黑盒測(cè)試后,在回頭審計(jì)代碼的問題,其實(shí)這樣白盒審計(jì)意義不大,在全局分析中發(fā)現(xiàn)并沒有對(duì)外部數(shù)據(jù)做xss全局過濾,另外注意到dedecms具有視圖類負(fù)責(zé)顯示輸出,封裝了很多輸出的功能,在平時(shí)白盒審計(jì)xss漏洞需要注意echo,innerHTML這類輸出到前端的關(guān)鍵詞,但在dedecms中還需要注意視圖類封裝的輸出函數(shù)
qrcode.php及加載的文件都沒有做xss過濾,通過common.inc.php會(huì)注冊(cè)全局變量
$id只能為整數(shù)類型,$type類型可控
加載模板qrcode.htm,利用視圖類格式化輸出$id,$type的值,$type可控,這里就存在xss漏洞
可以看到這里的觸發(fā)點(diǎn)$dtp->SetVar('type',$type);,然而在seay這種代碼掃描工具中是不會(huì)在意這些點(diǎn)的,同樣有些框架對(duì)sql操作也做了很好的封裝,如果只是依靠seay的結(jié)果來做代碼審計(jì),可能會(huì)忽略掉很多關(guān)鍵點(diǎn)
9.url 重定向漏洞
eay似乎沒有 url 重定向漏洞的掃描,不過該漏洞審計(jì)也比較簡單,主要關(guān)注能重定向的一些關(guān)鍵詞,再看重定向地址是否可控
plus/download.php
對(duì)$link做了base64解碼
程序中有一個(gè)很奇怪的限制,in_array($linkinfo['host'], $allowed),然而download.php中卻沒有$linkinfo這個(gè)參數(shù)dedecms后臺(tái)也有一些url重定向漏洞,這里就不多關(guān)注這個(gè)洞了
10.會(huì)員中心任意用戶密碼修改
在用戶密碼重置功能處,php存在弱類型比較,導(dǎo)致如果用戶沒有設(shè)置密保問題的情況下可以繞過驗(yàn)證密保問題,直接修改密碼(管理員賬戶默認(rèn)不設(shè)置密保問題)。值得注意的是修改的密碼是member表中的密碼,即使修改了管理員密碼也是member表中的管理員密碼,仍是無法進(jìn)入管理。
漏洞代碼分析
php弱類型比較問題很常見,在不同類型比較時(shí),如果使用的是==,php會(huì)將其中一個(gè)數(shù)據(jù)進(jìn)行強(qiáng)制轉(zhuǎn)換為另一個(gè),比如'123a'就會(huì)被強(qiáng)制轉(zhuǎn)換成123。這樣就出現(xiàn)了弱類型比較問題,當(dāng)然如果使用===判斷比較就不會(huì)出現(xiàn)問題了。常見比較如下
'' == 0 == false '123' == 123 //'123'強(qiáng)制轉(zhuǎn)換為123 'abc' == 0 //intval('abc')==0 '123a' == 123 //intval('123a')==123 '0x01' == 1 //被識(shí)別為十六進(jìn)制'0e123456789' == '0e987654321' //被識(shí)別為科學(xué)計(jì)數(shù)法 [false] == [0] == [NULL] == [''] NULL == false == 0 true == 1
dedecms的/member/resetpassword.php就是用來處理用戶密碼重置的問題,問題出在75行開始處理驗(yàn)證密保問題處。
這段代碼先是從數(shù)據(jù)庫取出相關(guān)用戶的密保問題及密保答案,在對(duì)用戶輸入做了一些處理后,進(jìn)行了關(guān)鍵性的判斷if($row['safequestion'] == $safequestion && $row['safeanswer'] == $safeanswer) ,就在這里用了弱類型判斷==。首先我們知道,如果沒有設(shè)置密保的話safequestion從數(shù)據(jù)庫取出默認(rèn)為'0',safeanswer為空。根據(jù)empty函數(shù)特性,'0'會(huì)被判斷為空,會(huì)進(jìn)入重新將$safequestion賦值為''。而'0' != '' ,所
跟蹤sn函數(shù)
跟蹤newmail。
可見在sn函數(shù)中將send參數(shù)設(shè)置了'N',其實(shí)就是生成了暫時(shí)密碼并插入了數(shù)據(jù)庫中,并進(jìn)行跳轉(zhuǎn):
漏洞復(fù)現(xiàn):
在找回密碼處,點(diǎn)擊通過安全問題取回。
11.會(huì)員中心任意用戶登陸
dedecms的會(huì)員模塊的身份認(rèn)證使用的是客戶端session,在Cookie中寫入用戶ID并且附上
ID__ckMd5
漏洞代碼分析
在/member/index.php中會(huì)接收uid和action參數(shù)。uid為用戶名,進(jìn)入index.php后會(huì)驗(yàn)證Cookie中的用戶ID與uid(用戶名)并確定用戶權(quán)限。
我們可以看到當(dāng)uid存在值時(shí)就會(huì)進(jìn)入我們現(xiàn)在的代碼中,當(dāng)cookie中的last_vid中不存在值為空時(shí),就會(huì)將uid值賦予過去,$last_vid = $uid;,然后PutCookie。
那么這么說,我們控制了$uid就相當(dāng)于可以返回任意值經(jīng)過服務(wù)器處理的md5值。
現(xiàn)在我們來看看,dedecms會(huì)員認(rèn)證系統(tǒng)是怎么實(shí)現(xiàn)的:/include/memberlogin.class.php
$this->M_ID等于Cookie中的DedUserID,我們繼續(xù)看看GetCookie函數(shù)它不但讀了cookie還驗(yàn)證了md5值。
這樣,由于index.php中我們可以控制返回一個(gè)輸入值和這個(gè)輸入值經(jīng)過服務(wù)器處理后的md5值。那么如果我們偽造DedUserID和它對(duì)應(yīng)的MD5就行了。
漏洞復(fù)現(xiàn):
- 先從member/index.php中獲取偽造的DedeUserID和它對(duì)于的md5
- 使用它進(jìn)行登錄
訪問member/index.php?uid=0000001并抓包(注意cookie中l(wèi)ast_vid值應(yīng)該為空)。
REF:
https://www.freebuf.com/articles/web/281747.html
https://blog.szfszf.top/article/25/
https://github.com/SukaraLin/php_code_audit_project/blob/master/dedecms/dedecms v5.7 sp2 代碼審計(jì).md
from https://xz.aliyun.com/t/12148
版權(quán)聲明:本文內(nèi)容由互聯(lián)網(wǎng)用戶自發(fā)貢獻(xiàn),該文觀點(diǎn)僅代表作者本人。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如發(fā)現(xiàn)本站有涉嫌抄襲侵權(quán)/違法違規(guī)的內(nèi)容, 請(qǐng)發(fā)送郵件至 舉報(bào),一經(jīng)查實(shí),本站將立刻刪除。