Misbruik van Android media-pyplyne en beeldparsers

Tip

Leer en oefen AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Leer en oefen GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE) Leer en oefen Azure Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Ondersteun HackTricks

Aflewering: Boodskap-apps ➜ MediaStore ➜ Geprivilegieerde parsers

Moderne OEM-builds voer gereeld geprivilegieerde media-indekseerders uit wat MediaStore opnuut skandeer vir “AI” of deelkenmerke. Op Samsung-firmware voor die April 2025-patch laai com.samsung.ipservice Quram (/system/lib64/libimagecodec.quram.so) en ontleed outomaties enige lêer wat WhatsApp (of ander apps) in MediaStore neersit.

In die praktyk kan ’n aanvaller ’n DNG stuur wat vermom is as IMG-*.jpg, wag dat die slagoffer op “download” tik (1-klik), en die geprivilegieerde diens sal die payload ontleed selfs al open die gebruiker nooit die galery nie.

$ 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], ...

Belangrike punte

  • Die aflewering vertrou op system media re-parsing (nie die chat client nie) en erf dus daardie proses se permissies (volledige lees/skryf-toegang tot die gallery, vermoë om nuwe media neer te sit, ens.).
  • Enige image parser wat deur MediaStore bereikbaar is (vision widgets, wallpapers, AI résumé features, ens.) word op afstand bereikbaar as die aanvaller ’n teiken kan oorreed om media te stoor.

Quram’s DNG Opcode Interpreter-foute

DNG-lêers heg drie opcode-lyste in wat by verskillende decode-stadia toegepas word. Quram kopieer Adobe se API, maar die Stage-3 handler vir DeltaPerColumn (opcode ID 11) vertrou aanvaller-geskepte plane bounds.

Mislukte vlakgrense in DeltaPerColumn

  • Aanvallers stel plane=5125 en planes=5123 selfs al bloot Stage-3 beelde slegs planes 0–2 (RGB) uit.
  • Quram bereken opcode_last_plane = image_planes + opcode_planes in plaas van plane + count, en kontroleer nooit of die resulterende plane-reeks binne die beeld pas nie.
  • Die loop skryf dus ’n delta na raw_pixel_buffer[plane_index] met ’n volledig beheerbare offset (bv. plane 5125 ⇒ offset 5125 * 2 bytes/pixel = 0x2800). Elke opcode voeg ’n 16-bis float waarde (0x6666) by die geteikende ligging, wat ’n presiese heap OOB add-primitive oplewer.

Om inkremente in arbitraire skrywes te verander

  • Die exploit korrupteer eers Stage-3 se QuramDngImage.bottom/right deur 480 ongemoude DeltaPerColumn-operasies sodat toekomstige opcodes reuse koördinate as in-bounds beskou.
  • MapTable opcodes (opcode 7) word dan op daardie valse bounds gerig. Deur ’n substitusietabel van netto nulles of ’n DeltaPerColumn met -Inf deltas te gebruik, maak die aanvaller enige streek nul en pas dan addisionele deltas toe om presiese waardes te skryf.
  • Omdat die opcode-parameters binne die DNG-metadata leef, kan die payload honderde duisende skrywes enkodeer sonder om prosesgeheue direk te raak.

Heap-vorming onder Scudo

Scudo groepeer allocations volgens grootte. Zufallig ken Quram die volgende objekte toe met identiese 0x30-byte chunk-groottes, sodat hulle in dieselfde streek land (0x40-byte spasiëring op die heap):

  • QuramDngImage descriptors vir Stage 1/2/3
  • QuramDngOpcodeTrimBounds en vendor Unknown opcodes (ID ≥14, insluitend ID 23)

Die exploit reël allocations in ’n volgorde om stukkies deterministies te plaas:

  1. Stage-1 Unknown(23) opcodes (20,000 entries) spray 0x30 chinks wat later vrygestel word.
  2. Stage-2 vrygestel daardie opcodes en plaas ’n nuwe QuramDngImage binne die vrygemaakte streek.
  3. 240 Stage-2 Unknown(23) entries word vrygestel, en Stage-3 ken onmiddellik sy QuramDngImage plus ’n nuwe raw pixel buffer van dieselfde grootte toe en hergebruik daardie plekke.
  4. ’n Geraadpleegde TrimBounds opcode hardloop eerste in lys 3 en allokeer nog ’n raw pixel buffer voordat dit Stage-2 state vrymaak, wat “raw pixel buffer ➜ QuramDngImage” nabuurskap verseker.
  5. 640 addisionele TrimBounds entries word gemerk met minVersion=1.4.0.1 sodat die dispatcher hulle oorslaan, maar hul onderliggende objekte bly geallokeer en word later primitive teikens.

Hierdie choreografie plaas die Stage-3 raw buffer direk voor die Stage-3 QuramDngImage, sodat die plane-gebaseerde overflow velde binne die descriptor draai in plaas van ewekansige state te laat crash.

Hergebruik van vendor “Unknown” Opcodes as Data Blobs

Samsung laat die hoë bit geset in vendor-spesifieke opcode IDs (bv. ID 23), wat die interpreter beveel om die struktuur te allokeer maar die uitvoering oor te slaan. Die exploit misbruik daardie dormante objekte as aanvaller-beheerde heaps:

  • Opcode-lis 1 en 2 Unknown(23) entries dien as aaneenlopende scratchpads om payload-bytes te stoor (JOP chain by offset 0xf000 en ’n shell command by 0x10000 relatief tot die raw buffer).
  • Omdat die interpreter steeds elke objek as ’n opcode behandel wanneer lys 3 verwerk word, is commandeer van een objek se vtable later genoeg om aanvaller-data te begin uitvoer.

Maak valse MapTable-objekte en omseil ASLR

MapTable-objekte is groter as TrimBounds, maar sodra die layout-korrupsie plaasvind, lees die parser vrolik ekstra parameters out-of-bounds:

  1. Gebruik die lineêre skryf-primitive om gedeeltelik ’n TrimBounds vtable-veeerder te oor skryf met ’n vervaardigde MapTable substitusietabel wat die laer 2 bytes van ’n naburige TrimBounds vtable na die MapTable vtable map. Slegs die lae bytes verskil tussen ondersteunende Quram boues, so ’n enkele 64K lookup-tabel kan sewe firmware-weergawes en elke 4 KB ASLR slide hanteer.
  2. Patch die res van die TrimBounds velde (top/left/width/planes) sodat die objek later soos ’n geldige MapTable optree wanneer dit uitgevoer word.
  3. Voer die valse opcode oor geneutraliseerde geheue uit. Omdat die substitusietabel-pen werklik na ’n ander opcode se vtable verwys, word die uitsetbytes leaked low-order addresses van libimagecodec.quram.so of sy GOT.
  4. Pas addisionele MapTable passe toe om daardie twee-bis lekkasies om te skakel in offsets na gadgets soos __ink_jpeg_enc_process_image+64, QURAMWINK_Read_IO2+124, qpng_check_IHDR+624, en libc se __system_property_get entry. Die aanvallers herbou effektief volle adresse binne hul gespraide opcode-streek sonder sagteware native memory disclosure APIs.

Uitlokkering van die JOP ➜ system() oorgang

Sodra die gadget-pointers en shell command binne die opcode spray gepositioneer is:

  1. ’n Finale golf van DeltaPerColumn skrywes voeg 0x0100 by offset 0x22 van die Stage-3 QuramDngImage, wat sy raw buffer pointer met 0x10000 skuif sodat dit nou na die aanvallers se command string verwys.
  2. Die interpreter begin die hekkie van 1040 Unknown(23) opcodes uitvoer. Die eerste gekorrupte entry het sy vtable vervang met die vervalste tabel by offset 0xf000, sodat QuramDngOpcode::aboutToApply qpng_read_data (die 4de inskrywing) uit die vervalste tabel oplos.
  3. Die gekette gadgets voer uit: laai die QuramDngImage pointer, voeg 0x20 by om na die raw buffer pointer te wys, dereferensieer dit, kopieer die resultaat in x19/x0, dan spring deur GOT-slots wat herskryf is na system. Omdat die raw buffer pointer nou die aanvallers-string is, voer die finale gadget system(<shell command>) binne com.samsung.ipservice uit.

Notas oor Allocator-variante

Daar bestaan twee payload-families: een aangepas vir jemalloc, en ’n ander vir scudo. Hulle verskil in hoe opcode-blokke geordend word om nabuurskap te bereik maar deel dieselfde logiese primitives (DeltaPerColumn bug ➜ MapTable zero/write ➜ valse vtable ➜ JOP). Scudo se gedeaktiveerde quarantine maak 0x30-byte freelist-hergebruik deterministies, terwyl jemalloc op size-class beheer via tile/subIFD sizing staatmaak.

Verwysings

Tip

Leer en oefen AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Leer en oefen GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE) Leer en oefen Azure Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Ondersteun HackTricks