0x00 前言
最近在學習java的相關漏洞,所以Struts2的漏洞自然是繞不開的。為了更好的理解漏洞原理,計划把Struts2所有的漏洞自己都做一個復現。並且自己去實現相關的POC。相關的環境搭建,以及POC實現細節,參考文章我都會盡可能的寫清楚。方便自己記錄學習過程的同時,方便看文章的人學習。
0x01 環境搭建
首先我們從Struts2官方提供的歷史版本中找到Struts2.0.1的版本進行下載,下載地址如下:
https://archive.apache.org/dist/struts/binaries/
然后在解壓縮之后的目錄中我們找到,apps/struts2-showcase-2.0.1.war的包,將其放在我們已經搭建好的servlet容器中。本文中采用的Apache Tomcat 9.0.0.M26的版本。我們將整個war包部署在web的根目錄,開啟web服務器之后。我們可以看到已經自動部署好。我們訪問,http://127.0.0.1:8080/struts2-showcase-2.0.1,將會跳轉到http://127.0.0.1:8080/struts2-showcase-2.0.1/showcase.action。訪問結果如下,說明安裝成功。
0x02 漏洞原理分析
我們首先來了解一下Struts2 中的validation機制。validation依靠validation和workflow兩個攔截器。validation會根據配置的xml文件創建一個特殊字段錯誤列表。而workflow則會根據validation的錯誤對其進行檢測,如果輸入有值,將會把用戶帶回到原先提交表單的頁面,並且將值返回。反之,在默認情況下,如果控制器沒有得到任何的輸入結果但是有validation驗證錯誤。那么用戶將會得到一個錯誤的信息提示。具體可以參考官方文檔中validation的說明。
https://struts.apache.org/core-developers/validation.html
那么這個機制到底和我們的漏洞有什么關系呢?在WebWork 2.1+ 和 Struts 2中存在一個altSyntax的特性,該特性允許用戶提交OGNL請求,當用戶提交惡意請求表單,故意觸發一個validation錯誤,頁面被workflow再次返回給用戶的時候,默認情況下相當於返回%{return_value},我們注入的惡意代碼,比如%{7*7}將會被當做%{%{7*7}}遞歸執行執行。
0x03 漏洞驗證
我們根據系統提供的例子,來做驗證。在瀏覽器中訪問:http://127.0.0.1:8080/struts2-showcase-2.0.1/validation/quizBasic.action,然后去提交表單。
首先需要關心一個配置項,在validation驗證的配置文件中,配置如下:
<validators> <field name="name"> <field-validator type="requiredstring"> <message>You must enter a name</message> </field-validator> </field> <field name="age"> <field-validator type="int"> <param name="min">13</param> <param name="max">19</param> <message>Only people ages 13 to 19 may take this quiz</message> </field-validator> </field> </validators>
意思是提交的name字段必須是String類型,否則會提示message節點中的內容。age必須是int類型,並且大小在13到19歲之間。我們用age來故意觸發一個錯誤。然后用name來進行代碼注入。
我們可以看到我們提交的name=%{7*7},age=12觸發了錯誤,然后name被解析成了49.嘗試獲取tomcat路徑。name=%{"tomcatBinDir{"+@java.lang.System@getProperty("user.dir")+"}"}結果如下:
0x04 反思
Struts2爆出了50多個漏洞了,很多的漏洞利用和挖掘思路都十分有意思。從側面來看,這些也反映出了java生態的混亂和脆弱。從挖掘思路來看,對於框架的細節不了解,是挖不到這樣的好漏洞的。研究必須要深入到每一行代碼。
0x05 參考鏈接
1. 【官方漏洞公告】https://cwiki.apache.org/confluence/display/WW/S2-001
2. 【王小龍的博客】http://bruce.wang/2017/12/01/Struts%202%20%E6%BC%8F%E6%B4%9E%E7%B3%BB%E5%88%97%E4%B9%8B%20S2-001/
3. 【validation詳細介紹】https://struts.apache.org/core-developers/validation.html
4. 【ONGL語言指導】http://commons.apache.org/proper/commons-ognl/language-guide.html