Android Media Pipelines और Image Parsers का दुरुपयोग

Tip

AWS हैकिंग सीखें और अभ्यास करें:HackTricks Training AWS Red Team Expert (ARTE)
GCP हैकिंग सीखें और अभ्यास करें: HackTricks Training GCP Red Team Expert (GRTE) Azure हैकिंग सीखें और अभ्यास करें: HackTricks Training Azure Red Team Expert (AzRTE)

HackTricks का समर्थन करें

Delivery: Messaging Apps ➜ MediaStore ➜ Privileged Parsers

आधुनिक OEM बिल्ड अक्सर privileged media indexers चलाते हैं जो “AI” या शेयरिंग फीचर्स के लिए MediaStore को नियमित रूप से फिर से स्कैन करते हैं। Samsung firmware पर April 2025 patch से पहले, com.samsung.ipservice Quram (/system/lib64/libimagecodec.quram.so) को लोड करता है और स्वचालित रूप से उन किसी भी फ़ाइल को parse कर लेता है जिन्हें WhatsApp (या अन्य ऐप्स) MediaStore में डालते हैं। व्यवहार में, एक attacker IMG-*.jpg के रूप में भेस किया गया एक DNG भेज सकता है, पीड़ित के “download” (1-क्लिक) पर टैप करने का इंतज़ार कर सकता है, और privileged service payload को parse कर लेगा भले ही user कभी gallery न खोले।

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

मुख्य निष्कर्ष

  • डिलीवरी system media re-parsing (not the chat client) पर निर्भर करती है और इसलिए यह उस प्रक्रिया की permissions inherited कर लेती है (gallery के लिए full read/write access, नए media डालने की क्षमता, आदि)।
  • कोई भी image parser जो MediaStore के माध्यम से पहुँच योग्य है (vision widgets, wallpapers, AI résumé features, आदि) दूर से पहुँच योग्य बन जाता है अगर attacker लक्ष्य को मीडिया save करने के लिए राज़ी कर सके।

Quram के DNG Opcode Interpreter बग

DNG फ़ाइलें तीन opcode सूचियाँ embed करती हैं जो अलग decode stages पर लागू होती हैं। Quram Adobe के API की नकल करता है, लेकिन इसका Stage-3 handler DeltaPerColumn (opcode ID 11) attacker-सप्लाई किए गए plane bounds पर भरोसा करता है।

DeltaPerColumn में plane bounds का विफल होना

  • Attackers plane=5125 और planes=5123 सेट करते हैं जबकि Stage-3 images केवल planes 0–2 (RGB) ही एक्सपोज़ करते हैं।
  • Quram opcode_last_plane = image_planes + opcode_planes compute करता है न कि plane + count, और कभी यह चेक नहीं करता कि प्राप्त plane range image के भीतर फिट होता है या नहीं।
  • इसलिए loop raw_pixel_buffer[plane_index] पर एक delta लिखता है एक पूरी तरह नियंत्रित offset के साथ (उदा., plane 5125 ⇒ offset 5125 * 2 bytes/pixel = 0x2800)। हर opcode लक्षित स्थान पर 16-bit float मान (0x6666) जोड़ता है, जिससे एक सटीक heap OOB add primitive बनता है।

increments को arbitrary writes में बदलना

  • exploit पहले Stage-3 QuramDngImage.bottom/right को 480 malformed DeltaPerColumn ऑपरेशनों से corrupt करता है ताकि आने वाले opcodes विशाल coordinates को in-bounds मानें।
  • फिर MapTable opcodes (opcode 7) को उन नकली bounds पर निशाना बनाया जाता है। सभी zeros वाला substitution table या -Inf deltas वाला DeltaPerColumn इस्तेमाल करके, attacker किसी भी क्षेत्र को zero कर देता है, फिर अतिरिक्त deltas लागू करके सटीक मान लिखता है।
  • क्योंकि opcode parameters DNG metadata के अंदर रहते हैं, payload सैकड़ों हजारों writes encode कर सकता है बिना process memory को सीधे छुए।

Scudo के तहत Heap Shaping

Scudo allocations को size के हिसाब से buckets करता है। Quram कुछ ऑब्जेक्ट्स को identical 0x30-byte chunk sizes में allocate करता है, इसलिए वे एक ही region में land होते हैं (heap पर 0x40-byte spacing):

  • QuramDngImage descriptors for Stage 1/2/3
  • QuramDngOpcodeTrimBounds and vendor Unknown opcodes (ID ≥14, including ID 23)

Exploit allocations की sequence बनाता है ताकि chunks deterministic तरीके से place हों:

  1. Stage-1 Unknown(23) opcodes (20,000 entries) 0x30 chunks spray करते हैं जो बाद में free होते हैं।
  2. Stage-2 उन opcodes को free करता है और freed region के अंदर नया QuramDngImage रखता है।
  3. 240 Stage-2 Unknown(23) entries free किए जाते हैं, और Stage-3 तुरंत अपना QuramDngImage और उसी साइज का नया raw pixel buffer allocate करता है, उन spots को reuse करते हुए।
  4. एक crafted TrimBounds opcode list 3 में पहले चलता है और Stage-2 state को free करने से पहले एक और raw pixel buffer allocate करता है, यह सुनिश्चित करता है कि “raw pixel buffer ➜ QuramDngImage” adjacency रहे।
  5. 640 अतिरिक्त TrimBounds entries को minVersion=1.4.0.1 के रूप में चिह्नित किया गया है ताकि dispatcher उन्हें skip करे, पर उनके backing objects allocated रहते हैं और बाद में primitive targets बन जाते हैं।

यह choreography Stage-3 raw buffer को तुरंत Stage-3 QuramDngImage से पहले रख देता है, इसलिए plane-based overflow descriptor के अंदर फ़ील्ड्स फ्लिप कर देता है बजाय कि random state crash होने के।

Vendor “Unknown” Opcodes को Data Blobs के रूप में पुन: उपयोग करना

Samsung vendor-specific opcode IDs में high bit सेट रखता है (उदा., ID 23), जो interpreter को उस structure को allocate करने का निर्देश देता है पर execution छोड़ देता है। exploit उन dormant objects को attacker-controlled heaps के रूप में abuse करता है:

  • Opcode list 1 और 2 के Unknown(23) entries contiguous scratchpads के रूप में काम करते हैं payload bytes स्टोर करने के लिए (JOP chain offset 0xf000 पर और shell command 0x10000 पर raw buffer के सापेक्ष)।
  • क्योंकि interpreter तब भी प्रत्येक object को opcode के रूप में मानता है जब list 3 process की जाती है, किसी एक object की vtable पर कब्ज़ा कर लेना बाद में attacker data के execution को शुरू करने के लिए पर्याप्त होता है।

Bogus MapTable Objects बनाना & ASLR को बायपास करना

MapTable objects TrimBounds से बड़े होते हैं, लेकिन एक बार layout corruption हो जाने पर parser खुशी-खुशी extra parameters आउट-ऑफ-बाउंड पढ़ लेता है:

  1. linear write primitive का उपयोग करके partial रूप से एक TrimBounds vtable pointer को overwrite किया जाता है एक crafted MapTable substitution table से जो lower 2 bytes को पड़ोसी TrimBounds vtable से MapTable vtable पर map करता है। supported Quram builds के बीच केवल low bytes अलग होते हैं, इसलिए एक single 64K lookup table सात firmware versions और हर 4 KB ASLR slide को संभाल सकता है।
  2. बाकी TrimBounds फ़ील्ड्स (top/left/width/planes) को patch किया जाता है ताकि object बाद में execute होने पर वैध MapTable जैसा व्यवहार करे।
  3. zeroed memory पर fake opcode execute किया जाता है। क्योंकि substitution table pointer असल में किसी दूसरे opcode की vtable को reference करता है, output bytes leaked low-order addresses बन जाते हैं from libimagecodec.quram.so या उसकी GOT।
  4. अतिरिक्त MapTable पास लागू करके उन two-byte leaks को उन gadgets की ओर offsets में convert किया जाता है जैसे __ink_jpeg_enc_process_image+64, QURAMWINK_Read_IO2+124, qpng_check_IHDR+624, और libc का __system_property_get entry। attackers प्रभावी तौर पर अपने sprayed opcode region के अंदर native memory disclosure APIs के बिना full addresses reconstruct कर लेते हैं।

JOP ➜ system() ट्रांज़िशन ट्रिगर करना

एक बार gadget pointers और shell command opcode spray के अंदर staged हो जाएँ:

  1. अंतिम wave के DeltaPerColumn writes Stage-3 QuramDngImage के offset 0x22 पर 0x0100 जोड़ते हैं, जिससे उसका raw buffer pointer 0x10000 से शिफ्ट हो जाता है और अब attacker command string को reference करता है।
  2. Interpreter 1040 Unknown(23) opcodes की tail execute करना शुरू कर देता है। पहला corrupted entry उसकी vtable को offset 0xf000 पर बने forged table से बदल दिया गया है, इसलिए QuramDngOpcode::aboutToApply fake table से qpng_read_data (चौथा एंट्री) resolve करता है।
  3. chained gadgets क्रियाएँ करती हैं: QuramDngImage pointer load करना, raw buffer pointer की ओर point करने के लिए 0x20 जोड़ना, उसे dereference करना, परिणाम को x19/x0 में copy करना, फिर GOT slots के माध्यम से jump करना जिन्हें system पर rewrite किया गया है। क्योंकि raw buffer pointer अब attacker string को पॉइंट कर रहा है, final gadget system(<shell command>) execute कर देता है inside com.samsung.ipservice

Allocator Variants पर नोट्स

दो payload families मौजूद हैं: एक jemalloc के लिए tuned, दूसरा scudo के लिए। वे opcode blocks के ordering में अलग होते हैं ताकि adjacency हासिल हो, पर उनके पास वही logical primitives होते हैं (DeltaPerColumn bug ➜ MapTable zero/write ➜ bogus vtable ➜ JOP)। Scudo की disabled quarantine 0x30-byte freelist reuse को deterministic बनाती है, जबकि jemalloc tile/subIFD sizing के माध्यम से size-class control पर निर्भर करता है।

References

Tip

AWS हैकिंग सीखें और अभ्यास करें:HackTricks Training AWS Red Team Expert (ARTE)
GCP हैकिंग सीखें और अभ्यास करें: HackTricks Training GCP Red Team Expert (GRTE) Azure हैकिंग सीखें और अभ्यास करें: HackTricks Training Azure Red Team Expert (AzRTE)

HackTricks का समर्थन करें