Apacha-Shiro PaddingOracle 分析 | 申博官网
登录
  • 欢迎进入申博官网!
  • 如果您觉得申博官网对你有帮助,那么赶紧使用Ctrl+D 收藏申博官网并分享出去吧
  • 这里是申博官方网!
  • 申博官网是菲律宾sunbet官网品牌平台!
  • 申博开户专业品牌平台!

Apacha-Shiro PaddingOracle 分析

申博_安全防护 申博 32次浏览 已收录 0个评论

环境搭建

git clone https://github.com/apache/shiro.git shiro-rootcd shiro-root
git checkout -f shiro-root-1.4.0

参考之前SHIRO-550的搭一下就行

漏洞分析

首先是SHIRO-550,触发点是cookie中的RememberMe,漏洞触发流程:

  1. base64 解码
  2. 使用 AES 解密
  3. 反序列化解密后的字符串

shiro-1.25以前,AES密钥是硬编码到源码中的,因此可以更改RememberMe的值进行反序列化RCE

而1.2.5之后,shiro采用了随机密钥,也就引出了SHIRO-721,通过padding oracle attack的方式得到,

根据p0师傅之前的文章,在shiro中,当我们更改padding值时,padding正确但反序列化错误则会爆deserialize error;padding错误爆padding error,
具体处理代码如下:

padding正确但爆反序列化error
try {
    ObjectInputStream ois = new ClassResolvingObjectInputStream(bis);
    @SuppressWarnings({"unchecked"})
    T deserialized = (T) ois.readObject();
    ois.close();
    return deserialized;
} catch (Exception e) {
    String msg = "Unable to deserialize argument byte array.";
    throw new SerializationException(msg, e);
}

padding错误爆padding error
try {
    return cipher.doFinal(bytes);
} catch (Exception e) {
    String msg = "Unable to execute 'doFinal' with cipher instance [" + cipher + "].";
    throw new CryptoException(msg, e);
}

而shiro中如果解密rememberMe的过程中有错误,统一的处理方式都是调用removeFrom,最终返回deleteMe

Apacha-Shiro PaddingOracle 分析

这就很矛盾,没办法构造出padding oracle需要的bool条件。

JAVA反序列化 – 反射机制

推荐阅读时间:30min 全文字数:1w 前言 真正反序列化漏洞的利用,肯定需要了解java反射原理。因为java反序列化的payload大多与反射机制密切相关。 那么这篇文章就是主要讲述反射机制,算是基础知识。 除了反射机制之外,后续还基于commons-collections链最后的反射机制触发点,进行了详细的反射机制特性的绕过说明。由于它与反射机制密切相关,就放在这边进行统一归纳理解。 可以配合本人的另一篇文章commons-collections食用 java反射机制 在Java中的反射机制是指在运行状态中,对于任意一个类都能够知道这个类所有的属性和方法;并且对于任意一个对象,都能够调用它的任意一个方法;这种动态获取信息以及动态

解决这个问题用到了java反序列化中的一个小trick,java中的ObjectOutputStream是一个Stream,他会按格式以队列方式读下去,后面拼接无关内容,不会影响反序列化。通过这种方式,在抓到的rememberMe之后加新的iv和value,就既能反序列化成功,又能验证padding是否正确了,从而满足了padding oracle所需要的bool条件。具体的padding oracle过程和CBC bit flipping就不详细写了,参考之前大佬们的文章即可。

除此之外,shiro的接口在验证登陆时有authc和user两种权限,authc是认证过,user是登录过,如果开启了rememberMe功能的话,user可以通过的,而authc通过不了。因此rememberMe只在有user权限的接口有用。

综上,该洞的利用条件如下:

  1. 可以登录
  2. 找到可以用rememberMe的接口
  3. 可以padding oracle

本地测试

网上的poc很多,这里直接找一个跑一下本地的shir-simpleweb环境就行,URLDNS很容易验证。

实战挖掘

漏洞刚出时找到了一个RuoYi CMS,使用了shiro 1.4.1。
本地照文档搭起来,看一下接口:

public AjaxResult ajaxLogin(String username, String password, Boolean rememberMe)
{
    UsernamePasswordToken token = new UsernamePasswordToken(username, password, rememberMe);
    Subject subject = SecurityUtils.getSubject();
    try
    {
        subject.login(token);
        return success();
    }
    ...
}

这里用到了rememberMe,下面找一下哪些接口有使用的权限。

// 所有请求需要认证
filterChainDefinitionMap.put("/**", "user,kickout,onlineSession,syncOnlineSession");
shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);

shiroConfig里很清楚,所有接口都有user权限,大概稳了。
exp打一发,收到了URLDNS,稳了

参考

https://p0sec.net/index.php/archives/126/
https://superxiaoxiong.github.io/2019/11/26/shiro-padding-oracle-attack%E5%88%86%E6%9E%90/


申博|网络安全巴士站声明:该文看法仅代表作者自己,与本平台无关。版权所有丨如未注明 , 均为原创丨本网站采用BY-NC-SA协议进行授权
转载请注明Apacha-Shiro PaddingOracle 分析
喜欢 (0)
[]
分享 (0)
发表我的评论
取消评论
表情 贴图 加粗 删除线 居中 斜体 签到

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址