Openwrt漏洞挖掘之不要用小米路由偷偷下小電影哦

jopen 8年前發布 | 39K 次閱讀 OpenWRT

本文是通過小米路由作為案例,講解如何挖掘openwrt的漏洞,并且通過一個小米路由的0day作為實例,讓大家更容易理解測試的方法。

1 提取固件內容

首先肯定是將固件中文件系統的內容提取出來,然后對其進行分析,也可以是分析其固件中應用程序是否存在漏洞,如Uhttpd等服務,也可以分析其web程序是否存在漏洞 如openwrt,由于本人對二進制并不熟悉,所以此次的內容就是針對openwrt luci的。

1.1 固件解包

通過執行Binwalk可以發現存在如下內容:

root@kali:~/miwifi# binwalk brcm4709_r2d_all_79e11_2.8.19.bin

DECIMAL HEXADECIMAL DESCRIPTION
--------------------------------------------------------------------------------
672 0x2A0LZMA compressed data,properties: 0x5D,dictionary size: 65536bytes,uncompressed size: 90046464bytes
30048716 0x1CA81CCTRX firmware header,little endian,image size: 3047424bytes,CRC32: 0xA85FDFF0,flags: 0x0,version: 1,header size: 28bytes,loader offset: 0x1C,linux kernel offset: 0x0,rootfs offset: 0x0
30048744 0x1CA81E8LZMA compressed data,properties: 0x5D,dictionary size: 65536bytes,uncompressed size: 5902752bytes

通過加上-e參數對其進行解壓,解壓之后將會得到一個目錄,進去查看之后內容如下:

root@kali:~/miwifi# cd _brcm4709_r2d_all_79e11_2.8.19.bin.extracted/
root@kali:~/miwifi/_brcm4709_r2d_all_79e11_2.8.19.bin.extracted# ls
1CA81E8 1CA81E8.7z 2A0 2A0.7z
root@kali:~/miwifi/_brcm4709_r2d_all_79e11_2.8.19.bin.extracted# file 2A0
2A0:UBI image,version1
root@kali:~/miwifi/_brcm4709_r2d_all_79e11_2.8.19.bin.extracted# file 1CA81E8
1CA81E8:data
root@kali:~/miwifi/_brcm4709_r2d_all_79e11_2.8.19.bin.extracted#

1.2 提取文件系統

與其他不同的是,miwifi使用的是UBI的文件系統,這個文件系統掛載起來比較麻煩,在嘗試了無數次之后發現一個自動化就能掛載的腳本

https://github.com/jrspruitt/ubi_reader 安裝方式:

$ sudo apt-getinstall liblzo2-dev
$ sudo apt-getinstall python-lzo
$ git clone https://github.com/jd-boyd/python-lzo.git
$ cd python-lzo
$ python setup.py install

通過執行

ubireader_extract_images2A0

可以得到如下結果

root@kali:~/miwifi/_brcm4709_r2d_all_79e11_2.8.19.bin.extracted# ubireader_extract_images 2A0
root@kali:~/miwifi/_brcm4709_r2d_all_79e11_2.8.19.bin.extracted# ls
1CA81E8 1CA81E8.7z 2A0 2A0.7z *ubifs-root*
root@kali:~/miwifi/_brcm4709_r2d_all_79e11_2.8.19.bin.extracted#
root@kali:~/miwifi/_brcm4709_r2d_all_79e11_2.8.19.bin.extracted/ubifs-root/2A0# ubireader_extract_files img-1883837156_vol-system.ubifs
Extractingfiles to:ubifs-root

將會生成一個名叫 ubifs-root 的文件夾里面還存放這一個文件,這個文件就是ubi鏡像的最終文件,在通過ubireader_extract_files對其進行提取即可,最后生成的文件夾,其中就存放的該固件的文件系統。

2 Openwrt的簡單介紹

OpenWrt 可以被描述為一個嵌入式的 Linux 發行版,(主流路由器固件有 dd-wrt,tomato,openwrt三類)而不是試圖建立一個單一的、靜態的系統。OpenWrt的包管理提供了一個完全可寫的文件系統,從應用程序供應商提供的選擇和配置,并允許您自定義的設備,以適應任何應用程序。

對于開發人員,OpenWrt 是使用框架來構建應用程序,而無需建立一個完整的固件來支持;對于用戶來說,這意味著其擁有完全定制的能力,可以用前所未有的方式使用該設備。

以上內容來自百度百科

Openwrt是一個支持用Lua進行開發嵌入式的linux路由系統,詳細的內容就不說了,就簡單說一下,基本在openwrt都是使用lua進行開發的,其中lua的目錄結構大概如下

所有的lua模塊和web調用的lua程序都在這個目錄下面:

/usr/lib/lua/
/usb/lib/lua/luci#這里存放的就是luci也就是openwrt web訪問所需的內容。

openwrt在開發的時候 基本上是MVC模式,既 Model,View,Controller,所以大家看下圖就可以一目了然

Openwrt漏洞挖掘之不要用小米路由偷偷下小電影哦

Controller目錄中存放的就是所有走web訪問的入口文件,Model中放的就是一些所需要的模塊,View就是html模板。

3 尋找漏洞

尋找漏洞的第一步自然是尋找一些高風險的漏洞,首先需要的就是查找出不需要登錄就可以調用的模塊,首先我們來看一個Contraller是怎么寫的文件位置:/usb/lib/lua/luci/controller/diagnosis/index.lua

module("luci.controller.diagnosis.index", package.seeall)
functionindex()
 localroot=node()
 if notroot.targetthen
root.target= alias("diagnosis")
root.index= true
 end
 localpage=node("diagnosis")
page.target=firstchild()
page.title=_("")
page.order= 110
page.sysauth= "admin"
page.mediaurlbase= "/xiaoqiang/diagnosis"
page.sysauth_authenticator= "htmlauth"
page.index= true
entry({"diagnosis"}, template("diagnosis/home"),_("首頁"), 1, 0x09)

entry({"diagnosis", "wanerr"},call("action_wanerr"),_(""), 2, 0x09)
entry({"diagnosis", "errindex"},call("action_errindex"),_(""), 3, 0x09)
end

functionaction_wanerr()
 localresult= {}
result["code"] = 0
result["data"] = {
 ["a"] =_("對不起,小米路由器出現網絡連接問題無法打開網頁"),
 ["b"] =_("1、請檢查網線是否正確連接路由器WAN口上"),
 ["c"] =_("2、請檢查網線是否損壞"),
 ["d"] =_("3、請檢查路由器WAN口是否損壞"),
 ["e"] =_("小米路由器技術支持")
 }
luci.http.write_json(result)
end

functionaction_errindex()
 localresult= {}
result["code"] = 0
result["data"] = {
 ["a"] =_("對不起,小米路由器出現網絡連接問題無法打開網頁"),
 ["b"] =_("立即進行網絡診斷"),
 ["c"] =_("小米路由器技術支持")
 }
luci.http.write_json(result)
end

其中最為關鍵的一個內容便是

entry({"diagnosis", "wanerr"},call("action_wanerr"),_(""), 2, 0x09)

這一段的意思就是,我通過訪問

http://127.0.0.1/cgi-bin/luci/diagnosis/index/wanerr

就可以調用action_wanerr 函數,然后0x09就是一個權限標志位,經過多次摸索發現0x9,0x01,0x0d的標志位是不需要登錄就可以訪問的。那我們就先查找出所有0x09,0x08,0x0d標志位的文件,如下

api/misystem.lua:33:entry({"api", "misystem", "topo_graph"},call("getTopoGraph"), (""), 114, 0x0d)
api/xqsystem.lua:61:entry({"api", "xqsystem", "upgrade_status"},call("upgradeStatus"), (""), 148, 0x0d)
api/xqsystem.lua:73:entry({"api", "xqsystem", "cancel"},call("cancelUpgrade"), (""), 160, 0x0d)
api/xqsystem.lua:123:entry({"api", "xqsystem", "flash_permission"},call("flashPermission"), (""), 200, 0x0d)
web/index.lua:74:entry({"web", "upgrading"}, template("web/syslock"),_("路由升級"), 101, 0x0d)
web/index.lua:81:entry({"web", "topo"}, template("web/topograph"),_(""), 130, 0x0d)
api/xqnetwork.lua:90:entry({"api", "xqnetwork", "wan_link"},call("getWanLinkStatus"), (""), 265, 0x09)
api/xqnetwork.lua:104:entry({"api", "xqnetwork", "pppoe_catch"},call("pppoeCatch"), (""), 264, 0x09)
api/misystem.lua:91:entry({"api", "misystem", "lsusb"},call("lsusb"), (""), 150, 0x09)
api/misystem.lua:97:entry({"api", "misystem", "r_ip_conflict"},call("rIpConflict"), (""), 155, 0x09)
api/misystem.lua:99:entry({"api", "misystem", "tb_info"},call("toolbarInfo"), (""), 156, 0x09)
api/xqsystem.lua:13:entry({"api", "xqsystem", "init_info"},call("getInitInfo"), (""), 101, 0x09)
api/xqsystem.lua:14:entry({"api", "xqsystem", "fac_info"},call("getFacInfo"), (""), 101, 0x09)
api/xqsystem.lua:133:entry({"api", "xqsystem", "set_payment_info"},call("setPaymentInfo"), (""), 207, 0x09)
api/xqsystem.lua:134:entry({"api", "xqsystem", "sign_order"},call("signOrder"), (""), 208, 0x09)
diagnosis/index.lua:16:entry({"diagnosis"}, template("diagnosis/home"),_("首頁"), 1, 0x09)
diagnosis/index.lua:18:entry({"diagnosis", "wanerr"},call("action_wanerr"),_(""), 2, 0x09)
diagnosis/index.lua:19:entry({"diagnosis", "errindex"},call("action_errindex"),_(""), 3, 0x09)
dispatch/index.lua:17:entry({"dispatch"}, template("index"),_("跳轉"), 1, 0x09)
web/index.lua:26:entry({"web", "logout"},call("action_logout"), 11, 0x09)
web/index.lua:41:entry({"web", "init", "hello"},call("action_hello"),_("歡迎界面"), 14, 0x09) --不需要登錄
web/index.lua:42:entry({"web", "init", "agreement"}, template("web/init/agreement"),_("用戶協議"), 14, 0x09) --不需要登錄
web/index.lua:43:entry({"web", "init", "privacy"}, template("web/init/privacy"),_("用戶體驗改進計劃"), 14, 0x09) --不需要登錄
web/index.lua:76:entry({"web", "webinitrdr"},call("action_webinitrdr"),_(""), 110, 0x09)
web/index.lua:79:entry({"web", "ieblock"}, template("web/ieblock"),_(""), 120, 0x09)
api/xqpassport.lua:12:entry({"api", "xqpassport", "login"},call("passportLogin"), (""), 401, 0x01)
api/xqpassport.lua:14:entry({"api", "xqpassport", "rigister"},call("routerRegister"), (""), 405, 0x01)
api/xqpassport.lua:15:entry({"api", "xqpassport", "binded"},call("getBindInfo"), (""), 406, 0x01)
api/xqnetdetect.lua:12: --entry({"api", "xqnetdetect", "wan_status"},call("getWanStatus"),_(""), 351, 0x01)
api/xqnetdetect.lua:13:entry({"api", "xqnetdetect", "sys_info"},call("getSysInfo"), (""), 352, 0x01)
api/xqnetdetect.lua:14:entry({"api", "xqnetdetect", "ping_test"},call("pingTest"), (""), 353, 0x01)
api/xqnetdetect.lua:15:entry({"api", "xqnetdetect", "detect"},call("systemDiagnostics"), (""), 354, 0x01)
api/xqnetdetect.lua:16:entry({"api", "xqnetdetect", "sys_status"},call("systemStatus"), (""), 355, 0x01)
api/xqnetdetect.lua:19:entry({"api", "xqnetdetect", "nettb"},call("nettb"), (""), 359, 0x01)
api/misns.lua:12:entry({"api", "misns", "prepare"},call("prepare"), (""), 201, 0x01)
api/misns.lua:17:entry({"api", "misns", "sns_init"},call("snsInit"), (""), 206, 0x01)
api/misns.lua:21:entry({"api", "misns", "authorization_status"},call("authorizationStatus"), (""), 210, 0x01)
api/xqsystem.lua:17:entry({"api", "xqsystem", "system_info"},call("getSysInfo"), (""), 104, 0x01)
api/xqsystem.lua:32:entry({"api", "xqsystem", "get_languages"},call("getLangList"), (""), 118, 0x01)
api/xqsystem.lua:33:entry({"api", "xqsystem", "get_main_language"},call("getMainLang"), (""), 119, 0x01)
api/xqsystem.lua:45:entry({"api", "xqsystem", "passport_bind_info"},call("getPassportBindInfo"), (""), 132, 0x01)
api/xqsystem.lua:60:entry({"api", "xqsystem", "flash_status"},call("flashStatus"), (""), 147, 0x01)
api/xqsystem.lua:86:entry({"api", "xqsystem", "device_mac"},call("getDeviceMacaddr"), (""), 173, 0x01)
service/cachecenter.lua:11:entry({"service", "cachecenter", "report_key"},call("reportKey"),_(""), nil, 0x01)
service/datacenter.lua:34:entry({"service", "datacenter", "media_delta"},call("mediaDelta"),_(""), nil, 0x01)
service/datacenter.lua:35:entry({"service", "datacenter", "media_metadata"},call("mediaMetadata"),_(""), nil, 0x01)
service/datacenter.lua:36:entry({"service", "datacenter", "share_miui_dir"},call("shareMiuiBackupDir"),_(""), nil, 0x01)
service/datacenter.lua:37:entry({"service", "datacenter", "get_file_list"},call("getFileList"),_(""), nil, 0x01)
service/datacenter.lua:38:entry({"service", "datacenter", "get_storage_info"},call("getStorageInfo"),_(""), nil, 0x01)
service/datacenter.lua:39:entry({"service", "datacenter", "get_youku_status"},call("getYoukuStatus"),_(""), nil, 0x01)
service/datacenter.lua:40:entry({"service", "datacenter", "bind_youku_appid"},call("bindYoukuAppid"),_(""), nil, 0x01)

先選擇幾個重點的模塊看一下,如:xqsystem,datacenter, misystem先選擇第一個來查看一下:通過如下內容:

api/misystem.lua:33:entry({"api", "misystem", "topo_graph"},call("getTopoGraph"), (""), 114, 0x0d)

得知,可以通過訪問 http:///cgi-bin/luci/api/misystem/topo_graph 來調用getTopoGraph,可以去看一下getTopoGraph函數的內容,

functiongetTopoGraph()
 local XQTopology = require("xiaoqiang.module.XQTopology")
 localresult= {
 ["code"] = 0
 }
 localsimplified=tonumber(LuciHttp.formvalue("simplified")) == 1 and true or false
 localgraph=simplifiedand XQTopology.simpleTopoGraph() or XQTopology.topologicalGraph()
result["graph"] =graph
result["show"] =graph.leafsand 1 or 0
 LuciHttp.write_json(result)
end

發現函數中也沒有做任何驗證,進行訪問即可得到如下信息

Openwrt漏洞挖掘之不要用小米路由偷偷下小電影哦

Openwrt漏洞挖掘之不要用小米路由偷偷下小電影哦

在測試其他的模塊也有一些信息泄漏的漏洞,

Openwrt漏洞挖掘之不要用小米路由偷偷下小電影哦 Openwrt漏洞挖掘之不要用小米路由偷偷下小電影哦

其中比較嚴重的漏洞是下面這個,可以獲取這個用戶使用離線下載的文件列表,函數如下:

functiongetFileList()
 localpayload= {}
payload["api"] = 3
payload["path"] = LuciHttp.formvalue("path")
payload["sharedOnly"] = true
tunnelRequestDatacenter(payload)
end

看內容應該是獲取path下目錄,但是也做了校驗,并不能跳出其設置的用戶目錄,但是比如我們獲取了下面這位用戶,看到他下了一些小電影,什么黑絲豹紋,都是什么意思哦

Openwrt漏洞挖掘之不要用小米路由偷偷下小電影哦

來自為知筆記(Wiz)

轉載請注明:安全工具箱 ? Openwrt漏洞挖掘之不要用小米路由偷偷下小電影哦

來自: http://www.92aq.com/2016/01/20/openwrt-xiaomi-loudong.html

 本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!