
TP-Link Tapo c200 IP कैमरे के uhttpd बाइनरी में पाए गए कमांड इंजेक्शन कमजोरी के लिए एक्सप्लॉइट
CVE-2021-4045 एक कमांड इंजेक्शन भेद्यता है जो TP-Link Tapo c200 IP कैमरे में रिमोट कोड निष्पादन की अनुमति देती है। यह सभी फर्मवेयर संस्करणों को 1.1.16 Build 211209 Rel. 37726N से पहले प्रभावित करती है, क्योंकि uhttpd में उपयोगकर्ता इनपुट पर अपर्याप्त जाँच होती है, जो डिवाइस के मुख्य बाइनरी में से एक है। पूर्ण लेख यहाँ पाया जा सकता है।
यह CryptoParty Madrid 2022 में भेद्यता दिखाने के लिए बनाए गए PoC का एक विस्तारित संस्करण है। इसके 2 मोड हैं:
शेल: लक्ष्य पर एक रूट शेल उत्पन्न करता है

आरटीएसपी: RTSP पर लाइव वीडियो स्ट्रीम तक पहुँच प्रदान करता है

फ़ंक्शन exec_and_read_json कमांड निष्पादित करने के लिए popen का उपयोग करता है:

exec_and_read_json का उपयोग 2 अनाम फ़ंक्शन करते हैं, जिन्हें मैंने set_language और wifi_connect नाम दिया है। वे क्रमशः भाषा और वाईफाई कॉन्फ़िगरेशन से निपटते हैं (स्पष्ट रूप से)। wifi_connect एकल उद्धरण (') को पार्स करता प्रतीत होता है, हालांकि, set_language ऐसा नहीं करता। इसका मतलब है कि यदि हम set_language फ़ंक्शन के लिए इनपुट को नियंत्रित कर सकते हैं, तो हम सफलतापूर्वक अपने स्वयं के कमांड इंजेक्ट कर सकते हैं।

फ़ंक्शन set_language का उपयोग uh_slp_proto_request करता है, वह फ़ंक्शन जिसका मैंने पहले उल्लेख किया था, जो इनपुट के रूप में उपयोगकर्ता से प्राप्त कुछ पार्स किए गए डेटा को पास करता है।

उपयोगकर्ता डेटा को पार्स करने के लिए, uh_slp_proto_request जाँचता है कि क्या यह एक मान्य JSON ऑब्जेक्ट है। फिर, यह कुंजी "method" द्वारा पहचाने गए एक स्ट्रिंग मान और "params" द्वारा पहचाने गए एक शब्दकोश मान प्राप्त करता है (कम से कम मुझे ऐसा लगता है, क्योंकि Ghidra द्वारा फ़ंक्शन कॉल को हल नहीं किया जा सका लेकिन यह इस तरह काम करता प्रतीत हुआ)। चयनित विधि के आधार पर, uh_slp_proto_request उस फ़ंक्शन का चयन करता है जिसे बुलाया जाएगा।
इसलिए, {"method": "setLanguage", "params":{}} भेजकर हम सफलतापूर्वक set_language फ़ंक्शन को कॉल करते हैं और {} को language_json पैरामीटर के रूप में पास करते हैं। फिर, set_language के अंदर, language_json ऑब्जेक्ट को स्ट्रिंग में बदल दिया जाता है और निष्पादित करने के लिए सीधे "ubus call system_state_audio set_language \'%s\'" में डाला जाता है।
{"method": "setLanguage", "params": {"payload": "'; touch poc;'"}} सबमिट करने पर, ubus call system_state_audio set_language '{"payload": "'; touch poc;'"}' निष्पादित होगा, जिसमें वास्तव में 3 कमांड हैं: ubus call system_state_audio set_language '{"payload": "', touch poc, और '"}'। दूसरा हमें पूर्ण कोड निष्पादन प्रदान करता है।
अब, uh_slp_proto_request का उपयोग एक अन्य अनाम फ़ंक्शन द्वारा किया जाता है जो सभी अनुरोधों का प्रबंधन करता है, जिसे मैंने main_server_function नाम दिया है। यदि अनुरोध मान्य है (अधिकतम लंबाई से अधिक नहीं है, सर्वर कॉन्फ़िगरेशन के आधार पर http या https का उपयोग करता है, आदि), तो main_server_function जाँचता है कि क्या URL में /cgi-bin/luci या /web-static है। यदि नहीं, तो uh_slp_proto_request को कॉल किया जाता है।

अनुमान लगाकर और कैमरे को कुछ अनुरोध भेजकर, हम जाँच सकते हैं कि uh_slp_proto_request द्वारा उपयोग किया गया डेटा नियमित POST डेटा है। इसलिए, यदि हम पिछले पेलोड के साथ / पर POST अनुरोध भेजते हैं, तो uh_slp_proto_request इस डेटा को प्रोसेस करेगा, set_language को कॉल करेगा और हमारा पेलोड exec_and_get_result द्वारा निष्पादित कमांड में इंजेक्ट हो जाएगा।
जैसा कि आप देख सकते हैं, मैंने प्रमाणीकरण के बारे में कुछ नहीं बताया, क्योंकि setLanguage विधि को बिना लॉगिन के बुलाया जा सकता है। यह किसी भी उपयोगकर्ता को केवल एक अप्रमाणित अनुरोध के साथ कैमरे का पूर्ण नियंत्रण लेने की अनुमति देता है।