http://nevado.skyscreamer.org/
Nevado JMS 是 Amazon SQS 的 JMS 驱动程序
流程分析 按照文档写一个消息接收
public class App { public static void main (String[] args) throws Exception { new ClassPathXmlApplicationContext("applicationContext.xml" ); NevadoConnectionFactory connectionFactory = new NevadoConnectionFactory(); NevadoConnection connection = connectionFactory.createConnection(); NevadoSession session = connection.createSession(false , NevadoSession.AUTO_ACKNOWLEDGE); NevadoQueue queue = session.createQueue("test" ); NevadoMessageConsumer consumer = session.createConsumer(queue); NevadoMessage message = consumer.receive(); connection.close(); } }
在上面的流程中,会创建一个test队列传到receive方法,具体为:
队列“test”传进createConsumer方法,在createConsumer方法时被传递进了NevadoMessageConsumer对象
在构造函数NevadoMessageConsumer中,因为传进的是queque类型,所以会进入else,此时_destination
就是队列test
回到消息接收中,receive()方法会监听队列,从队列中接收消息
继续跟进getUnfilteredMessage方法查看实现流程
getUnfilteredMessage方法是过滤被消费的消息,如果接收模式是2,就会先从缓存读取
当不满足条件时就会调用this._connection.getSQSConnector().receiveMessage
来接收队列消息,然后再将被接收过的消息添加到缓存中
具体为:
已知初始化时_connection
是NevadoConnection对象
getSQSConnector方法返回的是SQSConnector
这个接口封装了 Amazon SQS 相关的 API 调用,receiveMessage方法是接收消息
所以从代码分析,当不满足条件时,就会接收从Amazon SQS发送的队列消息
跟进实现receiveMessage方法的实现类
在receiveMessage方法中,会将取出的队列传进receiveSQSMessage方法进一步接收队列中的消息
跟进receiveSQSMessage方法
此时receiveSQSMessage方法返回的就是test里面的消息,返回receiveMessage
接收到队列消息后,将消息等参数传进convertSqsMessage方法
在convertSqsMessage方法中,会根据传进的destination类型来做不同的消息取出动作
随后将取出的消息传进deserializeMessage方法做反序列化
跟进deserializeFromString
在deserializeFromString方法中,会对传进的消息做一次base64解码操作,然后再使用Hessian2Input对象进行反序列化。
根据代码的流程,如果要进行漏洞利用,acknowledgeMode就必须不等于2且transacted是false才能进入else走到反序列化功能,如开头所写,NevadoSession的模式分为4种:
int AUTO_ACKNOWLEDGE = 1 ;int CLIENT_ACKNOWLEDGE = 2 ;int DUPS_OK_ACKNOWLEDGE = 3 ;int SESSION_TRANSACTED = 0 ;
且因为反序列化使用的是Hessian2Input,所以得知序列化的数据得是Hessian格式
该组件提供了一个反序列化工具类SerializeUtil.class,可以直接用来序列化恶意数据
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 public static String serializeToString (Serializable serializable) throws IOException { byte [] data = serialize(serializable); return new String(Base64.encodeBase64(data)); }public static byte [] serialize(Serializable serializable) throws IOException { ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); Hessian2Output hessian2Output = new Hessian2Output(byteArrayOutputStream); hessian2Output.setSerializerFactory(new SerializerFactory(SerializeUtil.class.getClassLoader())); hessian2Output.startMessage(); if (serializable instanceof Character) { serializable = new CharWrapper((Character)serializable); } hessian2Output.writeObject(serializable); hessian2Output.completeMessage(); hessian2Output.close();
漏洞验证: 方式一、本地部署验证 发送消息的客户端,destination类型是queque
public class Appclient { public static void main (String[] args) throws JMSException { new ClassPathXmlApplicationContext("applicationContext.xml" ); NevadoConnectionFactory connectionFactory = new NevadoConnectionFactory(); NevadoConnection connection = connectionFactory.createConnection(); NevadoSession session = connection.createSession(false , NevadoSession.AUTO_ACKNOWLEDGE); NevadoQueue queue = session.createQueue("test" ); NevadoMessageProducer producer = session.createProducer(queue); NevadoMessage message = session.createTextMessage("base64编码后的恶意数据" ); producer.send(message); connection.close(); }
接收消息:
方式二、搭配amazon sqs使用验证(没用过,理论是这样) 注册一个amazon,使用sqs服务
然后发送消息
或者
集群在接收消息后就会触发
结尾 在跟进的时候还发现了亚马逊接收消息有一个getObject,应该也是个反序列化的点,后来搜网上有文章,属于是nday这里就不继续说了
Maven依赖
<dependency> <groupId>com.amazonaws</groupId> <artifactId>aws-java-sdk</artifactId> <version>1.11.31</version> </dependency> <dependency> <groupId>org.skyscreamer</groupId> <artifactId>nevado-jms</artifactId> <version>1.3.2</version> </dependency>