
LINKSYS AC1900 EA7500v3 IGD UPnP स्टैक बफर ओवरफ्लो रिमोट कोड निष्पादन भेद्यता
यह भेद्यता नेटवर्क-निकटवर्ती हमलावरों को LINKSYS EA7500 राउटर के प्रभावित इंस्टॉलेशन पर मनमाना कोड निष्पादित करने की अनुमति देती है। इस भेद्यता का शोषण करने के लिए प्रमाणीकरण की आवश्यकता नहीं है।
विशिष्ट दोष IGD UPnP सेवा के लिए HTTP अनुरोध डेटा के प्रबंधन में मौजूद है। किसी दिए गए SOAP UPnP क्रिया अनुरोध के उपयोगकर्ता-आपूर्ति किए गए चर की सामग्री को पार्स करते समय, प्रक्रिया इसे एक निश्चित-लंबाई वाले स्टैक बफर पर कॉपी करने से पहले उपयोगकर्ता-आपूर्ति डेटा की लंबाई को ठीक से मान्य नहीं करती है। एक हमलावर रूट के संदर्भ में कोड निष्पादित करने के लिए इस भेद्यता का लाभ उठा सकता है।
उत्पाद/फर्मवेयर: Linksys EA7500 फर्मवेयर सभी संस्करण जिसमें Ver.3.0.1.207964 शामिल है - इस बाइनरी का उपयोग करने वाले अन्य राउटर मॉडल और फर्मवेयर संस्करण भी प्रभावित हैं
UPnP IGD सेवा बाइनरी /usr/sbin/IGD पर स्थित है और डिफ़ॉल्ट रूप से पोर्ट 49152 पर चल रही है। यह सेवा IGDdevicedesc.xml UPnP XML विवरण फ़ाइल प्रदान करती है जो कई फ़ंक्शनों का विवरण देती है जिन्हें XML बॉडी वाले HTTP अनुरोधों का उपयोग करके आमंत्रित किया जा सकता है। इनमें से एक फ़ंक्शन SetDefaultConnectionService है। इस फ़ंक्शन को स्ट्रिंग प्रकार के एक चर की आवश्यकता होती है। जब SetDefaultConnectionService फ़ंक्शन को आमंत्रित और निष्पादित किया जाता है, तो प्रोग्राम इस बफर से जुड़ी strncpy कॉल करने से पहले उपयोगकर्ता-आपूर्ति किए गए चर की लंबाई को मान्य नहीं करता है। strncpy कॉल के स्रोत पते और कॉपी आकार दोनों चर उपयोगकर्ता-नियंत्रित होते हैं, जिसमें कॉपी का आकार उपयोगकर्ता-आपूर्ति किए गए चर की लंबाई होती है। फिर डेटा को 184 बाइट्स के एक निश्चित बफर पर कॉपी किया जाता है, जिससे स्टैक बफर ओवरफ्लो भेद्यता उत्पन्न होती है।
SetDefaultConnectionService फ़ंक्शन को _set_connection_type के रूप में लेबल किया गया है। फ़ंक्शन 184-बाइट बफर को आरंभ करके शुरू होता है और फिर यदि अनुरोध में शामिल उपयोगकर्ता-आपूर्ति स्ट्रिंग चर शून्य नहीं है तो उसके बफर का पॉइंटर प्राप्त करता है। यह PAL_xml_node_GetFirstbyName और फिर PAL_xml_node_get_value को कॉल करके किया जाता है। नीचे कोड देखें:
int _set_connection_type(int **param_1)
{
int iVar1;
char *var_value;
size_t var_value_length;
undefined uVar2;
undefined1 *puVar3;
char **ppcVar4;
undefined4 *puVar5;
char *pcVar6;
int *piVar7;
char acStack_d4 [184]; -----> /* 184-बाइट बफर आरंभ करना */
memset(acStack_d4,0,0xb4);
iVar1 = PAL_xml_node_GetFirstbyName((*param_1)[0xf0],"NewConnectionType",0); -----> /* iVar1 अब उपयोगकर्ता-आपूर्ति मान की ओर इशारा करता है */
if ((iVar1 != 0) && (var_value = (char *)PAL_xml_node_get_value(), var_value != (char *)0x0)) { -----> /* सुनिश्चित करता है कि उपयोगकर्ता-आपूर्ति मान खाली नहीं है और उसका पॉइंटर प्राप्त करता है */
...
बाद में उसी फ़ंक्शन में, उपयोगकर्ता-आपूर्ति स्ट्रिंग का आकार प्राप्त करने के लिए एक strlen कॉल किया जाता है जिसमें 0x174 का स्थैतिक ऑफ़सेट जोड़ा जाता है। भेद्य स्थिति बाद के strncpy कॉल में ट्रिगर होती है जहां गंतव्य तर्क नव आरंभित 184-बाइट बफर का पता है, स्रोत उपयोगकर्ता-आपूर्ति स्ट्रिंग का पॉइंटर है, और कॉपी ऑपरेशन का आकार strlen कॉल द्वारा लौटाए गए उपयोगकर्ता-आपूर्ति स्ट्रिंग के आकार और 0x174 के स्थैतिक ऑफ़सेट का योग है। इससे बफर ओवरफ्लो भेद्यता उत्पन्न होती है क्योंकि स्रोत पता और आकार दोनों चर उपयोगकर्ता द्वारा नियंत्रित होते हैं और कोई आकार सत्यापन जाँच नहीं की जाती है। नीचे कोड देखें:
int _set_connection_type(int **param_1)
{
...
var_value_length = strlen((char *)(iVar1 + 0x174)); ----> /* iVar1 उपयोगकर्ता-आपूर्ति स्ट्रिंग का पॉइंटर है */
strncpy(acStack_d4,(char *)(iVar1 + 0x174),var_value_length + 1); ----> /* भेद्य strncpy कॉल */
...
स्टैक पर फ़ंक्शन रिटर्न पते को अधिलेखित करने का ऑफ़सेट 276 बाइट्स है। अगले 4 बाइट्स का उपयोग निष्पादन को एक मनमाने पते पर पुनर्निर्देशित करने और इस प्रकार प्रोग्राम के नियंत्रण प्रवाह को हाईजैक करने के लिए किया जा सकता है।
एक सुरक्षित स्ट्रिंग कॉपी फ़ंक्शन का उपयोग करें: strncpy का उपयोग करने के बजाय, जो गंतव्य बफर के नल-समाप्ति की गारंटी नहीं देता है, एक सुरक्षित स्ट्रिंग कॉपी फ़ंक्शन जैसे strncpy_s या memcpy_s का उपयोग किया जा सकता है। ये फ़ंक्शन सुनिश्चित करते हैं कि गंतव्य बफर हमेशा नल-समाप्त हो और बफर की क्षमता से अधिक डेटा की प्रतिलिपि बनाने की अनुमति न दें।
इनपुट सत्यापन: उपयोगकर्ता इनपुट को सत्यापित करें ताकि यह सुनिश्चित हो सके कि यह गंतव्य बफर के आकार से अधिक न हो। यदि इनपुट बफर आकार से लंबा है, तो इसे अस्वीकार करें या बफर में फिट होने के लिए इसे छोटा करें।
गतिशील रूप से आवंटित बफर का उपयोग करें: निश्चित आकार के स्टैक बफर के बजाय गंतव्य बफर के लिए मेमोरी को गतिशील रूप से आवंटित करें। यह दृष्टिकोण इनपुट डेटा आकार के अनुसार बफर आकार को समायोजित करने की अनुमति देता है। (सीमित संसाधनों वाले सिस्टम के लिए अनुशंसित नहीं)
PoE निष्पादन: python poc.py 192.168.1.1 49152
सॉफ्टवेयर डाउनलोड लिंक: https://support.linksys.com/kb/article/559-en/ (फर्मवेयर संस्करण Ver. 3.0.1.207964)
gdbserver-7.7.1-armel-eabi5-v1-sysv का उपयोग किया: https://github.com/stayliv3/gdb-static-cross/tree/master/prebuilt)।pkill IGD का उपयोग करें और फिर ./gdbserver :1337 /usr/sbin/IGD का उपयोग करके इसे पुनः लॉन्च करें। एक स्थिर डिबगिंग सत्र शुरू करने के लिए निम्नलिखित .gdbinit फ़ाइल का उपयोग किया जा सकता है:> set follow-fork-mode child
> set detach-on-fork off
> target remote 192.168.1.1:1337
> c