hacktricks/src/pentesting-web/deserialization/basic-java-deserialization-objectinputstream-readobject.md

155 lines
8.1 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Msingi wa Java Deserialization na ObjectInputStream readObject
{{#include ../../banners/hacktricks-training.md}}
Katika POST hii itafafanuliwa mfano unaotumia `java.io.Serializable` **na kwa nini kuandika upya `readObject()` kunaweza kuwa hatari sana ikiwa mtiririko wa kuingia unadhibitiwa na mshambuliaji**.
## Serializable
Interface ya Java `Serializable` (`java.io.Serializable`) ni interface ya alama ambayo madarasa yako yanapaswa kutekeleza ikiwa yanapaswa kuwa **serialized** na **deserialized**. Serialization ya kitu cha Java (kuandika) inafanywa na [`ObjectOutputStream`](http://tutorials.jenkov.com/java-io/objectoutputstream.html) na deserialization (kusoma) inafanywa na [`ObjectInputStream`](http://tutorials.jenkov.com/java-io/objectinputstream.html).
### Kumbusho: Ni mbinu zipi zinazoitwa kimya kimya wakati wa deserialization?
1. `readObject()` mantiki maalum ya kusoma ya darasa (ikiwa imeandikwa na *binafsi*).
2. `readResolve()` inaweza kubadilisha kitu kilichodeserialized na kingine.
3. `validateObject()` kupitia `ObjectInputValidation` callbacks.
4. `readExternal()` kwa madarasa yanayotekeleza `Externalizable`.
5. Waandishi hawatekelezwi kwa hivyo mnyororo wa gadget unategemea pekee callbacks za awali.
Mbinu yoyote katika mnyororo huo inayomalizika kwa kuita data inayodhibitiwa na mshambuliaji (utendaji wa amri, utafutaji wa JNDI, reflection, nk.) inageuza utaratibu wa deserialization kuwa gadget ya RCE.
Hebu tuone mfano na **darasa la Person** ambalo ni **serializable**. Darasa hili **linandika upya** kazi ya readObject, hivyo wakati **kitu chochote** cha **darasa hili** kinapokuwa **deserialized** kazi hii itatekelezwa.\
Katika mfano, kazi ya **readObject** ya darasa la Person inaita kazi `eat()` ya mnyama wake na kazi `eat()` ya Mbwa (kwa sababu fulani) inaita **calc.exe**. **Tutashuhudia jinsi ya kuandika na kusoma kitu cha Person ili kutekeleza kalkuleta hii:**
**Mfano ufuatao umetolewa kutoka <https://medium.com/@knownsec404team/java-deserialization-tool-gadgetinspector-first-glimpse-74e99e493649>**
```java
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");
}
}
```
### Hitimisho (hali ya kawaida)
Kama unavyoona katika mfano huu wa msingi, “udhaifu” hapa unatokea kwa sababu ya **metode ya readObject()** **kuita msimbo mwingine unaodhibitiwa na mshambuliaji**. Katika mnyororo wa vifaa wa ulimwengu halisi, maelfu ya madarasa yaliyomo katika maktaba za nje (Commons-Collections, Spring, Groovy, Rome, SnakeYAML, nk.) yanaweza kutumika vibaya mshambuliaji anahitaji tu *moja* ya vifaa vinavyoweza kufikiwa ili kupata utekelezaji wa msimbo.
---
## 2023-2025: Nini kipya katika mashambulizi ya deserialization ya Java?
* 2023 CVE-2023-34040: Deserialization ya vichwa vya rekodi za makosa ya Spring-Kafka wakati bendera za `checkDeserExWhen*` zimewezeshwa ziliruhusu ujenzi wa vifaa vya kiholela kutoka kwa mada zilizochapishwa na mshambuliaji. Imefanyiwa marekebisho katika 3.0.10 / 2.9.11. ¹
* 2023 CVE-2023-36480: Dhana ya mteja wa Java wa Aerospike ya seva inayotegemewa imevunjwa majibu ya seva yenye uharibifu yalikuwa na mizigo iliyosimbwa ambayo ilitafsiriwa na mteja → RCE. ²
* 2023 CVE-2023-25581: Uchanganuzi wa sifa za wasifu wa mtumiaji wa `pac4j-core` ulikubali blobs za Base64 zilizo na `{#sb64}` na kuziunda licha ya `RestrictedObjectInputStream`. Sasisha ≥ 4.0.0.
* 2023 CVE-2023-4528: Huduma ya JSCAPE MFT Manager (bandari 10880) ilikubali vitu vya Java vilivyoandikwa kwa XML vinavyosababisha RCE kama root/SYSTEM.
* 2024 Mnyororo mpya wa vifaa vingi uliongezwa kwa ysoserial-plus(mod) ikiwa ni pamoja na madarasa ya Hibernate5, TomcatEmbed, na SnakeYAML 2.x ambayo yanapita baadhi ya filters za zamani.
## Kinga za kisasa unazopaswa kutumia
1. **JEP 290 / Ufiltraji wa Serialization (Java 9+)**
*Ongeza orodha ya ruhusa au orodha ya kukataa ya madarasa:*
```bash
# Kubali tu DTO zako na java.base, kataa kila kitu kingine
-Djdk.serialFilter="com.example.dto.*;java.base/*;!*"
```
Mfano wa programu:
```java
var filter = ObjectInputFilter.Config.createFilter("com.example.dto.*;java.base/*;!*" );
ObjectInputFilter.Config.setSerialFilter(filter);
```
2. **JEP 415 (Java 17+) Kiwanda maalum cha Filters** tumia `BinaryOperator<ObjectInputFilter>` kutekeleza filters tofauti kwa kila muktadha wa utekelezaji (mfano, kwa kila wito wa RMI, kwa kila mtumiaji wa foleni ya ujumbe).
3. **Usifichue `ObjectInputStream` mbichi kwenye mtandao** pendelea uandishi wa JSON/Binary bila maana za utekelezaji wa msimbo (Jackson baada ya kuzima `DefaultTyping`, Protobuf, Avro, nk.).
4. **Mipaka ya Ulinzi wa Kina** Weka urefu wa juu wa array, kina, marejeleo:
```bash
-Djdk.serialFilter="maxbytes=16384;maxdepth=5;maxrefs=1000"
```
5. **Kuchunguza vifaa kwa muda mrefu** endesha zana kama `gadget-inspector` au `serialpwn-cli` katika CI yako ili kushindwa kwa ujenzi ikiwa kifaa hatari kinapatikana.
## Orodha ya zana iliyosasishwa (2024)
* `ysoserial-plus.jar` tawi la jamii lenye > 130 mnyororo wa vifaa:
```bash
java -jar ysoserial-plus.jar CommonsCollections6 'calc' | base64 -w0
```
* `marshalsec` bado ni rejeleo kwa uzalishaji wa vifaa vya JNDI (LDAP/RMI).
* `gadget-probe` ugunduzi wa haraka wa vifaa vya sanduku jeusi dhidi ya huduma za mtandao.
* `SerialSniffer` wakala wa JVMTI unaochapisha kila darasa lilosomwa na `ObjectInputStream` (inayofaa kutengeneza filters).
* **Ushauri wa kugundua** wezesha `-Djdk.serialDebug=true` (JDK 22+) ili kuandika maamuzi ya filter na madarasa yaliyokataliwa.
## Orodha ya haraka ya ukaguzi kwa utekelezaji salama wa `readObject()`
1. Fanya njia hiyo kuwa `private` na ongeza annotation ya `@Serial` (inasaidia uchambuzi wa statiki).
2. Kamwe usiite mbinu zinazotolewa na mtumiaji au ufanye I/O katika njia hiyo soma tu maeneo.
3. Ikiwa uthibitisho unahitajika, fanya baada ya deserialization, nje ya `readObject()`.
4. Pendelea kutekeleza `Externalizable` na ufanye usomaji wa maeneo wazi badala ya serialization ya kawaida.
5. Sajili `ObjectInputFilter` iliyoimarishwa hata kwa huduma za ndani (muundo unaostahimili kuathiriwa).
## Marejeleo
1. Spring Security Advisory CVE-2023-34040 Java Deserialization katika Spring-Kafka (Agosti 2023)
2. GitHub Security Lab GHSL-2023-044: Deserialization Hatari katika Mteja wa Java wa Aerospike (Julai 2023)
{{#include ../../banners/hacktricks-training.md}}