Description Link to heading

I made a safe with a pin of only two digits.

Attachement : My-pin.jar

Solving Link to heading

Using a online jar decompiler (http://www.javadecompilers.com/), we are able to see all the files used in that Jar and starting to reverse them.

jar_decompil.png

The class Secret is very interesting because that contains all the process and calculation.

class Secret
{
    private int cnt;
    private int[] box;
    private int[] mydata;
    private static Secret instance;
    
    private Secret() {
        this.cnt = 1;
        this.mydata = new int[] { 0, 1, 1, 1, 0, 1, 0, 1, 0, 0, 1, 1, 1, 0, 1, 0, 1, 0, 0, 1, 1, 0, 1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 0, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 1, 0, 1, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 1, 1, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 0, 1, 0, 0, 0, 0, 1, 1, 1, 0, 1, 0, 0, 0, 0, 1, 1, 1, 0, 0, 1, 1, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 0, 1, 0, 1, 0, 0, 1, 1, 1, 0, 1, 0, 1, 0, 0, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 1, 0, 0, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 1, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, 1, 1, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 0, 1, 1, 1, 0, 1, 1, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 0, 0, 1, 0, 1, 1, 0, 1, 1, 1, 1, 0, 0, 1, 1, 1, 0, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 0, 1, 0, 0, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 0, 1, 0 };
        this.box = new int[this.mydata.length / 9];
    }
    
    public static Secret getInstance() {
        return Secret.instance;
    }
    
    public void resetInstance() {
        Secret.instance = new Secret();
    }
    
    public void process(final char c) {
        if (this.cnt > 9) {
            return;
        }
        for (int n = this.mydata.length / 9, i = 1; i <= n; ++i) {
            final int n2 = 9 * i - this.cnt;
            final int n3 = this.box[i - 1] + this.mydata[n2] + (c - '0');
            this.mydata[n2] = n3 % 2;
            if (n3 >= 2) {
                this.box[i - 1] = 1;
            }
            else {
                this.box[i - 1] = 0;
            }
        }
        ++this.cnt;
    }
    
    private String misteri(int i) {
        String s = "";
        int n = 0;
        int n2 = 1;
        while (i > 0) {
            n |= (i & 0x1) << n2 % 8 - 1;
            i >>= 1;
            if (n2 % 8 == 0) {
                if (32 <= n && n < 128) {
                    s = invokedynamic(makeConcatWithConstants:(CLjava/lang/String;)Ljava/lang/String;, (char)n, s);
                }
                n = 0;
            }
            ++n2;
        }
        return invokedynamic(makeConcatWithConstants:(CLjava/lang/String;)Ljava/lang/String;, (char)n, s);
    }
    
    public String getData() {
        final int n = this.mydata.length / 9;
        String s = "";
        int i = 5;
        int n2 = 0;
        for (int j = 1; j <= n; ++j) {
            int n3 = 0;
            int n4 = 1;
            for (int k = 1; k <= 8; ++k) {
                n3 += this.mydata[9 * j - k] * n4;
                n4 <<= 1;
            }
            --i;
            n2 += (int)((n3 - 33) * Math.pow(85.0, i));
            if (i == 0) {
                s = invokedynamic(makeConcatWithConstants:(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;, s, this.misteri(n2));
                n2 = 0;
                i = 5;
            }
        }
        while (i > 0) {
            n2 += (int)(84.0 * Math.pow(85.0, --i));
        }
        return invokedynamic(makeConcatWithConstants:(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;, s, this.misteri(n2));
    }
    
    static {
        Secret.instance = new Secret();
    }
}

In this program, each time a user enters a PIN number using the graphical interface (via buttons), the process(char c) method of the Secret class is called with the number entered as a parameter. This method then modifies the internal data (mydata and box) of the Secret class according to this number.

The getData() method is then used to convert this internal data into a character string, which is displayed in the user interface. So, by entering a series of digits as a PIN code, the program generates a specific output based on these inputs.

public class Pin {
    public static void main(String[] args) {
        for (int i = 0; i < 512; i++) {
            String pin = String.format("%9s", Integer.toBinaryString(i)).replace(' ', '0');
            Secret secret = Secret.getInstance();
            secret.resetInstance();
            for (char c : pin.toCharArray()) {
                secret.process(c);
            }
            String data = secret.getData();
            if(data.contains("n00bz")) {
                System.out.println("PIN: " + pin + ", Flag: " + data);
            }
        }
    }
}

This code is designed to generate all possible PIN codes, convert them to binary, and process them using the Secret class’s process method. It then displays the PIN code and the corresponding output obtained from the Secret class’s getData() method, but only if this output contains the string “n00bz”.

The code generates all the numbers from 0 to 511 (512 numbers in total) in a for loop.

For each number generated, it converts it to binary and formats it to be 9 characters long. For example, the number 5 would be converted to “000000101”. String.format is used to ensure that the string length is always 9 characters, adding leading zeros if necessary.

It then retrieves an instance of the Secret class and resets the instance.

For each character of the formatted PIN code, it calls the process() method of the Secret class. This means it processes each PIN digit one by one.

It then obtains the output using the Secret class’s getData() method and stores it in the data variable.

Finally, it checks whether the string “n00bz” is contained in the output. If so, it prints the PIN code in binary and the corresponding output.

Result Link to heading

n00bz{y0uuu_n33d_t0_bRutefoRc3_1s_e4zyY_}