当前位置: 首页 > ds >正文

Solon框架模板漏洞深度剖析与修复实战

前言

分析发现 Solon 框架在3.1.0版本上存在一个有意思的模板漏洞,对这个漏洞进行简单分析后,发现整个漏洞的利用链是非常有意思的。同时发现最新版的修复方式过于简单,询问 AI 后,AI 也认为修复也是不完善的安全修复,于是进行一系列的绕过尝试,最后还是没有利用成功,简单进行分享。

环境搭建

Solon 框架简介

Solon 是一个轻量级的 Java 应用开发框架,类似于 Spring Boot ,但更加轻量。支持多种模板引擎,包括 Beetl、FreeMarker、Velocity 等。在模板处理方面,Solon 采用了灵活的渲染器映射机制,也是出现这个漏洞的关键原因。

测试环境搭建

https://solon.noear.org/start/build.do?artifact=helloworld_jdk8&project=maven&javaVer=1.8

可以下载 solon 的项目模板 并进行修改

修改一下 pom.xml 文件 设置 solon 的版本为 3.1.0

将原本的视图插件 solon-view-freemarker 替换为以下的任意一种

<dependency><groupId>org.noear</groupId><artifactId>solon-view-enjoy</artifactId>
</dependency><dependency><groupId>org.noear</groupId><artifactId>solon-view-beetl</artifactId>
</dependency><dependency><groupId>org.noear</groupId><artifactId>solon-view-thymeleaf</artifactId>
</dependency><dependency><groupId>org.noear</groupId><artifactId>solon-view-velocity</artifactId>
</dependency>

在 DemoController.java 中 添加代码 并启动运行

    @Mapping("/templates")public ModelAndView templates(Context ctx) throws IOException {ModelAndView modelAndView = new ModelAndView(ctx.param("templates"));return modelAndView;}

image

 

漏洞验证与分析

漏洞验证

我们选用视图插件solon-view-velocity,不同的视图插件对跨目录的处理有所不同,之后会对此进行详细解释

<dependency><groupId>org.noear</groupId><artifactId>solon-view-velocity</artifactId>
</dependency>

image

 

可以看到传入的参数通过 ../ 实现了跨目录的文件读取并将内容解析到页面上

核心调用链分析

通过调试对这个漏洞进行分析

遇到这种情况有一个小的 tips 我们可以通过尝试加载一个不存在的文件,这样 idea 的控制台中会输出相对详细的调用链,方便我们下断点进行调试分析。

image

 

image

 

org.noear.solon.core.handle.RenderManager#render

image

 

image

 

这里会根据文件后缀来选择视图插件,如果没有匹配的就选择用默认渲染器来处理

org.noear.solon.view.velocity.VelocityRender#render

image

 

org.noear.solon.view.velocity.VelocityRender#render_mav

image

 

org.apache.velocity.runtime.RuntimeInstance#getTemplate(java.lang.String, java.lang.String)

image

 

org.apache.velocity.runtime.resource.ResourceManagerImpl#getResource

image

 

整体流程顺下来应该是

用户输入 → Context.param() → ModelAndView() → RenderManager.render()→ 模板引擎处理

在模板引擎处理之前没有对模板文件的路径进行处理和限制,这样一来如果模板引擎处理的时候没有对模板文件的路径进行处理时,就会产生任意文件读取漏洞。

我们可以尝试看看利用别的视图插件看看效果如何。

solon-view-freemarker 为什么不可以

image

 

我们看到 freemarker 对 模板文件的路径进行了处理,不允许跨目录的访问

org.noear.solon.view.freemarker.FreemarkerRender#render

image

 

org.noear.solon.view.freemarker.FreemarkerRender#render_mav

image

 

freemarker.template.Configuration#getTemplate(java.lang.String, java.lang.String)

image

 

freemarker.template.Configuration#getTemplate(java.lang.String, java.util.Locale, java.lang.Object, java.lang.String, boolean, boolean)

image

 

freemarker.cache.TemplateCache#getTemplate(java.lang.String, java.util.Locale, java.lang.Object, java.lang.String, boolean)

image

 

调用 name = templateNameFormat.normalizeRootBasedName(name); 来对传入的模板文件名进行处理

freemarker.cache.TemplateNameFormat.Default020300#normalizeRootBasedName

image

 

对传入的参数进行规范化处理,以确保安全并处理路径中的特殊序列。

漏洞修复

org.noear.solon.core.handle.RenderManager#getViewRender

image

image

我们注意到修复方式是添加了这一部分代码

 if (mv.view().contains("../") || mv.view().contains("..\\")) {// '../','..\' 不安全throw new IllegalStateException("Invalid view path: '" + mv.view() + "'");}

看起来处理方式简单粗暴,实际上是非常有效的

用户输入 → Context.param() → ModelAndView() → RenderManager.render()→ RenderManager.getViewRender()安全检测→模板引擎处理

在模板引擎处理之前就添加了对传入路径的检测,一次 url 编码无法绕过,两次 url 编码虽然可以绕过检测,但是实际处理时,找不到文件所在的位置,再加上并不是从根目录开始读取文件的,最前面还存在目录限制,所以这样一来就无法利用这个漏洞了。

http://www.xdnf.cn/news/14008.html

相关文章:

  • python格式化字符串的几种方式
  • mysql表备份数据,改表名
  • Ubuntu下使用PyTurboJPEG加速图像编解码
  • 【阿里巴巴 x 浙江大学】信息与交互设计 - 交互设计流程与要素
  • PDB Bank怎么下载小分子sdf(选择哪个)和复合物
  • Spring依赖注入的四种方式(面)
  • DC3靶机渗透
  • python计算生态库:18个常用标准库+第三方库
  • 杭州电商代运营公司排名前十
  • SPRING AI 入门
  • 前端八股文 - JavaScript 篇
  • UE接口通信常见问题
  • Ubuntu下搭建Black Magic Probe (BMP) 编译环境
  • AbMole| 2-Deoxy-D-glucose(M5140;2-脱氧-D-葡萄糖)
  • 第七章接入技术
  • opencv opencv_contrib vs2020 源码安装
  • 简述Python里面search和match的区别
  • ZooKeeper详解以及应用部署(AI)
  • Spring Cache 详细介绍——补充
  • 深度解析 JuiceFS 权限管理:Linux 多种安全机制全兼容
  • JavaScript 原型(Prototype)详解
  • 金属切削机床制造企业如何破局?探索项目管理数字化转型
  • 学习STC51单片机35(芯片为STC89C52RCRC)智能小车3(PWM调速小车)
  • C++学习之虚析构函数
  • 【QT】QVariant 转换为自定义的枚举类型
  • 当机械工程师的餐桌变身实验室:立创电赛的真实创新启示录
  • 《深度优先搜索》题集
  • 结构型模式 (7种)
  • 鸿蒙期末总结
  • 高铁列车能否考虑加装飞翼?