Misbruik van Android Media-pipelines 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: Messaging Apps ➜ MediaStore ➜ Geprivilegieerde Parsers

Moderne OEM-boues voer gereeld geprivilegieerde media-indekseerders uit wat MediaStore weer deursoek 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 plaas. In praktyk kan ’n aanvaller ’n DNG stuur wat as IMG-*.jpg vermom is, wag dat die slagoffer op “download” tik (1-klik), en die geprivilegieerde diens sal die payload ontleed selfs al open die gebruiker nooit die gallery 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

  • Aflewering berus op stelsel media-herontleding (nie die chat-kliënt nie) en erflik 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 remote-bereikbaar as die aanvaller ’n teiken oortuig om media te stoor.

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

Moderne messaging stacks dekodeer ook outomaties audio vir transkripsie/soektog. Op Pixel 9 sal Google Messages binnekomende RCS/SMS-audio voor die gebruiker die boodskap oopmaak aan die Dolby Unified Decoder (UDC) in /vendor/lib64/libcodec2_soft_ddpdec.so oorhandig, wat die 0-click aanvalsvlak na media-codecs uitbrei.

Belangrike parse-beperkings

  • Elke DD+ syncframe het tot 6 blocks; elke block kan tot 0x1FF bytes van aanvaller- beheerste skip data na ’n skip buffer kopieer (≈ 0x1FF * 6 bytes per frame).
  • Die skip buffer word gesoek vir EMDF: syncword (0xX8) + emdf_container_length (16b) + variable-length fields. emdf_payload_size word met ’n onbeperkte variable_bits(8)-lus geparseer.
  • EMDF payload-bytes word toegeken binne ’n pasgemaakte per-frame “evo heap” bump allocator en dan byte-vir-byte gekopieer uit ’n bit-reader wat deur emdf_container_length beperk word.

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

  • ddp_udc_int_evo_malloc rig alloc_size+extra uit na 8 bytes via total_size += (8 - total_size) % total_size sonder wrap-detektering. Waardes naby 0xFFFFFFFFFFFFFFF9..FF krimp tot klein total_size op AArch64.
  • Die kopiëlus gebruik steeds die logiese payload_length van emdf_payload_size, so aanvaller-bytes oorskryf evo-heap data verby die verkleinde stuk.
  • Die oorlooplengte word presies begrens deur die aanvaller-gekose emdf_container_length; oorloop-bytes is aanvaller-beheerde EMDF payload-data. Die slab allocator word elke syncframe gereset, wat voorspelbare aanligging gee.

Sekondêre lees-primitief As emdf_container_length > skipl, lees EMDF-parsing verby geïnisialiseerde skip-bytes (OOB read). Alleenlik dit leaks zeros/known media, maar nadat aangrensende heap-metadata gekorrupteer is kan dit die gekorrupteerde streek teruglees om die exploit te valideer.

Eksploitasie-resep

  1. Konstrueer EMDF met reuse emdf_payload_size (via variable_bits(8)) sodat allocator-padding in ’n klein stuk omslaan.
  2. Stel emdf_container_length op die verlangde oorlooplengte (≤ totale skip data-begroting); plaas oorloop-bytes in die EMDF payload.
  3. Vorm die per-frame evo heap sodat die klein toekenning voor teikenstrukture in die decoder se statiese buffer (≈693 KB) of dinamiese buffer (≈86 KB) sit wat eenkeer per decoder-instansie toegeken word.
  4. Opsioneel kies emdf_container_length > skipl om na korrupsie die oor-geskryfde data uit die skip buffer terug te lees.

Quram se DNG Opcode Interpreter Foute

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

Foutiewe plane bounds in DeltaPerColumn

  • Aanvallers stel plane=5125 en planes=5123 selfs al stel Stage-3 beelde slegs plane 0–2 (RGB) bloot.
  • 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 lus 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-bit float waarde (0x6666) by die geteikende ligging, wat ’n presiese heap OOB add-primitief lewer.

Om inkremente in arbitrary writes te omskakel

  • Die exploit korrupteer eers Stage-3 QuramDngImage.bottom/right met 480 malformed DeltaPerColumn-operasies sodat toekomstige opcodes enorme koördinate as in-bounds beskou.
  • MapTable-opcodes (opcode 7) word dan op daardie vals bounds gemik. Deur ’n substitusietabel van net nulle of ’n DeltaPerColumn met -Inf deltas te gebruik, verwyder die aanvaller enige streek, 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 Shaping Onder Scudo

Scudo groepeer toewysings volgens grootte. Quram gebeur om die volgende objekte met identiese 0x30-byte stukgroottes toe te ken, 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 orden toewysings om deterministies stukkies te plaas:

  1. Stage-1 Unknown(23) opcodes (20,000 inskrywings) spray 0x30 stukkies wat later vrygemaak word.
  2. Stage-2 vrymaak daardie opcodes en plaas ’n nuwe QuramDngImage binne die vrygemaakte streek.
  3. 240 Stage-2 Unknown(23) inskrywings word vrygemaak, en Stage-3 ken onmiddellik sy QuramDngImage plus ’n nuwe raw pixel buffer van dieselfde grootte toe, wat daardie plekke hergebruik.
  4. ’n Gekonstruëerde TrimBounds opcode loop eerste in lys 3 en ken nog ’n raw pixel buffer toe voordat Stage-2 state vrygemaak word, wat “raw pixel buffer ➜ QuramDngImage” aangrensendheid waarborg.
  5. 640 addisionele TrimBounds inskrywings word minVersion=1.4.0.1 gemerk sodat die dispatcher hulle oorslaan, maar hul agterliggende objekte bly toegeken en word later primêre teikens.

Hierdie choreografie plaas die Stage-3 raw buffer direk voor die Stage-3 QuramDngImage, sodat die plane-gebaseerde oorloop velde binne die descriptor flips in plaas van lukraak toestand te laat crash.

Hergebruik van Vendor “Unknown” Opcodes as Databloeie

Samsung laat die hoë bit aan in vendor-spesifieke opcode IDs (bv. ID 23), wat die interpreter instrueer om die struktuur te allocate maar uitvoer te oorslaan. Die exploit misbruik daardie dormante objekte as aanvaller-beheerde heaps:

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

Konstrueer van Vals MapTable Objekte & Omseiling van ASLR

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

  1. Gebruik die lineêre skryf-primitief om gedeeltelik ’n TrimBounds vtable-pen te oor skryf met ’n gekonstrueerde MapTable substitusietabel wat laer 2 bytes van ’n aangrensende TrimBounds vtable na die MapTable vtable map. Net die lae bytes verskil tussen ondersteunde Quram builds, 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.
  3. Voer die vals opcode oor ge-zerode geheue uit. Omdat die substitusietabel-pen eintlik 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-byte leaks 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 inset te omskep. Die aanvallers bou effens volle adresse binne hul gesprayde opcode-streek sonder native memory disclosure APIs.

Triggereing van die JOP ➜ system() Oorskakeling

Sodra die gadget-penne en shell-opdrag binne die opcode-spray opgestel is:

  1. ’n Finale golf van DeltaPerColumn skrywes voeg 0x0100 by offset 0x22 van die Stage-3 QuramDngImage, wat sy raw buffer-pen met 0x10000 skuif sodat dit nou na die aanvaller-opdrag-string verwys.
  2. Die interpreter begin die staart van 1040 Unknown(23) opcodes uitvoer. Die eerste gekorrumpeerde inskrywing het sy vtable vervang met die vervalste tabel by offset 0xf000, so QuramDngOpcode::aboutToApply los qpng_read_data (die 4de inskrywing) uit die vals tabel op.
  3. Die geketende gadgets voer uit: laai die QuramDngImage pen, voeg 0x20 by om by die raw buffer-pen uit te kom, dereferenceer dit, kopieer die resultaat in x19/x0, en spring dan deur GOT-slotte wat na system herskryf is. Omdat die raw buffer-pen nou gelyk is aan die aanvaller-string, voer die finale gadget system(<shell command>) binne com.samsung.ipservice uit.

Aantekeninge oor Allocator-variantes

Daar bestaan twee payload-families: een ingestel vir jemalloc, ’n ander vir scudo. Hulle verskil in hoe opcode-blokke georden word om aangrensendheid te bereik, maar deel dieselfde logiese primitiewe (DeltaPerColumn bug ➜ MapTable zero/write ➜ vals vtable ➜ JOP). Scudo se gedeaktiveerde kwarantyn maak 0x30-byte freelist-hergebruik deterministies, terwyl jemalloc op grootte-klassiebeheer via tile/subIFD-sikering 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