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

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


免責聲明!

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



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