一、复现环境搭建
访问火线-靶场并搜索S2-048,然后启动registry.cn-beijing.aliyuncs.com/huoxian/s_struts2_s2-059:latest
环境启动后,默认页面。
二、漏洞复现
POST /showcase/integration/saveGangster.action HTTP/1.1
Host: localhost:8080
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:88.0) Gecko/20100101 Firefox/88.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Content-Type: application/x-www-form-urlencoded
Content-Length: 65
Origin: http://localhost:8080
Connection: close
Referer: http://localhost:8080/showcase/integration/editGangster.action;jsessionid=97012E36AD9CCCE9EF6767CAD815A25C
Cookie: JSESSIONID=97012E36AD9CCCE9EF6767CAD815A25C
Upgrade-Insecure-Requests: 1
name=%25{7*7}&age=13&__checkbox_bustedBefore=true&description=qwe
三、洞态IAST检测
四、漏洞原理分析及洞态IAST检测
S2-048原理分析的文章网上太多了,笔者也写不出更好的了,大家可以看一下n1nty大佬的分析:https://www.anquanke.com/post/id/86398
这里主要说一下IAST的检测过程。
从污点流图来看,和之前的S2漏洞并无二致。
按照n1nty大佬的说法,org.apache.struts2.s1.Struts1Action 将St1时代的action封装为St2的action,然后传进来,接着使用,进而实现兼容。
在 Struts1Action 的 execute 方法中,会调用对应的 Struts1 Action 的 execute 方法。在调用完后,会检查 request 中是否设置了 ActionMessage,如果是,则将会对 action messages 进行处理并回显给客户端。处理时使用了 getText 方法,这里就是漏洞的触发点。所以漏洞的触发条件是:在 struts1 action 中,将来自客户端的参数值设置到了 action message 中。 Action messages 会通过 getText 方法最终进入 com.opensymphony.xwork2.util.LocalizedTextUtil.getDefaultMessage(String, Locale, ValueStack, Object[], String) 方法。 此方法会将 action message 传入 com.opensymphony.xwork2.util.TextParseUtil.translateVariables(String, ValueStack)。com.opensymphony.xwork2.util.TextParseUtil.translateVariables(String, ValueStack) 方法主要用于扩展字符串中由 ${} 或 %{} 包裹的 OGNL 表达式,这里也就是 OGNL 的入口,随后 action message 将进入 OGNL 的处理流程,漏洞被触发。
看一下污点调用的图
其实就是拼接了ognl到action message里,然后
com.opensymphony.xwork2.util.LocalizedTextUtil.getDefaultMessage--->
com.opensymphony.xwork2.util.TextParseUtil.translateVariables(String, ValueStack)--->
OGNL FLOW
总结
这个插件兼容了St1时代的action,但是在组action message的时候,如果构造不规范的话,就容易出问题。流程的话,其实还是和之前的差不多的。