1. 程式人生 > >利用Thinkphp 5緩存漏洞實現前臺Getshell

利用Thinkphp 5緩存漏洞實現前臺Getshell

getc 基於 hsl mysq 發現 _id 代碼 應該 網頁

0×00 背景

網站為了實現加速訪問,會將用戶訪問過的頁面存入緩存來減小數據庫查詢的開銷。而Thinkphp5框架的緩存漏洞使得在緩存中註入代碼成為可能。(漏洞詳情見參考資料)

本文將會詳細講解:

1. 如何判斷緩存漏洞存在的可能性

2. 如何利用Thinkphp5的框架漏洞結合網站的一些配置實現前臺getshell

希望可以給予讀者一些關於漏洞應用的啟發。

0×01 環境

測試環境

1.某基於Thinkphp5.0.10搭建的論壇類測試網站

2.apache2

3.php5.6及以上版本,相關php組件

4.mysql

工具

1.dirsearch (github上的一個用python編寫的網站路徑掃描工具)

0×02 實現

判斷緩存漏洞存在的可能性

1.查看網頁的cookie,發現存在thinkphp_show_page_trace字段,確定網頁基於thinkphp框架。

技術分享

2.使用 dirsearch 掃描目標網站。python3 dirsearch.py -u site_ip_here -e php發現可以訪問 cache目錄,說明可能存在緩存漏洞。

技術分享

實施攻擊

1.考慮到這是一個論壇類網站,嘗試發帖註入緩存。

技術分享

2.這是最困難的一步,猜解緩存中的php文件名。根據框架實現,文件名是一個唯一字符串的md5碼(此處的md5要用php的函數計算,測試發現和網上的一些在線平臺計算結果不同)。考慮到論壇類網站有大量的帖子,需要用數據庫存儲,而帖子的索引應該為很有可能為id 。

再結合url的路徑名,猜測為article_id

echo(md5(“article_52″));

12a51218427a2df68e54e8f4c8b10109

技術分享

通過訪問緩存成功getshell

技術分享

0×03 原理分析:

框架

在thinkphp框架中,/thinkphp/library/think/cache/driver/File.php中定義了緩存的實現。其中,getCacheKey($name)函數實現了cache文件路徑的計算,為獲得緩存文件名稱提供了可能。

技術分享

而set()與get()函數以序列化對象的方式無過濾地實現了緩存數據的寫入與讀出,為代碼註入緩存提供可能。

技術分享

技術分享

通過測試,可以發現帖子中的內容可以直接寫入緩存文件。

技術分享

由於緩存文件是一個php文件,可以進行代碼註入。在代碼前加一個回車,使代碼行獨立於前面的註釋行。再在末尾加上註釋符號//,註釋剩余內容。

網頁實現

在處理帖子的代碼中,讀取帖子首先查詢cache文件,通過調用thinkphp5框架中的cache接口實現。

技術分享

0×04 防禦:

1. 從框架入手,在/thinkphp/library/think/cache/driver/File.php 中的set()函數中對於$value參數進行過濾,去除換行符號。(具體代碼見參考資料)缺點: 可能會導致緩存文件在展示時文本布局的改變。

2. 從網頁實現入手,讀取緩存時的使用的唯一索引可以設置的比較復雜,讓攻擊者無法猜到。如: 3ae282ad69314d68_article_id

3. 從服務器的配置入手,關閉從外部對於cache文件夾的直接訪問。

4. 從php的配置入手,關閉eval等危險函數。

0×05 參考資料:

https://paper.seebug.org/374/

利用Thinkphp 5緩存漏洞實現前臺Getshell