Hacking
Writeups
Forensics
ransomware

ransomware

Description

CTF: STACK the Flags 2022

[don't remember what the challenge description was]


challenge2.apk

Solution

Pwned by @skytect (opens in a new tab)

Finding the encryption script

Let's run the APK.

Initially, we're presented with a page asking for permission to display over other apps.

app screen

If we follow the instructions, we're presented with a dialog overlay the next time we launch the app.

app dialog

As with any APK challenge, let's open JADX (opens in a new tab).

jadx-gui challenge2.apk

We find a key!

JADX GUI

Let's try using the key with the dialog. After we successfully enter 16 characters within 5 seconds on an Android emulator, the dialog is dismissed.

If we dig further in JADX, we find code that suggests a decrypted file in /data/data/com.jaga.app/flag_decrypt.txt.

JADX GUI

Let's check out the file with adb.

❯ adb shell
emu64a:/ $ su
emu64a:/ # cat /data/data/com.jaga.app/flag_decrypt.txt
import java.util.Arrays;

public class Main {
    public static void main(String args[]) {
      String pt = "??????????????????????????????";
      String ct = "yu1gpulonjtqxn3ct6gkjxph";
      String ring1 = "abcdefghijklmnopqrstuvwxyz{}1234567890";
      String ring2 = "qw1234567890ertyuiopasdf{}ghjklzxcvbnm";
      int initial_shift = 3;
      int periodic_increment = 7;
      int periodic_length = 4;

      char[] ch = ring1.toCharArray();
      char[] ch_pt = pt.toCharArray();

      ring2 = shift(ring2, initial_shift);

      int temp_period = periodic_length;
      for (int i = 0; i < pt.length(); i++) {
          temp_period--;

          int index = new String(ch).indexOf(ch_pt[i]);
          ct = ct + ring2.charAt(index);
          if (temp_period == 0) {
              ring2 = shift(ring2, periodic_increment);
              temp_period = periodic_length;
          }
      }
    }

    public static String shift(String text, int shift) {
        for (int i = 0; i < shift; i++) {
            text = text.charAt(text.length() - 1) + text.substring(0, text.length() - 1);
        }
        return text;
    }
emu64a:/ #

It looks like we found some Java code we have to reverse engineer.

import java.util.Arrays;
 
public class Main {
    public static void main(String args[]) {
      String pt = "??????????????????????????????";
      String ct = "yu1gpulonjtqxn3ct6gkjxph";
      String ring1 = "abcdefghijklmnopqrstuvwxyz{}1234567890";
      String ring2 = "qw1234567890ertyuiopasdf{}ghjklzxcvbnm";
      int initial_shift = 3;
      int periodic_increment = 7;
      int periodic_length = 4;
 
      char[] ch = ring1.toCharArray();
      char[] ch_pt = pt.toCharArray();
 
      ring2 = shift(ring2, initial_shift);
 
      int temp_period = periodic_length;
      for (int i = 0; i < pt.length(); i++) {
          temp_period--;
 
          int index = new String(ch).indexOf(ch_pt[i]);
          ct = ct + ring2.charAt(index);
          if (temp_period == 0) {
              ring2 = shift(ring2, periodic_increment);
              temp_period = periodic_length;
          }
      }
    }
 
    public static String shift(String text, int shift) {
        for (int i = 0; i < shift; i++) {
            text = text.charAt(text.length() - 1) + text.substring(0, text.length() - 1);
        }
        return text;
    }
}

Reversing the encryption script

First, I rewrite and simplify the script in Python with some help from Copilot.

def shift(text: str, shift: int) -> str:
    for _ in range(shift):
        text = text[-1] + text[:-1]
    return text
 
pt = "??????????????????????????????"
ct = "yu1gpulonjtqxn3ct6gkjxph"
ring1 = "abcdefghijklmnopqrstuvwxyz{}1234567890"
ring2 = "bnmqw1234567890ertyuiopasdf{}ghjklzxcv"
 
 
temp_period = 0
for c in pt:
    temp_period += 1
 
    index = ring1.index(c)
    ct += ring2[index]
 
    if temp_period == 4:
        ring2 = shift(ring2, 7)
        temp_period = 0

After staring at the script for some time, I came up with the following solve script.

ct = "yu1gpulonjtqxn3ct6gkjxph"
pt = ""
 
for i, c in enumerate(ct):
    lookup = {a: b for a, b in zip(shift(ring2, 7*(i // 4)), ring1)}
    pt += lookup[c]
 
print(pt)  # stf22{c1ph4rsw1thatw15t}

stf22{c1ph4rsw1thatw15t}