ThinkAdmin v5和v6 未授權列目錄/任意檔案讀取(CVE-2020-25540)
漏洞簡介
ThinkAdmin是一套基于ThinkPHP架構的通用背景管理系統。ThinkAdmin v6版本存在路徑周遊漏洞。攻擊者可利用該漏洞通過GET請求編碼參數任意讀取遠端伺服器上的檔案。
影響範圍
Thinkadmin ≤ 2020.08.03.01
漏洞分析複現
app/admin/controller/api/Update.php存在3個function,都是不用登入認證就可以使用的,引用清單如下:
version()可以擷取到目前版本:2020.08.03.01,≤這個版本的都有可能存在漏洞
URL:http://think.admin/ThinkAdmin/public/admin.html?s=admin/api.Update/version
列目錄
node():
直接把POST的rules和ignore參數傳給InstallService::instance()->getList(),根據上面的use引用可以知道檔案路徑在vendor/zoujingli/think-library/src/service/InstallService.php:
$ignore可以不用關注,他會透過_scanList()去周遊$rules數組,調用scanDirectory()去遞歸周遊目錄下的檔案,最後在透過_getInfo()去擷取檔案名與哈希,由下面代碼可以知道程式沒有任何驗證,攻擊者可以在未授權的情況下讀取伺服器的檔案清單。
讀取網站根目錄Payload: http://think.admin/ThinkAdmin/public/admin.html?s=admin/api.Update/node
POST:
也可以使用../來進行目錄穿越
示範站:

任意檔案讀取
get():
首先從GET讀取<code>encode</code>參數并使用<code>decode()</code>解碼:
解密UTF8字元串的,剛好上面有個加密UTF8字元串的encode(),攻擊時直接調用那個就可以了:
跟進ModuleService::instance()->checkAllowDownload(),檔案路徑vendor/zoujingli/think-library/src/service/ModuleService.php:
首先$name不能夠是database.php,接着跟進getAllowDownloadRule():
有一個允許的清單:
也就是說$name必須要不是database.php且要在允許清單内的檔案才能夠被讀取,先繞過安全清單的限制,比如讀取根目錄的1.txt,隻需要傳入:
而database.php的限制在Linux下應該是沒辦法繞過的,但是在Windows下可以透過"來替換.,也就是傳入:
對應encode()後的結果為:
34392q302x2r1b37382p382x2r1b1a1a1b1a1a1b2r33322u2x2v1b2s2p382p2q2p372t0y342w34
Windows讀取database.php:
示範站讀取/etc/passwd:
GET:
v5連允許清單都沒有,可以直接讀任意檔案。
漏洞修複
臨時方案:
更新到最新版!