王洪義 沙樂天,2
1(南京郵電大學計算機學院、軟件學院、網絡空間安全學院 南京 210023) 2(江蘇省無線傳感網高技術研究重點實驗室 南京 210023)
隨著物聯網的快速發展,越來越多的物聯網設備可以在網絡中訪問,比如路由器、攝像頭和打印機等.根據Statista的研究,到2025年,全球物聯網設備的總裝機量預計達到309億臺[1].據統計,在所有物聯網設備中,無線路由器和網絡攝像頭比其他嵌入式設備遭受的攻擊更多,主要因為它們提供的Web服務暴露了可利用的漏洞.在75%的場景中,路由器充當物聯網場景中的網關[2],當路由器設備被攻擊后局域網設備都存在被攻擊的可能性.遺憾的是由于缺乏先進的防御機制和面向互聯網的特性,路由器設備已成為黑客攻擊的主要目標.
通常情況下大多數路由器都提供了基于Web的界面,用于管理和配置設備的功能.據統計,包含Web服務的無線路由器占其總數的83.6%.常見的Web服務器是HTTP服務器,它通過HTTP協議提供基本的網絡服務,后端二進制程序提供大量的接口,可以直接對設備進行操作.模糊測試是一種針對軟件和系統十分有效的漏洞挖掘方法.該方法通過向被測設備發送大量非預期的輸入,并通過監控其狀態發現潛在的漏洞.本文認為,目前最先進的研究沒有提取足夠的固件信息來指導模糊測試,無效的測試用例導致模糊測試的低效和無效性.本文利用固件靜態分析指導模糊測試中測試用例的構建,從而提高模糊測試的效率和準確性.本文主要貢獻如下:
1) 提出一種新的基于共享鍵自動識別固件中多二進制漏洞的靜態分析方法;
2) 提出一種新的基于靜態分析與模糊測試相結合的漏洞檢測方法,即通過靜態分析生成的結果構建模糊測試的測試用例;
3) 設計并實現一個原型系統,可以檢測現有Fuzzer無法觸發的漏洞.該系統共發現16個漏洞,其中4個是零日漏洞.
隨著物聯網問題的日益增多[3].基于靜態分析技術已經提出了不同的自動化漏洞檢測工具[4-6].Firmalice[7]是一個二進制的分析框架,它利用符號執行和程序切片技術檢測二進制固件中繞過身份驗證的漏洞.李明琪等人[8]通過權限校驗分析和參數一致性分析方法,檢測應用軟件中存在的缺失對使用者的權限校驗以及在發送控制指令時缺失保護字段的2類安全漏洞.DTaint[9]通過使用指針別名分析以自下而上的方式構建敏感數據流,檢測固件中的污點式漏洞.唐梟[10]提出一種基于動態污點分析的輸入數據字段分類方法,改進了基于代碼覆蓋率的遺傳模糊測試方法.SaTC[11]應用有針對性的數據流分析方法準確檢測不可信用戶輸入的危險使用.不幸的是現有的靜態分析工作一次只關注單個二進制程序或者模塊,而忽略了后端多二進制之間不安全交互的檢測.與動態分析相比,靜態分析擁有更高的覆蓋率,然而無法準確地確定代碼執行的路徑,這是靜態分析的共同挑戰.
動態分析特別是模糊測試,作為現在流行的漏洞檢測技術,解決了靜態分析無視實際運行環境以及代碼約束的問題.SRFuzzer[12]是一個用于測試物理路由器的全自動模糊框架,它首先從運行的設備捕獲大量Web請求,然后對用戶輸入語義進行建模以生成測試用例.田里等人[13]使用Seq2Seq模型進行二次學習,構建以協議管理、策略配置、詳情查詢模塊為核心的物聯網協議漏洞檢測系統.此外,Boofuzz[14]是一個先進的協議模糊器,需要手動編寫協議格式描述文件以支持測試.PS-Fuzz[15]是一個基于協議狀態導向的灰盒模糊測試工具,它通過程序插樁以固件中與協議處理相關的字段為引導對目標設備進行模糊測試.不幸的是以上研究沒有對目標設備的固件進行足夠的分析,無法生成有效的測試用例,從而受困于代碼覆蓋和攻擊面,這是動態模糊分析的共同挑戰.
本文主要研究針對路由器設備的漏洞檢測,然而,現有的漏洞挖掘技術面臨挑戰:模糊測試階段針對原始種子變異位置的確定以及靜態分析階段對于后端二進制之間不安全交互的檢測.生成有效的測試用例至關重要,通過對數據進行有針對性的變異,可以提高測試用例的有效性,從而更好地揭示被測試程序中的潛在漏洞.本節利用真實設備中部分反編譯代碼來展示本文的發現.
本文發現路由器前端總是以鍵值對的形式發送請求數據,而后端則根據共享的鍵獲取對應的值來解析該請求.圖1所示為真實設備中的部分反編譯程序,左側顯示出前端GET請求,右側顯示后端對該請求的處理程序.GET數據包含2個參數鍵:action與usbName.在后端處理請求時,通過sub_2BA8C函數讀取它們的值,并在沒有進行任何過濾的情況下將其傳遞到doSystemCmd()函數中,從而造成命令注入漏洞.由此發現,前后端總是通過相同的關鍵字(如圖1中的action)進行數據通信,本文稱其為共享鍵.本文認為共享鍵的識別是確定變異位置的關鍵,后端通過前端請求數據進行響應,惡意的輸入未經過濾則造成漏洞.

圖1 前后端共享相同的鍵
現代物聯網設備的固件是復雜的,據統計86%的固件是基于Linux的[16].與其他基于Linux的系統類似,路由器設備中的固件包含大量相互依賴的二進制文件.在本文的漏洞檢測過程中,這種交互是值得重視的.若只關注那些面向網絡的二進制文件,就導致忽略與之關聯的其他二進制文件中存在的漏洞.圖2所示為真實設備中的部分反編譯程序.在mod_ssi.so中(圖2左端),第9行的ssi_env_add()函數將從請求中解析出的數據賦值給QUERY_STRING.在domnloadFlile.cgi(圖2右端)第6行中,getenv()函數獲取QUERY_STRING的值并將其賦值給變量a.變量a在第8行被格式化后賦值給變量b.最終,變量b的值被傳入函數system()執行,從而出現漏洞.以往的針對嵌入式設備固件的靜態分析缺乏對多二進制之間不安全交互的檢測,本文認為可以通過識別具有共享鍵的相關函數(如表1所示)來建立后端多個二進制之間的依賴關系.然后依靠傳統的數據流分析實現多二進制不安全交互的檢測.

表1 常見的多二進制關聯函數

圖2 多二進制通過共享鍵進行通信
本文提出了一個針對路由器Web服務器的模糊測試框架,用于檢測緩沖區溢出漏洞與命令注入漏洞.該框架的漏洞檢測模型如圖3所示,原型系統主體由3大部分組成,分別為固件獲取部分、靜態分析部分和模糊測試部分,各個部分協同工作,完成路由器設備的漏洞檢測工作.

圖3 漏洞檢測模型
本部分主要包含3個子模塊:爬蟲模塊、下載模塊和解包模塊.這些模塊的主要功能是獲取解包后的固件鏡像,為后續的靜態分析部分提供輸入必要的數據基礎.
首先,爬蟲模塊是負責從給定網站鏈接中爬取路由器固件鏡像的URL的程序;其次,下載模塊是用于下載固件文件的程序,該模塊接收來自爬蟲模塊的URL,并將其下載到指定的本地目錄中;最后,解包模塊是用于解包路由器固件鏡像的程序.
本部分主要包含2個子模塊:關鍵字提取模塊和敏感數據流分析模塊.這些模塊的主要功能是從固件中提取敏感信息,為后續的模糊測試樣本構造提供依據.
3.2.1 關鍵字提取模塊
本模塊主要負責提取后端Web服務中與前端共享的關鍵字,為敏感數據流分析模塊提供支持.如圖1所示,前端請求的數據始終以鍵值對的形式出現.將在前端文件和后端二進制文件之間共享的關鍵字叫“共享鍵”.從前端提取這些共享鍵,并使用它們來定位處理前端請求的二進制程序(下文稱為“邊界二進制”).然后,將后端文件按照匹配數量降序排列,并選取匹配數量最高的3個文件作為邊界二進制文件.
靜態分析關鍵字提取過程見算法1,該算法以固件鏡像路徑dir_path作為輸入,最終得到二進制與其對應的關鍵字映射結構result.函數list_files()用于根據傳入類型返回目標文件,而extract_backend_keywords()與extract_backend_keywords()則負責進行關鍵字提取.
算法1.關鍵字提取算法.
輸入:固件鏡像存儲路徑dir_path;
輸出:固件二進制與其對應關鍵字的映射結構result.
① FORfrontend_fileinlist_files(dir_
path,Type.frontend)
②frontend_keywords.update(extract_
frontend_keywords(frontend_file));
③ END FOR
④ FORbackend_fileinlist_files(dir_path,
Type.backend)
⑤backend_keywords=extract_backend_
keywords(backend_file);
⑥match_counts[backend_file]=count_
matches(frontend_keywords,
backend_keyword);
⑦ END FOR
⑧sorted_matches=sort_by_value_
desc(match_counts)[:3];
⑨matched_keywords=frontend_keywords&
backend_keywords;
⑩result[backend_file]=matched_keywords;
3.2.2 敏感數據流分析模塊
本模塊主要負責根據關鍵字提取模塊確定的邊界二進制中的共享鍵為起點進行數據流分析.該模塊直接檢測共享鍵的引用位置,以此作為敏感數據流中的起點,從而避免從二進制的入口函數進行分析,它會檢索所有由給定關鍵字出發并最終到達危險函數的數據流路徑,為模糊測試變異模塊中變異位置的確定提供支持.準確檢測固件中多個二進制文件之間的不安全交互是一項挑戰.如表1所示,包含存儲類函數的二進制被稱為set類二進制,包含讀取類函數的二進制文件被稱為get類二進制.正如圖2所示,多個二進制文件之間進行數據交換具有共同的特點,即存儲函數和讀取函數共享相同的關鍵字.因此,通過共享鍵建立2類文件之間的依賴關系.分析敏感變量的傳遞路徑,收集所有可以達到表2中常見的危險函數的路徑.

表2 常見的危險函數
敏感路徑生成過程見算法2.該算法以二進制與其對應的關鍵字映射結構為輸入,最終得到敏感變量到危險函數的路徑.getCallChain()用于獲取與敏感關鍵字相關的數據流路徑.isContainsFocusFun()函數判斷敏感關鍵字的數據流路徑中是否包含表2危險函數.
算法2.敏感路徑生成算法.
輸入:二進制文件與關鍵字映射路徑bin_paray_mappings;
輸出:敏感路徑集合keywords_paths.
① FORbin_para_mappinginbin_paray_
mappings
②cur_bin=read(bin_para_mapping.bin_
path); /*讀取二進制*/
③ FORkeywordinbin_para_mapping.
keywords
④callChain=getCallChain(cur_bin,
keyword);
⑤flag=isContainsFocusFun(callChain);
/*進行危險函數檢查*/
⑥ IFflag==true
⑦keywords_paths.add(keyword,
callChain);
⑧ END IF
⑨ END FOR
⑩ END FOR
/*返回敏感路徑集合*/
本節主要包含4個子模塊:種子生成模塊、變異模塊、監視模塊和電源控制模塊.
3.3.1 種子生成模塊
本模塊主要負責生成模糊測試的初始種子.使用爬蟲器和攔截器收集原始請求,并將其存儲到本地文件中.爬蟲器通過解析網頁元素自動填充網頁,特別是對于登錄頁面,使用預先編寫的本地用戶密碼文件進行填充.而攔截器用于監視和攔截網絡通信中的數據包.采用基于代理服務器的方法,捕獲通過代理服務器的所有網絡通信數據包,將其記錄到本地文件中.
3.3.2 變異模塊
本模塊主要負責生成模糊測試的測試用例.首先標記變異位置,然后通過變異策略處理該位置的值.在變異位置標記中,主要借助靜態分析部分敏感數據流分析模塊的結果.只關注敏感變量(敏感數據流的起點)在原始數據包中的位置.如圖4所示,左側為原始數據包,右側為標記后的數據包.經靜態分析,list的值最終到達危險函數,用特殊字符$$標記該位置.

圖4 變異位置標記
根據不同的類型生成對應的參數值,主要采用以下變異策略:
1) 字符串.通過不斷更改字符串的長度生成不同的隨機字符串.
2) 數值.通過修改參數的邊界值生成參數,以測試程序的邊界情況.
3) 自定義命令.針對無響應的命令注入漏洞,基于ping等內置命令構造畸形有效載荷構造.
3.3.3 監視模塊
本模塊主要負責對目標設備狀態的監視.監視模塊包含2個監控器:基于響應的監控器和基于代理的監控器.
基于響應的監視器負責監測緩沖區溢出類漏洞以及有響應的命令注入類漏洞.滿足以下條件之一時本模塊會對異常情況進行日志記錄操作.
1) 心跳監測.心跳監測機制,即設置定時程序對設備是否正常工作進行監控.
2) 響應差異分析.通過分析和對比正常請求和變異數據請求所得到的響應數據,實現對設備異常狀態的檢測.
基于代理的監視器負責監測無響應的命令注入類漏洞.變異模塊定義了畸形的有效載荷來請求外部路由器.本文在本地網絡中建立一個監視服務器用于接收路由器發送的請求.一旦命令注入被觸發,本模塊會對異常情況進行日志記錄操作.
3.3.4 電源控制模塊
本模塊主要確保模糊測試的持續進行.該模塊由監視模塊控制.如果后端服務陷入無響應狀態,監視模塊會向電源控制模塊發送重啟命令,以重新啟動設備.
本文選擇4家提供固件在線下載服務的主流路由器設備廠商,包括Tenda,D-Link,Netgear與TP-Link.如表3所示,選用46個固件樣本,覆蓋ARM32和MIPS32這2種架構.原型系統共處理了377.6M的固件樣本.

表3 數據集樣本
如表4所示,固件獲取部分從供應商的網站上爬取531個固件鏡像的下載鏈接,并使用定制的下載模塊成功下載所有的固件鏡像,由于部分固件存在加密,最終解包程序成功解包435個固件鏡像,本模塊下載成功率為100%,解包成功率為81.9%.出于本系統需要使用物理設備進行模糊測試,排除了個別價格昂貴的設備,選取了46個固件.

表4 固件獲取
為評估本系統構建測試用例的有效性,如表5所示,本文選取部分固件樣本用來與先進的物聯網設備模糊器Boofuzz和SIoTFuzzer[17]進行比較.對于Boofuzz,雖然可以在輸入中插入特殊字符,但它對命令注入漏洞檢測效果不佳;對于SIoTFuzzer,由于在靜態分析指導模糊測試階段,只關注前端Web管理界面生成有狀態的測試用例而忽略后端二進制對請求數據的限制,僅檢測3個漏洞.

表5 漏洞檢測數據對比
本文系統共發出37個異常警告,其中24個警告被認定為真實存在的漏洞,包括12個已知漏洞與4個零日漏洞(存在相同的異常警告屬于同一漏洞的情況).我們已向國家信息安全漏洞共享平臺報告,并被授予CNVD編號.漏洞檢測成果如表6所示:

表6 驗證已知漏洞與發現未知漏洞
本文提出了一種新的基于靜態分析和模糊測試相結合的路由器設備漏洞檢測方法.該方法利用靜態分析生成的結果指導模糊測試階段測試用例的構建,在靜態分析階段,通過識別具有鍵值特征的函數實現對多二進制之間的自動化漏洞檢測;在模糊測試階段,通過靜態分析的結果構建出測試用例,使用更有針對性的突變策略來引發更多漏洞.評估結果表明,本文方法優于目前最先進的方法,能夠成功檢測到現有Fuzzer無法觸發的漏洞.