[原創]DLink路由器韌體的一次分析記錄

gjden發表於2016-04-25
DLink路由器韌體的一次分析記錄


   一、前言
 
   去年DLink被爆了多個命令注入漏洞,於是我打算分析驗證一下這些漏洞,不過在分析過程中有一些意外的收穫,透過IDA分析時發現了DLink的多個緩衝區溢位漏洞。但是後來發現這些漏洞在新版本的韌體中被修復了,這就意味著這些漏洞已經被廠商知曉並進行了修補。
   雖然DLink犯了很多低階錯誤導致了一系列本應該避免的漏洞,但是並不意味著其他路由器廠商也不會犯,甚至在各種物聯網裝置韌體中,這類低階編碼錯誤比較普遍。
 
   二、準備
 
   首先找到了兩篇分析DLink路由器的文章
   一篇是Craig 的<<Hacking the D-Link DIR-890L>>
   http://www.devttys0.com/2015/04/hacking-the-d-link-dir-890l/
   一篇是360的文章
   http://bobao.360.cn/news/detail/1433.html

   巧合的是作者Craig當天出這篇漏洞細節的文章時,360在同一天得到DLink公司感謝信。不過這兩篇講的都是HNAP協議的命令注入漏洞,我在分析同一版本的時候發現,該HNAP協議還存在多個溢位漏洞,但是當我決定驗證一下該漏洞時,才知道該漏洞新韌體版本中已經被修復了。最後從網上找到了漏洞通報。

   [原創]DLink路由器韌體的一次分析記錄

   連結:http://www.07net01.com/2015/07/885184.html
 
   另外,我從同事那裡借了一臺DLink路由器來做測試,該路由器型號為DIR-806
   DLink路由器的正面,有六根天線。

   [原創]DLink路由器韌體的一次分析記錄
 
   背面如下:

   [原創]DLink路由器韌體的一次分析記錄

   首先我需要確認該路由器的韌體版本號,這需要登入到路由器上檢視。從路由器工具欄下的韌體更新項可以看到,韌體版本為1.00,韌體時間為2013的,那麼可以肯定的是該韌體也存在我想要驗證的漏洞。

   [原創]DLink路由器韌體的一次分析記錄

   因此,該路由器應該會支援該漏洞的測試和驗證,但是後來測試該版本似乎會有一點不同,當然漏洞還是差不多,只是字元處理上有一點不同而已。
 
   三、韌體分析

   首先我需要得到韌體,一種方法是拆開路由器,透過串列埠、JTag來獲取或者直接讀flash。不過幸好DLink提供有官網的更新韌體。目前我透過如下連結下載了890L_103的韌體,更高版本的韌體已經修補了該漏洞。
 
ftp://ftp2.dlink.com/PRODUCTS/DIR-890L/REVA/DIR-890L_REVA_FIRMWARE_1.03.B07.ZI
 
   下載韌體並解壓後,我們得到韌體檔案DIR890A1_FW103b07.bin,透過binwalk我們可以看到如下資訊:
 
   [原創]DLink路由器韌體的一次分析記錄
 
   其中我們可以看到該韌體採用的是Squashfs檔案系統,那麼這好辦了,可以直接使用binwalk提取該檔案系統。
   binwalk -Me DIR890A1_FW103b07.bin

   [原創]DLink路由器韌體的一次分析記錄

   但是binwalk提取Squashfs檔案系統會出問題,它無法解析檔案系統資料。

   [原創]DLink路由器韌體的一次分析記錄

   好在他已經把該檔案系統資料提取出來,最開始我試圖透過unsquashfs來分析該檔案系統,但是仍然失敗,不過它提示瞭如下資訊:

   [原創]DLink路由器韌體的一次分析記錄

   意思是可以直接用gzip來解壓,但在我使用gzip解壓時任然有問題,最後透過7z來成功提取出了Dlink的檔案系統。如圖可以看出這個一個標準的linux檔案根目錄:

   [原創]DLink路由器韌體的一次分析記錄
 
   首先我需要關注的是一個處理web服務的程式,該程式開啟各種服務埠,並且為外部訪問提供配置,修改等服務。該檔案存在於htdocs目錄下:

   [原創]DLink路由器韌體的一次分析記錄

   四、路由服務模組分析

   透過IDA直接開啟該檔案,可以很清晰的看到該檔案透過傳入引數處理各種服務,其中 HTTP 和UPnP服務介面在之前的版本中存在命令注入漏洞和資訊洩露漏洞,可以參考如下連結:
   http://www.s3cur1ty.de/node/703
   http://www.s3cur1ty.de/node/714
   hnap還有一個命令注入的漏洞,這個漏洞在如下連結中有清晰的表述:
   http://www.devttys0.com/2015/04/hacking-the-d-link-dir-890l/
   此版本我打算分析一下hnap服務的處理,hnap是一種基於 HTTP-SOAP 實現的網路管理協議。DLink使用類似如下的方式來處理該協議命令:
   GET /HNAP1 HTTP/1.1
   Authorization:Basic YWMEHZY+
   Cookie:udi=xyzzzz
   Accept-Encoding: identity
   Soapaction: "http://purenetworks.com/HNAP1/GetDeviceSettings"
   Host: 192.168.0.1:80
   Connection: close

 
   HTTP協議中使用了Soapaction來處理hnap請求
   首先,透過IDA反彙編後,可以在主函式中很快的找到該服務的handler函式。

   [原創]DLink路由器韌體的一次分析記錄

   如果你和我的版本相同的話,可以直接根據地址定位到此處。Ok,接下來進入該handler看看。

   [原創]DLink路由器韌體的一次分析記錄

   從程式碼中可以看出,該服務檔案透過獲取環境變數來得到HTTP頭部相關資訊,我們直接F5來看更加明瞭

   [原創]DLink路由器韌體的一次分析記錄

   從這裡可發現環境變數"HTTP_SOAPACTION"就是用來獲取hnap請求命令的。Dlink接下來透過strstr來進行過濾,如果我們hnap請求裡不包含字串

   "http://purenetworks.com/HNAP1/GetDeviceSettings"

   那麼會試圖進行登入請求處理

   http://purenetworks.com/HNAP1/Login

   登入處理會獲取cookie相關的引數並進行處理,從我分析的結果來看,好像沒有發現什麼。

   [原創]DLink路由器韌體的一次分析記錄

   如果既不是hnap請求,也不是登入請求,那麼程式會將"HTTP_COOKIE"、"HTTP_HNAP_AUTH"、"HTTP_SOAPACTION"這三個環境變數的值傳入函式sub_19BB8.如下圖所示:

   [原創]DLink路由器韌體的一次分析記錄

   接下來,我進入到該函式進行仔細分析。這個函式的三個引數都是我們可以控制的,所以如果函式里面存在問題,那麼就有戲了。當我進入該函式一看,嚇了一跳,這一個函式不止一個漏洞。該函式首先需要保證cookie和auth不能為空,並且cookie必須存在”uid=”的字串才能夠繼續執行。否則會直接返回。因此要構造poc,如下顯藍色標記的是必須的。

   GET /HNAP1 HTTP/1.1
   Authorization:Basic YWMEHZY+
   Cookie:udi=xyzzzz
   Accept-Encoding: identity
   Soapaction: "http://purenetworks.com/HNAP1/GetDeviceSettings"
   Host: 192.168.0.1:80
   Connection: close


   那麼透過如下分析你可以構造自己poc來觸發這些漏洞。

   1.首先是auth引數的處理,此引數處理直接使用strtok()函式來分割,分割透過空格來實現。
 
   [原創]DLink路由器韌體的一次分析記錄

   R2中儲存的目的地址,該地址為堆疊地址,其堆疊空間長度固定為512個位元組,看到這裡就你可以邪惡的一笑了。
   我們只需要構造一個字串,將該字串以構造為如下:

   Authorization:Basic YWMEHZY+0Xaa{800}

   然後透過python指令碼將構造的請求包提交給路由器,我們就能看到該路由器崩潰的效果。
 
   2.然後是hnap命令的處理問題,該函式處理hnap命令字串時,同樣沒有進行長度驗證,透過strcat函式將hnap命令字串連線到同樣一個緩衝中。

   [原創]DLink路由器韌體的一次分析記錄

   看到了吧,又是一個緩衝區溢位。
 
   3.這還沒有完,該函式除了將分割的第二個字串無限制的複製到堆疊外,當cookie的uid有效時,他還會將其複製到堆疊的另外一個緩衝區裡
   首先將該字串透過atoi()函式進行轉換,得到一個整數,然後將該整數與堆疊中的一個值進行比較,如果比這個值大,則會將其透過函式strcpy複製到堆疊中。我們知道atoi函式對於諸如此類的字串:
   “12aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa”
   同樣會成功的返回12,那麼我們可以構造一個255開頭的長字串來觸發溢位。

   [原創]DLink路由器韌體的一次分析記錄

   當然該函式可能還有其他地方會出現異常和漏洞,但是我的分析也在此處完結了,剩餘的時間就是去驗證一下漏洞了。
上傳的附件:

相關文章