springcloud dataflow任意文件写入(CVE-2024-22263)
概述
信息参考:https://spring.io/security/cve-2024-22263
披露时间: 2024.5.23
分析时间:2024.6.18
github源码:https://github.com/spring-cloud/spring-cloud-dataflow
github 修复 commit :Improved validateUploadRequest and applied after tmp directory was cr… · spring-cloud/spring-cloud-dataflow@2ac9bfa
分析版本:2.11.2
其余信息:分析时候暂无公开poc
环境搭建
官网查看docker-compose 的搭建方式,修改镜像版本
在原本的yaml中修改
向skipper-server服务中添加远程调式端口
设置jvm启动变量JDK_JAVA_OPTIONS ,添加远程调式
由于默认版本是jdk11所以添加:
-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=*:8453 |
version: '3' |
POST /api/package/upload HTTP/1.1 |
import json |
接下来继续分析
|
首先会创建临时目录
然后再将临时目录与name拼接,作为临时文件上传目录。
漏洞点就出现在这里,如果name中有../等进行目录遍历,那么就可以设置任意的目录为上传目录
然后与name,version与extension相加然后得到要写入数据的文件的完整路径(name拼接了两次)
然后解压到上传目录
最后还拼接得到(这里加上了-version),再检查是否存在
也就是说会异常
走到finally代码块
会删除临时目录,原本正常的请求,由于上一级目录删除了,上传的文件就删除了,但通过目录遍历,上传目录已经不是临时目录中的子目录了,所以不会删除
最终效果:
利用
springboot fat 从任意文件写入到RCE
或者是写ssh公钥(物理机环境)
写计划任务反弹shell
修复分析
主要修改
packageDirPath.toFile().getCanonicalPath() 是Java中的用于获取文件路径的规范路径。规范路径是指消除路径中的冗余部分(如..和.)之后的路径。
如:若packageDirPath 为 /tmp/upload/../../yyjccc
则packageDirPath.toFile().getCanonicalPath() 为 /yyjccc
然后再判断上传目录是否以临时目录开头,若进行了目录遍历(像上面临时目录为/tmp/upload,目标目录为/yyjccc)就会抛出异常,就无法继续下去,因此也是修复了漏洞