Android Media Pipeline’lerini ve Görüntü Ayrıştırıcılarını Kötüye Kullanma
Tip
AWS Hacking’i öğrenin ve pratik yapın:
HackTricks Training AWS Red Team Expert (ARTE)
GCP Hacking’i öğrenin ve pratik yapın:HackTricks Training GCP Red Team Expert (GRTE)
Azure Hacking’i öğrenin ve pratik yapın:
HackTricks Training Azure Red Team Expert (AzRTE)
HackTricks'i Destekleyin
- abonelik planlarını kontrol edin!
- 💬 Discord grubuna veya telegram grubuna katılın ya da Twitter’da bizi takip edin 🐦 @hacktricks_live.**
- Hacking ipuçlarını paylaşmak için HackTricks ve HackTricks Cloud github reposuna PR gönderin.
Dağıtım: Mesajlaşma Uygulamaları ➜ MediaStore ➜ Ayrıcalıklı Ayrıştırıcılar
Modern OEM build’ları, “AI” veya paylaşım özellikleri için MediaStore’u yeniden tarayan ayrıcalıklı medya indeksleyicilerini düzenli olarak çalıştırır. Nisan 2025 yamasından önceki Samsung firmware’lerinde, com.samsung.ipservice Quram (/system/lib64/libimagecodec.quram.so) yükler ve WhatsApp (veya diğer uygulamaların) MediaStore’a bıraktığı herhangi bir dosyayı otomatik olarak ayrıştırır. Pratikte bir saldırgan, IMG-*.jpg olarak gizlenmiş bir DNG gönderebilir, kurbanın “download” (1-click) seçeneğine dokunmasını bekleyebilir ve kullanıcı galeriyi hiç açmasa bile ayrıcalıklı servis payload’u ayrıştıracaktır.
$ 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], ...
Anahtar çıkarımlar
- Teslimat, sistem medya yeniden-parse etmesine (chat client değil) dayanır ve bu nedenle o sürecin izinlerini miras alır (galeriye tam okuma/yazma erişimi, yeni medya bırakma yeteneği, vb.).
MediaStoreüzerinden ulaşılabilen herhangi bir image parser (vision widget’ları, duvar kağıtları, AI résumé özellikleri, vb.) hedefin medyayı kaydetmesi sağlanabilirse uzaktan erişilebilir hale gelir.
0-click DD+/EAC-3 decoding path (Google Messages ➜ mediacodec sandbox)
Modern messaging yığınları ayrıca transkripsiyon/arama için audio’yu otomatik olarak decode eder. Pixel 9’da, Google Messages gelen RCS/SMS audio’yu kullanıcı mesajı açmadan önce /vendor/lib64/libcodec2_soft_ddpdec.so içindeki Dolby Unified Decoder (UDC)’ye verir; bu da 0-click yüzeyini media codec’lerine genişletir.
Önemli parse kısıtları
- Her DD+ syncframe en fazla 6 block içerir; her block attacker-kontrollü skip data’dan skip buffer’a en fazla
0x1FFbyte kopyalayabilir (frame başına ≈0x1FF * 6byte). - Skip buffer, EMDF için taranır:
syncword (0xX8)+emdf_container_length(16b) + variable-length alanlar.emdf_payload_sizeunboundedvariable_bits(8)döngüsü ile parse edilir. - EMDF payload byte’ları custom per-frame bir “evo heap” bump allocator içinde allocate edilir ve sonra
emdf_container_lengthile sınırlandırılmış bir bit-reader’dan byte-by-byte kopyalanır.
Integer-overflow → heap-overflow primitive (CVE-2025-54957)
ddp_udc_int_evo_mallocalloc_size+extra’yı 8 byte hizalar viatotal_size += (8 - total_size) % total_sizewrap tespiti olmadan. AArch64’te0xFFFFFFFFFFFFFFF9..FFyakınındaki değerler küçüktotal_size’lara küçülür.- Kopya döngüsü hala
emdf_payload_size’dan gelen mantıksalpayload_length’i kullanır, dolayısıyla attacker byte’ları evo-heap içindeki küçültülmüş chunk’ın ötesindeki veri ile overwrite yapar. - Overflow uzunluğu attacker tarafından seçilen
emdf_container_lengthile kesin olarak sınırlıdır; overflow byte’ları attacker-kontrolünde EMDF payload verileridir. Slab allocator her syncframe’de resetlendiği için adjacency öngörülebilirdir.
İkincil read primitive
Eğer emdf_container_length > skipl ise EMDF parsing initialize edilmiş skip byte’larının ötesini okur (OOB read). Tek başına sıfırlar/known media leak eder, ancak bitişik heap metadata’yı bozduktan sonra bozulmuş bölgeyi skip buffer’dan geri okuyarak exploit’i doğrulayabilir.
Eksploit tarifi
- Allocator padding’in wrap olmasına neden olacak şekilde büyük
emdf_payload_size(viavariable_bits(8)) içeren EMDF oluşturun. - Taşma uzunluğunu istediğiniz şekilde ayarlamak için
emdf_container_length’i (≤ toplam skip data bütçesi) seçin; overflow byte’larını EMDF payload içine yerleştirin. - Per-frame evo heap’i şekillendirerek küçük allocation’ın decoder’ın static buffer’ı (≈693 KB) veya decoder instance başına bir kez allocate edilen dynamic buffer (≈86 KB) içindeki hedef yapılardan önce oturmasını sağlayın.
- Opsiyonel olarak
emdf_container_length > skiplseçip bozulmadan sonra skip buffer’dan üzerine yazılmış veriyi geri okuyun.
Quram’ın DNG Opcode Interpreter Hataları
DNG dosyaları farklı decode aşamalarında uygulanan üç opcode listesi gömer. Quram Adobe’nun API’sini kopyalıyor, fakat DeltaPerColumn (opcode ID 11) için Stage-3 handler attacker tarafından verilen plane bounds’a güveniyor.
DeltaPerColumn içinde başarısız plane bounds
- Saldırganlar Stage-3 görüntülerin sadece 0–2 (RGB) plane’leri açığa çıkarmasına rağmen
plane=5125veplanes=5123ayarlıyor. - Quram
opcode_last_plane = image_planes + opcode_planes’i hesaplıyor,plane + countyerine, ve ortaya çıkan plane aralığının image içine sığıp sığmadığını hiç kontrol etmiyor. - Döngü bu yüzden
raw_pixel_buffer[plane_index]’e tamamen kontrollü bir offset ile delta yazar (ör. plane 5125 ⇒ offset5125 * 2 bytes/pixel = 0x2800). Her opcode hedeflenen konuma 16-bit float değer (0x6666) ekler ve bu hassas bir heap OOB add primitive verir.
İncrementleri keyfi yazmalara çevirme
- Exploit önce Stage-3
QuramDngImage.bottom/right’ı bozar; 480 malformedDeltaPerColumnoperasyonu ile gelecekteki opcode’ların devasa koordinatları in-bounds olarak değerlendirmesini sağlar. - Ardından
MapTableopcode’ları (opcode 7) bu sahte bound’lara yönlendirilir. Tüm sıfırlardan oluşan bir substitution table veya-Infdeltalı birDeltaPerColumnkullanarak saldırgan herhangi bir bölgeyi sıfırlar, sonra ek deltalara uygulayarak kesin değerler yazar. - Opcode parametreleri DNG metadata içinde yaşadığı için payload yüzbinlerce yazmayı process memory’ye doğrudan dokunmadan encode edebilir.
Scudo Altında Heap Şekillendirme
Scudo allocasyonları boyuta göre bucket’lar. Quram aşağıdaki objeleri aynı 0x30-byte chunk boyutlarıyla allocate eder, böylece aynı bölgeye düşerler (heap’te 0x40-byte spacing):
- Stage 1/2/3 için
QuramDngImagedescriptor’ları QuramDngOpcodeTrimBoundsve vendorUnknownopcode’lar (ID ≥14, ID 23 dahil)
Exploit, chunk’ları deterministik olarak yerleştirmek için allocasyon sıralarını ayarlar:
- Stage-1
Unknown(23)opcode’ları (20,000 entry) daha sonra free edilecek 0x30 chunk’ları spray eder. - Stage-2 bu opcode’ları free eder ve freed bölge içine yeni bir
QuramDngImageyerleştirir. - 240 Stage-2
Unknown(23)entry free edilir ve Stage-3 hemen kendiQuramDngImage’ını plus aynı boyutta yeni bir raw pixel buffer allocate eder, bu bölgeleri yeniden kullanır. - Crafted
TrimBoundsopcode list 3’te ilk çalışır ve Stage-2 state’i free etmeden önce başka bir raw pixel buffer allocate eder; bu “raw pixel buffer ➜ QuramDngImage” adjacency’yi garanti eder. - 640 ek
TrimBoundsentryminVersion=1.4.0.1olarak işaretlenir, dispatcher onları atlar fakat backing objektler allocate kalır ve daha sonra primitive hedeflere dönüşür.
Bu koreografi Stage-3 raw buffer’ı Stage-3 QuramDngImage’ın hemen önüne koyar, böylece plane-tabanlı overflow descriptor içindeki alanları çevirir ve rastgele state çökertmez.
Vendor “Unknown” Opcode’larını Data Blob olarak Yeniden Kullanma
Samsung vendor-specific opcode ID’lerinin high bit’ini setli bırakır (ör. ID 23), bu interpreter’a yapıyı allocate etmesini ama execution’ı atlamasını söyler. Exploit bu uyuyan objeleri attacker-kontrollü heap’lar olarak suistimal eder:
- Opcode list 1 ve 2
Unknown(23)entry’leri payload byte’larını saklamak için ardışık scratchpad’ler olarak hizmet eder (raw buffer relatifinde offset 0xf000’de JOP chain ve 0x10000’de bir shell komutu). - Interpreter list 3 işlenirken her bir objeyi hala bir opcode gibi ele aldığından, daha sonra bir objenin vtable’ını ele geçirmek tek başına attacker verisini çalıştırmaya başlamaya yeter.
Sahte MapTable Objeleri Oluşturma ve ASLR’yi Aşma
MapTable objeleri TrimBounds’dan daha büyük, fakat layout corrup sonrası parser memnuniyetle ekstra parametreleri OOB okur:
- Linear write primitive kullanılarak bir
TrimBoundsvtable pointer’ı kısmen overwrite edilir; buraya crafted birMapTablesubstitution table yerleştirilir. Bu tablo komşu birTrimBoundsvtable’ından düşük 2 byte’ıMapTablevtable’ına map eder. Desteklenen Quram build’leri arasında sadece düşük byte’lar farklı olduğu için tek bir 64K lookup table yedi firmware versiyonunu ve her 4 KB ASLR slide’ını kapsayabilir. TrimBounds’un geri kalan alanları (top/left/width/planes) patch’lenir, böylece obje ileride çalıştırıldığında geçerli birMapTablegibi davranır.- Sahte opcode sıfırlanmış hafıza üzerinde çalıştırılır. Çünkü substitution table pointer gerçekte başka bir opcode’un vtable’ına işaret eder, output byte’lar
libimagecodec.quram.soveya onun GOT’undan leaked düşük sıralı adresler olur. - Ek
MapTablepass’ları bu iki byte’lık leak’leri__ink_jpeg_enc_process_image+64,QURAMWINK_Read_IO2+124,qpng_check_IHDR+624gibi gadget’lara ve libc’nin__system_property_getgirişine yönelik offset’lere çevirir. Saldırganlar native memory disclosure API’lerine dokunmadan sprayed opcode bölgesinde tam adresleri yeniden inşa eder.
JOP ➜ system() Geçişini Tetikleme
Gadget pointer’ları ve shell komutu opcode spray içinde yerleştirildikten sonra:
- Son bir dalga
DeltaPerColumnwrite’ı Stage-3QuramDngImage’ın offset 0x22’sine0x0100ekler, raw buffer pointer’ını 0x10000 kaydırır ve artık attacker komut string’ine referans verir. - Interpreter 1040
Unknown(23)opcode’unun tail’ini çalıştırmaya başlar. İlk bozulmuş entry’nin vtable’ı offset 0xf000’deki forged table ile değiştirilmiştir, böyleceQuramDngOpcode::aboutToApplyfake table’danqpng_read_data’yı (4. giriş) çözer. - Zincirlenmiş gadget’lar şu adımları yapar:
QuramDngImagepointer’ını yükle, raw buffer pointer’ına işaret etmek için 0x20 ekle, dereference et, sonucux19/x0içine kopyala, sonra GOT slot’larısystemolacak şekilde yeniden yazılmış olan yerlere atla. Raw buffer pointer artık attacker string’e eşit olduğundan, son gadgetsystem(<shell command>)’ucom.samsung.ipserviceiçinde çalıştırır.
Allocator Varyantları Hakkında Notlar
İki payload ailesi vardır: biri jemalloc için tune edilmiş, diğeri scudo için. Bunlar adjacency elde etmek için opcode blok sıralamalarında farklılık gösterir, ancak aynı mantıksal primitive’leri paylaşırlar (DeltaPerColumn bug ➜ MapTable zero/write ➜ bogus vtable ➜ JOP). Scudo’nun devre dışı bırakılmış quarantine’ı 0x30-byte freelist reuse’u deterministik kılar; jemalloc ise tile/subIFD boyutlandırması ile size-class kontrolüne dayanır.
References
- Project Zero – A look at an Android ITW DNG exploit
- Project Zero – Pixel 0-click: CVE-2025-54957 in Dolby UDC
Tip
AWS Hacking’i öğrenin ve pratik yapın:
HackTricks Training AWS Red Team Expert (ARTE)
GCP Hacking’i öğrenin ve pratik yapın:HackTricks Training GCP Red Team Expert (GRTE)
Azure Hacking’i öğrenin ve pratik yapın:
HackTricks Training Azure Red Team Expert (AzRTE)
HackTricks'i Destekleyin
- abonelik planlarını kontrol edin!
- 💬 Discord grubuna veya telegram grubuna katılın ya da Twitter’da bizi takip edin 🐦 @hacktricks_live.**
- Hacking ipuçlarını paylaşmak için HackTricks ve HackTricks Cloud github reposuna PR gönderin.


