1. 程式人生 > >ThinkCMF X2.2.2多處SQL注入漏洞分析

ThinkCMF X2.2.2多處SQL注入漏洞分析

 

 1.     漏洞描述

ThinkCMF是一款基於ThinkPHP+MySQL開發的中文內容管理框架,其中X系列基於ThinkPHP 3.2.3開發,最後更新到2.2.2版本。最近剛好在滲透測試專案中遇到這個CMS,便審了下原始碼發現多處SQL注入漏洞,在Github給專案方提issues後,提交到CVE官方後很快就拿到了分配的多個編號:CVE-2018-19894CVE-2018-19895CVE-2018-19896CVE-2018-19897CVE-2018-19898

2.    

影響版本

ThinkCMF X2.2.2https://github.com/thinkcmf/cmfx

3.     漏洞分析

3.1  CommentadminController.class.php checkdelete方法SQL注入(CVE-2018-19894

漏洞位於/application/Comment/Controller/CommentadminController.class.phpcheckdelete方法, 62行為例,$_POST['ids']引數通過join後,傳遞到where語句中,但並沒有使用where語句的

in方法,而是直接拼接到SQL語句中,導致SQL注入。

測試Pyload

http://127.0.0.1/cmfx/index.php?g=Comment&m=commentadmin&a=check&check=1

POST:  ids[]=1&ids[]=2 and updatexml(1,concat(0x7e,(SELECT user()),0x7e),1)

3.2 NavController.class.phpedit_post方法SQL注入(CVE-2018-19895

跟進`application/Admin/Controller/NavController.class.php`

,在檔案的173行。`$parentid`直接由`$_POST['parentid']`傳遞進來,隨後被直接拼接到where語句中。

測試Payload

http://127.0.0.1/cmfx/index.php?g=Admin&m=nav&a=edit_post

POST: parentid=1 and updatexml(1,concat(0x7e,(SELECT user()),0x7e),1)

3.3 SlideController.class.php delete方法SQL注入(CVE-2018-19896

application/Admin/Controller/SlideController.class.php93行,delete方法中,$_POST['ids']通過implode方法變成字串,隨後直接拼接進入where語句的in子句中。

測試payload

http://127.0.0.1/cmfx/index.php?g=Admin&m=slide&a=delete

POST: ids[]=1&ids[]=0 and updatexml(1, concat(0x7e,user(),0x7e),1)

3.4 AdminbaseController.class.php_listorders方法存在SQL注入(CVE-2018-19897

_listorders方法用於排序,在很多地方被呼叫。這裡以LinkController.class.php中的listorders()為例進行分析,這裡主要用做友情連結的排序。我們以phpstorm+phpstudy+ xdebug打下斷點,一步步追蹤。測試payload為:

http://127.0.0.1/cmfx/index.php?g=Admin&m=Link&a=listorders

POST: listorders[key][0]=exp&listorders[key][1]=0 and updatexml(1, concat(0x7e,user(),0),1)

首先進入application/Admin/Controller/LinkController.class.php 70行的listorders方法,71行呼叫父類的_listorders()方法。

跟到application/Admin/Controller/LinkController.class.php 166行的_listorders()方法,$_POST['listorders']為二維陣列傳遞給$ids,經過foreach迴圈,輸入的payload進入$data中,仍然為二維陣列,而$data則進入save方法。

跟進到simplewind/Core/Library/Think/Model.class.php 396行的save方法,該方法為thinkphp的核心函式。由於$data不為空,跳過之前的很多判斷直接到452行,$data$options進入update方法,$data仍然為二維陣列不變。

   

跟進到simplewind/Core/Library/Think/Db/Driver.class.php 893行的update()方法,$data經過parseSet方法後拼接到$sql中。跟到371parseSet方法的定義,$data經過foreach迴圈後,$val變為一維陣列,$key為鍵值。而當$val為陣列並且陣列的第一個元素為exp時,$val[1]會和$key直接用等號拼接傳遞到$set387行陣列$set被逗號implode後拼接到SET子句中。

   

返回到update方法,SET子句被拼接到$sql中,最終執行的sql語句為

UPDATE `cmf_links` SET `listorder`=0 and updatexml(1, concat(0x7e,user(),0),1) WHERE `link_id` = 'key'

   

3.5  ArticleController.class.php edit_post方法SQL注入(CVE-2018-19898

ThinkCMF X2.2.2是基於ThinkPHP 3.2.3開發的,ThinkPHP 3.x版本之前被爆出存在bind注入,這個漏洞就是ThinkPHP3.x注入的典型案例。漏洞位於前臺文章編輯處,測試payload如下:

http://127.0.0.1/cmfx/index.php?g=portal&m=article&a=edit_post

POST: post[id][0]=bind&post[id][1]=0 and updatexml(1, concat(0x7e,user(),0x7e),1)-- -

application/Portal/Controller/ArticleController.class.php 182行,輸入的引數通過I("post.post")傳遞到$article;跟進到/simplewind/Core/Common/functions.phpI方法定義,在428行,會呼叫think_filter方法對引數進行過濾。

 

 由於正則字元中沒有匹配bind,所以導致了後面的注入漏洞,ThinkPHP官方的修復措施就是在此處匹配時加上了bind。接下來進入典型的資料庫更新操作了,$articles為多維陣列包含payload

我們F7繼續跟進,會進入simplewind/Core/Library/Think/Model.class.phpwhere方法,給$this->options['where']賦值後,返回當前物件。隨後進入simplewind/Core/Library/Think/Model.class.phpsave方法,隨後執行到update方法

   

繼續往下,進入到parseSet方法,可以看到傳遞的引數在進行引數繫結操作,其中時間字串被賦於佔位符0,此處會進行迴圈操作,將所有的引數進行繫結。

隨後進入parseWhere函式

分析parseWhere後,發現會執行 parseWhereItem方法,當$exp=='bind'的時候即$val[0]=='bind',會對$val[1]進行拼接,仔細看這裡會多一個`:`,表示為引數繫結時的佔位符。

這裡也就理解為什麼第二個陣列構造的時候需要新增一個數字0,這是由於parseSet方法以及賦值了一個佔位符:0,用來替代時間字串,在隨後的SQL語句執行階段可被用來賦值,否則佔位符沒被賦值會因語法問題產生報錯。

   

隨後可以看到bindValue:0繫結為時間字串,實際上這裡有三個引數需要繫結,因此第二個陣列的首位值可以為012

   

執行時產生XPATH異常報錯,得到我們想要的資料。

   

4.     修復建議

由於ThinkCMF X系列在2.2.2版本後已經不再更新,建議使用者及時升級到Think CMF5

 

轉載:https://anquan.baidu.com/article/490 本文來自百度安全SiemPent Team

歡迎關注,有問題一起學習歡迎留言、評論