---
title: 'mBank 3.122.4 — niezależny audyt bezpieczeństwa (analiza statyczna i dynamiczna)'
url: 'https://www.kvc.pl/analizy-techniczne-pl/mbank-audyt-bezpieczenstwa'
markdown: 'https://www.kvc.pl/analizy-techniczne-pl/mbank-audyt-bezpieczenstwa.md'
date: '2026-10-14'
description: 'Niezależna analiza statyczna i dynamiczna produkcyjnego pakietu APK mBank 3.122.4 (pl.mbank) w środowisku WSA z MagiskSU. Weryfikacja TrustKit, 21 domen z przypiętymi certyfikatami, FaceTec, eksportowanych komponentów, BlikC HCE, baz SQLite, telemetrii oraz powiązanej aplikacji maklerskiej eMakler giełda (pl.mbank.bmmobile 6.7.4, .NET MAUI). Wyniki rozdzielają fakty statyczne, potwierdzenia wykonaniowe oraz weryfikację hipotez bezpieczeństwa.'
---

# mBank 3.122.4 — niezależny audyt bezpieczeństwa (analiza statyczna i dynamiczna)

**Autor:** Marek Wesołowski (WESMAR) · [github.com/wesmar](https://github.com/wesmar) · [kvc.pl](https://kvc.pl)

> **Aktualizacja, 14 października 2026 r.:** mBank odpowiedział na reklamację po 19 dniach kalendarzowych, w ustawowym limicie 15 dni roboczych. Potwierdził blokadę bezpieczeństwa i brak bieżących ograniczeń, lecz nie wyjaśnił wymogu dwóch skanów antywirusowych ani nie rozstrzygnął jasno wszystkich zastrzeżeń. [Analiza odpowiedzi, podstaw prawnych i dalszych kroków](#odpowiedz-mbanku-2026-10-14).
> 
> **W skrócie.** Artykuł przedstawia wyniki niezależnego audytu bezpieczeństwa aplikacji mBank 3.122.4, pakiet `pl.mbank`, versionCode 99201. Zakres prac objął analizę statyczną manifestu, konfiguracji bezpieczeństwa sieci TrustKit obejmującej 21 domen i 78 skrótów SPKI SHA-256, eksportowanych komponentów w liczbie 6 aktywności, 4 usług, 3 odbiorników oraz 1 dostawcy treści, uprawnień i bibliotek natywnych. Analizę dynamiczną zrealizowano w środowisku WSA 2407 z aktywnym MagiskSU oraz proxy rejestrującym BurpSuite. Aplikacja pozostaje zalogowana w trybie obserwacyjnym. Żadna operacja finansowa nie była wykonywana.

 **Status z 22 września 2026 r.** Środowisko WSA: `127.0.0.1:58526`, Android 13, API 33, architektura x86_64, aktywny MagiskSU. Wersja produkcyjna `pl.mbank 3.122.4` pomyślnie aktywowana i zalogowana w widoku `MainActivity`. Dekompilacja JADX zakończona: 44 677 plików Java. Działanie flagi `FLAG_SECURE` potwierdzone wykonaniowo: zrzut klatki zablokowany, rozmiar pliku wyjściowego 0 B. Analiza statyczna modułu tożsamości SAM, mechanizmów anty-root, baz danych SQLite oraz komponentu `EMaklerProvider` została zakończona. Przygotowano zestaw skryptów Frida do kontrolowanych testów dynamicznych. 

Werdykt końcowy: ocena 8,1/10 — bardzo dobra z minusem

Prawidłowo wdrożone mechanizmy bezpieczeństwa obejmują reguły `allowBackup=false`, `usesCleartextTraffic=false`, dyrektywę bazową `cleartextTrafficPermitted=false`, bibliotekę TrustKit z parametrem `enforcePinning=true` dla 21 domen oraz usługę BlikC HCE zabezpieczoną dedykowanym uprawnieniem NFC. Warstwa tokenizacji płatności zawiera aktywny moduł RASP uPaid MDC z dynamicznym ładowaniem XOR, weryfikacją sum kontrolnych DEX oraz kontrolą integralności obfuskacji R8. Nowoczesne tokeny sesyjne spoczywają w magazynie CryptoPreferences zabezpieczonym sprzętowym kluczem TEE Android Keystore. Zidentyfikowane uchybienia i obszary ryzyka obejmują uprawnienia `QUERY_ALL_PACKAGES` oraz `READ_PHONE_STATE`, rozbudowane żądania lokalizacyjne, dług technologiczny w postaci archiwalnego magazynu mBank.xml ze stałym kluczem zastępczym, zewnętrzny moduł biometrii FaceTec oraz wyeksportowaną aktywność `BiometricSettingsDeeplinkActivity` bez deklaracji uprawnień. Ogólny poziom bezpieczeństwa przewyższa aplikację eDO App w wymiarze transportu sieciowego i ochrony RASP modułu płatności. Końcowy minus wynika z obecności otwartego kodu brokera eMakler oraz nadwrażliwości heurystyk antyfraudowych. 

Ocena ważona architektury bezpieczeństwa

| Oś oceny | Waga | Ocena | Uzasadnienie inżynierskie |
|---|---|---|---|
| Dane w spoczynku | 25% | **7,0/10** | Koegzystencja dwóch architektur: nowoczesny magazyn CryptoPreferences chroniony sprzętowym kluczem TEE w Android Keystore oraz brak danych kartowych i sald w pamięci trwałej. Ocenę obniża archiwalny magazyn mBank.xml ze stałym kluczem AES (MBA-A-08) i starszym KDF (MBA-A-06). |
| Transport i pinning | 20% | **9,5/10** | Rygorystyczna konfiguracja TrustKit z wymuszeniem enforcePinning na 21 domenach, 78 skrótów SPKI SHA-256, bezwzględne zablokowanie ruchu jawnego HTTP. |
| Ochrona przed modyfikacją (RASP) | 15% | **8,5/10** | Warstwa RASP uPaid MDC w module płatności BLIK: dynamiczny loader XOR (pl.mbank.mcore.xe3.b), 32 natywne metody JNI w libnative-library.so, weryfikacja obfuskacji R8 i sum kontrolnych DEX, natychmiastowy reset sesji portfela po wykryciu anomalii. |
| Komponenty i IPC | 15% | **8,0/10** | Odsyłacze nieeksportowane, kluczowe formularze renderowane natywnie. Odnotowano uchybienie MBA-A-07 w komponencie EMaklerProvider oraz lukę konfiguracji WebApps. |
| Biometria i sprzęt TEE | 15% | **9,0/10** | Sprzętowa izolacja kluczy tokenizacji HCE BLIK oraz biometrii w TEE Keystore z limitem autoryzacji 60 sekund. |
| Prywatność i scoring | 10% | **6,0/10** | Zgoda na QUERY\_ALL\_PACKAGES, odczyt stanu połączeń głosowych oraz nadwrażliwość heurystyk antyfraudowych blokująca bezpieczne sesje stacjonarne na WSA. |
| **Średnia ważona** | **100%** | **8,1/10** | **Ocena końcowa: 8,1/10 — bardzo dobra z minusem (bardzo dobry z minusem)** |

**Wynik ważony: 8,1/10 — ocena bardzo dobra z minusem.** Architektura sieciowa, integracja ze sprzętowym modułem TEE oraz dedykowany silnik RASP uPaid MDC reprezentują wysoki standard inżynierski. Zidentyfikowane uchybienia dotyczą długu technologicznego w postaci archiwalnego magazynu mBank.xml opisanego w ustaleniach MBA-A-08 i MBA-A-06, otwartego kodu modułu maklerskiego eMakler oraz nadwrażliwości heurystyk antyfraudowych.

---

## 1. Zakres badania i granice wniosków

Badanie przeprowadzono na kontrolowanej instalacji testowej w środowisku WSA z wykorzystaniem dedykowanego rachunku bankowego. Celem prac jest niezależna ocena architektury bezpieczeństwa klienta mobilnego. W analizie wyodrębniono trzy kategorie ustaleń:

1. **Dowód statyczny:** fakty wynikające bezpośrednio ze zdekodowanego manifestu, zasobów oraz kodu bajtowego DEX.
2. **Dowód wykonaniowy:** fakty zarejestrowane w logach systemowych logcat, sesji ADB oraz analizie ruchu TLS w proxy BurpSuite.
3. **Hipoteza audytowa:** wektor wymagający weryfikacji w kontrolowanych warunkach testowych.

Zasada integralności środowiska: wszelkie czynności prowadzono w reżimie pasywnym bez inicjowania operacji finansowych, takich jak przelewy, modyfikacja limitów transakcyjnych czy zmiana danych profilowych. Zakres badania obejmuje monitorowanie zachowania zalogowanej aplikacji, rejestrację pakietów sieciowych oraz analizę reakcji na spreparowane obiekty Intent.

## 2. Materiał i powtarzalność

| Element | Wartość |
|---|---|
| Pakiet | `pl.mbank` |
| Wersja | `3.122.4` |
| VersionCode | `99201` |
| minSdk / targetSdk | `29` / `35` |
| Stos technologiczny | Kotlin, Java w środowisku uruchomieniowym Android Runtime |
| Plik APK `base.apk` | 123 489 608 B (~118 MiB) |
| SHA-256 `base.apk` | `447B0EDFD998E5F3C54B3D40721C2059CA4C4CD4392D0DED0A427AE54AC85782` |
| Źródło pochodzenia | Sklep Google Play, pobranie poleceniem `adb pull` ze środowiska WSA |
| Data instalacji | 2026-09-22 23:10:39 |

## 3. Środowisko testowe

| Warstwa | Stan środowiska |
|---|---|
| Podsystem WSA | Wersja `2407.40000.4.0`, Android 13, API 33, architektura x86\_64 |
| Połączenie ADB | `127.0.0.1:58526` |
| Uprawnienia root | MagiskSU aktywny |
| Poziom SELinux | `Enforcing` |
| Proxy rejestrujące | BurpSuite z certyfikatem badawczym |
| Framework Frida | Skrypty przygotowane do testów kontrolowanych |
| Status mBank | Aktywna sesja w wersji produkcyjnej |

## 4. Identyfikacja i weryfikacja artefaktu

Dane identyfikacyjne pakietu uzyskane z polecenia `dumpsys package pl.mbank` w podsystemie WSA:

```text
userId    = 10088
codePath  = /data/app/~~2Scj4FO7bWZRi2PMCLv43w==/pl.mbank-ohHMJGPG8zUqbNgM7AkRBw==
versionCode=99201 minSdk=29 targetSdk=35
versionName=3.122.4
pkgFlags  = [ HAS_CODE ALLOW_CLEAR_USER_DATA LARGE_HEAP ]
firstInstallTime=2026-09-22 23:10:39
```

Certyfikat podpisujący podlega weryfikacji po pełnej dekompilacji JADX poprzez zestawienie z odciskiem publikowanym przez domenę `mbank.pl`.

---

## 5. Analiza manifestu aplikacji

### 5.1. Główne flagi konfiguracyjne

| Właściwość | Wartość | Ocena techniczna |
|---|---|---|
| `android:allowBackup` | `false` | Kopia zapasowa wyłączona |
| `android:usesCleartextTraffic` | `false` | Transmisja jawnym tekstem zablokowana |
| `android:debuggable` | domyślnie false z braku deklaracji | Tryb debugowania wyłączony |
| `android:networkSecurityConfig` | `@xml/network_security_config` | Dedykowana konfiguracja bezpieczeństwa sieci |
| `android:requestLegacyExternalStorage` | `true` | Zezwolenie na tradycyjny model dostępu do pamięci masowej |
| `android:largeHeap` | `true` | Alokacja powiększonej sterty pamięci |
| `android:fullBackupContent` | `@xml/synerise_backup_rules` | Selektywne reguły kopii zapasowej Synerise |

**MBA-O-01: Obecność flagi requestLegacyExternalStorage=true.** Flaga wymusza tradycyjny model dostępu do pamięci masowej z pominięciem mechanizmu Scoped Storage. Na urządzeniach z poziomem API 29, odpowiadającym wartości minSdk aplikacji, umożliwia to odczyt i zapis w katalogach ogólnodostępnych. Tworzy to potencjalne ryzyko zapisu danych aplikacji w lokalizacjach dostępnych dla innych procesów. Zakres reguł wykluczeń zdefiniowany w `synerise_backup_rules.xml` podlega szczegółowej weryfikacji.

### 5.2. Analiza eksportowanych komponentów

#### Aktywności eksportowane

| Komponent | Zabezpieczenie | Uwagi architektoniczne |
|---|---|---|
| `pl.mbank.core.activity.StartActivity` | brak deklaracji permission | Punkt wejścia aplikacji przyjmujący zewnętrzne obiekty Intent |
| `pl.mbank.feature.androidpay.view.activity.AndroidPayTokenVerificationActivity` | `readPermission` oraz `writePermission = pl.mbank.permission.ROUTE_INTERNAL` | Dostęp ograniczony uprawnieniem wewnętrznym |
| `pl.mbank.feature.androidpay.view.activity.AndroidPayPushTokenizeActivity` | `pl.mbank.permission.ROUTE_INTERNAL` | Dostęp ograniczony uprawnieniem wewnętrznym |
| `pl.mbank.pinpad.biometry.ui.view.BiometricSettingsDeeplinkActivity` | **brak deklaracji permission** | Aktywność wyeksportowana bez ochrony uprawnieniem |
| `pl.mbank.feature.notification.view.NotificationsActivity` | `pl.mbank.permission.ROUTE_INTERNAL` | Dostęp ograniczony uprawnieniem wewnętrznym |
| `pl.mbank.EMaklerActivity` | `pl.mbank.eMaklerProviderPermission` | Alias aktywności. Dostęp ograniczony uprawnieniem dostawcy maklerskiego |

**MBA-A-01: Wyeksportowanie BiometricSettingsDeeplinkActivity bez deklaracji uprawnień.** Aktywność `pl.mbank.pinpad.biometry.ui.view.BiometricSettingsDeeplinkActivity` oznaczono atrybutem `exported="true"` bez wymogu posiadania uprawnienia `android:permission`. Pozwala to dowolnej aplikacji w systemie na przesłanie jawnego obiektu Intent. Analiza statyczna metody `onCreate()` wykazała, że aktywność realizuje wstrzyknięcie komponentu DI i wykonuje przekierowanie do klasy `LegacyBiometricSettingsActivity`, po czym kończy własne działanie. W implementacji wykluczono odczyt parametrów ze strumienia wejściowego, co potwierdza brak wywołań `getIntent()` oraz `getData()`. Eliminuje to wektor wstrzyknięcia parametrów do sesji. Aplikacja zewnętrzna może wywołać jedynie przejście do wewnętrznego ekranu konfiguracji biometrii, który egzekwuje własną kontrolę sesji. Test dynamiczny w środowisku WSA potwierdził to zachowanie: polecenie `am start` skierowane do omawianej aktywności otworzyło `LegacyBiometricSettingsActivity` w kontekście trwającej sesji bez transferu nieautoryzowanych danych.

#### Usługi eksportowane

| Komponent | Zabezpieczenie | Rola komponentu |
|---|---|---|
| `pl.mbank.core.authenticator.NmbAuthenticationService` | `ROUTE_INTERNAL` | Moduł integracji z Android AccountManager |
| `pl.mbank.feature.blikc.service.BlikCHceService` | `android.permission.BIND_NFC_SERVICE` | Obsługa transakcji zbliżeniowych BLIK Contactless w standardzie HCE |
| `com.google.android.gms.auth.api.signin.RevocationBoundService` | Uprawnienie systemowe GMS | Usługa odwoływania sesji Google Sign-In |
| `androidx.work.impl.background.systemjob.SystemJobService` | `BIND_JOB_SERVICE` | Harmonogram zadań biblioteki WorkManager |

Usługę `BlikCHceService` zabezpieczono uprawnieniem `android.permission.BIND_NFC_SERVICE`, co stanowi poprawną implementację standardu emulacji kart hosta Host Card Emulation w systemie Android.

#### Dostawcy treści

| Komponent | Zabezpieczenie |
|---|---|
| `pl.mbank.EMaklerProvider` | `readPermission` oraz `writePermission = pl.mbank.eMaklerProviderPermission` |

Dostęp do dostawcy treści ograniczono dedykowanym uprawnieniem aplikacyjnym.

---

## 6. Konfiguracja bezpieczeństwa sieci: TrustKit oraz Network Security Config

### 6.1. Konfiguracja bazowa Network Security Config

```xml
<base-config cleartextTrafficPermitted="false">
    <trust-anchors>
        <certificates src="system" />
    </trust-anchors>
</base-config>
```

**Ocena techniczna:** Konfiguracja poprawna. Globalna transmisja jawnym tekstem została zablokowana. Magazyn kotwic zaufania ograniczono wyłącznie do certyfikatów systemowych. W konsekwencji instalacja certyfikatu inspekcyjnego BurpSuite w magazynie użytkownika nie pozwala na przechwycenie ruchu TLS bez uprzedniego przełamania mechanizmu przypinania certyfikatów.

### 6.2. Wdrożenie biblioteki TrustKit i przypinanie certyfikatów

Aplikacja wykorzystuje bibliotekę **TrustKit-Android** firmy Data Theorem jako dedykowaną warstwę weryfikacji certyfikatów nadbudowaną nad standardowym plikiem konfiguracji sieci. Każda domena posiada:

- regułę `cleartextTrafficPermitted="false"`;
- sekcję `<pin-set>` zawierającą od 4 do 5 skrótów SPKI SHA-256 zapewniających redundancję awaryjną;
- dyrektywę `<trustkit-config enforcePinning="true"/>`.

| Zasięg konfiguracji | Wartość |
|---|---|
| Liczba zdefiniowanych domen | **21** |
| Łączna liczba przypiętych skrótów SPKI SHA-256 | **78** |
| Domeny z zezwoleniem na nieszyfrowany ruch HTTP | 0 |
| Egzekwowanie reguły enforcePinning | **100% domen** |
| Obecność sekcji debug-overrides | **brak** |

**Objęte domeny:** `m.mbank.pl`, `m.mbank.cz`, `m.mbank.sk`, `online.mbank.pl`, `online.mbank.cz`, `online.mbank.sk`, `www.mbank.pl`, `www.mbank.cz`, `www.mbank.sk`, `csp.mbank.pl`, `skp.mbank.pl`, `eo.eombank.pl`, `form.mbank.pl/cz/sk`, `ecommerce.cdn-az.mbank.pl`, `podpis.mbank.pl`, `mojeid.mbank.pl`.

**Weryfikacja statyczna.** Konfiguracja biblioteki TrustKit została wdrożona rygorystycznie. Wyłączono ruch otwarty, pominięto sekcję `debug-overrides`, wykluczono certyfikaty użytkownika oraz wymuszono regułę `enforcePinning="true"` dla wszystkich domen. Implementacja spełnia wymagania bezpiecznego przypinania kluczy publicznych w standardzie HPKP i SPKI. Weryfikacja odporności w warunkach dynamicznych wymaga kontrolowanego testu proxy z certyfikatem badawczym po załadowaniu skryptu neutralizującego TrustKit we frameworku Frida.

### 6.3. Wektory obejścia mechanizmu pinningu

| Hipoteza badawcza | Status weryfikacji |
|---|---|
| Obejście TrustKit przez przechwycenie metody PinningTrustManager.checkServerTrusted() | Hipoteza P0: przygotowano skrypt `03_trustkit_bypass.js` |
| Obejście przez modyfikację fabryki SSLContext w maszynie JVM | Hipoteza P0: skrypt `01_ssl_pinning_bypass.js` |
| Obejście natywne przez hook na symbol SSL\_verify\_peer\_certificate w libssl.so | Hipoteza P0: implementacja w skrypcie 03 |
| Transmisja nieszyfrowana do domen zewnętrznych poza regułami NSC | Weryfikacja w toku analizy dziennika logcat |

---

## 7. Analiza uprawnień aplikacji

### 7.1. Uprawnienia o podwyższonym poziomie ryzyka

| Uprawnienie | Uzasadnienie techniczne i wektory ryzyka |
|---|---|
| `ACCESS_FINE_LOCATION`, `ACCESS_COARSE_LOCATION` | Odczyt precyzyjnych i przybliżonych współrzędnych geograficznych: moduł lokalizacji placówek lub telemetria kontekstowa |
| `READ_PHONE_STATE` | Odczyt parametrów sieci komórkowej oraz próba dostępu do numerów IMEI i IMSI: profilowanie urządzenia |
| `QUERY_ALL_PACKAGES` | Pełna enumeracja zainstalowanych pakietów oprogramowania: detekcja narzędzi modyfikujących system |
| `WRITE_EXTERNAL_STORAGE`, `READ_EXTERNAL_STORAGE` | Dostęp do współdzielonej pamięci urządzenia: zapis pobieranych dokumentów i potwierdzeń |
| `GET_ACCOUNTS`, `MANAGE_ACCOUNTS` | Dostęp do kont systemowych: zaszłość wsteczna zbędna od wersji Android 8.0, poziom API 26 |
| `SMARTCARD`, `org.simalliance.openmobileapi.SMARTCARD` | Bezpośrednia komunikacja z kartą SIM oraz modułem Secure Element: obsługa usługi BlikC HCE |
| `com.google.android.gms.permission.AD_ID` | Odczyt identyfikatora reklamowego na potrzeby analityki zachowań w modułach Synerise i Firebase |
| `ACCESS_ADSERVICES_ATTRIBUTION` | Integracja z interfejsem Attribution API w celach telemetrycznych |

**MBA-O-02: Połączenie uprawnień QUERY\_ALL\_PACKAGES oraz READ\_PHONE\_STATE.** Zestawienie tych przywilejów umożliwia tworzenie szczegółowego profilu środowiska wykonawczego: odczyt parametrów identyfikacyjnych urządzenia oraz pełnej listy zainstalowanego oprogramowania. Zestaw ten typowo wspiera algorytmy oceny ryzyka nadużyć w modułach anti-fraud, lecz w wymiarze ochrony prywatności oznacza głębokie profilowanie stacji klienta. Rzeczywisty zakres danych telemetrycznych wysyłanych do infrastruktury bankowej podlega weryfikacji w analizie pakietów TLS.

---

## 8. Biblioteki i komponenty zewnętrzne

### 8.1. Zestawienie komponentów i bibliotek natywnych

| Komponent | Obsługiwane ABI | Rola architektoniczna | Uwagi techniczne |
|---|---|---|---|
| **`libnativeSeclib.so`** | arm64, armv7, x86, **x86\_64** | Natywny moduł bezpieczeństwa aplikacji | Eksportuje pojedynczy symbol JNI: `Java_pl_mbank_nativelib_SecLib_initialize`. Zwarta powierzchnia ataku. |
| **`libPhoenixAndroid.so`** | arm64, armv7 | Moduł biometrii FaceTec 3D Liveness, biblioteki Botan i OpenCV | Brak kompilacji dla architektury x86/x86\_64; komponent nieaktywny w środowisku WSA. |
| **`libbeda.so`**, **`libc5ba.so`** | arm64, armv7, x86, x86\_64 | Niskopoziomowy moduł antytamper RASP | Silnie zaciemnione biblioteki o rozmiarze od 899 KB do 1,20 MB z bezpośrednimi wywołaniami systemowymi jądra Linux: `mprotect`, `syscall`, `_exit`, `fork`. |
| **`libnative-library.so`** | arm64, armv7, x86, x86\_64 | Główny silnik RASP i kryptografii uPaid MDC | Rozmiar od 1,29 MB do 2,02 MB. Dynamiczna rejestracja 32 metod natywnych w klasie `o.h` przez `JNI_OnLoad` oraz sprzężenie ze zdarzeniami unieważniania sesji. |
| **Firebase** | nd. | Powiadomienia push Cloud Messaging oraz telemetria zdarzeń | Transmisja danych analitycznych do infrastruktury Google. |
| **Synerise** | nd. | Automatyzacja komunikacji i analityka behawioralna | Dedykowane reguły kopii w pliku `synerise_backup_rules.xml`. |
| **Picasso** | nd. | Asynchroniczne ładowanie obrazów przez PicassoProvider | Standardowa biblioteka pomocnicza; brak bezpośrednich ryzyk bezpieczeństwa. |
| **Room** | nd. | Lokalna warstwa dostępu do bazy SQLite | Koordynacja unieważniania instancji przez MultiInstanceInvalidationService. |

### 8.2. Weryfikacja pakietów blokowanych w security-packages-list.json

Plik `assets/security-packages-list.json` o rozmiarze 65 KB zawiera bazę 643 wpisów służących do identyfikacji niebezpiecznego oprogramowania. Identyfikatory zapisano w postaci skrótów SHA-256:

```json
{
  "Timestamp": "66B85AB21E7D848FD89A5D01C17F6AAC",
  "Applications": [
    { "PackageName": "fc04fdeee345485421a5e1df4b7fded2bdc062666f48d1993dbda84f4a8b3963" },
    { "PackageName": "6733e8b20b34cb5fe82c976a5a7c1b5161afc185f2d20dcdea17d06d048a3d8d" },
    ...
  ]
}
```

Analiza dekompilatu klasy `pl.mbank.feature.securitycheck.dangerousapps.blacklist.SecurityRepository` ujawniła algorytm wyliczania i weryfikacji skrótów:

```java
// SecurityRepository.e(): wyliczenie skrótu SHA-256 z nazwy pakietu
for (ApplicationInfo applicationInfo : installedApplications) {
    String hashCode = Hashing.sha256()
        .hashString(applicationInfo.packageName, StandardCharsets.UTF_8)
        .toString();
    if (hashSet.contains(hashCode)) {
        a.a(null, c.a(arrayList), "[ThreatFound] Unsafe app: " + applicationInfo.packageName);
        arrayList.add(new a(hashCode, null, 2, null));
    }
}
```

Skrót stanowi standardowy ciąg szesnastkowy SHA-256 wyliczony bezpośrednio z tekstowej nazwy pakietu `applicationInfo.packageName` w kodowaniu UTF-8. Skrót pomija strukturę binarną pliku APK, certyfikaty oraz kod DEX.

Analiza dopasowań ujawniła obecność popularnych narzędzi zdalnego zarządzania pulpitowego, powszechnie wykorzystywanych przez grupy przestępcze w atakach vishingowych:

| Zidentyfikowany pakiet | Rola oprogramowania | Skrót SHA-256 w security-packages-list.json | Pozycja w pliku |
|---|---|---|---|
| `com.anydesk.anydeskandroid` | AnyDesk Remote Desktop | `1add8f698faa3f372aea8197004c5b165571dcd0877aec2d4873ac3ed62d4fa7` | linia 857 |
| `com.teamviewer.host.market` | TeamViewer Host | `800c18bdfa241ffdf3863af45bc3a4127d678cf9d3a6ea5382fadce82a30137f` | linia 647 |
| `com.teamviewer.quicksupport.market` | TeamViewer QuickSupport | `1b741cd155b568184d28c557f43bdf7ee773bd69d1a1a82e27eca2eaadaacb7b` | linia 1058 |
| `com.teamviewer.teamviewer.market.mobile` | TeamViewer Remote Control | `9d15f9f0e7aa13b9b1e581ae5bc08f401b7181bbe3a01f15f0a10eb2dc7b50e9` | linia 383 |

Pakiet `com.topjohnwu.magisk` (skrót `1d61da52...`) pozostaje poza omawianym zbiorem. Detekcja narzędzi uprawnień roota odbywa się niezależnie za pośrednictwem modułów `xr2` oraz biblioteki natywnej `libnativeSeclib`.

**Dynamiczna synchronizacja i telemetria zwrotna:**
Lista wykazuje pełną synchronizację dwukierunkową ze środowiskiem serwerowym:

1. **Pobieranie aktualizacji:** Metoda `SecurityRepository.g()` wykonuje zapytanie sieciowe `this.a.C4(timestamp)`, przesyłając znacznik czasu bieżącego zbioru. Serwer zwraca skompresowany strumień danych, który po dekodowaniu Base64 i dekompresji GZIP zapisywany jest w magazynie preferencji pod kluczem `security_threats_list`.
2. **Telemetria zagrożeń:** W przypadku wykrycia zainstalowanego pakietu z czarnej listy metoda `SecurityRepository.l()` przesyła wykaz zidentyfikowanych zagrożeń bezpośrednio do serwera bankowego wywołaniem `this.a.J3(arrayList)`.
3. **Detekcja podszywania pod markę banku:** Metoda `SecurityRepository.e()` weryfikuje etykietę każdej zainstalowanej aplikacji (`getApplicationLabel`). Funkcja `i0.a0(label, "mbank", true)` sprawdza obecność frazy `mbank`. W przypadku braku obecności pakietu na liście zaufanych następuje rejestracja zdarzenia `[ThreatFound] Suspicious app: <etykieta>, <pakiet>`, co stanowi zabezpieczenie przed fałszywymi klonami aplikacji.

**MBA-O-04: Dynamicznie aktualizowana czarna lista narzędzi zdalnego dostępu i złośliwego oprogramowania.** Zbiór 643 skrótów SHA-256 w `security-packages-list.json` ukierunkowany jest na identyfikację narzędzi zdalnego pulpitu (AnyDesk, TeamViewer) oraz trojanów bankowych. Mechanizm łączy lokalną bazę z pobieraniem aktualizacji z serwera mBanku oraz automatycznym raportowaniem wykrytych pakietów do infrastruktury backendowej.

### 8.3. Moduł biometryczny FaceTec w bibliotece libPhoenixAndroid.so

Analiza ciągów tekstowych w bibliotece `libPhoenixAndroid.so` dla architektury arm64 o rozmiarze 3,47 MB wykazała obecność następujących komponentów:

- Symbole interfejsu JNI FaceTec: `Java_com_facetec_passportreaderapp_PassportReaderActivity_registerPassportReader`, `Java_com_facetec_sdk_JNI_rnm/fnm` realizujące weryfikację biometrii twarzy oraz dokumentów tożsamości.
- Biblioteka kryptograficzna Botan: klasa `N5Botan25Integer_Overflow_DetectedE` wbudowana w moduł FaceTec.
- Biblioteka widzenia komputerowego OpenCV: symbole `N2cv12RemapInvokerE`, `SVMDetector`, `opencv-object-detector-hog`.
- Dostępność architektur: bibliotekę skompilowano wyłącznie dla środowisk arm64-v8a oraz armeabi-v7a.

**MBA-A-02: Zewnętrzny łańcuch dostaw FaceTec oraz brak wsparcia dla platformy x86\_64.** Moduł FaceTec pozostaje nieaktywny w środowisku WSA z uwagi na brak binariów x86_64. W kontekście badania wyklucza to jeden z mechanizmów detekcji wirtualizacji. W obszarze ochrony prywatności przetwarzanie strumienia wideo twarzy przez bibliotekę dostawcy zewnętrznego rodzi wymóg formalnej weryfikacji powierzenia przetwarzania danych w umowie DPA.

---

## 8.4. Analiza dekompilatu JADX

### 8.4.1. DeeplinkTranslator: statyczne mapowanie identyfikatora hosta w zasobach lokalnych

Plik `assets/webapps/webapps_host_mapping.json` o rozmiarze 29 bajtów:

```json
{ "ib": "online.mbank.pl" }
```

Konfiguracja definiuje pojedynczą relację: `hostid=ib` mapowane na `online.mbank.pl`. Dane odczytywane są bezpośrednio z zasobów lokalnych pakietu za pośrednictwem metody `WebAppsConfigImpl.a()` wywołującej `context.getAssets().open(str)`. Wyklucza to hipotezę o możliwości podrobienia mapowania w komunikacji sieciowej.

```java
// WebAppsConfigImpl.a(): odczyt pliku z zasobów lokalnych
InputStream open = this.a.getAssets().open(str);
// str = determinant + "/" + configName
// np. "webapps/webapps_host_mapping.json"
```

**Ocena techniczna:** Statyczna definicja hostów w zasobach aplikacji zapobiega ingerencji w routing przez manipulację odpowiedzią serwera, co wyklucza podatność na modyfikację parametrów w locie.

### 8.4.2. Weryfikacja reguł białych list komponentu WebApps

| Plik zasobu | Rozmiar | Zawartość reguły | Ocena techniczna |
|---|---|---|---|
| `webapps_host_mapping.json` | 29 B | `{"ib": "online.mbank.pl"}` | Pojedynczy stały host w zasobach |
| `webapps_resources_white_list.json` | 204 B | `online.mbank.pl`, `(www.)?mbank.pl`, `(.+.)*csp.mbank.pl`, `ecommerce.cdn-az.mbank.pl` | Ograniczenie do domen banku |
| `webapps_websocket_white_list.json` | 46 B | `^wss://online.mbank.pl/.*` | Ograniczenie do dedykowanego endpointu WebSocket |
| `webapps_deeplinks_white_list.json` | 1708 B | 25 reguł regex dla schematu `mbankpl://app/...` | Ściśle zdefiniowane ścieżki odsyłaczy |
| **`webapps_popup_white_list.json`** | **25 B** | \**`\["^https://.*"\]`\*\* | **Dopuszczenie dowolnej domeny HTTPS** |

**MBA-A-05: Brak ograniczenia domenowego w konfiguracji webapps\_popup\_white\_list.json.**Plik konfiguracyjny białej listy okien wyskakujących zawiera wyłącznie wyrażenie: `^https://.*`. W konsekwencji komponent WebView w trybie okna wyskakującego akceptuje dowolny adres URL z protokołem HTTPS. Weryfikację reguły realizuje metoda `ag0.a.a(url)`, która porównuje adres z konfiguracją `POPUPS_WHITELIST` za pomocą metody `matches()`. Warunek `^https://.*` ogranicza walidację wyłącznie do protokołu TLS, pomijając weryfikację samej nazwy domeny. Stanowi to wyłączenie mechanizmu obrony w głąb. Wpływ podatności zależy od możliwości wskazania docelowego adresu URL przez podmiot zewnętrzny. Weryfikacja wykonaniowa w środowisku WSA wykazała, że wywołanie polecenia `am start` z adresem `mbankpl://app/...` skierowane do `MainActivity` kończy się błędem `SecurityException: not exported` pod identyfikatorem UID 10088. Komponent obsługujący odsyłacze nie jest eksportowany, co eliminuje wektor wstrzyknięcia adresu pomiędzy aplikacjami w systemie operacyjnym. Zagrożenie ogranicza się do potencjalnej manipulacji adresem w istniejącym widoku WebView bądź przekierowania z zewnętrznej przeglądarki systemowej. Dalsza analiza wymaga dynamicznego śledzenia skryptem `05_webview_deeplink_tracer.js` w aktywnej sesji.

Reguły dla zasobów i połączeń WebSocket poprawnie ograniczają komunikację do domen własnych banku. Wyrażenia regularne odsyłaczy głębokich posiadają precyzyjną strukturę, aczkolwiek wzorce pokroju `^mbankpl://app/uwapps(/.*)?$` dopuszczają dowolny ciąg znaków po segmencie bazowym.

### 8.4.3. Implementacja usługi BlikCHceService dla płatności zbliżeniowych HCE

```java
// pl.mbank.feature.blikc.service.BlikCHceService extends HostApduService
public h blikCInfoStorage;           // magazyn danych BLIK
public f mainCommandApduHandler;     // handler komend APDU
public e1 paymentEventsHandler;      // handler zdarzeń płatności

@Override public void onCreate() {
    getComponent().a(this);  // DI inject przez Dagger
    super.onCreate();
}
```

Usługa `BlikCHceService` stanowi implementację standardu Android HCE. Dostęp do komponentu zabezpieczono uprawnieniem `android.permission.BIND_NFC_SERVICE`. Przetwarzanie poleceń protokołu APDU oddelegowano do modułu `mcore.kk0.f`. Mechanizm rotacji tokenów transakcyjnych podlega weryfikacji w testach dynamicznych.

### 8.4.4. Architektura komponentu StartActivity

```java
// pl.mbank.core.activity.StartActivity
public me0.a pairingHelper;           // logika parowania urządzeń
public v50.a intentRouter;            // router intencji
public hf0.c remoteConfigSplashGate;  // brama Remote Config na splash
```

Komponent `StartActivity` został wyeksportowany bez deklaracji uprawnień i przyjmuje wywołania z innych procesów. Przejście po ekranie powitalnym kontrolują komponenty `splashGateReady` oraz `remoteConfigSplashGate`. W przypadku braku aktywnej sesji aplikacja wymusza przejście do procedury logowania.

### 8.4.5. Interfejs JNI biblioteki SecLib i ewaluacja kodu integralności

```java
// pl.mbank.nativelib.SecLib
public final class SecLib {
    static { System.loadLibrary("nativeSeclib"); }
    private final native int initialize();
    public final int a() { return initialize(); }
}
```

Struktura JNI obejmuje pojedynczy symbol natywny: `Java_pl_mbank_nativelib_SecLib_initialize`. Implementacja procedury zawarta jest w bibliotece `libnativeSeclib.so`. Weryfikacja wykonawcza w klasie `pl.mbank.mcore.xr2.e`:

```java
int a = this.a.a(); // wywołanie SecLib.initialize()
return new pl.mbank.mcore.fa0.f(a == 8 ? pl.mbank.mcore.fa0.h.SAFE : pl.mbank.mcore.fa0.h.ROOTORJAILBREAK, 8992);
```

Biblioteka natywna musi zwrócić kod `8`, aby stan urządzenia został zakwalifikowany jako bezpieczny ze statusem `SAFE`. Zwrócenie standardowej wartości `0` logika aplikacji kwalifikuje jako naruszenie integralności środowiska ze statusem `ROOTORJAILBREAK`.

Analiza biblioteki x86\_64 w programie IDA 9.4 wykazała zwartą strukturę procedury weryfikacyjnej. Funkcja wykonuje polecenie systemowe `which su`, po czym sprawdza dostępność programu `su` w dziewięciu ścieżkach systemowych: `/bin`, `/sbin`, `/system`, `/system/bin`, `/system/sbin`, `/system/xbin`, `/vendor/bin`, `/su/bin` oraz `/su/xbin`. Wartość 8 stanowi bazowy kod stanu. Wykrycie obecności pliku `su` w zmiennej środowiskowej `PATH` ustawia bit 1, dając kod stanu 9. Odnalezienie pliku w zdefiniowanych ścieżkach ustawia bit 2, co generuje kod 10 lub 11.

Kontrolowane wywołanie funkcji w procesie aplikacji z użyciem frameworka Frida 17.18.0 zwróciło wartość **9**, stanowiącą sumę bitową wartości bazowej 8 oraz flagi 1. Biblioteka zidentyfikowała obecność pliku wykonywalnego `su` w środowisku WSA pod ścieżką `/product/bin/su`. Aplikacja kontynuuje działanie i wyświetla formularz wprowadzania kodu PIN. Wykrycie modyfikacji systemu nie skutkuje przerwaniem wykonywania procesu.

### 8.4.6. Integracja z platformą tokenizacji Mastercard MPSDK CBPP

Wdrożenie platformy Mastercard Cloud-Based Payments Platform obejmuje klasy `ProvisionRequestEncrypted`, `ChangeMobilePinRequestEncrypted` oraz `ReplenishRequestEncrypted`. Transmisja podlega szyfrowaniu na poziomie warstwy aplikacji. Klucze tokenów transakcyjnych pozostają pod wyłączną kontrolą biblioteki Mastercard SDK.

### 8.4.7. Architektura silnika RASP platformy uPaid MDC oraz dynamiczny loader bibliotek natywnych

Wcześniejsze analizy bezpieczeństwa koncentrowały się na pomocniczym module `libnativeSeclib.so` oraz statycznej klasie `SecLib.initialize()`. Szczegółowa dekompilacja pakietów `pl.mbank.mcore.vf3`, `pl.mbank.mcore.xe3`, `c.o` oraz `o.h` wykazała obecność wielopoziomowego silnika ochrony środowiska wykonawczego RASP zintegrowanego w ramach platformy uPaid Mobile Development Center.

#### Dynamiczny obfuskowany loader biblioteki natywnej

Inicjalizacja podsystemu natywnego w klasie `pl.mbank.mcore.xe3.b` opiera się na dynamicznym wyliczaniu nazwy modułu w trakcie działania procesu:

1. Klasa wewnętrzna `pl.mbank.mcore.xe3.b$a` generuje tablicę 84 bajtów za pomocą łańcucha 32-bitowych przesunięć bitowych bez znaku.
2. Metoda `c.o.eu.e1` dekoduje sekwencje szesnastkowe do postaci znaków unikodowych.
3. Metoda `c.o.eu.y` wykonuje operację bitową XOR z wykorzystaniem klucza dynamicznego `1a9UjiRSHasdfFJDfsdAIhreSJ1`.
4. Ostatecznym wynikiem procedury jest identyfikator `native-library`, przekazywany do `System.loadLibrary()`. W ten sposób następuje załadowanie biblioteki `libnative-library.so` o rozmiarze 1,79 MB dla architektury ARM64 oraz 2,02 MB dla x86\_64.

#### Most JNI i rejestracja metod w klasie o.h

Biblioteka `libnative-library.so` rezygnuje ze statycznych symboli formatu `Java_`. Wszystkie punkty wejścia podlegają dynamicznej rejestracji przez funkcję `JNI_OnLoad` za pośrednictwem `RegisterNatives` środowiska JNI. Docelowym punktem montowania metod natywnych jest klasa `o.h`, deklarująca 32 niskopoziomowe metody natywne, w tym:

- `o(Context)`: inicjalizacja kontekstu sprzętowego oraz struktur kryptograficznych,
- `d()`: generowanie sygnatury atestacyjnej środowiska,
- `h(String)`: kryptograficzna weryfikacja integralności tokenów,
- `yy(String)` oraz `u(String)`: statyczne metody zwrotne wywoływane przez kod maszynowy C++ po wykryciu anomalii.

#### Pętla sprzężenia zwrotnego i selektywne zerowanie tożsamości

Podsystem uPaid MDC odpowiada za bezpieczeństwo operacji portfelowych i tokenizacji kart zbliżeniowych BLIK Contactless, podlegając asynchronicznej inicjalizacji w klasie `pl.mbank.mcore.ck0.g`. W przypadku zidentyfikowania manipulacji w pamięci chronionego modułu, obecności debuggerów ptrace lub haków dynamicznych, kod maszynowy w `libnative-library.so` wykonuje wywołanie powrotne do maszyny wirtualnej:

1. Funkcja C++ przekazuje identyfikator zagrożenia do metody `o.h.yy()` lub `o.h.u()`.
2. Zdarzenie trafia do dyspozytora `c.o.ex` i zostaje przekierowane do interfejsu nasłuchującego `pl.mbank.mcore.xe3.c`.
3. Interfejs deleguje obsługę do procedury `pl.mbank.mcore.vf3.ub`.
4. Procedura wykonuje asynchroniczną transmisję wektora naruszenia do infrastruktury telemetrycznej banku za pośrednictwem metody `dm.d()`.
5. Następuje unieważnienie sesji portfela poprzez wywołanie `w4.reset()`. Skutkuje to wyczyszczeniem kluczy sesyjnych oraz zerowaniem tokenów autoryzacyjnych modułu płatniczego.

Architektura ta wyjaśnia obserwację wykonawczą udokumentowaną w rozdziale 10.3: pasywne podłączenie frameworka Frida do głównego komponentu `MainActivity` pozwala na dalsze stabilne działanie procesu, ponieważ mechanizm ochronny RASP izoluje specyficzny podsystem płatniczy i koncentruje się na unieważnieniu struktur kryptograficznych portfela oraz asynchronicznym raportowaniu zdarzeń.

#### Weryfikacja obfuskacji R8 oraz integralności klas w pamięci

Platforma uPaid MDC zawiera mechanizmy autoweryfikacji procesu budowania:

- **Weryfikacja obfuskacji klas domenowych**: Klasa `pl.mbank.mcore.vf3.th` za pośrednictwem `SecurityModuleApi.a.I().a()` sprawdza stan zaciemnienia kluczowych struktur aplikacji. Podsystem bada obecność oryginalnych nazw klas domenowych, takich jak `CardHolder`, `MobileDcApiConfiguration` oraz `ApiErrorDetails`. Brak zaciemnienia nazw przez R8 jest traktowany jako modyfikacja binarna i powoduje zatrzymanie aplikacji.
- **Weryfikacja sum kontrolnych klas w pamięci**: Komponent `classChecksumChecker` oblicza sumy kontrolne bajtokodu załadowanych klas DEX. Zabezpiecza to proces przed wstrzykiwaniem obcych klas w czasie działania aplikacji.
- **Detekcja flagi debugowania**: Podczas procedury startowej badana jest flaga `ApplicationInfo.FLAG_DEBUGGABLE`. Wykrycie aktywnego debugowania powoduje wyrzucenie wyjątku `DebugVersionException`.

#### Zaciemnione biblioteki libbeda.so oraz libc5ba.so

W strukturze pakietu APK znajdują się dodatkowo biblioteki `libbeda.so` o rozmiarze 1,06 MB oraz `libc5ba.so` o rozmiarze 1,20 MB. Analiza sekcji dynamicznej tych plików wykazała zaawansowane spłaszczenie przepływu sterowania oraz zredukowanie czytelnych ciągów tekstowych do około 100 pozycji. Biblioteki importują bezpośrednie wywołania systemowe jądra Linux: `mprotect`, `syscall`, `__system_property_get`, `_exit`, `fork`, `kill`, `dlopen` oraz `dlsym`. Zestaw ten służy do niskopoziomowej ochrony stron pamięci przed modyfikacją oraz bezpośredniego kończenia procesu bez powiadamiania środowiska uruchomieniowego Androida.

---

## 8.5. Moduł weryfikacji integralności urządzenia: pakiety xr2 oraz vr2

Analiza pakietu `pl.mbank.mcore.xr2` wykazała obecność sześciu detektorów integrowanych przez moduł agregujący `pl.mbank.mcore.xr2.i`:

| Klasa | Kod błędu | Badany wektor | Logika detekcji |
|---|---|---|---|
| `xr2.a` | `8961` | Pakiety uprawnień root oraz narzędzi maskujących | Wywołanie `PackageManager.getPackageInfo()` dla 18 pakietów: `com.topjohnwu.magisk`, `com.koushikdutta.superuser`, `de.robv.android.xposed.installer`, `eu.chainfire.supersu`, `com.saurik.substrate`, `com.devadvance.rootcloak` |
| `xr2.b` | `8962` | Uprawnienia zapisu na partycjach systemowych | Parsowanie wyniku polecenia `mount` pod kątem flagi `rw` na ścieżkach: `/`, `/bin`, `/sbin`, `/su/bin`, `/su/xbin`, `/system`, `/system/bin`, `/system/sbin`, `/system/xbin`, `/vendor/bin` |
| `xr2.d` | `8964` | Flagi kompilacji jądra i obrazu systemu | Weryfikacja `Build.TAGS` pod kątem obecności ciągu `test-keys` |
| `xr2.e` | `8992` | Weryfikacja w warstwie biblioteki natywnej | Sprawdzenie warunku `SecLib.initialize() == 8` |
| `xr2.k` | `8968` | Dostępność plików wykonywalnych su oraz busybox | Wywołanie `which su` oraz `which busybox` przez `ProcessBuilder("/system/bin/sh")` |
| `xr2.l` | `8976` | Właściwości systemowe platformy Android | Odczyt parametrów przez `getprop`: `ro.secure` równe 1, `ro.debuggable` różne od 1, `ro.build.selinux` równe 1, `.adb.root` różne od 1 |

### 8.5.1. Analiza zachowania aplikacji w środowisku WSA z aktywnym MagiskSU

Uruchomienie produkcyjnego klienta mBank na emulatorze WSA z aktywnym modułem MagiskSU nie wynika z braku detekcji uprawnień roota. Test wykonaniowy wykazał, że funkcja natywna zwraca kod 9 w wyniku odnalezienia pliku `su` przez polecenie systemowe. WSA udostępnia program pod ścieżką `/product/bin/su`, widoczną w środowisku procesu.

Metoda `vr2.j.p()` łączy wynik testu lokalnego z oceną integralności pobieraną z usługi sieciowej:

```java
public final boolean p() {
    b a2 = k.a(n());
    Boolean k = k();
    return k != null ? k.booleanValue() : a2 != b.UNSAFE;
}
```

Analiza statyczna pakietu `pl.mbank` wykazała brak instrukcji bezwzględnego zakończenia procesu powiązanych ze statusem roota, takich jak `finish()`, `System.exit()` czy `killProcess`. Detektory pakietu `xr2` przekazują kod stanu, na przykład `ROOTORJAILBREAK` o kodzie `8961`, do obiektu oceny `fa0.f`.

Wykrycie zmodyfikowanego środowiska skutkuje stopniowaną degradacją funkcjonalności klienta:

- Blokada metod biometrycznych: próba włączenia logowania odciskiem palca, skanem twarzy lub tęczówki kończy się odmową i wymuszeniem autoryzacji kodem PIN.
- Komunikat błędu: aplikacja wyświetla ciąg `biometric_security_error_disabled` o treści: „Twój telefon ma nieoryginalny lub modyfikowany system operacyjny. Ze względów bezpieczeństwa nie możesz skorzystać z tych metod”.
- Potwierdzenie wykonaniowe: zachowanie to zarejestrowano na platformie WSA z Magiskiem podczas próby konfiguracji biometrii.
- Weryfikacja serwerowa: egzekwowanie ograniczeń transakcyjnych na poziomie backendu za pośrednictwem API Play Integrity stanowi przedmiot dalszych testów dynamicznych z przechwytywaniem odpowiedzi usługi.

### 8.5.2. Telemetria stanu połączeń i próba sprzętowej identyfikacji urządzenia

Równolegle z detekcją roota aplikacja korzysta z uprawnienia `READ_PHONE_STATE` w dwóch odrębnych wektorach funkcjonalnych:

1. **Detekcja rozmowy telefonicznej (IncomingCallReceiver):** Odbiornik `pl.mbank.feature.callDetector.IncomingCallReceiver` nasłuchuje zdarzeń systemowych `TelephonyManager.ACTION_PHONE_STATE_CHANGED`. Odczytuje parametr `TelephonyManager.EXTRA_STATE`, identyfikując stany `RINGING`, `OFFHOOK` oraz `IDLE`. Moduł ten służy celom ochrony antyfraudowej, ostrzegając użytkownika przed autoryzacją operacji finansowych podczas trwającej rozmowy telefonicznej (ochrona przed atakiem typu vishing).
2. **Próba odczytu sprzętowego numeru IMEI (tb1.q):** W klasie `pl.mbank.mcore.tb1.q` (linia 320) kod wykonuje bezpośrednie odwołanie `this.f34055b.getImei(i)` dla każdego dostępnego slotu karty SIM. Od poziomu systemu Android 10 (poziom API 29) wywołanie to kończy się zgłoszeniem wyjątku `SecurityException`, gdyż odczyt sprzętowych identyfikatorów urządzenia został zastrzeżony dla uprawnień systemowych `READ_PRIVILEGED_PHONE_STATE`. Obecność tej metody w kodzie produkcyjnym dokumentuje dążenie architektury do pozyskiwania stałych identyfikatorów sprzętowych na potrzeby profilowania stacji klienta.

---

## 8.6. Architektura kryptograficzna tożsamości: moduł SAM

Zarządzanie tożsamością klienta, przechowywanie poświadczeń sesyjnych oraz ochrona klucza prywatnego RSA zaimplementowane są w pakiecie `pl.mbank.sam.internal`.

**MBA-A-06: Zastosowanie algorytmu PKCS#12 PBE o niskiej liczbie iteracji oraz szyfrowanie klucza prywatnego RSA w trybie AES-CTR bez ochrony integralności (AEAD).** Łańcuch kryptograficzny tożsamości łączy funkcję wyprowadzania klucza PKCS#12 PBE o parametrze 10 000 iteracji SHA-256 z szyfrowaniem symetrycznym w trybie AES-CTR pozbawionym mechanizmu kontroli integralności danych. Wektor ataku offline po wyodrębnieniu rekordu z systemowej bazy kont pozwala na odzyskanie kodu PIN w czasie liczonym w sekundach oraz modyfikację struktury wyodrębnionego klucza tożsamości.

### 8.6.1. Przepływ danych kryptograficznych w module SAM

Schemat przepływu danych tożsamości obejmuje trzy etapy: derywację klucza symetrycznego z kodu PIN, szyfrowanie surowego klucza prywatnego oraz utrwalenie rekordu w systemie operacyjnym:

flowchart TD subgraph KDF ["1. Wyprowadzanie klucza tożsamości (KDF)"] PIN(["PIN użytkownika
4–8 cyfr"]) --> PBE[["PKCS#12 PBE
SHA-256 · 10 000 iteracji"]] Salt[("Sól KDF: s0.b
z kontenera tożsamości")] --> PBE PBE --> Key(["Klucz AES-256
obiekt SecretKeySpec"]) end subgraph CRYPT ["2. Szyfrowanie klucza RSA (brak ochrony AEAD)"] RSA(["Klucz prywatny RSA
format PKCS#8"]) --> Cipher[["AES/CTR/NoPadding
klasa internal.h0"]] Key --> Cipher IV[("Wektor IV: s0.a
z kontenera tożsamości")] --> Cipher Cipher --> CT(["Szyfrogram klucza RSA
brak tagu MAC / AEAD"]) end subgraph STORAGE ["3. Trwały kontener tożsamości"] IV -.-> Serializer(["Serializacja rekordu w0
IV : Sól : Szyfrogram"]) Salt -.-> Serializer CT --> Serializer Serializer --> AccountDB[("Android AccountManager
typ: pl.mbank · accounts_ce.db")] end 

### 8.6.2. Funkcja wyprowadzania klucza z kodu PIN (KDF)

W klasie `pl.mbank.sam.internal.j0` zidentyfikowano procedurę wyprowadzania klucza z kodu PIN użytkownika:

```java
public final SecretKeySpec a(@NotNull char[] cArr, @NotNull byte[] bArr) {
    return new SecretKeySpec(
        SecretKeyFactory.getInstance("PBEWITHSHA256AND256BITAES-CBC-BC")
            .generateSecret(new PBEKeySpec(cArr, bArr, 10000, 256))
            .getEncoded(), 
        "AES"
    );
}
```

Implementacja wykorzystuje algorytm PKCS#12 PBE z biblioteki BouncyCastle, zarejestrowany pod identyfikatorem `PBEWITHSHA256AND256BITAES-CBC-BC`, z funkcją skrótu SHA-256 oraz stałą liczbą 10 000 iteracji. Z fabryki kluczy pobierany jest surowy ciąg 256 bitów metodą `getEncoded()`, stanowiący klucz szyfrujący dla warstwy prezentacji tożsamości.

Zestawienie parametrów implementacji z obowiązującymi wytycznymi bezpieczeństwa:

| Parametr | Implementacja mBank SAM | Rekomendacje OWASP i NIST SP 800-132 | Status zgodności |
|---|---|---|---|
| Algorytm KDF | PKCS#12 PBE (BouncyCastle) | PBKDF2-HMAC-SHA256 lub Argon2id | Niezgodny; przestarzały schemat PKCS#12 |
| Liczba iteracji | 10 000 | Minimum 600 000 dla PBKDF2-HMAC-SHA256 | Krytycznie niska; 60-krotnie poniżej progu |
| Koszt pamięciowy | Pomijalny (brak pamięciożerności) | Wysoki (Argon2id, scrypt) | Podatny na zrównoleglenie na układach ASIC i GPU |
| Odporność na brute-force | PIN 4 cyfry: poniżej 1 s na GPU; PIN 6 cyfr: poniżej 10 s | Trwała odporność wieloletnia | Wąska przestrzeń przeszukania kodu numerycznego |

### 8.6.3. Szyfrowanie klucza prywatnego RSA w trybie AES-CTR

Procedura szyfrowania klucza prywatnego RSA w klasie `pl.mbank.sam.internal.h0` wykorzystuje tryb strumieniowy `AES/CTR/NoPadding`:

```java
j0Var.b("AES/CTR/NoPadding", s0Var.a, j0Var.a(cArr, s0Var.f42389b), bArr);
```

Parametry operacji:

- `s0Var.a`: wektor inicjalizacyjny IV pobierany z kontenera.
- `j0Var.a(cArr, s0Var.f42389b)`: klucz AES wygenerowany przez funkcję KDF.
- `bArr`: surowe bajty klucza prywatnego RSA w formacie PKCS#8.

Tryb CTR zapewnia poufność danych. Jest jednak pozbawiony mechanizmu kontroli integralności. W architekturze brakuje uwierzytelnienia kryptograficznego w postaci tagu MAC, trybu GCM bądź konstrukcji Poly1305. Cecha plastyczności (malleability) trybu CTR sprawia, że zmiana dowolnego bitu w szyfrogramie skutkuje przewidywalną modyfikacją odpowiadającego mu bitu w odzyskanym tekście jawnym podczas deszyfrowania. W przypadku manipulacji szyfrogramem aplikacja nie wykrywa naruszenia integralności na etapie operacji symetrycznej, zgłaszając dopiero błąd parsowania struktury ASN.1 i DER klucza prywatnego. Standard OWASP MASVS w wymaganiu MASVS-CRYPTO-1 nakazuje stosowanie szyfrowania uwierzytelnionego AEAD.

### 8.6.4. Struktura kontenera tożsamości w0 i wektor ataku offline

Dane tożsamości podlegają serializacji w strukturze `w0` w postaci ciągu wartości rozdzielanych dwukropkiem:
`IV : Sól : Szyfrogram`

Kontener rejestrowany jest w usłudze systemowej **Android AccountManager** pod typem konta `pl.mbank`, obsługiwanym przez komponent `NmbAuthenticationService`. Baza kont składowana jest w systemowym pliku chronionym poświadczeniami:
`/data/system_ce/0/accounts_ce.db`

flowchart LR Acc[("Systemowa baza kont
accounts_ce.db")] --> Dump(["Pozyskanie rekordu
uprawnienia root / ADB"]) Dump --> Split(["Rozbicie formatu w0
IV : Sól : Szyfrogram"]) Split --> Crack[["KDF PKCS#12 offline
10 000 iteracji SHA-256"]] Dict(["Słownik kodów PIN
0000–9999 (10^4)"]) --> Crack Crack --> Done(["Odzyskany kod PIN
i klucz prywatny RSA"]) 

Z uwagi na numeryczny format kodu PIN oraz umieszczenie soli i wektora IV bezpośrednio w kontenerze, atak słownikowy na wyodrębnioną bazę charakteryzuje się znikomym kosztem obliczeniowym. Weryfikacja wykonawcza wymaga uprawnień roota do odczytania magazynu `accounts_ce.db` na urządzeniu z aktywnym kluczem CE po odblokowaniu ekranu. Z tego względu wagę podatności ustalono na poziomie średnim. Wektor MBA-A-08 cechuje się wyższą krytycznością z uwagi na obecność stałego klucza bezpośrednio w pakiecie APK.

---

## 8.7. Sprzętowy magazyn kluczy AndroidKeyStore

Dla operacji krytycznych czasowo, biometrycznie oraz ochrony nowoczesnych preferencji aplikacja korzysta ze sprzętowego magazynu kluczy `AndroidKeyStore`:

| Alias klucza | Klasa implementująca | Algorytm | Parametry ochrony | Przeznaczenie |
|---|---|---|---|---|
| `"blikc_alias_key"` | `kj0` / `lj0` / `nk0` | `AES-256-CBC` / PKCS7 | Wymóg autoryzacji użytkownika z oknem ważności 60 sekund: `setUserAuthenticationParameters(60, 3)` | Ochrona tokenów transakcyjnych BLIK Zbliżeniowy w standardzie HCE |
| `"FingerprintAuthorization"` | `kj0` / `lj0` | `AES-CBC` / PKCS7 | `setUserAuthenticationRequired(true)` | Integracja z `BiometricPrompt.CryptoObject` na potrzeby autoryzacji biometrycznej |
| `"LOGIN_KEY"` | `cb0.g` / `cb0.h` | `AES-GCM` / `RSA-PKCS1` | `KeyGenParameterSpec` w `AndroidKeyStore`, sprzętowy KEK w TEE | Szyfrowanie kopertowe (envelope encryption): owijanie i odwijanie klucza DEK generowanego przez `q8` dla warstwy `CryptoPreferences` |

Klucze sprzętowe podlegają izolacji w module TEE. Ograniczenie czasu ważności autoryzacji do 60 sekund dla operacji BLIK zapobiega wykonaniu nieautoryzowanych transakcji zbliżeniowych po zablokowaniu ekranu urządzenia.

---

## 8.8. Bazy danych SQLite oraz magazyn tożsamości AccountManager

### 8.8.1. Analiza zawartości lokalnej bazy danych SQLite

Weryfikacja binarnej zawartości katalogu `/data/data/pl.mbank/databases/` wykazała standardowy nagłówek `SQLite format 3` w pliku `nmbMobile` bez szyfrowania SQLCipher. Analiza klasy `pl.mbank.core.legacy.services.db.DataBaseHelper` wykazała obecność tabel `dictionaries` oraz `dictionary_values`. Tabele te przechowują słowniki systemowe: kody walut, opisy operacji oraz typy dokumentów. Baza nie zawiera historii rachunku, sald kont ani danych kart płatniczych.

### 8.8.2. Magazyn danych tożsamości w usłudze AccountManager

Główny rekord tożsamości `AccountData` rejestrowany jest w systemie Android za pośrednictwem komponentu `pl.mbank.core.authenticator.NmbAuthenticationService`:

- Nazwa konta: `mBank`
- Typ konta: `pl.mbank`
- Atrybuty w `AccountManager`: `deviceToken`, `encryptedDeviceSecret`, `encryptedRsaSignKey`, `aesDeviceSecretKey`, `encryptedRandom`, `rsaPublicServerCommKey`.

---

## 8.9. Asymetria autoryzacji w komponencie EMaklerProvider: podatność MBA-A-07

Komponent `pl.mbank.feature.emakler.legacy.sso.emakler.EMaklerProvider` pośredniczy w logowaniu jednokrotnym SSO do usługi maklerskiej eMakler.

```xml
<provider 
    android:authorities="pl.mbank.EMaklerProvider" 
    android:exported="true" 
    android:name="pl.mbank.feature.emakler.legacy.sso.emakler.EMaklerProvider" 
    android:readPermission="pl.mbank.eMaklerProviderPermission" 
    android:writePermission="pl.mbank.eMaklerProviderPermissionWrite" />
```

**MBA-A-07: Asymetria weryfikacji tożsamości w EMaklerProvider: pominięcie walidacji podpisu w metodzie insert().**1. **Klasyfikacja poziomu ochrony uprawnień:** Uprawnienia `pl.mbank.eMaklerProviderPermission` oraz `pl.mbank.eMaklerProviderPermissionWrite` zdefiniowano z atrybutem `android:protectionLevel="dangerous"`. Deklaracja ta nie wymusza poziomu ochrony `signature`, co pozwala dowolnej aplikacji na uzyskanie uprawnienia po zatwierdzeniu przez użytkownika. 2. **Weryfikacja wywołującego w metodzie query():** Implementacja metody `query()` pobiera identyfikator UID procesu przez `Binder.getCallingUid()`, odczytuje strukturę `SigningInfo` i weryfikuje skrót SHA-1 certyfikatu wywołującego z białą listą zdefiniowaną w `pl.mbank.mcore.tp1.b`. 3. **Pominięcie kontroli w metodzie insert():** Metoda `insert()` nie realizuje procedury weryfikacji tożsamości wywołującego `p(packageName)`: ```java @Override public Uri insert(Uri uri, ContentValues contentValues) { if (j().match(uri) != 1) return null; k().delete("TokenTable", null, null); k().insert("TokenTable", null, contentValues); i().getContentResolver().notifyChange(h().a(), null); return uri; } ``` Dowolny proces posiadający uprawnienie `eMaklerProviderPermissionWrite` może dokonać zapisu w tabeli `TokenTable`, co umożliwia usunięcie bądź nadpisanie tokenu SSO bez kryptograficznej walidacji tożsamości nadawcy.

---

## 8.10. Zabezpieczenie przed nakładkami interfejsu i usługami dostępności

Plik `assets/accessibility-white-list.json` o rozmiarze 168 KB zawiera bazę 1648 skrótów SHA-256 autoryzowanych komponentów ułatwień dostępu.

Weryfikację uprawnień i usług realizuje klasa `pl.mbank.mcore.qr2.n` zintegrowana z komponentem `AccessibilityBackgroundService` oraz nasłuchem stanu `AccessibilityManager.AccessibilityStateChangeListener`. Skrót wyliczany jest ze standardowego ciągu UTF-8 w formacie `<nazwa_pakietu>/<klasa_usługi>`:

```java
// pl.mbank.mcore.qr2.n.m(): SHA-256 z identyfikatora komponentu
public final String m(String str) {
    return Hashing.sha256().hashString(str, StandardCharsets.UTF_8).toString();
}
```

Analiza zasobu potwierdziła dopasowania dla kluczowych usług asystujących głównych producentów systemowych:

| Zidentyfikowana usługa | Producent / przeznaczenie | Skrót SHA-256 w accessibility-white-list.json |
|---|---|---|
| `com.google.android.marvin.talkback/.TalkBackService` | Google Android Accessibility Suite | `3ef9642a0969a5b2227d855c4dc3dcc70c283153f78c345609cc1e72cb14f3c8` |
| `com.samsung.android.app.talkback/.TalkBackService` | Samsung Voice Assistant / TalkBack | `16b99cb3de0f9cc1294708f9fe5eb5afc55b9e248c0d865ec1d36812cbb8bbc0` |

Logika w metodzie `n.k()` weryfikuje każdą aktywną usługę systemową. Jeśli aktywny komponent ułatwień dostępu nie figuruje w bazie białej listy, aplikacja rejestruje wpis `[Accessibility] Unknown service: <komponent>` i uruchamia okno dialogowe `AccessibilityDialogFragment` z ostrzeżeniem dla użytkownika.

Mechanizm ten stanowi barierę chroniącą przed trojanami bankowymi (np. Sharkbot, Teabot, Xenomorph) nadużywającymi interfejsu `AccessibilityService` do nakładania fałszywych formularzy logowania (overlay) oraz automatycznego zatwierdzania przelewów (ATS). Jednocześnie generuje on fałszywe alarmy w przypadku legalnego oprogramowania automatyzującego, menedżerów haseł z funkcją autouzupełniania bądź niestandardowych narzędzi ułatwień dostępu w zmodyfikowanych dystrybucjach systemu Android.

## 8.11. Ekstrakcja danych aplikacji przez mechanizm kopii zapasowej MIUI

Kopia wykonana w systemie Xiaomi 13T zawiera plik `mBank(pl.mbank).bak` o rozmiarze 124 689 979 bajtów i skrócie SHA-256 `0103aa7d6e1d596cdac156eb54ae9c2cf2a92164bcbf47dffe84b3465e3eb88d`. Nagłówek MIUI poprzedza standardowy strumień `ANDROID BACKUP` w wersji 5 z wartością pola szyfrowania `none`. Dostęp do archiwum nie wymaga podania kodu blokady urządzenia ani kluczy z Android Keystore.

Archiwum zawiera prywatne katalogi aplikacji: `shared_prefs`, bazy SQLite, pliki wewnętrzne oraz profil WebView z magazynem lokalnym, sesyjnym i bazą ciasteczek. Kopia została wygenerowana pomimo obecności flagi `android:allowBackup="false"` w manifeście, co wskazuje na nadrzędność mechanizmu producenta nad standardową flagą platformy Android.

Główny plik konfiguracyjny `shared_prefs/mBank.xml` zawierał 143 rekordy: jeden wpis z kluczem AES oraz 142 zaszyfrowane pary klucz-wartość. Implementacja w klasie `pl.mbank.mcore.i90.e` wykorzystuje algorytm AES-CBC z dopełnieniem PKCS#7. Nazwy pól szyfrowane są ze stałym zerowym wektorem IV, natomiast wartości szyfrowane są z wektorem utworzonym z pierwszych 16 bajtów jawnej nazwy pola. Klucz AES-128 zapisano w tym samym pliku pod stałą nazwą `47C61146870D6E18826E53807E2EB97C`. W przypadku braku tego rekordu metoda `e.x()` sięga po wbudowaną w kod APK stałą `132F1A90***DEE8`, identyczną dla wszystkich instalacji. Schemat szyfrowania jest w pełni deterministyczny: stały klucz, zerowy IV dla nazw oraz deterministyczny IV dla wartości generują identyczny szyfrogram na każdym urządzeniu. Opracowany skrypt deszyfrujący odzyskał komplet 142 wpisów bez dostępu do telefonu, kodu PIN oraz magazynu Android Keystore.

Odzyskane dane konfiguracyjne zawierają między innymi parametry `DeviceId`, `AnalyticsId`, identyfikator sesji parowania, trzy tokeny rejestracji Firebase, klucz i wektor szyfrowania powiadomień, sól oraz wektor innego magazynu, a także flagi stanu zabezpieczeń. W pliku nie stwierdzono obecności kodu PIN, loginu, numeru rachunku ani salda konta. Wstępne dopasowanie ciągu testowego PIN w surowym pliku XML wynikało z przypadkowej zbieżności bajtów wewnątrz szyfrogramu; w zdekodowanych polach wartość ta nie występuje.

Baza `token` zawiera pojedynczy rekord Base64 o długości 44 znaków, reprezentujący 32 bajty danych binarnych. Wartość zamaskowano w raporcie jako `wnQ+***DuU=`; jej skrót SHA-256 wynosi `c4afc73752b039da95abae3406bfc2b91929249b0515bd1a7cdf86b06e62336e`. Rekord ten stanowi element mechanizmu logowania jednokrotnego eMakler i nie jest tożsamy z tokenem sesji głównej bankowości.

Plik bazy `MCBP.db` platformy płatności Mastercard zawiera tabele profili kart, kluczy mobilnych, portfela oraz dzienników transakcyjnych. W analizowanej kopii tabele te pozostawały puste, co potwierdza brak ekspozycji tokenów płatniczych w tym kanale.

**MBA-A-08: Odwracalne szyfrowanie konfiguracji w kopii zapasowej MIUI.** Aplikacja szyfruje lokalne ustawienia, lecz przechowuje klucz symetryczny w tym samym pliku XML bez powiązania ze sprzętowym magazynem Android Keystore. Mechanizm ten wykazuje dwie wady implementacyjne: obecność uniwersalnego, zapasowego klucza AES-128 `132F1A90***DEE8` zaszytego w kodzie APK dla plików pozbawionych wpisu z kluczem oraz w pełni deterministyczny schemat kryptograficzny obejmujący stały klucz, zerowy wektor IV dla nazw oraz wektor IV wyliczany bezpośrednio z nazwy pola dla wartości. Umożliwia to całkowite odszyfrowanie identyfikatorów urządzenia, tokenów rejestracyjnych Firebase oraz klucza szyfrowania powiadomień bezpośrednio z pliku kopii, bez znajomości kodu PIN i bez dostępu do urządzenia. Zgodnie ze standardem OWASP MASVS w kategorii MASVS-CRYPTO zapisanie klucza szyfrującego w tym samym zasobie bądź wbudowanie stałego klucza w kod aplikacji stanowi krytyczną niezgodność architektoniczną.

### 8.11.1. Koegzystencja architektur pamięci trwałej: mBank.xml a sprzętowy CryptoPreferences

Szczegółowa inwentaryzacja katalogu `shared_prefs` w wyekstrahowanej kopii zapasowej ujawniła równoległą obecność dwóch odmiennych generacji magazynów konfiguracyjnych:

1. **Warstwa starsza (`shared_prefs/mBank.xml`):**
    Implementacja w klasie `pl.mbank.mcore.i90.e` bazująca na symetrycznym szyfrowaniu AES-CBC z kluczem zapisanym w pliku lub uniwersalnym kluczem zapasowym w kodzie APK (`132F1A90***DEE8`). Schemat ten odpowiada za podatność MBA-A-08 i pozwala na odtworzenie 142 parametrów technicznych w trybie offline. Stanowi dług technologiczny aplikacji.
2. **Warstwa nowoczesna (`shared_prefs/<uuid>.xml`):**
    Implementacja interfejsu `pl.mbank.mcore.xd3.a` w klasie `pl.mbank.mcore.kw.h7` powiązana z podsystemem uPaid MDC. Pliki noszą nazwy losowo generowanych identyfikatorów UUID. Warstwa ta implementuje schemat szyfrowania kopertowego (envelope encryption) powiązany ze sprzętowym magazynem `AndroidKeyStore`:

    - Klasa `pl.mbank.mcore.kw.q8` generuje losowy, symetryczny klucz szyfrowania danych DEK (Data Encryption Key).
    - Klasa `pl.mbank.mcore.rd3.a` realizuje operacje owijania i odwijania (wrap oraz unwrap) klucza DEK z użyciem klucza nadrzędnego KEK (Key Encryption Key) zakotwiczonego w `AndroidKeyStore`. Wzorzec ten opiera się na sekwencji metod sprawdzających obecność klucza, generowania specyfikacji oraz enkapsulacji (`hasKey`, `generate`, `wrap`, `unwrap`).
    - Silnik kryptograficzny `cb0.h` konfiguruje specyfikację `KeyGenParameterSpec` dla dostawcy `AndroidKeyStore`, obsługując transformacje `AES-GCM` oraz `RSA-PKCS1` z finalizacją szyfrowania przez wywołanie `Cipher.doFinal()`. Klucz nadrzędny powiązany jest ze stałym aliasem `LOGIN_KEY` zadeklarowanym w klasie `cb0.g`.
    - Zastosowanie sprzętowej enklawy TEE uniemożliwia odzyskanie klucza DEK oraz deszyfrację parametrów konfiguracyjnych poza fizycznym procesorem urządzenia.

Koegzystencja obu struktur potwierdza wdrożenie pełnej ochrony sprzętowej w procesorze urządzenia dla nowo projektowanych modułów oraz tokenów transakcyjnych. Archiwalny plik `mBank.xml` pozostaje komponentem przejściowym bez wsparcia `AndroidKeyStore`.

---

## 8.12. Analiza powiązanej aplikacji maklerskiej eMakler giełda: pl.mbank.bmmobile 6.7.4

Do obsługi rachunku maklerskiego mBank udostępnia aplikację eMakler giełda, pakiet `pl.mbank.bmmobile` w wersji 6.7.4. Aplikację zbudowano w technologii **.NET MAUI**, w przestrzeni nazw `Pomelo.*`, i skompilowano w trybie AOT. Kod zarządzany wyodrębniono ze skompresowanego magazynu `libassembly-store.so` w formacie XABA z kompresją LZ4/XALZ obejmującym 242 biblioteki, po czym poddano go dekompilacji do kodu źródłowego C#.

**Architektura mostka SSO z aplikacją bankową:** Aplikacja maklerska realizuje logowanie jednokrotne przez metodę `ReadTokenFromContentProvider` pobierającą token z dostawcy treści mBanku pod adresem `content://pl.mbank.EMaklerProvider/TokenTable`. Pobrany token przekazywany jest do usługi IdentityServer protokołem OIDC na ścieżce `/identityserver/connect/token` w domenie `https://bmmobile.mbank.pl` w celu wymiany na token sesyjny. Weryfikację poprawności tokenu przeprowadza serwer uwierzytelniający. W odniesieniu do podatności MBA-A-07 oznacza to, że nieuprawniona aplikacja z prawem zapisu może usunąć lub podmienić wpis w tabeli `TokenTable`, co wywołuje ryzyko odmowy usługi lub narzucenia sesji. Bezpośredni dostęp do konta wymaga jednak poprawnej walidacji po stronie serwera.

**Zaimplementowane mechanizmy zabezpieczeń sieciowych:**

- **Przypinanie certyfikatów:** Zastosowano dedykowany moduł walidacji `PomeloHttpClientHandler` implementujący interfejs `ICertPinningValidator`, egzekwowany również dla połączeń WebSocket silnika EngineIo przy obsłudze notowań giełdowych.
- **Bezpieczny magazyn danych:** Wykorzystano interfejs `SecureStorage` powiązany z Android Keystore do przechowywania kontekstu urządzenia.
- **Poprawność kryptograficzna:** Wykluczono stosowanie przestarzałych algorytmów, takich jak MD5, DES czy tryb ECB, oraz wyeliminowano procedury pomijania walidacji łańcucha certyfikatów.

**MBA-B-01: Brak obfuskacji kodu zarządzanego w aplikacji maklerskiej.** Pakiet `pl.mbank.bmmobile` został opublikowany z zachowaniem pełnej czytelności kodu IL. Dekompilacja ujawnia oryginalne nazwy typów i metod, w tym `AuthService`, `RsaKeyStoreCertService` oraz `ActivateTokenLogonAsync`, adresy endpointów API, identyfikator klienta SSO `bmmobile2:sso` oraz kompletną logikę biznesową. W procesie budowania nie zastosowano zaciemniania nazw, szyfrowania ciągów znakowych ani ochrony metadanych. Zaniechanie to radykalnie obniża koszt analizy inżynierii wstecznej.

**MBA-B-02: Obecność stałego parametru client\_secret w publicznym kliencie mobilnym.** Plik konfiguracyjny aplikacji zawiera zaszyte poświadczenia klienta OAuth2/OIDC: `AppClientId = bmmobile2:bm` z parametrem `AppClientSecret = FE813C06-***-DAB7C8B3F3E2` oraz `AppSsoClientId = bmmobile2:sso` z parametrem `AppSsoClientSecret = C594B5A9-***-B8023B03D2B5`. Zakres uprawnień obejmuje flagę `offline_access ... openid` umożliwiającą pobieranie długoterminowych tokenów odświeżających. Zgodnie ze specyfikacją RFC 8252 aplikacja mobilna stanowi klienta publicznego, który nie jest w stanie zagwarantować poufności klucza symetrycznego. Wobec braku obfuskacji binarnej wskazanej w ustaleniu MBA-B-01 wyodrębnienie tych wartości następuje bezpośrednio po rozpakowaniu zasobów. Architektura uwierzytelniania w publicznym kliencie mobilnym powinna opierać się na protokole PKCE określonym w specyfikacji RFC 7636, bez polegania na poufności parametru `client_secret`. Wymóg weryfikacji sekretu przez usługę IdentityServer podlega sprawdzeniu w teście dynamicznym.

**Spójność architektury bezpieczeństwa w portfolio aplikacji:** Zestawienie obu aplikacji wykazuje rozbieżność standardów bezpieczeństwa. Główna aplikacja bankowa stosuje deterministyczne szyfrowanie preferencji uniwersalnym kluczem opisanym w ustaleniu MBA-A-08, natomiast aplikacja maklerska została opublikowana bez obfuskacji kodu zgodnie z ustaleniem MBA-B-01 oraz z jawnym parametrem uwierzytelniającym wskazanym w MBA-B-02. Wskazuje to na brak jednolitego standardu ochrony w procesie wytwórczym obu produktów.

## 8.13. Analiza podatności na modyfikację i repakowanie aplikacji

W architekturze aplikacji mobilnych kod binarny oraz zasoby lokalne podlegają bezpośredniej kontroli użytkownika urządzenia. Lokalne mechanizmy sprawdzające integralność mogą zostać zmodyfikowane w procesie inżynierii wstecznej.

Czynniki techniczne wpływające na podatność pakietu na modyfikację:

1. **Jawność kodu zarządzanego:** Brak obfuskacji modułów .NET MAUI w aplikacji `pl.mbank.bmmobile` pozwala na bezpośrednią dekompilację do kodu C# i analizę logiki uwierzytelniania, co udokumentowano w ustaleniu MBA-B-01.
2. **Klientowa detekcja środowiska:** Procedura wykrywania roota omówiona w rozdziale 8.5.1 nie przerywa działania aplikacji i podlega neutralizacji przez modyfikację instrukcji warunkowych w kodzie bajtowym.
3. **Determinizm lokalnej kryptografii:** Zastosowanie stałego klucza zaszytego w kodzie APK, wskazane w ustaleniu MBA-A-08, eliminuje barierę ochrony lokalnych plików konfiguracyjnych.
4. **Architektura hybrydowa i selektywne osłony:** Zastosowanie zaawansowanego silnika RASP platformy uPaid MDC ogranicza się do modułu płatności i tokenizacji kart. Główna przestrzeń klas DEX oraz biblioteki .NET MAUI w aplikacji maklerskiej pozostają w standardowych formatach podlegających bezpośredniej dekompilacji.

**Rola weryfikacji serwerowej jako granicy zaufania:**
Kluczowa granica bezpieczeństwa spoczywa po stronie serwera bankowego. Obejmuje ona wymuszenie atestacji Play Integrity API podczas rejestracji urządzenia i autoryzacji operacji oraz kryptograficzne powiązanie sesji ze sprzętowym modułem bezpieczeństwa. Brak rygorystycznej walidacji po stronie backendu przenosi ryzyko na użytkownika końcowego.

**Zagrożenia wynikające z modyfikacji pakietu:**
Głównym wektorem ryzyka jest tworzenie trojanizowanych klonów aplikacji oraz kampanie phishingowe. Możliwość odtworzenia interfejsu i przepływów logowania sprzyja dystrybucji złośliwych pakietów poza oficjalnym sklepem Google Play w celu wyłudzania poświadczeń użytkowników.

## 8.14. Studium przypadku: kalibracja heurystyk anti-fraud i analiza prawno-techniczna procedur wsparcia

Aplikacja pobiera z systemu szereg parametrów telemetrycznych służących do oceny integralności środowiska wykonawczego, szczegółowo opisanych w rozdziale 8.5: pełną listę zainstalowanych pakietów na podstawie uprawnienia `QUERY_ALL_PACKAGES` w zestawieniu z czarną listą 643 skrótów, odczyt parametrów identyfikacyjnych przez metodę `tb1.q`, stan flag systemowych oraz status połączeń głosowych. Dane te zasilają silnik oceny ryzyka po stronie serwera. Rozbudowane zestawy reguł heurystycznych niosą ze sobą ryzyko błędnej klasyfikacji poprawnych operacji.

W toku eksploatacji środowiska badawczego udokumentowano blokadę karty i odmowy płatności, oceniane przez autora jako prawdopodobny błąd fałszywie pozytywny (false positive). Przyczyna decyzji serwerowej pozostaje niepotwierdzona. Odpowiedź banku i granice wniosków opisano w aktualizacji z 14 października w rozdziale 8.14.6.

### 8.14.1. Architektura stacji badawczej i kontekst wieloletniej eksploatacji WSA

Badania zrealizowano na stacji roboczej Lenovo ThinkPad T14 opartej na procesorze Intel Core Ultra architektury Lunar Lake pod kontrolą systemu operacyjnego Windows 11. Podsystem Windows Subsystem for Android w wersji 2407 (kompilacja 2407.40000.4.0, jądro x86\_64, Android 13) stanowi dla autora stałe środowisko produkcyjne i analityczne wykorzystywane nieprzerwanie od ponad pięciu lat.

Eksploatacja podsystemu WSA w architekturze stacjonarnej Windows wynika z określonych przesłanek inżynierskich:

- **Niezależność operacyjna:** Pełne uniezależnienie procesów uwierzytelniania i autoryzacji bankowej od fizycznego aparatu telefonicznego. Pozostawienie smartfona poza zasięgiem nie blokuje ciągłości realizowanych operacji.
- **Automatyzacja procesów rynkowych:** Przed przeniesieniem portfela inwestycyjnego do brokera XTB stacja WSA służyła do zautomatyzowanego nadzorowania zleceń na Giełdzie Papierów Wartościowych za pośrednictwem modułu eMakler powiązanego z aplikacją główną. Integracja w jednym środowisku systemowym umożliwiała równoległe przetwarzanie arkuszy notowań i deterministyczną realizację zleceń maklerskich.
- **Metodologia badawcza i suwerenność uprawnień:** W środowisku profesjonalnej inżynierii wstecznej, dekompilacji oraz analizy niskopoziomowej jądra systemu praca z maksymalnymi uprawnieniami stanowi warunek konieczny. Badacze zajmujący się architekturą hiperwizorów i rozbiorem kodu maszynowego operują bezpośrednio na koncie roota w Linuksie oraz na wbudowanym koncie Administratora w Windows. Sztuczne mechanizmy separacji uprawnień, takie jak sudo czy architektury UAC i LUA, projektowane są pod kątem przeciętnego konsumenta reprezentującego mainstreamowe wzorce użytkowe. Dla inżyniera analizującego kod bajtowy i struktury pamięci wprowadzenie pośrednich warstw restrykcji stoi w sprzeczności z elementarną metodologią dowodową, gdyż ogranicza transparentność rejestracji zdarzeń systemowych.

### 8.14.2. Przebieg incydentu i asymetria nałożonej blokady

W dniu 22 września 2026 r. wystąpiła blokada bezpieczeństwa opisana poniżej. Autor wiązał ją z aktywnością sesji WSA, lecz nie ma dostępu do reguł i logów decyzyjnych banku. Związek przyczynowy z WSA nie został potwierdzony w odpowiedzi reklamacyjnej. Zaobserwowano następującą asymetrię ograniczeń:

1. **Dostęp aplikacyjny:** Sesja mobilna w środowisku WSA zachowała pełną funkcjonalność. Aplikacja pozwalała na logowanie, wgląd w stan rachunku oraz autoryzację dyspozycji przelewów.
2. **Blokada instrumentu płatniczego:** Systemy anti-fraud nałożyły prewencyjną blokadę transakcyjną na powiązaną z kontem fizyczną kartę płatniczą.
3. **Skutek operacyjny:** Dwie kolejne próby wykonania standardowej transakcji bezgotówkowej w lokalu Bosko na warszawskim Ursynowie na kwotę 18 PLN zakończyły się dwukrotną odmową autoryzacji ze strony terminala płatniczego. Wobec braku możliwości realizacji płatności kartą powstała konieczność sporządzenia pisemnego oświadczenia, zdeponowania dokumentów tożsamości u personelu lokalu w charakterze zastawu oraz udania się z małżonką po fizyczną gotówkę w celu uregulowania zobowiązania.

### 8.14.3. Przebieg procedury odblokowania na infolinii bankowej

Kontakt z infolinią banku w celu przywrócenia funkcjonalności karty trwał około pół godziny. Procedura ujawniła strukturalne ograniczenia personelu pierwszej linii wsparcia (L1):

- **Weryfikacja tożsamości i asymetria dokumentów:** Konsultant zażądał numeru PESEL (podanego niezwłocznie z pamięci), imienia ojca, nazwiska panieńskiego matki oraz serii i numeru dowodu tożsamości. Podanie serii i numeru fizycznego dowodu osobistego spotkało się z odmową autoryzacji z uwagi na brak zgodności z bieżącym rekordem w kartotece bankowej. System weryfikacyjny nie zawiera podpowiedzi określającej zarejestrowany typ dokumentu. Posiadacz rachunku musi bezbłędnie pamiętać, czy w relacji z bankiem posłużył się tradycyjnym dokumentem tożsamości, czy cyfrowym mDowodem. W celu dokończenia weryfikacji badacz uruchomił w podsystemie WSA aplikację mObywatel, odczytał serię oraz numer mDowodu i podał je konsultantowi, co skutkowało poprawnym uwierzytelnieniem tożsamości.
- **Brak kompetencji technicznych personelu:** Konsultant wykazał brak wiedzy na temat technologii wirtualizacji Hyper-V oraz środowiska WSA w systemie Windows. Wyrażał zdziwienie faktem uruchomienia aplikacji Android na komputerze PC oraz dopytywał o techniczne nazwy pakietów, w tym komponenty powiązane z modułem eMakler.
- **Narzucenie warunku skanowania antywirusowego:** Konsultant uzależnił odblokowanie karty płatniczej od bezwzględnego przeprowadzenia pełnego skanowania stacji roboczej za pomocą dwóch niezależnych programów antywirusowych. Wyjaśnienia badacza dotyczące architektury systemu Windows, obecności zintegrowanego mechanizmu Microsoft Defender oraz bezcelowości skanowania środowiska inżynierskiego konsumenckimi narzędziami firm trzecich zostały odrzucone z powołaniem na sztywny skrypt procedury.
- **Znoszenie blokad wielopoziomowych:** Konsultant pierwszej linii realizował procedurę ściśle według wyuczonych na szkoleniach skryptów operacyjnych. Wykazał się jednak cierpliwością i stopniowo usuwał blokady zarejestrowane na różnych poziomach systemów bankowych, obejmujące reguły antyfraudowe, filtry antyphishingowe oraz blokady transakcyjne na samej karcie. Całość rozmowy została utrwalona w rejestratorze połączeń banku. W efekcie przeprowadzonej procedury wszystkie ograniczenia zostały zdjęte, co pozwoliło na kontynuację stabilnej pracy aplikacji w podsystemie WSA w szóstym roku jego eksploatacji.

### 8.14.4. Granice prawne blokady i wymogu skanowania

Bank może stosować blokady bezpieczeństwa. Nie oznacza to jednak, że każda blokada i każdy warunek jej zdjęcia są automatycznie uzasadnione. [Art. 41 ust. 2–4 ustawy o usługach płatniczych](https://api.sejm.gov.pl/eli/acts/DU/2026/623/text.pdf#page=38) określa przesłanki blokowania instrumentu, obowiązek powiadomienia z wyjątkami oraz odblokowanie po ustaniu podstaw blokady. Art. 42 ust. 3 wymaga obiektywnych, niedyskryminujących i proporcjonalnych postanowień umowy dotyczących użytkowania instrumentu.

**Korekta podstawy prawnej:** we wcześniejszej wersji artykułu błędnie wskazano art. 43 ust. 3. Właściwy przepis o odblokowaniu to **art. 41 ust. 4**. Samo potwierdzenie tożsamości klienta nie dowodzi jeszcze, że ustąpiło ryzyko przejęcia urządzenia lub poświadczeń. Analogicznie sama obecność WSA, roota czy narzędzi badawczych nie dowodzi infekcji.

W opisanej rozmowie konsultant miał uzależniać odblokowanie karty od dwóch skanów antywirusowych. Bank powinien wyjaśnić, czy była to rekomendacja, czy wiążący warunek, na jakim postanowieniu umowy oparty i jaki związek miał z ryzykiem dotyczącym fizycznej karty. Dwa skany nie są dowodem integralności systemu. Ich sens zależy od konkretnego zagrożenia, zakresu badania i kryteriów zakończenia procedury.

Na podstawie samej relacji z rozmowy nie przesądzam naruszenia prawa. Nie znam pełnej dokumentacji decyzji, obowiązującej umowy ani analizy banku. Oceny wymaga zasadność blokady i proporcjonalność warunku jej zdjęcia. Rozróżniam przy tym blokadę karty od całkowitego odcięcia dostępu do środków: według opisanego przebiegu dostęp aplikacyjny pozostał czynny.

### 8.14.5. Postępowanie reklamacyjne: zgłoszenie REK122475856

Całkowity czas trwania incydentu zamknął się w przedziale około dwóch godzin. Przedział ten objął dwukrotną odmowę autoryzacji w punkcie handlowym, procedurę zabezpieczenia roszczenia oświadczeniem i depozytem dokumentów tożsamości, pozyskanie fizycznej gotówki w asyście małżonki, około trzydziestominutowe połączenie z infolinią bankową oraz sformułowanie dokumentacji reklamacyjnej.

Wobec kwestionowanej blokady karty, publicznej odmowy autoryzacji oraz opisanych problemów procedury wsparcia, w dniu 25 września 2026 r. skierowano do banku oficjalne zgłoszenie reklamacyjne. Bank zarejestrował sprawę pod sygnaturą **REK122475856** w kategorii *Jakość obsługi Klienta* z ustawowym terminem odpowiedzi.

W treści zgłoszenia wskazano na:

- wystąpienie błędu fałszywie pozytywnego w heurystyce detekcji nadużyć;
- poniesioną szkodę wizerunkową oraz uciążliwość operacyjną wynikającą z dwukrotnego odrzucenia płatności 18 PLN w lokalu Bosko, konieczności pozostawiania dokumentów pod zastaw i awaryjnego pozyskiwania gotówki;
- procedurę infolinii trwającą około pół godziny i operującą na sztywnych skryptach weryfikacyjnych;
- żądanie kalibracji reguł decyzyjnych profilu pod kątem środowiska WSA oraz trwałego przywrócenia pełnej funkcjonalności karty;
- zastrzeżenie skierowania sprawy do UOKiK oraz KNF w przypadku powtórzenia kwestionowanych blokad. Właściwość instytucji i możliwość interwencji Rzecznika Finansowego doprecyzowano w aktualizacji z 14 października.

### 8.14.6. Aktualizacja z 14 października 2026 r.: odpowiedź banku

**mBank odpowiedział na reklamację REK122475856 14 października 2026 r.** Wiadomość zatytułowana „Rozwiązanie reklamacji REK122475856” została doręczona o **10:16:51 czasu polskiego (CEST)**. Datę i godzinę potwierdza nagłówek odbiorczego serwera pocztowego w zachowanym pliku MSG. Nie publikuję pliku wiadomości, prywatnych adresów ani danych pracownika. Poniżej omawiam stanowisko banku i jego braki.

#### Chronologia i termin

| Zdarzenie | Data / czas |
|---|---|
| Incydent opisany w rozdziale 8.14.2 | 22 września 2026 r. |
| Złożenie reklamacji według dokumentacji artykułu | 25 września 2026 r. |
| Doręczenie odpowiedzi | 14 października 2026 r., 10:16:51 CEST |
| Od daty reklamacji do odpowiedzi | **19 dni kalendarzowych, 13 dni roboczych** |
| Od daty incydentu do odpowiedzi | **22 dni kalendarzowe** |

Dni robocze policzono od następnego dnia po 25 września, pomijając soboty i niedziele; w tym przedziale nie przypadały polskie święta ustawowe. Jeżeli bank otrzymał reklamację 25 września, piętnasty dzień roboczy przypadał **16 października 2026 r.** Czasu nie liczę z dokładnością do godzin od złożenia reklamacji, ponieważ nie mam tu potwierdzonej godziny jej wpływu.

**Odpowiedź nie była spóźniona względem limitu 15 dni roboczych** dla reklamacji dotyczących usług płatniczych. Wynika on z [art. 15a ust. 2 ustawy o usługach płatniczych](https://api.sejm.gov.pl/eli/acts/DU/2026/623/text.pdf#page=25); [Rzecznik Finansowy wyjaśnia również zasady terminów reklamacyjnych](https://rf.gov.pl/jak-zlozyc-reklamacje-do-banku-lub-ubezpieczyciela-wazne-zmiany-od-13-lutego-2026-r/). Wewnętrzna kategoria „Jakość obsługi Klienta” nie zastępuje oceny rzeczywistego przedmiotu reklamacji. Dziewiętnaście dni oczekiwania na tak ogólną odpowiedź oceniam krytycznie, ale nie przedstawiam tego jako dowodu przekroczenia ustawowego terminu.

#### Co bank potwierdził, a czego nie wyjaśnił

Bank podziękował za zgłoszenie i wyraził nadzieję, że pomoże ono w tworzeniu algorytmów szacowania ryzyka. Odmówił przekazania szczegółów systemu antyfraudowego, powołując się na tajemnicę przedsiębiorstwa. Przywołał art. 50 ust. 2 Prawa bankowego, wyraził ubolewanie z powodu niedogodności związanych z blokadą i poinformował, że obecnie rachunek nie podlega ograniczeniom wpływającym na jego działanie.

To potwierdza **blokadę bezpieczeństwa i deklarowany brak aktualnych ograniczeń**. Nie potwierdza natomiast błędu algorytmu, związku przyczynowego z WSA, przeprowadzenia analizy przyczyny źródłowej ani zmiany reguł. Sformułowanie o przyszłym wykorzystaniu zgłoszenia nie jest potwierdzeniem wykonanej poprawki.

W odpowiedzi zabrakło odniesienia do konkretnych pytań:

- Dlaczego ograniczono fizyczną kartę przy zachowaniu dostępu aplikacyjnego? Różne kanały mogą mieć różne mechanizmy ochrony, ale bank nie wyjaśnił tej decyzji w opisanym przypadku.
- Czy sprawdzono przebieg rozmowy z infolinią i wymóg dwóch skanów antywirusowych? Czy był to warunek odblokowania, czy zalecenie?
- Jaka podstawa umowna uzasadniała ten warunek i co miało potwierdzać usunięcie zagrożenia?
- Czy bank uznał reklamację w całości, częściowo, czy ją odrzucił? Które zastrzeżenia rozpatrzył i z jakim wynikiem?

**Nie oczekuję publikacji kodu, progów scoringowych ani sygnatur detekcyjnych. Oczekuję rozliczenia konkretnej decyzji i procedury.** Tajemnica przedsiębiorstwa może uzasadniać ochronę mechaniki systemu. Sama w sobie nie wyjaśnia, dlaczego odpowiedź pomija wymóg narzucony przez konsultanta i nie wskazuje wyniku rozpatrzenia poszczególnych zastrzeżeń.

#### Czy podstawa prawna banku wystarcza?

**Bank prawidłowo powołuje obowiązek szczególnej staranności w ochronie środków.** [Art. 50 ust. 2 Prawa bankowego](https://api.sejm.gov.pl/eli/acts/DU/2026/38/text.pdf#page=54) rzeczywiście go ustanawia. Ustęp 1 tego samego artykułu przewiduje swobodę dysponowania środkami, z możliwością ograniczeń umownych. Obowiązek ochrony nie stanowi więc samodzielnego dowodu prawidłowości każdej decyzji operacyjnej.

[Art. 9 ustawy reklamacyjnej](https://eli.gov.pl/api/acts/DU/2026/823/text/I/D20260823.pdf#page=5) wymaga m.in. wyczerpującego stanowiska wobec zastrzeżeń i wskazania odpowiednich fragmentów umowy; uzasadnienie faktyczne i prawne jest wymagane, chyba że reklamację rozpatrzono zgodnie z wolą klienta. Odpowiedź zawiera ogólny przepis prawa, ale nie wskazuje konkretnego postanowienia umowy ani jasno nie rozstrzyga zastrzeżeń dotyczących obsługi.

Jeżeli roszczenia nie zostały uwzględnione, **art. 10** wymaga także pouczenia o dostępnych drogach dalszego dochodzenia praw. W otrzymanej wiadomości takiego pouczenia nie ma. Potwierdzenie braku bieżących ograniczeń nie jest jednoznaczne z uwzględnieniem całej reklamacji. To konkretna kwestia do wyjaśnienia przez bank i oceny przez Rzecznika Finansowego, a nie podstawa do ogłoszenia z góry prawomocnego naruszenia.

#### Właściwa droga dalszego działania

Zasadne jest żądanie uzupełnienia stanowiska banku o rozstrzygnięcie zastrzeżeń, podstawę umowną i ocenę procedury infolinii oraz zabezpieczenie nagrania rozmowy i dokumentacji blokady. Żądanie należy skierować przez [oficjalny kanał reklamacyjny mBanku](https://www.mbank.pl/pomoc/reklamacje/); wiadomość z odpowiedzią informuje, że odpisanie na nią nie przekazuje sprawy konsultantom.

**W sporze indywidualnym właściwym kolejnym adresatem jest [Rzecznik Finansowy](https://rf.gov.pl/dla-klientow/postepowania-interwencyjne/).** Wniosek powinien zawierać reklamację, odpowiedź, potwierdzenie wpływu oraz chronologię zdarzeń. Interwencja jest bezpłatna, lecz nie stanowi wiążącego rozstrzygnięcia sporu.

[KNF przyjmuje informacje o nieprawidłowościach](https://www.knf.gov.pl/dla_konsumenta/sposob_przyjmowania_informacji_nieprawidlowosci) na potrzeby nadzoru; nie rozstrzyga indywidualnego roszczenia klienta. [UOKiK ocenia praktyki naruszające zbiorowe interesy konsumentów](https://uokik.gov.pl/public/naruszanie-interesow-konsumentow). Zawiadomienie do tego urzędu ma sens jako sygnał o możliwej powtarzalnej procedurze, ale jeden incydent nie dowodzi sam w sobie naruszenia interesów zbiorowych.

**Wniosek inżynierski:** sprawa nie kończy się na zdjęciu blokady. Brakuje informacji, czy decyzja była zasadna, czy procedura odblokowania miała podstawę i czy zgłoszenie doprowadziło do jakiejkolwiek korekty. To pozostają pytania otwarte. Ogólna deklaracja bezpieczeństwa nie zastępuje odpowiedzi na reklamację dotyczącą konkretnego działania systemu.

## 9. Zestawienie ustaleń

| ID | Ustalenie | Ocena ryzyka | Pewność i status weryfikacji |
|---|---|---|---|
| **MBA-A-01** | `BiometricSettingsDeeplinkActivity` wyeksportowana bez uprawnień | **Niskie** | Potwierdzone; metoda `onCreate()` przekierowuje do wewnętrznego widoku bez przetwarzania parametrów wejściowych |
| **MBA-A-02** | FaceTec SDK w `libPhoenixAndroid.so`: brak binariów dla architektury x86\_64, przetwarzanie biometrii przez podmiot trzeci | **Średnie** | Potwierdzone; komponent nieaktywny w środowisku x86\_64 |
| **MBA-A-03** | Konfiguracja TrustKit: 21 domen, 78 skrótów SPKI SHA-256, `enforcePinning=true` | **Wzorcowe** | Potwierdzone statycznie; pełna redundancja pinów, brak trybu debug |
| **MBA-A-04** | `StartActivity` wyeksportowana bez deklaracji uprawnień | **Niskie** | Potwierdzone; brak aktywnej sesji wymusza procedurę logowania |
| **MBA-A-05** | Biała lista `webapps_popup_white_list.json`: reguła `^https://.*` dopuszcza dowolną domenę HTTPS | **Średnie / P0** | Potwierdzone statycznie; brak ograniczenia domenowego w trybie okna wyskakującego |
| **MBA-A-06** | Moduł SAM: KDF PKCS#12 PBE z 10 000 iteracji SHA-256 oraz szyfr AES-CTR bez uwierzytelnienia AEAD dla klucza prywatnego | **Średnie** | Potwierdzone statycznie w klasach `pl.mbank.sam.internal.j0` oraz `h0` |
| **MBA-A-07** | `EMaklerProvider`: asymetria autoryzacji IPC, pominięcie walidacji podpisu wywołującego w metodzie `insert()` przy uprawnieniu dangerous | **Średnie** | Potwierdzone statycznie w kodzie `EMaklerProvider` |
| **MBA-A-08** | Szyfrowanie `mBank.xml`: klucz AES zapisany w pliku, uniwersalny klucz zapasowy w APK, deterministyczny IV | **Wysokie** | Potwierdzone statycznie i wykonaniowo; pełna deszyfracja 142 wpisów z kopii MIUI |
| **MBA-O-01** | Flaga `requestLegacyExternalStorage=true` w manifeście | **Niskie** | Potwierdzone; zaszłość zgodnościowa dla poziomu API 29 |
| **MBA-O-02** | Uprawnienia `QUERY_ALL_PACKAGES` oraz `READ_PHONE_STATE` | **Prywatność** | Potwierdzone; enumeracja pakietów pod kątem czarnej listy 643 skrótów (AnyDesk, TeamViewer), detekcja stanu rozmowy dla ochrony anty-vishingowej oraz próba odczytu IMEI w `tb1.q` |
| **MBA-O-03** | Konfiguracja `FileProvider` ze ścieżką bazową `path="."` | **Niskie** | Potwierdzone statycznie; uprawnienia ograniczone do komponentów wewnętrznych |
| **MBA-O-04** | Bazy sygnatur `security-packages-list.json` (643 wpisy) oraz `accessibility-white-list.json` (1648 wpisów) | **Wzorcowe** | Potwierdzone; identyfikacja AnyDesk i TeamViewer, biała lista usług TalkBack, dynamiczna synchronizacja z serwerem i telemetria zagrożeń |
| **MBA-O-05** | Weryfikacja `SecLib.initialize()`: kod stanu 9 w środowisku WSA przy wykryciu pliku su w zmiennej PATH, brak blokady procesu | **Architektura** | Potwierdzone analizą w IDA oraz punktem zaczepienia Fridy |
| **MBA-O-06** | Baza `nmbMobile` SQLite bez szyfrowania: wyłącznie słowniki systemowe | **Bezpieczne** | Potwierdzone; brak danych finansowych i poświadczeń |
| **MBA-B-01** | Brak obfuskacji kodu w aplikacji maklerskiej `pl.mbank.bmmobile`: pełna jawność typów i metod w kodzie zarządzanym | **Średnie** | Potwierdzone; dekompilacja kodu IL z kontenera AssemblyStore |
| **MBA-B-02** | Obecność parametru `client_secret` w konfiguracji aplikacji maklerskiej dla zakresu `offline_access` | **Średnie** | Potwierdzone; wartości zapisane w konfiguracji `Pomelo.App` |
| **MBA-O-07** | Blokada karty i procedura odblokowania; podejrzenie false positive | **Operacyjne** | Odmowy płatności i relacja z infolinii opisane w rozdziale 8.14; bank potwierdził blokadę i brak bieżących ograniczeń w odpowiedzi z 14.10.2026. Przyczyna serwerowa i związek z WSA niepotwierdzone |
| **MBA-O-08** | Silnik RASP platformy uPaid MDC: dynamiczny loader xe3.b, most o.h z 32 metodami JNI, autoweryfikacja obfuskacji R8 oraz sum kontrolnych DEX | **Wzorcowe** | Potwierdzone statycznie; deszyfracja XOR nazwy native-library, natychmiastowe zerowanie tożsamości po naruszeniu integralności |

---

## 10. Weryfikacja dynamiczna w środowisku WSA: Android 13, x86\_64, Magisk

### 10.1. Ochrona bufora ekranu: weryfikacja flagi FLAG\_SECURE

Weryfikacja właściwości aktywnego okna zalogowanej sesji dla komponentu `MainActivity` poleceniem `dumpsys window windows`:

```text
Window #5 Window{47cee61 u0 pl.mbank/...MainActivity}:
  mAttrs={(0,0)(fillxfill) ...
    fl=LAYOUT_IN_SCREEN FORCE_NOT_FULLSCREEN SECURE LAYOUT_INSET_DECOR SPLIT_TOUCH HARDWARE_ACCELERATED DRAWS_SYSTEM_BAR_BACKGROUNDS
```

Flaga `SECURE` pozostaje aktywna zarówno w oknie głównym, jak i w stanie niezalogowanym w widoku `NotAuthenticatedMainActivity`. Próba wykonania zrzutu ekranu narzędziem systemowym:

```powershell
adb shell screencap -p /sdcard/screencap_test.png
```

Zwróciła plik o zerowym rozmiarze. Podsystem SurfaceFlinger zablokował dostęp do bufora klatki.

### 10.2. Rejestracja konta tożsamości w podsystemie Android AccountManager

Polecenie `dumpsys account` potwierdziło utworzenie konta tożsamości przez usługę mBanku w trakcie procedury parowania:

```text
Accounts: 2
  Account {name=mBank, type=pl.mbank}
  ServiceInfo: AuthenticatorDescription {type=pl.mbank}, ComponentInfo{pl.mbank/pl.mbank.core.authenticator.NmbAuthenticationService}, uid 10088
```

### 10.3. Weryfikacja odsyłaczy i widoków WebView za pomocą frameworka Frida

Do obserwacji warstwy WebView i odsyłaczy głębokich wykorzystano proces `frida-server 17.18.0` skompilowany dla architektury android-x86\_64 oraz skrypt `05_webview_deeplink_tracer.js` monitorujący metody `WebView.loadUrl`, `loadData`, `WebViewClient`, `DeeplinkTranslator` oraz `Uri.parse`. Badanie miało charakter wyłącznie obserwacyjny.

Wyniki wykonaniowe weryfikujące powierzchnię ataku:

- **Brak dostarczalności odsyłaczy głębokich między aplikacjami:** Próba uruchomienia adresu `mbankpl://app/...` przez polecenie `am start` została odrzucona przez system z wyjątkiem `SecurityException: not exported` dla identyfikatora UID 10088. Komponent `MainActivity` obsługujący odsyłacze nie posiada atrybutu `exported`, co zapobiega wstrzyknięciu adresu przez aplikację zewnętrzną.
- **Natywne renderowanie krytycznych formularzy:** Podczas pełnego przejścia procedury wniosku kredytowego skrypt śledzący nie zarejestrował wywołań metody `WebView.loadUrl`. Całość interfejsu renderowana jest za pomocą natywnych komponentów platformy Android, z pominięciem kontenera WebView i mostka JavaScript. Zawęża to zakres występowania podatności MBA-A-05 do modułów WebApps o mniejszym krytycznym znaczeniu biznesowym.
- **Stopniowane egzekwowanie ograniczeń środowiska:** Wyniki weryfikacji dynamicznej potwierdziły wnioski z rozdziału 8.5.1. Aplikacja zachowuje stabilność działania i umożliwia autoryzację kodem PIN w zmodyfikowanym środowisku systemowym.

---

## 11. Metodologia i zasady prowadzenia audytu

> Badanie prowadzono wyłącznie w trybie pasywnej obserwacji na aktywnym profilu badawczym. W trakcie testów wykluczono inicjowanie jakichkolwiek operacji finansowych, w szczególności przelewów, zmian limitów transakcyjnych oraz modyfikacji danych profilowych. Wykorzystanie frameworka Frida ograniczało się do monitorowania wywołań API bez modyfikacji logiki biznesowej. Testy obiektów Intent realizowano z użyciem bezpiecznych identyfikatorów testowych niewywołujących skutków po stronie serwerowej infrastruktury bankowej.

---

## 12. Wnioski końcowe i synteza porównawcza: iluzja heurystyk a rzeczywistość inżynierska

### 12.1. Nadreaktywność reguł anti-fraud i zjawisko zmęczenia alertami

Opisany incydent wskazuje na potrzebę zbadania kalibracji reguł i procedury odblokowania. Blokada fizycznej karty oraz dwie odmowy płatności 18 PLN są faktami opisanymi w studium przypadku. False positive pozostaje oceną autora, ponieważ bank nie ujawnił podstaw konkretnej decyzji. Nie utożsamiam samego działania aplikacji w WSA z dowodem bezpieczeństwa całej sesji.

Taksowanie standardowych, bezpiecznych operacji mianem incydentów krytycznych generuje zjawisko powszechnie określane w inżynierii bezpieczeństwa jako zmęczenie alertami bądź znieczulica alarmowa. Zjawisko to pociąga za sobą dwustronne konsekwencje operacyjne:

- **Degradacja procesów pierwszej linii wsparcia L1:** Personel infolinii, konfrontowany z ciągłym napływem fałszywych alarmów generowanych przez nadreaktywne reguły scoringowe, traci zdolność odróżniania rzeczywistych ataków od standardowych zachowań użytkowników. Prowadzi to do mechanicznego odczytywania wyuczonych skryptów, chaosu decyzyjnego oraz braku zrozumienia technicznego kontekstu problemu.
- **Zniechęcenie konsumenta i koszty wizerunkowe:** Skazanie klienta na dwugodzinny proces wyjaśniający, konieczność deponowania dokumentów tożsamości pod zastaw w lokalu usługowym oraz awaryjne pozyskiwanie gotówki na drobny rachunek budzi uzasadnioną frustrację. Tworzy to wizerunek instytucji operującej chaotycznie, w której nadmierny rygor proceduralny uderza w niewinnego użytkownika.

### 12.2. Podatność seniorów i osób naiwnych na socjotechnikę w warunkach dysfunkcyjnych procedur

Nieracjonalne zachowania personelu bankowego stwarzają bezpośrednie zagrożenie dla grup klientów o niższych kompetencjach cyfrowych, w szczególności seniorów, emerytów oraz osób podatnych na manipulację.

Gdy oficjalna infolinia uzależnia odblokowanie karty od instalacji lub uruchomienia dodatkowych narzędzi bez jasnego wyjaśnienia, może utrudniać klientowi odróżnienie prawidłowej procedury od socjotechniki. Zalecenie skanowania nie jest tym samym co żądanie zdalnego dostępu czy przekazania poświadczeń. Ryzyko dotyczy przyzwyczajenia do wykonywania niejasnych poleceń pod presją zagrożenia. Przestępcy stosujący vishing oraz caller ID spoofing wykorzystują następujący schemat:

1. Wprowadzają stan zagrożenia rzekomym włamaniem na rachunek.
2. Powołują się na rygorystyczne procedury bezpieczeństwa instytucji finansowej.
3. Wymuszają zainstalowanie narzędzi zewnętrznych w postaci aplikacji zdalnego pulpitu AnyDesk, TeamViewer bądź QuickSupport, ewentualnie żądają podania poświadczeń autoryzacyjnych.

Jasna procedura powinna wskazywać, jak klient może zweryfikować kanał kontaktu, czego bank nigdy nie żąda i jaki jest cel zalecanego działania. Brak tych granic może zwiększać podatność na manipulację. To ocena ryzyka projektowego, nie dowód, że opisany incydent doprowadził do oszustwa.

### 12.3. Asymetria obrony binarnej: prostota manipulacji pakietem mBanku a długotrwała persystencja w WSA

Analiza binarna pakietów mBanku ujawnia jaskrawą dysproporcję między deklarowanym rygorem reguł scoringowych a architekturą zabezpieczeń w kodzie:

- **Selektywna izolacja silnika RASP:** Zaawansowane mechanizmy obfuskacji dynamicznej oraz autoweryfikacji RASP platformy uPaid MDC zostały ograniczone do podsystemu tokenizacji płatniczej. Główny kontener aplikacji oraz przepływy bankowości ogólnej podlegają standardowej translacji R8, umożliwiając analizę przepływów biznesowych.
- **Jawność modułu maklerskiego .NET MAUI:** Komponent `pl.mbank.bmmobile` zawiera jawny kod pośredni C# IL w strukturze AssemblyStore. Pozwala to na pełną dekompilację logiki handlowej i procedur uwierzytelniania w ogólnodostępnych narzędziach dekompilacyjnych.
- **Pasywność ogólnych mechanizmów integralności:** Wbudowana funkcja `SecLib.initialize()` po napotkaniu binarnego pliku su zwraca kod stanu 9, powstrzymując się od przerwania działania procesu. W połączeniu z uniwersalnym kluczem zapasowym zaszytym w pliku APK oraz deterministycznym wektorem IV, ogólny poziom odporności kontenera na modyfikację pozostaje niski.

Dostępność kodu ułatwia analizę i przygotowanie hipotez dotyczących modyfikacji klienta. Nie dowodzi jednak, że zmodyfikowany APK zachowa autoryzację po stronie serwera, ominie wszystkie mechanizmy integralności albo umożliwi wieloletnie wykonywanie nieuprawnionych operacji. W tym audycie nie wykazano takiej persystencji ani przejęcia rachunku. Otwarte pozostaje pytanie o spójność ochrony kanałów: dlaczego w opisanym incydencie zablokowano fizyczną kartę, podczas gdy dostęp aplikacyjny pozostał czynny. Odpowiedź banku z 14 października tej kwestii nie wyjaśnia.

### 12.4. Triada architektoniczna: mBank w zestawieniu z eDO App oraz mObywatelem

Zestawienie mBanku z dwiema wcześniej poddanymi audytowi aplikacjami tożsamościowymi pozwala na wyciągnięcie syntetycznych wniosków inżynierskich:

flowchart TD subgraph EDO["eDO App 1.7.1 PWPW"] direction TB E1(["Karta kryptograficzna e-dowód standard ICAO 9303"]) --> E2[["Protokoły PACE i Chip Authentication"]] E2 --> E3[("Brak magazynu danych w spoczynku / TEE Keystore")] E3 --> E4(["Wysoki rygor sprzętowy / trudna adaptacja pod WSA"]) end subgraph MOB["mObywatel 4.87.2 COI"] direction TB M1(["mDowód w sprzętowym Android Keystore"]) --> M2[["Hybryda: CMS bez verify i stała sól PBKDF2"]] M2 --> M3[("SQLCipher / podatność formatów archiwalnych")] M3 --> M4(["Średni rygor / bezpośrednie wykonanie na WSA"]) end subgraph MBK["mBank 3.122.4 mBank S.A."] direction TB B1(["Koegzystencja: TEE Keystore obok archiwum XML"]) --> B2[["Moduł RASP uPaid w płatnościach / kod 9 w SecLib"]] B2 --> B3[("Telemetria pakietów QUERY_ALL_PACKAGES")] B3 --> B4(["Fałszywe alarmy antyfraud / wygoda na WSA"]) end 

| Wymiar architektury | eDO App 1.7.1 PWPW | mObywatel 4.87.2 COI | mBank 3.122.4 mBank S.A. |
|---|---|---|---|
| **Kotwica zaufania** | Fizyczny procesor karty e-dowodu w standardzie ICAO 9303 | Sprzętowy Android Keystore z TEE i StrongBox dla mDowodu | Sprzętowy moduł TEE Android Keystore dla tokenów oraz algorytmy serwerowe |
| **Dane w spoczynku** | Brak lokalnego magazynu tożsamości; odczyt w locie przez NFC | SQLCipher dla mLegitymacji; klucze prywatne w pamięci aplikacji | Magazyn CryptoPreferences chroniony TEE Keystore obok archiwalnego pliku mBank.xml |
| **Ochrona binarna i obfuskacja** | Spłaszczenie przepływu i szyfrowanie literałów narzędziem Dotfuscator | Standardowa minifikacja R8; usterki w opublikowanym kodzie UI Kotlin | R8 oraz RASP uPaid MDC z dynamicznym loaderem XOR; otwarty kod brokera eMakler |
| **Detekcja środowiska** | Ścisłe powiązanie z silnikiem Mono; awarie SIMD pod Houdini | Weryfikacja integralności platformy przez silnik Conscrypt i Play Integrity | Kod stanu 9 w SecLib oraz reset sesji portfela w module RASP uPaid MDC |
| **Skuteczność ochrony** | Pełna odporność na klonowanie tożsamości bez fizycznej karty | Odporność mDowodu; dług techniczny w podsystemach legacy | Wysoki rygor w płatnościach i TLS; nadwrażliwość heurystyk antyfraudowych |
| **Eksploatacja w WSA** | Wymaga zaawansowanego patchowania ICU, trimmera i instrukcji SIMD | Działa bezpośrednio w środowisku maszyny wirtualnej ART | Działa stabilnie od ponad pięciu lat; pełna wygoda inżynierska |

### 12.5. Podsumowanie: wygoda inżynierska a specyfika architektury wielowarstwowej

Ocena architektury mBanku prowadzi do jednoznacznej konkluzji:

- **Perspektywa inżyniera i badacza systemowego:** Z punktu widzenia programisty, analityka niskopoziomowego oraz zaawansowanego inwestora giełdowego, środowisko stworzone przez mBank jest wyjątkowo wygodne i pożądane. Brak uciążliwych blokad roota w głównym oknie aplikacji, jawność struktur modułu maklerskiego eMakler oraz stabilne działanie w podsystemie Windows Subsystem for Android na wydajnej stacji roboczej Lenovo ThinkPad T14 z procesorem architektury Lunar Lake umożliwiają automatyzację procesów rynkowych, swobodę badań binarnych oraz suwerenne zarządzanie finansami bez sięgania po fizyczny telefon.
- **Perspektywa masowego bezpieczeństwa bankowego:** Z punktu widzenia powszechnych standardów ochrony kapitału i tożsamości, ocena końcowa 8,1/10 (bardzo dobra z minusem, w skali ocen: bardzo dobry z minusem) odzwierciedla dojrzałość modułów krytycznych oraz obecność długu technologicznego. Zabezpieczenie kanału TLS z użyciem TrustKit i 78 pinów oraz ochrona tokenizacji płatności przez silnik RASP uPaid MDC i sprzętowy TEE Keystore reprezentują wysoki poziom inżynierski. Koegzystencja z archiwalnym magazynem mBank.xml, brak obfuskacji brokera eMakler oraz agresywne heurystyki monitorowania pakietów generujące fałszywe alarmy dla legalnych sesji wyznaczają obszary wymagające dalszych prac modernizacyjnych.

---

*Raport w toku. Data rozpoczęcia: 22 września 2026. Aktualizacja postępowania reklamacyjnego i oceny prawnej: 14 października 2026. Autor: Marek Wesołowski (WESMAR).*

### Add a comment

---

## Navigation

- Parent: [Analizy techniczne (PL)](https://www.kvc.pl/analizy-techniczne-pl.md)
- Previous: [eDO App 1.7.1 — audyt bezpieczeństwa i reverse engineering na WSA](https://www.kvc.pl/analizy-techniczne-pl/edo_app-audyt-bezpieczenstwa.md)
