Skip to content

Latest commit

 

History

History
70 lines (46 loc) · 3.63 KB

File metadata and controls

70 lines (46 loc) · 3.63 KB

CVE-2016-6802权限绕过分析

前言

该漏洞和前面的CVE-2010-3863相似,还是路径标准化导致的问题,只是漏洞点不一样。先看看影响版本:

shiro < 1.3.2

这里漏洞环境使用上一个Shiro-550的原生 shiro 环境,权限配置如下: image-20221020161442418

该漏洞利用有前提条件:项目部署不在根目录,我这里写的dotast image-20221020160506290

启动后访问登录页面 image-20221020160547330

漏洞复现

访问登录后的页面/dotast/account/index.jsp,因为无权限会 302 跳转到登录页面 image-20221020160725969

访问/a/../dotast/account/index.jsp,成功绕过 Shiro 的鉴权访问到登录后的页面 image-20221020160859488

漏洞分析

还是和之前一样,将断点打在getPathWithinApplication()方法上 image-20221020161902086

之前在CVE-2010-3863分析的时候得知,出现问题的地方在于getRequestUri()方法返回了未进行标准化处理的路径。但从上图中可以看到getRequestUri()方法已经将我们的构造的路径进行了处理,返回了/dotast/account/index.jsp

根据漏洞信息可以得知,该条 CVE 出现漏洞点在getContextPath()方法中,我们跟进一下getContextPath()方法 image-20221020165234298

接着跟进request.getContextPath()方法,到Request#getContextPath()方法 image-20221020165902691

先是通过this.getServletContext().getContextPath()方法获取当前工程路径,然后通过this.getRequestURI()方法获取传入的 URL 路径,随后进入 while 循环中

接着往下走,该处逻辑为以/为分隔符进行截取字符串,进行路径标准化image-20221020170826165

然后不断与canonicalContextPath进行对比,也就是/dotast,过程如下:

1. /a           --> 标准化为 /a      --> equals("/dotast") == false
2. /a/..        --> 标准化为 /       --> equals("/dotast") == false
3. /a/../dotast --> 标准化为 /dotast --> equals("/dotast") == true

image-20221020171927505

因此 return 回去/a/../dotast/account/index.jsp的前 12 个字符串,也就是/a/../dotast

image-20221020162246444

这里将/a/../dotast传入到了decodeRequestString()方法中,继续跟进 image-20221020162425795

decodeRequestString()方法只做了一个 URL 解码的操作就 return 回去了,现在回到一开始的getPathWithinApplication()方法 image-20221020162551341

接下来跟进startsWithIgnoreCase()方法 image-20221020163043400

根据/a/../dotast的长度截取/dotast/account/index.jsp字符串,这里/a/../dotast为 12 ,因此得到/dotast/accou。接着又将两个字符串进行equals()对比是否相等,很显然并不相等,因此 return 回去之后会进入 else 条件里。 image-20221020163215015

返回的/dotast/account/index.jsp在去除掉我们设置的目录/dotast后也就是/account/index.jsp,就会和配置文件中的/account/**匹配成功,因而导致绕过鉴权,访问到/account/index.jspimage-20221020163626531