Вводные

На исследование представлен файл APKey.zip объемом 1144778 байт с хеш-суммой SHA256 0e901ee8858a83d64bf65daead62785c89ac157440b8c1affbc62b32036cccf1. Пароль на архив hackthebox.

Проверим архив

Вычислим контрольную сумму, чтобы удостовериться в валидности файлов.

$ ls -la APKey.zip 
-rw-r--r-- 1 kiberdruzhinnik kiberdruzhinnik 1144778 Sep 10 16:44 APKey.zip
$ echo "0e901ee8858a83d64bf65daead62785c89ac157440b8c1affbc62b32036cccf1  APKey.zip" | sha256sum -c
APKey.zip: OK

Контрольная сумма совпала, поэтому можно приступать к распаковке архива.

$ unzip APKey.zip 
Archive:  APKey.zip
[APKey.zip] APKey.apk password: 
  inflating: APKey.apk

Исследование приложения

Перед нами стандартный контейнер с Android-приложением.

$ file APKey.apk 
APKey.apk: Android package (APK), with MANIFEST.MF and classes.dex

Загрузим файл в jadx.

Сразу же видим MainActivity с обфусцированными методами.

Alt text

Далее явно идет проверка на имя пользователя admin и пароль, результатом которого будет хеш-сумма MD5 a2a3d412e92d896134d9c9126d756f.

Alt text

Нам стоит посмотреть внимательнее на функции b.a(g.a()).

Функция g.a похожа на набор байт. Она содержит в себе вызовы функций h.a, i.a, f.a, e.a, c.a, d.a, a.a. Если посмотреть на эти функции, то они будут аналогичны текущей функции. Все эти функции возвращают строку.

Alt text

С помощью онлайн компилятора Java восстановим недостающие строки (изначальные вызовы будут написаны в комментарии рядом).

public static String a() {
        StringBuilder sb = new StringBuilder();
        ArrayList arrayList = new ArrayList();
        arrayList.add("722gFc");
        arrayList.add("n778Hk");
        arrayList.add("jvC5bH");
        arrayList.add("lSu6G6");
        arrayList.add("HG36Hj");
        arrayList.add("97y43E");
        arrayList.add("kjHf5d");
        arrayList.add("85tR5d");
        arrayList.add("1UlBm2");
        arrayList.add("kI94fD");
        sb.append((String) arrayList.get(8));
        sb.append("kHtZuV"); // h.a()
        sb.append("rSE6qY"); // i.a()
        sb.append("6HxWkw"); // f.a()
        sb.append("HyeaX9"); // e.a()
        ArrayList arrayList2 = new ArrayList();
        arrayList2.add("ue7888");
        arrayList2.add("6HxWkw");
        arrayList2.add("gGhy77");
        arrayList2.add("837gtG");
        arrayList2.add("HyTg67");
        arrayList2.add("GHR673");
        arrayList2.add("ftr56r");
        arrayList2.add("kikoi9");
        arrayList2.add("kdoO0o");
        arrayList2.add("2DabnR");
        sb.append((String) arrayList2.get(9));
        sb.append("FlEGyL"); // c.a()
        ArrayList arrayList3 = new ArrayList();
        arrayList3.add("jH67k8");
        arrayList3.add("8Huk89");
        arrayList3.add("fr5GtE");
        arrayList3.add("Hg5f6Y");
        arrayList3.add("o0J8G5");
        arrayList3.add("Wod2bk");
        arrayList3.add("Yuu7Y5");
        arrayList3.add("kI9ko0");
        arrayList3.add("dS4Er5");
        arrayList3.add("h93Fr5");
        sb.append((String) arrayList3.get(5));
        sb.append("wAxcoc"); // d.a()
        sb.append("85S94kFpV1"); // a.a()
        return sb.toString();
    }

Результатом этой функции будет строка 1UlBm2kHtZuVrSE6qY6HxWkwHyeaX92DabnRFlEGyLWod2bkwAxcoc85S94kFpV1, которая передается в функцию b.a для дешифровки.

Alt text

Проведем аналогичную работу с этой функцией.

public static String b() {
        char charAt = "wAxcoc".charAt(1);
        char charAt2 = "rSE6qY".charAt(2);
        char charAt3 = "rSE6qY".charAt(1);
        return String.valueOf(charAt) + String.valueOf(charAt2) + String.valueOf(charAt3);
}

public static String a(String str) {
        char charAt = "kHtZuV".charAt(0); // h.a()
        char charAt2 = "85S94kFpV1".charAt(8); // a.a()
        char charAt3 = "HyeaX9".charAt(5); // e.a()
        char charAt4 = "rSE6qY".charAt(4); // i.a()
        char charAt5 = "kHtZuV".charAt(1); // h.a()
        char charAt6 = "kHtZuV".charAt(4); // h.a()
        char charAt7 = "kHtZuV".charAt(3); // h.a()
        char charAt8 = "kHtZuV".charAt(3); // h.a()
        char charAt9 = "kHtZuV".charAt(0); // h.a()
        char charAt10 = "85S94kFpV1".charAt(8); // a.a()
        char charAt11 = "85S94kFpV1".charAt(8); // a.a()
        char charAt12 = "rSE6qY".charAt(0); // i.a()
        char charAt13 = "FlEGyL".charAt(3); // c.a()
        char charAt14 = "6HxWkw".charAt(3); // f.a()
        char charAt15 = "6HxWkw".charAt(0); // f.a()
        char charAt16 = "FlEGyL".charAt(0); // c.a()
        SecretKeySpec secretKeySpec = new SecretKeySpec((String.valueOf(charAt) + String.valueOf(charAt2) + String.valueOf(charAt3) + String.valueOf(charAt4) + String.valueOf(charAt5).toLowerCase() + String.valueOf(charAt6) + String.valueOf(charAt7).toLowerCase() + String.valueOf(charAt8) + String.valueOf(charAt9) + String.valueOf(charAt10).toLowerCase() + String.valueOf(charAt11).toLowerCase() + String.valueOf(charAt12) + String.valueOf(charAt13).toLowerCase() + String.valueOf(charAt14) + String.valueOf(charAt15) + String.valueOf(charAt16)).getBytes(), b());
        Cipher cipher = Cipher.getInstance(b());
        cipher.init(2, secretKeySpec);
        return new String(cipher.doFinal(Base64.decode(str, 0)), "utf-8");
    }

В результате получаем следующий код, который можно запустить и получить флаг:

import java.util.ArrayList;
import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
import java.util.Base64;

public class MyClass {
    
    public static String b() {
        char charAt = "wAxcoc".charAt(1);
        char charAt2 = "rSE6qY".charAt(2);
        char charAt3 = "rSE6qY".charAt(1);
        return String.valueOf(charAt) + String.valueOf(charAt2) + String.valueOf(charAt3);
    }

    public static String a(String str) throws Exception {
        char charAt = "kHtZuV".charAt(0); // h.a()
        char charAt2 = "85S94kFpV1".charAt(8); // a.a()
        char charAt3 = "HyeaX9".charAt(5); // e.a()
        char charAt4 = "rSE6qY".charAt(4); // i.a()
        char charAt5 = "kHtZuV".charAt(1); // h.a()
        char charAt6 = "kHtZuV".charAt(4); // h.a()
        char charAt7 = "kHtZuV".charAt(3); // h.a()
        char charAt8 = "kHtZuV".charAt(3); // h.a()
        char charAt9 = "kHtZuV".charAt(0); // h.a()
        char charAt10 = "85S94kFpV1".charAt(8); // a.a()
        char charAt11 = "85S94kFpV1".charAt(8); // a.a()
        char charAt12 = "rSE6qY".charAt(0); // i.a()
        char charAt13 = "FlEGyL".charAt(3); // c.a()
        char charAt14 = "6HxWkw".charAt(3); // f.a()
        char charAt15 = "6HxWkw".charAt(0); // f.a()
        char charAt16 = "FlEGyL".charAt(0); // c.a()
        SecretKeySpec secretKeySpec = new SecretKeySpec((String.valueOf(charAt) + String.valueOf(charAt2) + String.valueOf(charAt3) + String.valueOf(charAt4) + String.valueOf(charAt5).toLowerCase() + String.valueOf(charAt6) + String.valueOf(charAt7).toLowerCase() + String.valueOf(charAt8) + String.valueOf(charAt9) + String.valueOf(charAt10).toLowerCase() + String.valueOf(charAt11).toLowerCase() + String.valueOf(charAt12) + String.valueOf(charAt13).toLowerCase() + String.valueOf(charAt14) + String.valueOf(charAt15) + String.valueOf(charAt16)).getBytes(), b());
        Cipher cipher = Cipher.getInstance(b());
        cipher.init(2, secretKeySpec);
        Base64.Decoder decoder = Base64.getDecoder();
        return new String(cipher.doFinal(decoder.decode(str)), "utf-8");
    }
    
    public static void main(String args[]) throws Exception {
      System.out.println(a("1UlBm2kHtZuVrSE6qY6HxWkwHyeaX92DabnRFlEGyLWod2bkwAxcoc85S94kFpV1"));
    }
}

Флаг

HTB{m***_0**********_w****_n**_h***}