[漏洞分析]thinkcmf 1.6.0版本從sql注入到任意代碼執行


0x00 前言

該漏洞源於某真實案例,雖然攻擊沒有用到該漏洞,但在分析攻擊之后對該版本的cmf審計之后發現了,也算是有點機遇巧合的味道,我沒去找漏洞,漏洞找上了我XD

thinkcmf 已經非常久遠了,該版本看github上的更新時間已經是4年前了,也就是2014年的時候,那時候我沒學安全呢。。。

 

0x01 前台sql注入

前台在登錄方法中存在注入,thinkcmf是基於thinkphp3.2寫的,直接看

文件application\User\Controller\LoginController.class.php 方法 dologin

很明顯的注入,通過extract我們可以注冊$where數組,而后直接傳入where方法,沒有經過I方法過濾的引入參數是會引發表達式注入的。

比如這樣子:

 

這里由於有驗證碼,無法輕易的編寫批量腳本。當然引入打碼工具另說。

注入之后,我們想到的一定是登錄后台了。

那么先了解一下thinkcmf的管理員密碼是怎么加密的。

看到 install\index.php 文件的 sp_password 方法

解釋一下,$pre就是表前綴,$pw是密碼,意思是

存儲在數據庫的密碼 =  表前綴md5的前12位+密碼md5+表前綴md5的后四位

比如值為c535018ee946e10adc3949ba59abbe56e057f20f883e89af 存儲在數據庫的密碼。

那么拆分一下就是

c535018ee946(表前綴md5的前12位)
e10adc3949ba59abbe56e057f20f883e(密碼md5)
89af(表前綴md5的后四位)

知道所謂的加密算法之后,我們就可以輕易獲取到管理員密碼的md5值,通過碰撞md5值的形式獲取到管理員的真實密碼。

現在我們可以登錄上后台了,可登錄后台之后要怎么getshell呢?

仔細分析了一下thinkcmf的后台,似乎沒有可以getshell的地方。

 

0x02 權限驗證處的任意代碼執行

認真看了看代碼,發現后台的一些操作會有權限驗證,而跟蹤權限驗證代碼的時候發現了一個eval的代碼塊。

看到權限驗證處application\Common\Lib\iAuth.class.php  check 方法

使用了eval來引入變量,那么這個$command是否可控呢?

經分析其來源於sp_auth_rule表中的condition字段,備注為規則附加條件

而這些數據在安裝的時候就早已經寫入到數據庫中了,除非我們有辦法可以來修改這里的值?

是的,前面的sql注入排上用場了。

thinkphp 自 3系列開始就使用pdo作為連接數據庫的驅動,而這里這個注入不涉及到參數綁定等問題,那么我們就可以利用它來執行多語句,插入數據或者修改數據了。

簡單測試一下,比如修改一下后台管理員的user_email字段。

 

 查看數據庫,成功修改

 

多語句執行可以為我們省下很多事,比如密碼過於復雜無法猜解出明文時,我們可以直接修改密碼的hash值為我們想要的。

分析一下權限驗證的代碼,它是怎么觸發的?

隨便找了個需要登錄后台的文件比如 application\Portal\Controller\AdminPageController.class.php

該controller繼承於AdminbaseController,跟蹤下去

而在AdminbaseController初始化的函數中,發現了檢測權限的代碼,跟進

 

發現如果$uid是1的話就直接返回了,這個$uid其實就是數據庫里面的id字段值,也就是說要觸發權限驗證就必須是一個低權限的用戶。

繼續走,如果訪問的不是url為admin/index/index 就會進行鑒權,跟進sp_auth_check方法

最終來到了我們的check方法。

具體意思都寫在解釋里面了,看到eval代碼塊,我們只要閉合掉左括號,即可引入我們的惡意代碼。

 那么整個利用過程就是登錄一個低權限的用戶,通過sql注入寫入代碼到我們可以訪問的url的condition字段中。

比如我填加了一個低權限的用戶hack,他擁有內容管理的權限

 

 對應他能夠訪問的url有

那么我們只要在sp_auth_rule表中對應的url的condition字段插入代碼,然后登陸該用戶訪問該url即可觸發代碼執行。

比如我們通過sql注入插入一段執行phpinfo的代碼

payload:

where[id][0]=exp&where[id][1]=in (1);update sp_auth_rules set `condition`='1);phpinfo();die();//' where id=30#

請求

 

查看一下表sp_auth_rule,成功插入

 

 那么后台登陸用戶hack之后,訪問url

http://127.0.0.1/index.php?g=Portal&m=AdminPage&a=add

即可看到phpinfo執行了

 

 

而在之后的研究中,我發現此處權限驗證的代碼來自於thinkphp 自身。

看到文件simplewind\Core\Library\Think\Auth.class.php  getAuthList方法的代碼

是不是有種似曾相識的感覺,是的就是thinkcmf根據tp的改寫的。

那么這里就引申出來一個審計點:

tp3框架中如果使用了auth類來驗證權限,且有注入點,那么是可以嘗試去審計一下任意代碼執行。

 類似的例子,暫時沒看到,以后看到了更新上來。

 

0x03 總結

總結一下利用:

通過前台的sql注入,獲取到后台權限(獲取管理員密碼,或者修改管理員hash值),登陸進后台,添加低權限用戶,再通過sql注入來注入代碼。登陸低權限用戶,訪問注入了代碼的url,即可觸發任意代碼執行。

而在實際中,往往是已經有了低權限的用戶,我們只需要觀察用戶能夠訪問的URL,直接注入代碼即可,免去了添加低權限用戶的步驟。

整個利用構造下來還是比較有趣的,不完美的是還是需要登錄后台,因為很多網站或許會把后台隱藏掉,但是也有可能會因為不理解tp支持的url模式而導致繞過 ,這里就不細說了,懂的人自然懂。

打完收工~


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM