Case study * Aegis Authenticator

Jak działa authenticator
wygenerować kod logowania?

Sześciocyfrowy kod zmienia się co 30 sekund. Użyj REA, aby znaleźć obliczenia w Android APK, a następnie odbudować go z zegarem można kontrolować.

Aegis 3.4.3 * Android * oficjalne wydanie APK * 6.9 MB

Zobacz Aegis na GitHub

Od APK do kodu, który możesz odtworzyć

  1. 01 * Znajdź funkcję3077 klas → metody generowania REA przeszukuje pakiet i śledzi kod używany przez akcje wyświetlania i kopiowania.
  2. 02 * przeczytaj obliczeniaCzas + klucz konta → sześć cyfr REA zwraca metody i wartości domyślne. Agent wyjaśnia, jak do siebie pasują.
  3. 03 * Odbuduj i sprawdźZmień zegar. Uważaj na kod.Nowa wersja demonstracyjna przeglądarki odtwarza regułę i sprawdza ją w publicznych przypadkach referencyjnych.

Zapytaj swojego agenta

Aplikacja pokazuje zmieniający się kod logowania. Chcemy znaleźć co sprawia, że się zmienia i odtworzyć to zachowanie.

Twój agent kodowania

Zbadaj aegis-v3.4.3.apk za pomocą REA. Wyjaśnij, jak powstaje sześciocyfrowy kod logowania i dlaczego zmienia się co 30 sekund. Zbuduj małe demo, w którym mogę zmieniać czas.

Przykładowy monit dla pobranego APK, ze skonfigurowaną analizą Androida REA. Pobierz APK i konfiguracji analizy ↓

Wypróbuj generator kodu

Aplikacja grupuje czas w 30-sekundowe bloki. Łączy numer bloku z kluczem konta, aby wygenerować kod. Ten sam klucz i blok tworzą ten sam kod.

Przesuń zegar na 60 sekund

  1. Czas59 sekundNasz regulowany przykładowy zegar
  2. 30-sekundowy blokBlok 1floor(59 / 30)
    30-59 sekund
  3. Wygenerowany kod287082Klucz konta + blok → sześć cyfr

Po 59 sekundach: 287082. Po 60 sekundach: 359152. Poruszanie się w obrębie jednego bloku pozostawia kod niezmieniony.

Klucz jest stały, publiczny Dane testowe RFC 6238. Demo implementuje obliczenia odzyskane z APK .

Znajdź kod za pomocą REA

  1. Zawęź APK do trzech klas

    Agent → REA
    inspect_android_package
    {"path": "aegis-v3.4.3.apk"}
    
    search_android_classes
    {"path": "aegis-v3.4.3.apk",
     "query": "Totp"}
    REA → agent * wybrane wyniki
    Package: com.beemdevelopment.aegis
    Version: 3.4.3
    Classes: 3,077
    
    Three matches:
      otp.TotpInfo
      ui.views.TotpProgressBar
      importers.TotpAuthenticatorImporter

    TotpInfo jest kandydatem do obliczeń; pozostałe dwa dotyczą paska postępu i zaimportowanych kont. TOTP oznacza hasło jednorazowe oparte na czasie.

  2. Podłącz generator do wyświetlacza aplikacji

    Agent → REA
    inspect_android_class
    {"path": "aegis-v3.4.3.apk",
     "class_name":
      "com.beemdevelopment.aegis.otp.TotpInfo"}
    
    trace_android_references
    {"path": "aegis-v3.4.3.apk",
     "class_name":
      "com.beemdevelopment.aegis.otp.OtpInfo",
     "method_name": "getOtp"}
    REA → agent * metody i rozmówcy
    TotpInfo methods:
      getOtp()      · overload 0
      getOtp(long)  · overload 1
    
    OtpInfo.getOtp callers:
      ui.views.EntryHolder.getOtp
      ui.MainActivity.copyEntryCode

    REA identyfikuje przeciążenie znacznika czasu i znajduje wywołujących metody bazowej. Kontrola EntryHolder.getOtp następnie pokazuje wywołanie wyświetlacza TotpInfo.getOtp(timestamp).

Żądania pokazują skróconą ścieżkę wejściową. Nazwy klas wynikowych pomijają wspólne com.beemdevelopment.aegis prefiks.

Przeczytaj obliczenia

REA zwraca konwersja zegara, ustawienia domyślne i metody generowania. Konstruktorzy ustawiają 30-sekundowy interwał i sześć cyfr; metoda znacznika czasu zamienia sekundy na numer bloku.

REA * wybrana zdekompilowana Java
// TotpInfo defaults and clock
setPeriod(30);
getOtp(System.currentTimeMillis() / 1000);

// OtpInfo default algorithm and digits
this(bArr, "SHA1", 6);

// Block passed to the generator
(long) Math.floor(j / ((double) this._period))

// generateOTP → getHash
byte[] hash = getHash(bArr, str, j);

// getHash: account key + encoded block
Mac mac = Mac.getInstance(str);
mac.init(secretKeySpec);
return mac.doFinal(bArrArray);

// OTP.toString, case 0
this._code % ((int) Math.pow(10.0d, i))

// Keep leading zeroes
while (sb.length() < i) {
    sb.insert(0, "0");
}
Czytelne podsumowanie * interpretacja agenta
// Group time into 30-second blocks
seconds = current_time_ms / 1000
block = floor(seconds / 30)

// Generate a number from the key and block
hash = HMAC_SHA1(account_key,
                 big_endian_8_bytes(block))
number = select_31_bits(hash)

// Format the default six-digit code
code = number % 1_000_000
code = pad_with_zeroes(code, 6)

Czas wybiera blok. Sekundy od 30 do 59 dają blok 1. Po 60 sekundach blok staje się 2.

Kluczowe sprawy też. Generator łączy klucz konta z blokiem. Konto z innym kluczem może wyświetlać jednocześnie inny kod.

Zachowaj sześć cyfr. Reszta po podzieleniu przez 1 000 000 jest uzupełniana zerami w razie potrzeby, więc kod może zaczynać się od 0.

Fragmenty kilku sprawdzonych metod, z zawijaniem linii do wyświetlania. Prawy panel jest podsumowaniem wyjaśniającym. Kod Aegis to GPL-3.0.

Wewnątrz generatora

Wydany APK stawia generateOTP w kotlin.ExceptionsKt. REA podąża za wywołaniem z TotpInfo i zwraca to ciało; oryginalne źródło wywołuje pomocnika HOTP.

REA * generateOTP, kompletne ciało
public static OTP generateOTP(byte[] bArr, String str,
        int i, long j)
        throws NoSuchAlgorithmException, InvalidKeyException {
    byte[] hash = getHash(bArr, str, j);
    int i2 = hash[hash.length - 1] & 15;
    return new OTP(
        (hash[i2 + 3] & 255)
        | ((hash[i2] & 127) << 24)
        | ((hash[i2 + 1] & 255) << 16)
        | ((hash[i2 + 2] & 255) << 8), i, 0);
}

Ostatni bajt skrótu wybiera pozycję. Cztery bajty w tej pozycji zapewniają dodatnią liczbę 31-bitową; formatowanie redukuje ją do żądanej liczby cyfr. Ostatni argument konstruktora wybiera gałąź formatowania kodu wprowadzoną przez kompilację.

Porównaj z pasującym źródłem wydania.

Sprawdź rekonstrukcję

Zebraliśmy wybrane REA-zwrócone metody Java w małym programie testowym. Ich dorobek odpowiadał niezależnej rekonstrukcji na 133 przypadki testowe, w tym granice bloków czasowych i kody zaczynające się od zera.

Przykładowy czas Blok Kod sześciocyfrowy
30 sekund 1 287082
59 sekund 1 287082
60 sekund 2 359152
1,111,111,109 sekund 37,037,036 081804

Generator pasuje również do sześciu opublikowanych przypadków referencyjnych SHA-1 w RFC 6238. Sprawdź implementację przeglądarki przeciwko nim:

Przeczytaj obliczenia demo

Przypadki referencyjne używają ośmiu cyfr. Kontrola weryfikuje również ich sześciocyfrowe wyniki.

Weryfikacja uruchamia wyodrębnione metody Java i nowe demo. Android APK został sprawdzony statycznie.

Sprawdź sam APK

Skonfiguruj REA na macOS lub Linux pobierz te dwa pliki do tego samego folderu. W Windows Użyj środowiska Linux, takiego jak WSL.

Analiza Androida wymaga pełnego JDK 17 lub nowszego. Wybierz go za pomocą JAVA_HOME lub PATH. W tym przypadku zastosowano JDK 21.

Wskaż REA w pliku dostawcy i sprawdź APK :

macOS / Linux
REA_JADX_MCP_JAR="$PWD/jadx-headless-mcp-0.7.1-all.jar" \
npx rea-agents@latest inspect-android-package \
  ./aegis-v3.4.3.apk --format json --full-output

Twój agent może kontynuować przez REA CLI, korzystając z powyższego monitu. Dla MCP, dodać REA_JADX_MCP_JAR do środowiska serwera REA i podłącz go ponownie.

Następne pytanie: co się dzieje, gdy konto używa ośmiu cyfr lub innego przedziału czasu?

Źródła

Sprawdzony za pomocą REA 6.1.0 w dniu 9 października 2026 r. Zdekompilowane fragmenty są przypisywane Aegis ; diagram, czytelne podsumowanie i rekonstrukcja przeglądarki to nowy materiał dydaktyczny.

Top