Basiese Java Deserialisering met ObjectInputStream readObject
Reading time: 7 minutes
tip
Leer en oefen AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Leer en oefen GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Leer en oefen Azure Hacking:
HackTricks Training Azure Red Team Expert (AzRTE)
Ondersteun HackTricks
- Kyk na die subskripsie planne!
- Sluit aan by die 💬 Discord groep of die telegram groep of volg ons op Twitter 🐦 @hacktricks_live.
- Deel hacking truuks deur PRs in te dien na die HackTricks en HackTricks Cloud github repos.
In hierdie POST gaan 'n voorbeeld verduidelik word wat java.io.Serializable
gebruik en waarom die oorskrywing van readObject()
uiters gevaarlik kan wees as die inkomende stroom deur 'n aanvaller beheer word.
Serializable
Die Java Serializable
-koppelvlak (java.io.Serializable
) is 'n merk-koppelvlak wat jou klasse moet implementeer as hulle geserialiseer en gedeserialiseer moet word. Java objekserialisering (skryf) word gedoen met die ObjectOutputStream
en deserialisering (lees) word gedoen met die ObjectInputStream
.
Herinnering: Watter metodes word implisiet tydens deserialisering aangeroep?
readObject()
– klas-spesifieke leeslogika (as geïmplementeer en privaat).readResolve()
– kan die gedeserialiseerde objek met 'n ander een vervang.validateObject()
– viaObjectInputValidation
terugroepe.readExternal()
– vir klasse watExternalizable
implementeer.- Konstruktors word nie uitgevoer nie – daarom is gadgetkettings uitsluitlik afhanklik van die vorige terugroepe.
Enige metode in daardie ketting wat eindig met die aanroep van aanvaller-beheerde data (opdraguitvoering, JNDI soektogte, refleksie, ens.) verander die deserialisering roetine in 'n RCE gadget.
Kom ons kyk na 'n voorbeeld met 'n klas Persoon wat serialiseerbaar is. Hierdie klas oorskry die readObject funksie, so wanneer enige objek van hierdie klas gedeserialiseer word, gaan hierdie funksie uitgevoer word.
In die voorbeeld roep die readObject funksie van die klas Persoon die funksie eat()
van sy troeteldier aan en die funksie eat()
van 'n Hond (om een of ander rede) roep 'n calc.exe aan. Ons gaan kyk hoe om 'n Persoon objek te serialiseer en te deserialiseer om hierdie sakrekenaar uit te voer:
Die volgende voorbeeld is van https://medium.com/@knownsec404team/java-deserialization-tool-gadgetinspector-first-glimpse-74e99e493649
import java.io.Serializable;
import java.io.*;
public class TestDeserialization {
interface Animal {
public void eat();
}
//Class must implements Serializable to be serializable
public static class Cat implements Animal,Serializable {
@Override
public void eat() {
System.out.println("cat eat fish");
}
}
//Class must implements Serializable to be serializable
public static class Dog implements Animal,Serializable {
@Override
public void eat() {
try {
Runtime.getRuntime().exec("calc");
} catch (IOException e) {
e.printStackTrace();
}
System.out.println("dog eat bone");
}
}
//Class must implements Serializable to be serializable
public static class Person implements Serializable {
private Animal pet;
public Person(Animal pet){
this.pet = pet;
}
//readObject implementation, will call the readObject from ObjectInputStream and then call pet.eat()
private void readObject(java.io.ObjectInputStream stream)
throws IOException, ClassNotFoundException {
pet = (Animal) stream.readObject();
pet.eat();
}
}
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(String[] args) throws Exception {
// Example to call Person with a Dog
Animal animal = new Dog();
Person person = new Person(animal);
GeneratePayload(person,"test.ser");
payloadTest("test.ser");
// Example to call Person with a Cat
//Animal animal = new Cat();
//Person person = new Person(animal);
//GeneratePayload(person,"test.ser");
//payloadTest("test.ser");
}
}
Gevolgtrekking (klassieke scenario)
Soos jy in hierdie baie basiese voorbeeld kan sien, verskyn die “kwesbaarheid” hier omdat die readObject() metode ander aanvaller-beheerde kode aanroep. In werklike wêreld gadget kettings kan duisende klasse wat in eksterne biblioteke (Commons-Collections, Spring, Groovy, Rome, SnakeYAML, ens.) bevat is, misbruik word – die aanvaller het net een bereikbare gadget nodig om kode-uitvoering te verkry.
2023-2025: Wat is nuut in Java deserialisering aanvalle?
- 2023 – CVE-2023-34040: Spring-Kafka deserialisering van fout-record koppe wanneer
checkDeserExWhen*
vlae geaktiveer is, het arbitrêre gadgetkonstruksie vanuit aanvaller-gepubliseerde onderwerpe toegelaat. Reggestel in 3.0.10 / 2.9.11. ¹ - 2023 – CVE-2023-36480: Aerospike Java kliënt vertroude-bediener aanname gebroke – kwaadwillige bediener antwoorde het serialiseerde payloads bevat wat deur die kliënt gedeserialiseer is → RCE. ²
- 2023 – CVE-2023-25581:
pac4j-core
gebruikersprofiel attribuut parsing het{#sb64}
-geprefikseerde Base64 blobs aanvaar en dit gedeserialiseer ten spyte van 'nRestrictedObjectInputStream
. Opgradeer ≥ 4.0.0. - 2023 – CVE-2023-4528: JSCAPE MFT Bestuurderdiens (poort 10880) het XML-gecodeerde Java-objekte aanvaar wat gelei het tot RCE as root/SYSTEM.
- 2024 – Meerdere nuwe gadget kettings is by ysoserial-plus(mod) gevoeg, insluitend Hibernate5, TomcatEmbed, en SnakeYAML 2.x klasse wat sommige ou filters omseil.
Moderne versagtings wat jy moet implementeer
- JEP 290 / Serialisering Filtrering (Java 9+) Voeg 'n toelaat-lis of ontken-lis van klasse by:
# Aanvaar slegs jou DTO's en java.base, verwerp alles anders
-Djdk.serialFilter="com.example.dto.*;java.base/*;!*"
Programmatiese voorbeeld:
var filter = ObjectInputFilter.Config.createFilter("com.example.dto.*;java.base/*;!*" );
ObjectInputFilter.Config.setSerialFilter(filter);
- JEP 415 (Java 17+) Konteks-Spesifieke Filter Fabrieke – gebruik 'n
BinaryOperator<ObjectInputFilter>
om verskillende filters per uitvoeringskonteks toe te pas (bv. per RMI oproep, per boodskapqueue verbruiker). - Moet nie rou
ObjectInputStream
oor die draad blootstel nie – verkies JSON/Binary kodering sonder kode-uitvoering semantiek (Jackson na deaktivering vanDefaultTyping
, Protobuf, Avro, ens.). - Verdediging-in-diepte beperkings – Stel maksimum array lengte, diepte, verwysings in:
-Djdk.serialFilter="maxbytes=16384;maxdepth=5;maxrefs=1000"
- Deurlopende gadget skandering – hardloop gereedskap soos
gadget-inspector
ofserialpwn-cli
in jou CI om die bou te laat misluk as 'n gevaarlike gadget bereikbaar word.
Opgedateerde gereedskap spiekbrief (2024)
ysoserial-plus.jar
– gemeenskapsvork met > 130 gadget kettings:
java -jar ysoserial-plus.jar CommonsCollections6 'calc' | base64 -w0
marshalsec
– steeds die verwysing vir JNDI gadget generasie (LDAP/RMI).gadget-probe
– vinnige swart-doos gadget ontdekking teen netwerk dienste.SerialSniffer
– JVMTI agent wat elke klas druk wat deurObjectInputStream
gelees word (nuttig om filters te skep).- Detectie wenk – aktiveer
-Djdk.serialDebug=true
(JDK 22+) om filterbesluite en verwerpte klasse te log.
Vinning checklist vir veilige readObject()
implementasies
- Maak die metode
privaat
en voeg die@Serial
annotasie by (help statiese analise). - Moet nooit gebruikers-geleverde metodes aanroep of I/O in die metode uitvoer nie – lees slegs velde.
- As validasie nodig is, voer dit na deserialisering uit, buite
readObject()
. - Verkies om
Externalizable
te implementeer en doen eksplisiete veldlesings in plaas van standaard serialisering. - Registreer 'n geharde
ObjectInputFilter
selfs vir interne dienste (kompromieer-bestande ontwerp).
Verwysings
- Spring Security Advisory – CVE-2023-34040 Java Deserialisering in Spring-Kafka (Aug 2023)
- GitHub Security Lab – GHSL-2023-044: Onveilige Deserialisering in Aerospike Java Kliënt (Jul 2023)
tip
Leer en oefen AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Leer en oefen GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Leer en oefen Azure Hacking:
HackTricks Training Azure Red Team Expert (AzRTE)
Ondersteun HackTricks
- Kyk na die subskripsie planne!
- Sluit aan by die 💬 Discord groep of die telegram groep of volg ons op Twitter 🐦 @hacktricks_live.
- Deel hacking truuks deur PRs in te dien na die HackTricks en HackTricks Cloud github repos.