Zloupotreba Android medijskih tokova i parsera slika

Tip

Učite i vežbajte AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Učite i vežbajte GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE) Učite i vežbajte Azure Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Podržite HackTricks

Dostava: aplikacije za razmenu poruka ➜ MediaStore ➜ privilegovani parseri

Moderni OEM buildovi redovno pokreću privilegovane indeksere medija koji ponovo skeniraju MediaStore zbog “AI” ili funkcija deljenja. Na Samsung firmware-u pre April 2025 patch-a, com.samsung.ipservice učitava Quram (/system/lib64/libimagecodec.quram.so) i automatski parsira bilo koji fajl koji WhatsApp (ili druge aplikacije) ubace u MediaStore. U praksi, napadač može poslati DNG maskiran kao IMG-*.jpg, sačekati da žrtva dodirne “download” (1-klik), i privilegovani servis će parsirati payload čak i ako korisnik nikada ne otvori galeriju.

$ file IMG-2025-02-10.jpeg
TIFF image data ...
$ exiftool IMG-2025-02-10.jpeg | grep "Opcode List"
Opcode List 1 : [opcode 23], [opcode 23], ...

Ključni zaključci

  • Isporuka zavisi od sistemskog ponovnog parsiranja medija (ne chat klijenta) i stoga nasleđuje dozvole tog procesa (potpuni pristup za čitanje i pisanje galeriji, mogućnost dodavanja novih medija, itd.).
  • Bilo koji image parser dostupan preko MediaStore (vision widgets, wallpapers, AI résumé features, itd.) postaje udaljeno dostupan ako napadač ubedi metu da sačuva medij.

0-click DD+/EAC-3 decoding path (Google Messages ➜ mediacodec sandbox)

Savremeni messaging stackovi takođe automatski dekodiraju audio za transkripciju/pretragu. Na Pixel 9, Google Messages prosleđuje dolazni RCS/SMS audio u Dolby Unified Decoder (UDC) unutar /vendor/lib64/libcodec2_soft_ddpdec.so pre nego što korisnik otvori poruku, čime se 0-click površina proširuje na media codecs.

Ključna ograničenja parsiranja

  • Svaki DD+ syncframe ima do 6 blokova; svaki blok može kopirati do 0x1FF bajtova od strane napadača kontrolisanih skip data u skip buffer (≈ 0x1FF * 6 bajtova po frame-u).
  • The skip buffer is scanned for EMDF: syncword (0xX8) + emdf_container_length (16b) + variable-length fields. emdf_payload_size is parsed with an unbounded variable_bits(8) loop.
  • EMDF payload bytes are allocated inside a custom per-frame “evo heap” bump allocator and then copied byte-by-byte from a bit-reader bounded by emdf_container_length.

Integer-overflow → heap-overflow primitiv (CVE-2025-54957)

  • ddp_udc_int_evo_malloc poravnava alloc_size+extra na 8 bajtova putem total_size += (8 - total_size) % total_size bez detekcije wrap-a. Vrednosti blizu 0xFFFFFFFFFFFFFFF9..FF na AArch64 se skupljaju na veoma mali total_size.
  • Copy loop i dalje koristi logičku payload_length iz emdf_payload_size, tako da bajtovi napadača prepisuju evo-heap podatke van umanjenog chunka.
  • Dužina overflow-a je precizno ograničena od strane napadačem izabranog emdf_container_length; overflow bajtovi su EMDF payload podaci pod kontrolom napadača. Slab allocator se resetuje za svaki syncframe, što daje predvidivu susednost.

Sekundarni read primitiv Ako je emdf_container_length > skipl, EMDF parsiranje čita preko inicijalizovanih skip bajtova (OOB read). Samo po sebi, leaks zeros/known media, ali nakon korumpiranja susedne heap metadata može pročitati nazad korumpiranu regiju da bi potvrdio exploit.

Recept za eksploataciju

  1. Sastaviti EMDF sa ogromnim emdf_payload_size (putem variable_bits(8)) tako da se allocator padding omota u mali chunk.
  2. Podesiti emdf_container_length na željenu dužinu overflow-a (≤ ukupni budžet skip podataka); postaviti overflow bajtove u EMDF payload.
  3. Oblikovati per-frame evo heap tako da mala alokacija stoji pre ciljnih struktura unutar dekoderovog statičkog buffera (≈693 KB) ili dinamičkog buffera (≈86 KB) koji se alocira jednom po decoder instanci.
  4. Opcionalno izabrati emdf_container_length > skipl da bi se nakon korupcije pročitali nazad prepisani podaci iz skip buffera.

Quram-ove greške u DNG opcode interpreteru

DNG fajlovi ugrađuju tri liste opkoda koje se primenjuju u različitim fazama dekodiranja. Quram kopira Adobe-ov API, ali njegov Stage-3 handler za DeltaPerColumn (opcode ID 11) veruje opsezima plane koje dostavi napadač.

Neispravni opsezi plane u DeltaPerColumn

  • Napadači postave plane=5125 i planes=5123 iako Stage-3 slike izlažu samo plane 0–2 (RGB).
  • Quram računa opcode_last_plane = image_planes + opcode_planes umesto plane + count, i nikada ne proverava da li rezultatni opseg plane staje u sliku.
  • Petlja zato piše delta u raw_pixel_buffer[plane_index] sa potpuno kontrolisanim offset-om (npr. plane 5125 ⇒ offset 5125 * 2 bytes/pixel = 0x2800). Svaki opcode dodaje 16-bit float vrednost (0x6666) na ciljnu lokaciju, što daje precizan heap OOB add primitiv.

Pretvaranje inkremenata u proizvoljna pisanja

  • Exploit prvo korumpira Stage-3 QuramDngImage.bottom/right koristeći 480 malformisanih DeltaPerColumn operacija tako da budući opkodi tretiraju ogroman koordinat kao in-bounds.
  • MapTable opkodi (opcode 7) su potom usmereni na te lažne opsege. Korišćenjem substitution table sastavljene od nula ili DeltaPerColumn sa -Inf deltas, napadač može da izuzme bilo koju oblast (zero), a zatim primeni dodatne delte da napiše tačne vrednosti.
  • Pošto parametri opkoda žive unutar DNG metadata, payload može enkodirati stotine hiljada pisanja bez direktnog dodirivanja procesa memorije.

Oblikovanje heapa pod Scudo

Scudo grupiše alokacije po veličini. Quram slučajno alocira sledeće objekte sa identičnim chunk veličinama od 0x30, tako da završe u istom regionu (0x40-byte razmak na heapu):

  • QuramDngImage deskriptori za Stage 1/2/3
  • QuramDngOpcodeTrimBounds i vendor Unknown opkodi (ID ≥14, uključujući ID 23)

Exploit sekvencira alokacije da deterministički pozicionira chunke:

  1. Stage-1 Unknown(23) opkodi (20,000 unosa) prskaju 0x30 chunke koji se kasnije oslobode.
  2. Stage-2 oslobađa te opkode i postavlja novi QuramDngImage unutar oslobođenog regiona.
  3. 240 Stage-2 Unknown(23) unosa se oslobodi, i Stage-3 odmah alocira svoj QuramDngImage plus novi raw pixel buffer iste veličine, ponovo koristeći ta mesta.
  4. Sastavljen TrimBounds opcode pokreće prvi u listi 3 i alocira još jedan raw pixel buffer pre oslobađanja Stage-2 stanja, garantujući susednost “raw pixel buffer ➜ QuramDngImage”.
  5. Još 640 TrimBounds unosa su označena sa minVersion=1.4.0.1 tako da dispatcher preskoči njihovo izvršavanje, ali njihovi backing objekti ostaju alocirani i kasnije postaju ciljevi primitiva.

Ova koreografija stavlja Stage-3 raw buffer odmah pre Stage-3 QuramDngImage, tako da plane-bazirani overflow menja polja unutar deskriptora umesto da ruši nasumično stanje.

Ponovna upotreba vendor “Unknown” opkoda kao data blobova

Samsung ostavlja high bit postavljen u vendor-specifičnim ID-jevima opkoda (npr. ID 23), što instruira interpreter da allocate strukturu ali preskoči izvršenje. Exploit zloupotrebljava te dormant objekte kao heapove pod kontrolom napadača:

  • Opcode liste 1 i 2 Unknown(23) unosi služe kao kontinuirani scratchpad-i za skladištenje payload bajtova (JOP chain na offsetu 0xf000 i shell komanda na 0x10000 relativno u raw bufferu).
  • Pošto interpreter i dalje tretira svaki objekat kao opcode kada se lista 3 procesuira, okupacija vtable-a jednog objekta kasnije je dovoljna da počne izvršavanje podataka napadača.

Kreiranje lažnih MapTable objekata i zaobilaženje ASLR-a

MapTable objekti su veći od TrimBounds, ali kada se desi korupcija layout-a parser rado čita dodatne parametre out-of-bounds:

  1. Iskoristiti linearni write primitiv da delimično prepišete TrimBounds vtable pointer sa srojenom MapTable substitution tabelom koja mapira donja 2 bajta iz susednog TrimBounds vtable-a na MapTable vtable. Samo niskobajtne razlike postoje između podržanih Quram build-ova, tako da jedna 64K lookup tabela može pokriti sedam firmware verzija i svaki 4 KB ASLR slide.
  2. Zakrpiti ostala TrimBounds polja (top/left/width/planes) tako da objekat funkcioniše kao validan MapTable kada se kasnije izvrši.
  3. Izvršiti lažni opcode preko iznuljene memorije. Pošto pointer na substitution table zapravo referencira vtable drugog opkoda, output bajtovi postaju leaked low-order addresses iz libimagecodec.quram.so ili njegovog GOT.
  4. Primijeniti dodatne MapTable prolaze da se te dvosmjerne curenja (two-byte leaks) pretvore u offset-e ka gadget-ima kao što su __ink_jpeg_enc_process_image+64, QURAMWINK_Read_IO2+124, qpng_check_IHDR+624, i libc-ov __system_property_get entry. Napadači efikasno ponovo sagrađuju pune adrese unutar svog sprayanog regiona opkoda bez nativnih memorijskih disclosure API-ja.

Pokretanje prelaza JOP ➜ system()

Kada su gadget pointeri i shell komanda postavljeni unutar opcode spray-a:

  1. Završni talas DeltaPerColumn pisanja dodaje 0x0100 na offset 0x22 Stage-3 QuramDngImage, pomerajući njegov raw buffer pointer za 0x10000 tako da sada referencira napadačev komandni string.
  2. Interpreter počinje da izvršava rep od 1040 Unknown(23) opkoda. Prvi korumpirani unos ima svoju vtable zamenjenu lažnom tabelom na offsetu 0xf000, tako da QuramDngOpcode::aboutToApply resolve-uje qpng_read_data (četvrti unos) iz lažne tabele.
  3. Povezani gadget-i rade: load-uju pointer QuramDngImage, dodaju 0x20 da pokažu na raw buffer pointer, dereferenciraju ga, kopiraju rezultat u x19/x0, zatim skaču kroz GOT slotove prepisane na system. Pošto raw buffer pointer sada pokazuje na napadačev string, finalni gadget izvršava system(<shell command>) unutar com.samsung.ipservice.

Beleške o varijantama alokatora

Postoje dve porodice payload-a: jedna podešena za jemalloc, druga za scudo. Razlikuju se u tome kako su opcode blokovi poredjani da bi se postigla susednost, ali dele iste logičke primitive (DeltaPerColumn bug ➜ MapTable zero/write ➜ bogus vtable ➜ JOP). Scudo-ovo onemogućeno karantinsko ponašanje čini ponovno korišćenje 0x30-byte freelist-a determinističkim, dok jemalloc zavisi od kontrole size-class preko tile/subIFD sizing-a.

References

Tip

Učite i vežbajte AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Učite i vežbajte GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE) Učite i vežbajte Azure Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Podržite HackTricks