
CVE-2019-12489
यह एक भेद्यता (CVE-2019-12489) की संक्षिप्त रिपोर्ट है, जो Fastweb के Fastgate मॉडम/राउटर और Ghidra के साथ प्रयोग करते हुए खोजी गई। यह भेद्यता एक HTTP अनुरोध के माध्यम से कमांड इंजेक्शन के निष्पादन की अनुमति देती है और इसका उपयोग SSH शेल को सक्षम करने के लिए किया जा सकता है।
सभी फर्मवेयर फ़ाइलें http://59.0.121.191:8080/ACS-server/file/FILENAME पर स्थित हैं
जहाँ FILENAME के बराबर है:
उदाहरण के लिए, अंतिम फर्मवेयर प्राप्त करने के लिए बस http://59.0.121.191:8080/ACS-server/file/0.00.89_FW_200_Askey पर जाएँ।
फ़ाइलों को निकालने के लिए हमें https://github.com/nlitsme/ubidump पर उपलब्ध उपयोगिता की आवश्यकता है (यह पहला है जिसने मेरे लिए काम किया)।
फ़ाइल पर binwalk करने से हमें मिलता है:
$ binwalk 0.00.89_FW_200_Askey
DECIMAL HEXADECIMAL DESCRIPTION
--------------------------------------------------------------------------------
94 0x5E JFFS2 filesystem, little endian
3276894 0x32005E UBI erase count header, version: 1, EC: 0x0, VID header offset: 0x800, data offset: 0x1000
हमें JFFS2 फ़ाइल सिस्टम की आवश्यकता नहीं है, केवल UBI भाग की। ऐसा करने के लिए हम dd का उपयोग करके फ़ाइल को काट सकते हैं। इसके लिए हमें कुल आयाम और UBI प्रारंभ बिंदु की आवश्यकता है।
फ़ाइल का आयाम ls का उपयोग करके प्राप्त किया जा सकता है:
$ ls -la
total 55836
drwxr-xr-x 3 riccardo users 4096 set 24 10:07 .
drwx------ 83 riccardo users 12288 set 24 10:08 ..
-rw-r--r-- 1 riccardo users 57147506 set 24 10:05 0.00.89_FW_200_Askey
मान 57147506 वही है जो हमें चाहिए।
binwalk के आउटपुट को देखते हुए हम देख सकते हैं कि UBI भाग 3276894 पर शुरू हो रहा है। इन दो मानों के साथ हम dd का उपयोग इस प्रकार कर सकते हैं:
$ dd if=0.00.89_FW_200_Askey of=0.00.89_FW_200_Askey.UBI bs=1 skip=3276894 count=57147506
अब हम ubidump का उपयोग कर सकते हैं (सिस्टम कॉन्फ़िगरेशन के आधार पर कुछ प्रारंभिक कॉन्फ़िगरेशन के बाद):
$ git clone https://github.com/nlitsme/ubidump.git
$ sudo pip install crcmod
$ yay -S python-lzo
$ python ubidump/ubidump.py -s bump 0.00.89_FW_200_Askey.UBI
अब हमारे पास bump/rootfs_ubifs/ में फ़ाइल सिस्टम है।
अब हम विश्लेषण में थोड़ा और आगे बढ़ सकते हैं।
फ़ाइल सिस्टम में चारों ओर देखने पर हम देख सकते हैं कि वेब GUI mini_httpd द्वारा प्रबंधित है:
$ grep -i -r "mini_httpd"
etc/sniproxy/urlfilter3.sh:ln -sf /usr/sbin/mini_httpd $URLFILTER_WEBD_PATH
etc/sniproxy/urlfilter3.sh:$URLFILTER_WEBD_PATH -d $URLFILTER_WEB_PATH -c "**.cgi" -u admin -S -E /web/mini_httpd.pem -p $webd_https_port
bin/web.sh:#mv /tmp/mini_httpd /usr/sbin
bin/web.sh:killall -9 mini_httpd
bin/web.sh:mini_httpd -d /web -c "STATUSAPI/**.cgi|STATUSAPI/*" -u admin -T "UTF-8" -p 8080
और हम देख सकते हैं कि mini_httpd एक .cgi फ़ाइल पर निर्भर करता है:
$ grep -i -r "status.cgi"
web/factory/mtcmd/mt_info.htm: "url":"/status.cgi",
web/fw-router/app/app.js:.value('apiServiceUrl', '/status.cgi')
**web/js/status.js:var CGI_NAME='status.cgi';**
web/js/status.js: "url":"http://192.168.101.93/STATUSAPI/status.cgi",
web/js/status.js: "url":"http://192.168.101.93/STATUSAPI/status.cgi",
web/js/status.js: "url":http://192.168.101.93/STATUSAPI/status.cgi,
इसलिए, Ghidra का उपयोग करके, हम status.cgi में देखना शुरू कर सकते हैं।
बहुत सारे विवरणों को छोड़ते हुए, भेद्यता का वर्णन नीचे किया गया है।
पहली चीज़ जो देखनी है वह है इस चित्र की तरह एक main विधि:

हम देख सकते हैं कि setup को कॉल किया गया है। थोड़ा चारों ओर देखने के बाद run_service(...) सभी कार्यक्षमताओं का मूल प्रतीत होता है।

&service_tab की खोज करने पर हम देख सकते हैं कि कुछ विशिष्ट स्ट्रिंग्स run_service(...) द्वारा निष्पादित वास्तविक कोड से जुड़ी हैं।

इन विधियों को एक-एक करके देखने के बाद मुझे usb_remove मिला।

विवरण में:
mountVal = (char *)find_val(httpparams,"mount");
URL अनुरोध में स्ट्रिंग को सीधे एक वेरिएबल में लेता है
sprintf((char *)&mountLocation,"/mnt/%s",mountVal);
URL अनुरोध में पैरामीटर दिए गए एक पूर्ण पथ बनाता है
mountLocation
mountLocation सीधे एक कमांड में उपयोग किया जाता है
अब, कमांड इंजेक्शन को रोकने के लिए जाँचें हैं। विशेष रूप से:
invalidChars = 0x60273b7c;
का उपयोग कुछ अमान्य वर्णों जैसे ` ' ; | की जाँच करने के लिए किया जाता है, लेकिन & सूची में मौजूद नहीं है, इसलिए यदि पैरामीटर mount &ping -c 10 192.168.1.172& के बराबर है, तो जाँच /statusapi/bin/umount -lf &ping -c 10 192.168.1.172& के निष्पादन की अनुमति देगी।
mount कमांड विफल हो जाएगा लेकिन उसके बाद वाला ping निष्पादित हो जाएगा।
प्रकाशित पैच कोड को सरल बनाता है, विशेष वर्णों की जाँच को हटाकर केवल यह जाँच करता है कि फ़ोल्डर मौजूद है या नहीं।

इस भेद्यता का शोषण करने और SSH को सक्षम करने का कोड fastwebEnableSSH.py में है https://github.com/garis/Fastgate/blob/master/fastwebEnableSSH.py