CVE-2016-8735分析
针对CVE-2016-8735复现并分析。
漏洞简述
Tomcat启动JmxRemoteLifecycleListener监听器,在/conf/server.xml中添加
漏洞分析
复现过程
1 | java -cp ysoserial-0.0.5-SNAPSHOT-all.jar ysoserial.exploit.RMIRegistryExploit localhost 10001 Groovy1 calc.exe |
POC分析
根据攻击命令发现攻击函数为RMIRegistryExploit在ysoserial-0.0.5-SNAPSHOT-all.jar包中的ysoserial.exploit中。通过解压缩软件将RMIRegistryExploit从ysoserial-0.0.5-SNAPSHOT-all.jar解压出来。由于解压出来为class,对其进行反编译。
第13行定义了RMIRegistryExploit类,第20行需传递一个数组,21行抛出Exception异常类型。
第23行-25行定义了host为数组的第一位数值,port(int)为数组的第二位数值(通过Integer.parseInt将整形对象转换成int型),command为数组的第三位数值。
在26行使用java.rmi.registry.LocateRegistry中的LocateRegistry.getRegistry方法来返回对Registry对象的引用。
在27行定义一个string 名字为className,通过StringBuilder创建一个新实例(结合后面代码中的append可发现用于快速进行字符相加),并获取CommonsCollections1的包的名字,最后把待执行的命令加上包的名字整体作为string赋值给className。28行获得该类(className)并初始化该类。
第29行执行exploit.warp,传递三个参数;第35行使用ExecCheckingSecurityManager的wrap并传一个对象,该对象包含三个参数(payloadClass、command、registry),跟踪ExecCheckingSecurityManager(ysoserial.secmgr.ExecCheckingSecurityManager)查看warp的作用(用于并发)。
倒回去看RMIRegistryExploit.java,className来源于CommonsCollections1,跟踪CommonsCollections1类(ysoserial.payloads. CommonsCollections1),该类继承了PayloadRunner。
跟踪PayloadRunner(ysoserial.payloads.util. PayloadRunner)的run方法,在第22行发现该方法将传进来的args、clazz并发设为新对象并转换成byte。
第29行使用Deserializer.deserialize将serialized反序列化赋值为对象obj。
倒回去看CommonsCollections1,第41行到53行,用Transformer创建了transformers数组,数组中按顺序包含了ConstantTransformer、InvokerTransformer、InvokerTransformer、InvokerTransformer、ConstantTransformer对象。
ConstantTransformer获取其构造函数中传入的类;InvokerTransformer执行其构造函数中传入的方法。
跟踪transformers,第58行使用Reflections.setFieldValue();方法:利用反射机制,将transformerChain对象的iTransformers属性赋值为transformers。
修复建议
- 升级Tomcat
- 改变JMX密码认证