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

0x00 前言php

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

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

 

0x01 前臺sql注入算法

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

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

很明顯的注入,經過extract咱們能夠註冊$where數組,然後直接傳入where方法,沒有通過I方法過濾的引入參數是會引起表達式注入的。shell

好比這樣子:數據庫

 

這裏因爲有驗證碼,沒法輕易的編寫批量腳本。固然引入打碼工具另說。數組

注入以後,咱們想到的必定是登陸後臺了。安全

那麼先了解一下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模式而致使繞過 ,這裏就不細說了,懂的人天然懂。

打完收工~

相關文章
相關標籤/搜索