Wenn Sie nichts über Java-Deserialisierungs-Payloads wissen, könnte es schwierig sein herauszufinden, warum dieser Code einen Calc ausführt.
Zunächst müssen Sie wissen, dass ein Transformer in Java etwas ist, das eine Klasse empfängt und sie in eine andere transformiert.
Es ist auch interessant zu wissen, dass die Payload, die hier ausgeführt wird, äquivalent ist zu:
Also, wie ist die erste Payload präsentiert, die den "einfachen" Einzeilern entspricht?
Zuerst können Sie in der Payload erkennen, dass eine Kette (Array) von Transformations erstellt wird:
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);
Wenn Sie den Code lesen, werden Sie feststellen, dass Sie, wenn Sie irgendwie die Transformation des Arrays verketten, in der Lage sein könnten, beliebige Befehle auszuführen.
Also, wie werden diese Transformationen verkettet?
Im letzten Abschnitt des Payloads können Sie sehen, dass ein Map-Objekt erstellt wird. Dann wird die Funktion decorate von LazyMap mit dem Map-Objekt und den verketteten Transformatoren ausgeführt. Aus dem folgenden Code können Sie sehen, dass dies dazu führen wird, dass die verketteten Transformatoren im Attribut lazyMap.factory kopiert werden:
protectedLazyMap(Map map,Transformer factory) {super(map);if (factory ==null) {thrownewIllegalArgumentException("Factory must not be null");}this.factory= factory;}
Und dann wird das große Finale ausgeführt: lazyMap.get("anything");
Dies ist der Code der get-Funktion:
publicObjectget(Object key) {if (map.containsKey(key) ==false) {Object value =factory.transform(key);map.put(key, value);return value;}returnmap.get(key);}
Und dies ist der Code der transform-Funktion
publicObjecttransform(Object object) {for (int i =0; i <iTransformers.length; i++) {object = iTransformers[i].transform(object);}return object;}
Also, denken Sie daran, dass wir innerhalb der factorychainedTransformer gespeichert haben und innerhalb der transform-Funktion alle diese verketteten Transformer durchlaufen und nacheinander ausführen. Das Lustige ist, dass jeder Transformer objectals Eingabe verwendet und object die Ausgabe des zuletzt ausgeführten Transformers ist. Daher werden alle Transformationsschritte verkettet ausgeführt, um die bösartige Payload auszuführen.
Zusammenfassung
Am Ende, aufgrund der Art und Weise, wie lazyMap die verketteten Transformer innerhalb der get-Methode verwaltet, ist es, als ob wir den folgenden Code ausführen würden:
Beachten Sie, dass value die Eingabe jeder Transformation und die Ausgabe der vorherigen Transformation ist, was die Ausführung einer Einzeiler ermöglicht:
Beachten Sie, dass hier die Gadgets erklärt wurden, die für die ComonsCollections1 Payload verwendet werden. Aber es bleibt offen, wie das Ganze ausgeführt wird. Sie können hier sehen, dass ysoserial zur Ausführung dieser Payload ein AnnotationInvocationHandler-Objekt verwendet, da dieses Objekt beim Deserialisieren die Funktion payload.get()aufrufen wird, die die gesamte Payload ausführt.
Java Thread Sleep
Diese Payload könnte nützlich sein, um zu identifizieren, ob die Website anfällig ist, da sie eine Pause ausführen wird, wenn dies der Fall ist.