脚本小子的良心-高频次shiro漏洞的利用&源码详细分析&关于shiro漏洞打法

admin 2023年1月2日16:06:10评论96 views字数 6652阅读22分10秒阅读模式

关于shiro简介

哈哈,我荔枝以后公众号只发发有意义有价值对各位新人有帮助的文章,今天就简单过一过shiro的基本内容吧。我们今天的靶场以vulhub为准,如果大家想复现学习的话,就拿vulhub去练练手感。为了能让任何人都读得懂,就还是得从低到高,一步一步来。

首先我们所说的shiro漏洞,指的就是Apache Shiro这个Java安全框架,它基本用来执行身份验证、授权、密码和会话管理。Shiro框架直观、易用,同时也能提供健壮的安全性。shiro的漏洞是很常见的漏洞同样也是也是各类攻防排名第一拿shell的漏洞。如今主流的shiro利用就是反序列化进去写内存马,这个用法也是最最最常见的用法,拿shell也是非常的快,本篇文章主要说说shiro常规用法和常规用法之外的一些操作,由操作带动源码解析再带动漏洞为什么会产生.

Apache Shiro 漏洞复现

关于利用有两个漏洞,能拿出来复现咋们最好都复现一下,CVE-2020-1957与CVE-2016-4437,后面内容详细的分析550(CVE-2016-4437),就是我们用的最多的那个可以直接代码执行写内存马的漏洞

CVE-2020-1957

全称 Apache Shiro 认证绕过漏洞(CVE-2020-1957),在Apache Shiro 1.5.2以前的版本中,在使用Spring动态控制器时,攻击者通过构造..;这样的跳转,可以绕过Shiro中对目录的权限限制。还等啥捏,起吧。这里面有一个搭载Spring 2.2.2与Shiro 1.5.1的应用

脚本小子的良心-高频次shiro漏洞的利用&源码详细分析&关于shiro漏洞打法

环境启动后,访问http://ip:8080查看首页

脚本小子的良心-高频次shiro漏洞的利用&源码详细分析&关于shiro漏洞打法

这个应用中对URL权限的配置如下:

@Bean
public ShiroFilterChainDefinition shiroFilterChainDefinition() {
    DefaultShiroFilterChainDefinition chainDefinition = new DefaultShiroFilterChainDefinition();
    chainDefinition.addPathDefinition("/login.html""authc"); // 需要从登录表单中接受post
    chainDefinition.addPathDefinition("/logout""logout");
    chainDefinition.addPathDefinition("/admin/**""authc");
    return chainDefinition;
}

在Apache Shiro 1.5.2之前的版本,由于Shiro拦截器和requestURI的匹配流程与Web框架的拦截器的匹配流程有差异,我们构造一个特殊的http请求就可以绕过Shiro的认证,从而未授权访问敏感路径。此漏洞有两种攻击方式,第一种攻击方式适用于Shiro < 1.5.0版本,由于Shiro 1.5.0版本修复补丁考虑不全面,导致补丁绕过,出现了第二种攻击方式,适用于Shiro < 1.5.2版本。

该漏洞起源于SHIRO-682。在Spring中,/resource/xx与/resource/xx/都会被截短成/resource/xx以访问相应资源,在shiro中,/resource/xx与/resource/xx/被视为两个不同路径。所以在Spring集成shiro时,只需要在访问路径后添加/就存在绕过权限校验的可能。分析我们请求的URL在整个项目的传入传递过程。在使用了shiro的项目中,是我们请求的URL(URL1),进过shiro权限检验(URL2), 最后到springboot项目找到路由来处理(URL3)。漏洞的出现就在URL1,URL2和URL3有可能不是同一个URL,这就导致我们能绕过shiro的校验,直接访问后端需要首选的URL。

直接请求管理页面/admin/,无法访问,将会被重定向到登录页面:

脚本小子的良心-高频次shiro漏洞的利用&源码详细分析&关于shiro漏洞打法

构造恶意请求/xxx/..;/admin/,即可绕过权限校验,访问到管理页面:

脚本小子的良心-高频次shiro漏洞的利用&源码详细分析&关于shiro漏洞打法

我们简短的说一下这个payload:/xxx/..;/admin/为啥子会实现利用成功

当我们访问xxxx时,他是无需认证就访问内容的,如果访问admin就跳转到login登陆,访问/xxx/..;/admin/就会越权访问admin目录,首先我们传入的URL请求先经过shiro的解析处理,就是shiro中的PathMatchingFilterChainResolver类与配置的过滤器规则进行匹配进行判断。然后由getPathWithinApplication检测并返回路径,从请求上下文对象中获取具体的URI,也就是/xxxxx/..;/admin,然后传入decodeAndCleanUriString中,这里就很关键了,我们的分号;把后面进行截断,此时的URI就成为/xxxxx/..,返回并作为参数传入normalize。然后他会对URI进行规范化操作:比如循环替换反斜线、对多个下划线进行多余替换等操作,URI结果仍为/xxxxx/..不变并返回到上层的getChain进行具体权限判断。然后打到for循环里进行权限判断并且返回集合,当/xxxxx/../xxxxx/**进行匹配时成功匹配。因此请求/xxxxx/..;/admin,在shiro中经过处理变为/xxxxx/..,与过滤器/xxxxx/**规则进行匹配通过校验,成功转向后方的Spring Boot。恶意请求/xxxxx/..;/admin通过Shiro的校验后,传递到Spring Boot中进行解析,根据Controller设置的路由选择对应Servlet,然后就是获取请求对应的Servlet路径,拿到属性结果并进入循环if分支,然后Spring Boot使用JDK获取Servlet,经过JDK解析后,从Mapping中得到Servlet结果为/admin。最后返回给Spring Boot,形成了对/admin这个Servlet的未授权访问,最终再返回给攻击者。

修复很简单,只需要修改了requestURI的获取方式,经过更准确的解析获取就行。

CVE-2016-4437

Apache Shiro 1.2.4及以前版本中,加密的用户信息序列化后存储在名为remember-me的Cookie中。攻击者可以使用Shiro的默认密钥伪造用户Cookie,触发Java反序列化漏洞,进而在目标机器上执行任意命令。一样的操作,把环境开起来。

由于Apache Shiro默认使用了CookieRememberMeManager,其处理Cookie的流程:得到rememberMe的Cookie值 -> Base64解码 -> AES解密 ->反序列化。然而AES的密钥是硬编码的,就导致了攻击者可以构造恶意数据造成反序列化的RCE漏洞。

rememberMe生成过程:序列化->AES加密->Base64编码->生成rememberMe内容

服务端接收Cookie值时:检索Cookie中的rememberMe内容->Base64解密->AES解密(加密密钥硬编码) ->反序列化(未做处理)

AES的加密密钥在Shiro的1.2.4之前版本中使用的是硬编码,其默认密钥的base64编码后的值可在代码中找到,只要找到密钥后就可以通过构造恶意的序列化对象进行编码,加密,然后作为Cookie加密发送,服务端接收后会解密并触发反序列化漏洞。

Shiro反序列化的特征:在返回包的Set-Cookie中存在rememberMe=deleteMe 字段

脚本小子的良心-高频次shiro漏洞的利用&源码详细分析&关于shiro漏洞打法

首先验证是不是用了shiro框架。有一种就是大师傅见多识广,你不脱裤子我都知道你时真的黑哈哈。好了开个玩笑,BurpSuite进行抓包,在请求包中的cookie字段中添加rememberMe=666;,看响应包header中是否返回rememberMe=deleteMe值,若有,则证明该系统使用了Shiro框架。

脚本小子的良心-高频次shiro漏洞的利用&源码详细分析&关于shiro漏洞打法

当然用现在的工具也是可以达到同样的效果。

脚本小子的良心-高频次shiro漏洞的利用&源码详细分析&关于shiro漏洞打法
脚本小子的良心-高频次shiro漏洞的利用&源码详细分析&关于shiro漏洞打法

爆破key

好这就涉及到第一步:爆破key

[*] kPH+bIxk5D2deZiIxcaaaA==

爆破利用链

脚本小子的良心-高频次shiro漏洞的利用&源码详细分析&关于shiro漏洞打法

通过key和利用链来进行代码执行

命令执行:

脚本小子的良心-高频次shiro漏洞的利用&源码详细分析&关于shiro漏洞打法

记得找一下静态资源!我这里直接注入内存马:

直接注入后连接

脚本小子的良心-高频次shiro漏洞的利用&源码详细分析&关于shiro漏洞打法

然后利用虚拟终端,尝试反弹shell到攻击机上(正常状态下应该是公网VPS)

脚本小子的良心-高频次shiro漏洞的利用&源码详细分析&关于shiro漏洞打法

当然了,我们利用工具很多:

脚本小子的良心-高频次shiro漏洞的利用&源码详细分析&关于shiro漏洞打法

shiro的利用有dnslog带出,直接盲打等,还有在shiro在不出网的情况下通过时延进行判断的,而回显一定是反序列化漏洞中最好的解决方式,好再不做赘述了,只走一遍基本操作。还有如果不成功建议找静态资源去注入,切记!其实shiro本质上是代码执行,执行系统命令也是通过调用java的exec来执行系统命令。写内存马也是通过代码执行把马加载到内存中,并且这里利用了java组件的特性。

shiro漏洞挖掘过程

我们这会以一个漏洞挖掘者的思路来分析这个漏洞是怎么挖到的,然后逐步解析。shiro-550是一个通过反序列化来rce的漏洞,那么这里肯定涉及到了java反序列化这个知识点。为了让我们有层次性的去接受这个东西,我画一张思维导图看看

脚本小子的良心-高频次shiro漏洞的利用&源码详细分析&关于shiro漏洞打法

推荐一篇首发自安全客的文章:Java安全之Shiro550反序列化漏洞分析,在里面详细的介绍了java的反序列化原理和payload构造方法

简单的的理解就是:

反序列化可以导致命令执行,因为shiro是java写的,涉及到用了一段有漏洞的java代码,就导致了反序列化漏洞,然后就导致了rce。

Shiro 550 反序列化漏洞产生原因是:

shiro接受了Cookie里面rememberMe的值,然后去进行Base64解密后,再使用AES密钥解密后的数据,进行反序列化。如果反过来思考,我们构造该值为一个cc链序列化后的值进行该密钥AES加密后进行base64加密,那么这时候就会去进行反序列化我们的payload内容,这时候就可以达到一个命令执行的效果。

获取rememberMe值 -> Base64解密 -> AES解密 -> 调用readobject反序列化操作

环境搭建调试过程我实在遭不住一个一个截图,过程就是你先下个架包对吧

脚本小子的良心-高频次shiro漏洞的利用&源码详细分析&关于shiro漏洞打法

打开shiro/web目录,对pom.xml进行配置依赖配置一个cc4和jstl组件进来,然后配置mavenconftoolchains.xml,指定JDK1.6的路径和版本,然后然后你自己百度试试,编译真的太痛苦了。妈的就不自己写了,粘贴一手别的佬的文,我们学学别人的思路。

还原挖掘源过程

shiro反序列化是一个叫做readObject的函数导致的,所以这里我们在shiro的框架中先全局搜索这个函数。

脚本小子的良心-高频次shiro漏洞的利用&源码详细分析&关于shiro漏洞打法

然后根据这个readObject找到对应的函数,这里因为我是知道漏洞发生点的,就直接定位不浪费时间了。

实战中也是一样的方法,但是需要自己去跟。也就是说,readObject可以找到最终漏洞的触发函数,但是漏洞不一定能够成功触发,还需要输入端可控才可以,因为没有输入端就没法构造payload。这里找到漏洞触发函数

脚本小子的良心-高频次shiro漏洞的利用&源码详细分析&关于shiro漏洞打法

就是这个deserialize函数,可以看出来这是一个泛型方法(我默认看的人都懂java),这个方法其实挺好读懂的

脚本小子的良心-高频次shiro漏洞的利用&源码详细分析&关于shiro漏洞打法

这两段都是获取文件流,然后

脚本小子的良心-高频次shiro漏洞的利用&源码详细分析&关于shiro漏洞打法

这里ois = object input stream 也就是对象输入流,最后用一个泛型方法调用ois.readObject(),就直接把流里面的数据反序列化。上面这个方法写出来本质上就是给数据做反序列化的,不存在什么漏洞不漏洞,漏洞是否发生,还需要往前看,看这个方法是怎么用的,找到这个方法中传入的bytes数据流是否可控,这是我们往前看的目的。

于是再次全局搜索这个这个方法的名字deserialize

脚本小子的良心-高频次shiro漏洞的利用&源码详细分析&关于shiro漏洞打法

定位到函数

脚本小子的良心-高频次shiro漏洞的利用&源码详细分析&关于shiro漏洞打法

这个函数convertBytesToPrincipals

脚本小子的良心-高频次shiro漏洞的利用&源码详细分析&关于shiro漏洞打法

看得出来是一个解密函数,也就是把bytes值传进来,然后调用decrypt函数来解密,最后把解密后的数据再调用deserialize来反序列化。看到这里,再次重复我们之前的搜索大法,也就是看到底哪里使用了这个解密函数 全局搜索

脚本小子的良心-高频次shiro漏洞的利用&源码详细分析&关于shiro漏洞打法

找到方法的调用处

脚本小子的良心-高频次shiro漏洞的利用&源码详细分析&关于shiro漏洞打法

让我们来阅读一下这个方法getRememberedPrincipals

这个方法有个subjectContext的形参,这个参数是从外界传入,经过传入之后,首先通过这一段获取bytes

脚本小子的良心-高频次shiro漏洞的利用&源码详细分析&关于shiro漏洞打法

然后走下面的逻辑,通过这一段

脚本小子的良心-高频次shiro漏洞的利用&源码详细分析&关于shiro漏洞打法

获取到principals,最后如果不出错,就把principals返回出来。

其实光看这个还是看不明白,因为还是没找到外界的直接输入点,所以继续搜索这个方法getRememberedPrincipals

脚本小子的良心-高频次shiro漏洞的利用&源码详细分析&关于shiro漏洞打法

找到一个调用他的方法

脚本小子的良心-高频次shiro漏洞的利用&源码详细分析&关于shiro漏洞打法

还是subjectContext,依旧没找到输入点,继续搜索getRememberedIdentity方法

脚本小子的良心-高频次shiro漏洞的利用&源码详细分析&关于shiro漏洞打法
脚本小子的良心-高频次shiro漏洞的利用&源码详细分析&关于shiro漏洞打法

依旧没找到输入点,继续搜索resolvePrincipals

脚本小子的良心-高频次shiro漏洞的利用&源码详细分析&关于shiro漏洞打法

这里可以看到createSubject方法调用了下面这个方法,继续搜索createSubject方法

脚本小子的良心-高频次shiro漏洞的利用&源码详细分析&关于shiro漏洞打法

最终得到doFilterInternal方法,可以看到在这里获取request中的值,然后最终request值中的一部分会被反序列化 其实上面形参还对不上号,但是看得有点头晕,懒得找了。根据经验判断就是这样。那么问题来了,request的值在哪,从哪里传进来,虽然通过这样的方法找到了filter,那么怎么构造payload呢,说好的输入点,怎么最后就是个request 呢,我怎么知道request是什么东西?别慌,其实这一步的目的就是为了找到漏洞的触发输入点是否可控,这里看到了request,其实可以证明,输入还是大概率可控的,但是为啥还没找到输入点,其实我也不知道。

这些就基本还原了真实的漏洞挖掘过程,最开始的时候框架也不了解,源码也没读过,就知道一个readobject和一个反序列化,这种情况,大概率就是一步步的去反向的跟踪,跟踪输入点,这是很符合逻辑的方法。整个源码还有很多看不懂的地方,比如这个subjectcontext是啥,或者有些基础差一点的可能连这个filter也看不懂,不知道什么是filter,甚至往里面传request是什么意思也不懂,这种情况应当去恶补java基础再看。如果有了java基础,但是没有shiro的框架基础,框架里面很多东西看起来都是迷迷糊糊,这个时候建议就去看一看shiro的教程,快速的过一遍,看看这个框架到底是干啥的,整体架构先了解一下。在有了上述基础之后再来看,再加上刚刚其实这个漏洞的大体思路已经被理出来了,现在就可以正向的来调试代码了。

shiro的环境搭建

这个是最恶心的,我贴几个文章,大家有兴趣的自己去搭建。

https://www.anquanke.com/post/id/225442#h2-4

https://blog.csdn.net/weixin_54648419/article/details/122800154

https://cloud.tencent.com/developer/article/1944740

总结

首先方法是shiro存在一个readobject的反序列化触发点,然后这个触发点经过我们分析是用户可控的,并且可控的点在前端的cookie处,所以最终导致了漏洞的产生。近几年的 hw 中,shiro 550都担任了非常重要的角色,并且也不断的衍生出各种各样的工具,如果不学原理只用工具去梭哈梭哈,你就会爱上梭哈,说的就是我这种脚本小子哈哈,如果你想有更好的关于550更深入的学习,看我这不入流的文肯定不行:

推荐文章

看看这些优秀的文章,向他们学习哈哈。By师傅:天下大木头,然师傅的工具也很好用嘿嘿嘿。

脚本小子的良心-高频次shiro漏洞的利用&源码详细分析&关于shiro漏洞打法

Shiro 550 漏洞学习(一)

http://wjlshare.com/archives/1542

Shiro 550 漏洞学习(二):内存马注入及回显 

http://wjlshare.com/archives/1545

Shiro550 漏洞学习(三):Shiro自身利用链以及更通用的Tomcat回显方案 

http://wjlshare.com/archives/1549


原文始发于微信公众号(猫因的安全):脚本小子的良心-高频次shiro漏洞的利用&源码详细分析&关于shiro漏洞打法

  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2023年1月2日16:06:10
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   脚本小子的良心-高频次shiro漏洞的利用&源码详细分析&关于shiro漏洞打法https://cn-sec.com/archives/1494537.html

发表评论

匿名网友 填写信息