Złośliwe oprogramowanie szpiegujące, które wciąż pozostaje w fazie tworzenia, jest w stanie odczytywać wiadomości oraz inne poufne dane przesyłane przez użytkowników za pośrednictwem aplikacji WhatsApp.
Jeden z użytkowników Twittera odkrył nowy przykład złośliwego oprogramowania na system Android, o którym natychmiast poinformował w tweecie. Oprogramowanie to wyposażone jest w wiele funkcji szpiegujących, jak na przykład przesyłanie historii przeglądarki, zdjęć, bazy danych aplikacji WhatsApp, w której przechowywane są wszystkie wiadomości. Nie jest na razie jasne, do jakich celów zostało stworzone. Złośliwe oprogramowanie składa się z funkcji MainActivity.class uruchamiającej nową usługę – OwnMe.class. Kod źródłowy powiązanych plików jest odnajdowany w tym miejscu na stronie Github użytkownika earthshakira. OwnMe.class to rozszerzenie klasy Android Service. Chwilę po przywołaniu startService() wykonana zostaje funkcja onStartCommand().
Najpierw pojawia się wyskakujące okienko adresowane do użytkownika z informacją „Service started” (co pozwala sądzić, że ten przykład złośliwego oprogramowania jest nadal w fazie rozwoju). Przestępcy bowiem dążą do tego, by ich działania były jak najbardziej ukryte po to, by nie wzbudzać wśród użytkowników żadnych podejrzeń.
Ponadto funkcja definiuje wiele zmiennych, takich jak upLoadServerUri, android_id, username (nazwa użytkownika), obiekty JSON ping i handshake. Obiekt handshake zawiera informację o pustym polu baterii oraz pustym polu cpu. Puste pola, nieprzypisane nigdzie indziej, również potwierdzają stwierdzenie, iż ten przykład złośliwego oprogramowania jest nadal dopracowywany i w danej chwili nie jest aktywnie wykorzystywany. Po zakończeniu tej procedury złośliwe oprogramowanie przechodzi dalej, do funkcji startExploit().
Gdy złośliwe oprogramowanie ma dostęp do Internetu, w następnej kolejności uruchamia funkcję connectWebSocket(), która przy dostępie do Internetu łączy z ws://ipofthec2:8080. Po otrzymaniu informacji z serwera wykonywana jest funkcja onMessage() z otrzymaną informacją jako parametrem. Następnie tworzy ona obiekt JSON v8, następnie przypisywany do uzyskanego parametru wiadomości. Jeśli przypisanie v8 się nie powiedzie, do serwera przesyłana jest wiadomość null.
W przypadku, gdy wiadomość zawiera słowo „screenshot”, element response (odpowiedź) uzyskuje wartość none (brak), a elementowi type (typ) przypisywana jest wartość response (odpowiedź) obiektu JSON v8. Na tym etapie nie dochodzi jednak do przywołania faktycznej funkcji screenshot i w tym momencie nic nie zostaje przesłane do serwera, co jeszcze mocniej potwierdza założenie o ciągłym doskonaleniu tej funkcji.
W przypadku, gdy wiadomość zawiera słowo “whatsapp”, przywołana zostaje funkcja uploadWhatsApp(), która wykonuje to, co sugeruje jej nazwa: ładuje bazę danych WhatsApp do web c2 w oparciu o następujące zapytanie: “ipofthec2/db/upload_whatsapp.php.
username i android_id pochodzą z uprzednio zdefiniowanych zmiennych ramach funkcji onStartCommand().
W przypadku, gdy wiadomość zawiera słowo “browserhistory”, element response z obiektu JSON v8 otrzymuje zwrotną wartość funkcji getHistory().
Funkcja getHistory() wysyła string zawierający wartości id, tytuł, czas, url i wizyty z zakładek użytkownika. GetHistory() obecnie dostarcza jedynie zachowane zakładki, a nie faktyczną historię przeglądarki mobilnej, co mogłaby sugerować nazwa funkcji.
W przypadku, gdy wiadomość zawiera słowo “ contacts”, element response z obiektu JSON v8 otrzymuje zwrotną wartość funkcji getContacts().
getContacts() zczytuje kontakty z telefonu i dostarcza odpowiedzi w postaci _id kontaktu, wyświetlanej nazwy (display_name) oraz numerów telefonu, jeśli są one dostępne.
W przypadku, gdy wiadomość zawiera słowo “calllog”, element response z obiektu JSON v8 otrzymuje zwrotną wartość funkcji getCallLogs().
Jeśli aplikacja nie posiada zezwolenia android.permission.READ_CALL_LOG, funkcja getCallLogs() odpowie komunikatem „No permission” (brak zezwolenia). W przeciwnym razie kontakty zostaną przeszukane i zostaną dodane wartości nazwa, numer, typ, data i czas trwania do obiektu JSON, następnie odesłane w postaci stringu.
W przypadku, gdy wiadomość zawiera słowo „fetch”, element response z obiektu JSON v8 otrzymuje zwrotną wartość funkcji getBase64(v8.get(“path)).
getBase64() tworzy nową bitmapę w oparciu o dostarczony parametr, którą powinna być lokalna ścieżka pliku obrazu. Gdy obraz przekracza szerokość 480, zostanie on przeskalowany i skompresowany. Wynik zostanie przesłany w postaci stringu w formacie base64.
W przypadku, gdy wiadomość zawiera słowo „gallery”, element response z obiektu JSON v9 otrzymuje zwrotną wartość funkcji v4.get(v5).toString(). Ta zwrotna wartość zawiera ścieżkę, folder i stronę z karty SD. Element id uzyskuje wartość android_id, element page wartość bieżącej strony, a total ilość dostępnych stron.
Funkcja mWebSocketClient.send() przesyła te dane do połączenia WebSocket. Proces powtarza się do momentu, gdy pętla osiągnie maksymalną liczbę dostępnych stron.
W przypadku, gdy wiadomość zawiera słowo “camera”, przywołana zostaje funkcja openCameraVideo() wraz z parametrem typu kamery (tylna lub przednia) i liczbą ramek.
Gdy aktywna wersja SDK urządzenia jest mniejsza niż 21, otwarty zostaje konkretny aparat, który robi zdjęcie (to zdjęcie nie jest przesyłane na serwer). W przeciwnym razie przywołana zostaje funkcja takePictureR().
Funkcja takePictureR() zasadniczo wykonuje zdjęcie na urządzeniu z systemem Android posiadającym wersję SDK wyższą niż 21. Zdjęcie to jest następnie kodowane w oparciu o base64 i umieszczane w obiekcie JSON, a w dalszej kolejności przesyłane do połączenia WebSocket.
Ta funkcja dostarcza informacji o aktualnym poziomie baterii i zużyciu procesora. Jednak nie ma ona zastosowania przy sprawdzaniu treści wiadomości, jak miało to miejsce w przedstawionych powyżej przypadkach komend, dlatego nie jest jeszcze w aktywnym użyciu.
W przypadku, gdy w wiadomości nie zostanie znaleziona żadna komenda, obiekt JSON v8 dodaje wartość „error” (błąd) i „no command found” (nie znaleziono komendy), a następnie odsyła do połączenia WebSocket.
Klasa BootCompletedIntentReceiver.java extends rozszerza klasę BroadCastReceiver. W przypadku otrzymania nowej transmisji funkcja onReceive() sprawdza, czy string “android.intent.action.BOOT_COMPLETED” jest tożsamy z zakładanym działaniem. Jeśli tak faktycznie jest, OwnMe.class zostaje uruchomione jako usługa. Oznacza to, że za każdym razem, gdy urządzenie skończy się uruchamiać, zainicjowana zostanie złośliwa aplikacja.
IoCs and Yara-Zasady
zasada Android_Buhsam_dex_hunt
{
meta:
author (autor) = "Ransombleed" (okup)
description = "Spyware that uses websockets" (oprogramowanie szpiegujące wkorzystujące wtyczki stron www)
stringi:
$a = "OwnMe.java" wide nocase
$a2 = "NetWatcher.java" wide nocase
$a3 = "/db/upload_whatsapp.php?user_name=" wide nocase
$a4 = "/WhatsApp/Databases/msgstore.db.crypt12" wide nocase
$b = "WebSocket" wide nocase
$b2 = "ws://" wide nocase
stan:
1 of ($a*) and 1 of ($b*)
}
Hasła Pliku:
SHA-256 4bed89b58c2ecf3455999dc8211c8a7e0f9e8950cb9aa83cd825b8372b1eaa3d
Analiza przeprowadzona przez RansomBleed, pełny raport dostępny jest pod linkiem: G DATA Whitepaper Android.Trojan-Spy.Buhsam.A [PDF]
Komentarze