Σε αρκετές περιπτώσεις μπορείτε να βρείτε ένα payload απο deserialization java που χρησιμοποιεί transformers από τις Apache common collections όπως το παρακάτω:
Αν δεν γνωρίζετε τίποτα για τα java deserialization payloads, μπορεί να είναι δύσκολο να καταλάβετε γιατί αυτός ο κώδικας θα εκτελέσει ένα calc.
Πρώτα απ' όλα, πρέπει να ξέρετε ότι ένας Transformer στην Java είναι κάτι που λαμβάνει μια κλάση και την μετατρέπει σε μια διαφορετική.
Επίσης, είναι ενδιαφέρον να γνωρίζετε ότι το payload που εκτελείται εδώ είναι ισοδύναμο με:
Λοιπόν, πώς είναι το πρώτο payload που παρουσιάζεται ισοδύναμο με αυτά τα "απλά" one-liners;
Πρώτον, μπορείτε να παρατηρήσετε στο payload ότι δημιουργείται μια αλυσίδα (πίνακας) μετασχηματισμών:
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);
Αν διαβάσετε τον κώδικα, θα παρατηρήσετε ότι αν με κάποιον τρόπο αλυσσοδέσετε τη μετατροπή του πίνακα, θα μπορούσατε να εκτελέσετε αυθαίρετες εντολές.
Στην τελευταία ενότητα του payload μπορείτε να δείτε ότι ένα αντικείμενο Map δημιουργείται. Στη συνέχεια, η συνάρτηση decorate εκτελείται από το LazyMap με το αντικείμενο map και τους αλυσιδωτούς μετασχηματιστές. Από τον παρακάτω κώδικα μπορείτε να δείτε ότι αυτό θα προκαλέσει την αντιγραφή των αλυσιδωτών μετασχηματιστών μέσα στο χαρακτηριστικό lazyMap.factory:
protectedLazyMap(Map map,Transformer factory) {super(map);if (factory ==null) {thrownewIllegalArgumentException("Factory must not be null");}this.factory= factory;}
Και τότε εκτελείται η μεγάλη φιναλε: lazyMap.get("anything");
Αυτός είναι ο κώδικας της συνάρτησης get:
publicObjectget(Object key) {if (map.containsKey(key) ==false) {Object value =factory.transform(key);map.put(key, value);return value;}returnmap.get(key);}
Και αυτός είναι ο κώδικας της συνάρτησης transform
publicObjecttransform(Object object) {for (int i =0; i <iTransformers.length; i++) {object = iTransformers[i].transform(object);}return object;}
Έτσι, θυμηθείτε ότι μέσα στο factory είχαμε αποθηκεύσει chainedTransformer και μέσα στη transform συνάρτηση περνάμε από όλους αυτούς τους αλυσίδωτους μετασχηματιστές και εκτελούμε ο ένας μετά τον άλλο. Το αστείο είναι ότι κάθε μετασχηματιστής χρησιμοποιεί objectως είσοδο και το object είναι η έξοδος από τον τελευταίο μετασχηματιστή που εκτελέστηκε. Επομένως, όλοι οι μετασχηματισμοί εκτελούνται αλυσίδωτα εκτελώντας το κακόβουλο payload.
Περίληψη
Στο τέλος, λόγω του πώς διαχειρίζεται το lazyMap τους αλυσίδωτους μετασχηματιστές μέσα στη μέθοδο get, είναι σαν να εκτελούσαμε τον παρακάτω κώδικα:
Σημειώστε πώς το value είναι η είσοδος κάθε μετασχηματισμού και η έξοδος του προηγούμενου μετασχηματισμού, επιτρέποντας την εκτέλεση μιας εντολής μίας γραμμής:
Σημειώστε ότι εδώ εξηγήθηκαν τα gadgets που χρησιμοποιούνται για το ComonsCollections1 payload. Αλλά μένει πώς όλα αυτά αρχίζουν να εκτελούνται. Μπορείτε να δείτε εδώ ότι ysoserial, προκειμένου να εκτελέσει αυτό το payload, χρησιμοποιεί ένα αντικείμενο AnnotationInvocationHandler γιατί όταν αυτό το αντικείμενο αποδομηθεί, θα καλέσει τη συνάρτηση payload.get() που θα εκτελέσει ολόκληρο το payload.
Java Thread Sleep
Αυτό το payload θα μπορούσε να είναι χρήσιμο για να προσδιορίσετε αν το web είναι ευάλωτο καθώς θα εκτελέσει έναν ύπνο αν είναι.