Podziel się swoimi sztuczkami hakerskimi, przesyłając PR-y doHackTricks i HackTricks Cloud github repos.
W tym POŚCIE zostanie wyjaśniony przykład z użyciem java.io.Serializable.
Serializable
Interfejs Serializable w Javie (java.io.Serializable) to interfejs znacznikowy, który muszą implementować twoje klasy, jeśli mają być serializowane i deserializowane. Serializacja obiektów w Javie (zapisywanie) odbywa się za pomocą ObjectOutputStream, a deserializacja (odczytywanie) za pomocą ObjectInputStream.
Zobaczmy przykład z klasą Person, która jest serializowalna. Ta klasa nadpisuje funkcję readObject, więc gdy dowolny obiekt tej klasy jest deserializowany, ta funkcja zostanie wykonana.
W przykładzie funkcja readObject klasy Person wywołuje funkcję eat() swojego zwierzaka domowego, a funkcja eat() psa (z jakiegoś powodu) wywołuje calc.exe. Zobaczymy, jak zserializować i deserializować obiekt Person, aby uruchomić ten kalkulator:
importjava.io.Serializable;importjava.io.*;publicclassTestDeserialization {interfaceAnimal {publicvoideat();}//Class must implements Serializable to be serializablepublicstaticclassCatimplementsAnimal,Serializable {@Overridepublicvoideat() {System.out.println("cat eat fish");}}//Class must implements Serializable to be serializablepublicstaticclassDogimplementsAnimal,Serializable {@Overridepublicvoideat() {try {Runtime.getRuntime().exec("calc");} catch (IOException e) {e.printStackTrace();}System.out.println("dog eat bone");}}//Class must implements Serializable to be serializablepublicstaticclassPersonimplementsSerializable {privateAnimal pet;publicPerson(Animal pet){this.pet= pet;}//readObject implementation, will call the readObject from ObjectInputStream and then call pet.eat()privatevoidreadObject(java.io.ObjectInputStream stream)throwsIOException,ClassNotFoundException {pet = (Animal) stream.readObject();pet.eat();}}publicstaticvoidGeneratePayload(Object instance,String file)throwsException {//Serialize the constructed payload and write it to the fileFile f =newFile(file);ObjectOutputStream out =newObjectOutputStream(new FileOutputStream(f));out.writeObject(instance);out.flush();out.close();}publicstaticvoidpayloadTest(String file) throwsException {//Read the written payload and deserialize itObjectInputStream in =newObjectInputStream(new FileInputStream(file));Object obj =in.readObject();System.out.println(obj);in.close();}publicstaticvoidmain(String[] args) throwsException {// Example to call Person with a DogAnimal animal =newDog();Person person =newPerson(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");}}
Podsumowanie
Jak widać na tym bardzo podstawowym przykładzie, "podatność" tutaj występuje, ponieważ funkcja readObject wywołuje inne podatne funkcje.