Powrót do strony głównej

Luka BAC w elektronicznych dziennikach: zostać nauczycielem bez uprawnień

Badanie ujawniło krytyczną lukę Broken Access Control w szkolnych elektronicznych dziennikach. Luka pozwala uzyskać dostęp do funkcji nauczyciela poprzez zmianę lokalnych parametrów. Odpowiedzialne struktury ignorują problem, mimo ryzyka wycieku danych milionów uczniów.

Jak uzyskać uprawnienia nauczyciela w szkolnym dzienniku przez lukę BAC?
Advertisement 728x90

# Krytyczna luka BAC w elektronicznych dziennikach szkolnych: jak stać się nauczycielem bez uprawnień

W trakcie reverse engineeringu popularnego elektronicznego dziennika szkolnego odkryto krytyczną lukę Broken Access Control (BAC), która pozwala każdemu użytkownikowi uzyskać pełny dostęp do funkcji nauczyciela. Analiza kodu aplikacji wykazała brak weryfikacji uprawnień po stronie serwera oraz przechowywanie kluczy sekretnych w formie jawnej.

Reverse engineering ujawnił słabe punkty

Badanie rozpoczęto od analizy pliku APK aplikacji za pomocą dekompilatora JADX. Pierwsze odkrycia okazały się niepokojące:

  • Debugowe ciasteczka w logach: Sesyjne ciasteczka X1_SSO były wypisywane w logcat bez szyfrowania, co umożliwiało ich przechwycenie.
  • Własnoręczne szyfrowanie: Zamiast deklarowanego AES używano prostego XOR z zahardkodowanym kluczem — nazwą pakietu aplikacji (ru.vendor.schoolapp).
  • Uniwersalna nakładka: W przypadku braku klucza urządzenia aplikacja stosowała stały identyfikator 000xpda.

Te luki już pozwalały na automatyzację dostępu do danych osobowych ucznia. Jednak dalsza analiza API ujawniła poważniejszy problem: brak weryfikacji uprawnień po stronie serwera. Podmiana guid użytkownika w zapytaniu bez tokena X1_SSO dawała dostęp do danych dowolnego ucznia.

Google AdInline article slot

Godne uwagi jest, że identyczne luki znaleziono w aplikacjach używanych co najmniej w trzech rosyjskich regionach, co zagraża danym setek tysięcy uczniów.

Odpowiedzialne ujawnienie: ignorowanie zagrożenia

Autor próbował powiadomić odpowiedzialne organy w ramach procedury Responsible Disclosure. Zwrócenie się do Ministerstwa Cyfryzacji zostało przekierowane do struktur regionalnych, a konkretnie do RCIT (Regionalne Centrum Informatyzacji), wskazanego jako deweloper.

RCIT zareagowało obietnicą „usunięcia uwag", ale rzeczywiste zmiany okazały się kosmetyczne:

Google AdInline article slot
  • Usunięto szyfrowanie XOR, które łatwo było wykryć.
  • Zastąpiono je AES, ale klucze pozostawiono w kodzie aplikacji.

Przykład z klasy Crypt.java:

package ru.vendor.schoolapp2.common;

import android.util.Base64;
import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;

/* JADX INFO: loaded from: classes2.dex */
public class Crypt {
    public static String alt_api_key = "gqhy671nmn3478fhsdjf4f09f45sf4fg4lf842d1";
    private static Cipher cipher = null;
    public static String encryptedTOKEN = "";
    private static SecretKeySpec key = null;
    public static String session_apikey = "0xt25240s9s12xv767v1ll17757e32e34x12ppix332vdi2i";
    private static String transformation = "AES/ECB/PKCS5Padding";

    private static byte[] encrypt(SecretKeySpec secretKeySpec, byte[] bArr) {
        try {
            Cipher cipher2 = Cipher.getInstance(transformation);
            cipher = cipher2;
            cipher2.init(1, secretKeySpec);
            return cipher.doFinal(bArr);
        } catch (Exception unused) {
            return null;
        }
    }

    private static byte[] decrypt(SecretKeySpec secretKeySpec, byte[] bArr) {
        try {
            Cipher cipher2 = Cipher.getInstance(transformation);
            cipher = cipher2;
            cipher2.init(2, secretKeySpec);
            return cipher.doFinal(bArr);
        } catch (Exception unused) {
            return null;
        }
    }

    public static String encryptString(String str) {
        return Base64.encodeToString(encrypt(key, str.getBytes()), 2);
    }

    public static String decryptString(String str) {
        byte[] bArrDecrypt = decrypt(key, Base64.decode(str, 2));
        if (bArrDecrypt != null) {
            return new String(bArrDecrypt);
        }
        return "";
    }

    public static void initKey() {
        key = createSecretKey();
    }

    private static SecretKeySpec createSecretKey() {
        return new SecretKeySpec(new byte[]{10, 20, 30, 40, 50, 23, 19, 31, 0, 0, 0, 0, 0, 0, 0, 0}, 0, 16, "AES");
    }
}

Ponowne zwrócenie się przez Roskomnadzor również nie doprowadziło do naprawy luk w innych regionach. System nadal polegał na weryfikacji ról po stronie klienta, co czyniło lukę BAC krytyczną.

Broken Access Control: jak stać się nauczycielem w minutę

Kluczowa luka polegała na tym, że aplikacja przechowywała dane sesji w pliku shared_prefs w formie jawnej. Dwa parametry określały dostęp:

Google AdInline article slot
  • user_sys_guid — identyfikator użytkownika.
  • rolename — ciąg z rolą („Uczeń" lub „Nauczyciel").

Eksperyment przeprowadzono na Waydroid (konteneryzowany Android) z rootem:

  • Logowanie na konto ucznia.
  • Edycja pliku /data/data/ru.vendor.schoolapp/shared_prefs/:

* Zamiana rolename na „Nauczyciel".

* Podstawienie user_sys_guid nauczyciela (uzyskanego wcześniej przez API).

  • Restart aplikacji.

Wynik: interfejs natychmiast przełączył się w tryb nauczyciela z pełnym dostępem do dziennika, w tym przyciskami „ZAPISZ” i „DODAJ KOLUMNĘ”. Serwer nie weryfikował roli użytkownika, w pełni ufając danym wysłanym przez klienta.

To klasyczny przykład Broken Access Control (BAC), gdy serwer nie waliduje praw dostępu przy każdym zapytaniu.

Podsumowanie: bezpieczeństwo jako pozory

Badanie wykazało systemowe problemy w rozwoju państwowych rozwiązań IT:

  • Brak podstawowego bezpieczeństwa: Przechowywanie kluczy w kodzie i ignorowanie weryfikacji praw — fatalne błędy.
  • Kosmetyczne poprawki: Zamiana XOR na AES bez refaktoryzacji architektury nie rozwiązuje problemu.
  • Skala zagrożenia: Luki dotyczą kilku regionów, pod zagrożeniem dane milionów uczniów.

Takie luki otwierają drogę do masowego nieautoryzowanego dostępu, w tym zmiany ocen i danych osobowych. Odpowiedzialne struktury nadal ignorują zagrożenie, mimo dowodów.

Co ważne

  • Luka BAC pozwala każdemu użytkownikowi stać się nauczycielem, zmieniając zaledwie dwa parametry w lokalnym pliku.
  • Sekretne klucze API i szyfrowania są sztywno wpisane w kod aplikacji, co czyni je dostępnymi po dekompilacji.
  • Odpowiedzialne organy ograniczają się do kosmetycznych poprawek, nie usuwając przyczyn źródłowych.
  • Problem dotyczy kilku regionów, co wskazuje na szablonowe podejście do rozwoju bez uwzględnienia bezpieczeństwa.

— Editorial Team

Advertisement 728x90

Czytaj dalej