PB-CMS代码审计学习
前言
好久没更新博客了,感觉学到后面不懂的东西更多,通常学一个东西为了理解它就要学更多的东西,所以越来越不想更新博客了。。。
环境
项目地址:https://gitee.com/LinZhaoguan/pb-cms/tree/v1.0.0/
shiro反序列化漏洞
直接来看pom.xml文件,搜到shiro
1.4.1版本,采用的加密模式还是AES-CBC,从1.4.2版本开始采用的是AES-GCM
所以直接拿工具一把梭即可
然后命令执行
在这里1.4.1版本其实shiro550不能打,打shiro550版本要小于1.2.4。但是在shiro反序列化漏洞修复的时候如果仅对shiro版本升级而没有重新生成密钥那么AES加密的默认密钥硬编码仍然会在代码里面,就会同样存在反序列化风险,这里去看看是否存在
确实存在,位置在src/main/java/com/puboot/common/config/ShiroConfig.java
搜了一下这里怎么生成一个新的shirokey,可以利用官方提供的方法生成一个
1 | import org.apache.shiro.codec.Base64; |
每次运行都会得到不一样的key,然后我们替换一下key看还能不能爆破出来
可以看到爆破到天荒地老也没法爆出来除非刚好字典里面有这个key,所以修复用这种方式即可,比如我把刚刚那个密钥加到字典里面可以看到就能爆出来了
shiro权限绕过
Shiro 1.5.3版本之前,当shiro和springboot一起使用时可能会导致身份验证绕过
漏洞的主要原因就是shiro和spring对路径的解析有差异,下面开始复现
我们直接访问/cms/admin
时会跳转到登录界面,但是当使用/;/cms/admin
时即可跳过认证
这个虽然绕过了但是没啥权限什么都干不了
代码分析
这个洞之前没碰过跟着看下代码
shiro
断点下在org/apache/shiro/web/filter/mgt/PathMatchingFilterChainResolver.java#getChain
这里,然后开始调试
可以看到这里通过getPathWithinApplication()
方法获取到的requestURI
只有一个/
跟进去分析一下,来到getPathWithinApplication()
方法下
可以看到这里调用了getRequestUri()
方法后requestUri
就已经变成了/
最后也就是返回的这个,那么继续跟进getRequestUri()
方法看看
从这里的英文注释中可以看到这个函数的功能就是截取分号之前的东西,但是还是看一下具体的处理逻辑,跟进decodeAndCleanUriString()
方法
这里可以看到uri.indexOf(';')
会获取到分号的位置然后赋值给semicolonIndex
最后截取0到分号的位置的东西返回,然后继续往下,会拿着pathPattern
去匹配鉴权规则
然后匹配不上返回null
因为上面这里返回null,前面匹配不上路径对应的鉴权模式,所以不会设置匹配到的鉴权对于的FIlter。跟着调用chain.doFilter
,从而实现绕过
这里走完之后就会去到spring的url处理
spring
断点下在org.springframework.web.util.UrlPathHelper.java#getPathWithinServletMapping
然后调试一下
这里可以看到getPathWithinApplication()
处理之后pathWithinApp
就已经变为了/cms/admin
了所以跟进上面那个函数看看
到这里似乎和shiro是一样的函数,所以直接跟进去看看
来到这里继续跟进
这里三步可以看到先过滤了分号然后过滤了重复的/
得到/cms/admin
,spring能正常处理这个url所以实现了绕过,如果没有加分号这里得到的就是login
这里看了很多分析文章,最终的总结就是url进入tomcat后tomcat判断/;/cms/admin
cms下的admin,进入到shiro时;
后面被截断变为/
,绕过鉴权,此时再进入spring时又被理解为/cms/admin
最终导致shiro权限的绕过,这块看了很多文章只能勉强理解到这里了,再深入感觉得去看shiro的鉴权规则
SSRF结合Fastjson
新知识点,学习一下
登录后台发现本来的功能是这样的
然后来到数据库中
发现这里多了个点,不知道是作者有意这样写的还是怎么,当去掉这个点后会发现上面那个文章列表多了一个功能?自己去弄了下发现并没有啊,是我操作有问题?不知道这个wsyu9a师傅怎么弄的,本来想手动学习一下的,无奈只能看看了
Thymeleaf模板注入漏洞
Thymeleaf的模板注入之前没接触过,但是应该和其它的模板注入差不多,这个洞已经被提了issues
pb-cms存在后台命令执行漏洞 · Issue #I51W2D · LinZhaoguan/pb-cms - Gitee.com
这里先看看引起漏洞的情况
第一种
1 |
|
如上,模板的路径可控,这里如果输入的是/path?lang=en
就会去寻找en.html这个模板,找到就显示,没找到就报错,但是如果我们输入的是spel表达式就会被解析执行,所以这个漏洞的本质还是spel表达式注入,和ssti还是不一样
第二种
controller无返回值,则以GetMapping的路由为视图名称
1 |
|
这种就不能有返回值,有了反而不会导致代码执行,这个要执行是要调用到applyDefaultViewName
方法,里面会判断当ModelAndView
为空,则通过getDefaultViewName
获取请求路径作为ViewName
,更详细的就不看了,这个漏洞还有待更深入的学习
回归漏洞,先复现一下
在主题管理这里新增个主题,然后启用访问前台即可触发
代码分析
来到如下位置下断点调试一下
可以看到这里和我们第一种情况的写法基本一样,这里通过,bizThemeService.selectCurrent().getName()
获取到我们的输入然后返回造成了模板注入
感觉这个审出来也挺猛,为什么就能看出来那个是我们后台可控的呢?
我尝试自己跟一下看看,找了半天终于在下面这里找打新增主题了
这个时候可以看到我们的参数已经被传进来了,就在bizTheme
这个里面,所以还得继续往前推进,在这个BizTheme类下找到定义的参数
里面有个@Data
注解相当于有getter和setter了实例化的时候就会自动赋值了,然后结合上面的@PostMapping
注解即可理解为可控,看看GPT怎么说的,根据Spring MVC的工作原理,当接收到一个POST请求时,Spring会尝试将请求体中的数据映射到方法的参数上,所以这里可控
总结
稍微学习了一下新洞,后面还有个文件上传不知道是不是我找的接口不对没能利用成功,想学习的师傅可以参考File upload vulnerability · Issue #I8T4WR · LinZhaoguan/pb-cms - Gitee.com
这个issue自己去理解一下
参考
https://tttang.com/archive/1592/
https://wsyu9a.github.io/blog/2024/03/05/240304PB-CMS/
模板注入–Spring boot Thymeleaf 模板注入 - TT0TT - 博客园 (cnblogs.com)
https://xz.aliyun.com/t/10514