Desprecitor

BreizhCTF 2018 - Mobile.

Desprecitor - BreizhCtf 2018

This write up is about the second APK that was given to us at the BreizhCTF : Desprecitor

Decompilation

To reverse Android application, I usually start by reversing the source code . For that i use 2 tools : Jadx and APKTool when Jadx is not sufficient.

For this chall, I only used Jadx with the command

jadx Desprecitor.apk

Once this command executed desassembled file of this applications are located in the folder Desprecitor.

Here I also unzipped the apk to get the file enc.bin from the assets folder.

Finding the vulnerability

We are given 3 interesting files :

Data.java

package fr.breizhctf.saxx.desprecito;

import java.io.Serializable;
import javax.crypto.SealedObject;
import javax.crypto.SecretKey;

public class Data implements Serializable {
    private final SecretKey key;
    private final SealedObject sealed;

    public Data(SealedObject sealed, SecretKey key) {
        this.sealed = sealed;
        this.key = key;
    }

    public SealedObject getSealed() {
        return this.sealed;
    }

    public SecretKey getKey() {
        return this.key;
    }
}

Flag.java

package fr.breizhctf.saxx.desprecito;

import java.io.Serializable;

public class Flag implements Serializable {
    private final String flag;

    public Flag(String flag) {
        this.flag = flag;
    }

    public String getFlag() {
        return this.flag;
    }
}

Desprecitor.java

package fr.breizhctf.saxx.desprecito;

import java.io.FileOutputStream;
import java.io.ObjectOutputStream;
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SealedObject;
import javax.crypto.SecretKey;

public class Desprecitor {
    public static void main(String[] args) throws Exception {
        if (args.length != 4) {
            System.out.println("Desprecitor <<algorithm>> <<cipher mode>> <<flag>> <<output_file>>");
            return;
        }
        SecretKey secretKey = KeyGenerator.getInstance(args[0]).generateKey();
        Cipher theCipher = Cipher.getInstance(args[1]);
        theCipher.init(1, secretKey);
        Data enc = new Data(new SealedObject(new Flag(args[2]), theCipher), secretKey);
        ObjectOutputStream fileObject = new ObjectOutputStream(new FileOutputStream(args[3]));
        fileObject.writeObject(enc);
        fileObject.close();
        System.out.println("File created: " + args[3]);
    }
}

And we where also given enc.bin in the assets which contained data that look like serialized data.

Finding the vulnerability

After searching a litlle in the Desprecitor.java we can see that when the flag got encrypted, he was put in a SealedObject which is secure, but the key of the SealedObject and the SealedObject are stored in a Data object. The Data object is then saved in a file using Serialization.

To get back the flag we just have to revert the operation using deserialization.

Getting the password

Here is my Java code that do the opposite :

import java.io.FileInputStream;
import java.io.ObjectInputStream;
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SealedObject;
import javax.crypto.SecretKey;

public class Desprecitor {
    public static void main(String[] args) throws Exception {
        Data e = null;

        ObjectInputStream fileObject = new ObjectInputStream(new FileInputStream("enc.bin"));
        e = (Data) fileObject.readObject();
        SecretKey secretKey = e.getKey();
        System.out.println(((Flag)e.getSealed().getObject(secretKey)).getFlag());
        fileObject.close();
    }
}

And the flag is :

BZHCTF{#Desprecito_Quiero_respirar_tu_DES_CIPHER_despacito#}

@Areizen