淺談路由器漏洞挖掘
前言
去年公司買了個華碩路由器,型號為AC86U,我閑來無事嘗試挖掘了下,一個月內,從路由器漏洞挖掘零基礎到混了三個CVE。在此分享我一些漏洞挖掘思路。

前期準備
首先了解我們的路由器,做一些基礎工作。
登錄路由器后臺了解基本的一些功能,比如能不能開啟ssh連接等等。訪問官網看看能不能下到固件等,如果不能下載到固件,則需要考慮硬件dump或者網絡截取的方法來獲取固件。
華碩的路由器是可以直接開啟ssh登錄的,這里打開系統管理有一個服務選項,其中有一個啟用SSH的功能。

登錄之后就可以做一些基礎準備了。
確定挖掘目標
使用netstat -anpt命令,查看路由器有哪些開放的端口,哪些是可以通過外網訪問到的,而哪些是只有本地訪問到的。
tcp 0 0 0.0.0.0:5152 0.0.0.0:* LISTEN 294/envrams tcp 0 0 0.0.0.0:5473 0.0.0.0:* LISTEN 1846/u2ec tcp 0 0 0.0.0.0:18017 0.0.0.0:* LISTEN 1043/wanduck tcp 0 0 0.0.0.0:36098 0.0.0.0:* LISTEN 1928/miniupnpd tcp 0 0 0.0.0.0:3394 0.0.0.0:* LISTEN 1846/u2ec tcp 0 0 192.168.50.1:515 0.0.0.0:* LISTEN 1847/lpd tcp 0 0 192.168.50.1:1990 0.0.0.0:* LISTEN 1155/wps_monitor tcp 0 0 127.0.0.1:47753 0.0.0.0:* LISTEN 1912/mcpd tcp 0 0 192.168.50.1:16363 0.0.0.0:* LISTEN 2111/uuplugin tcp 0 0 192.168.50.1:9100 0.0.0.0:* LISTEN 1847/lpd tcp 0 0 0.0.0.0:7788 0.0.0.0:* LISTEN 1733/cfg_server tcp 0 0 127.0.0.1:80 0.0.0.0:* LISTEN 1644/httpd tcp 0 0 192.168.50.1:80 0.0.0.0:* LISTEN 1644/httpd tcp 0 0 127.0.0.1:38770 0.0.0.0:* LISTEN 2111/uuplugin tcp 0 0 127.0.0.1:53 0.0.0.0:* LISTEN 1635/dnsmasq tcp 0 0 192.168.50.1:53 0.0.0.0:* LISTEN 1635/dnsmasq tcp 0 0 192.168.50.1:22 0.0.0.0:* LISTEN 1764/dropbear tcp 0 0 127.0.0.1:38746 0.0.0.0:* LISTEN 2117/uuplugin tcp 0 0 192.168.50.1:3838 0.0.0.0:* LISTEN 1847/lpd
使用iptables命令查看規則。眾所周知漏洞修復的手法多種多樣,常見手法例如,直接修復程序上的漏洞,砍掉整個功能(可憐的公式編輯器),添加防火墻規則。有些的修復手法就是通過添加規則擋掉外部流量來做的。
使用iptables -nvL --line-number命令來查看規則。
Chain INPUT (policy ACCEPT 0 packets, 0 bytes) num pkts bytes target prot opt in out source destination 1 118K 7060K DROP tcp -- lo * 127.0.0.1 127.0.0.1 tcp dpt:38770 2 0 0 ACCEPT tcp -- br0 * 0.0.0.0/0 0.0.0.0/0 tcp dpt:16363 3 0 0 ACCEPT 2 -- eth0 * 0.0.0.0/0 0.0.0.0/0 4 826 188K INPUT_PING icmp -- * * 0.0.0.0/0 0.0.0.0/0 icmptype 8 5 1846K 433M ACCEPT all -- * * 0.0.0.0/0 0.0.0.0/0 state RELATED,ESTABLISHED 6 1770 85622 DROP all -- * * 0.0.0.0/0 0.0.0.0/0 state INVALID 7 4429K 973M PTCSRVWAN all -- !br0 * 0.0.0.0/0 0.0.0.0/0 8 202K 22M PTCSRVLAN all -- br0 * 0.0.0.0/0 0.0.0.0/0 9 34 1768 DROP tcp -- !lo * 0.0.0.0/0 0.0.0.0/0 tcp dpt:5152 10 202K 22M ACCEPT all -- br0 * 0.0.0.0/0 0.0.0.0/0 state NEW 11 4429K 973M ACCEPT all -- lo * 0.0.0.0/0 0.0.0.0/0 state NEW 12 0 0 ACCEPT udp -- * * 0.0.0.0/0 0.0.0.0/0 udp spt:67 dpt:68 13 0 0 INPUT_ICMP icmp -- * * 0.0.0.0/0 0.0.0.0/0 14 378 96645 DROP all -- * * 0.0.0.0/0 0.0.0.0/0
可以看到有的端口的包是完全丟棄掉的,比如5152端口。
在剩余的程序中,通過百度或者其他搜索引擎了解它是干什么的,一般來講應用較廣身經百戰的項目漏洞比較少且難以發現,并且在網上都是可以查到他是干什么的,例如這里面的miniupnpd,dnsmasq等。而查不到的則很有可能是廠商自己實現的功能也就是我們的目標,其中功能越多越容易出現漏洞。
環境準備
在路由器上安裝編譯好的gdb,這里我是直接從github上下載編譯好的,在本地使用python搭建下載服務,在路由器上使用wget下載下來,需要注意的是,路由器重啟之后所有下載的文件就會消失,需要我們重新下載到路由器上,因此非必要的情況下不要重啟路由器。
漏洞挖掘
這里以我挖掘危害較輕的一個漏洞為例。這里我選擇的是cfg_server。
由于程序代碼量很大,因此我們需要找到最關鍵的部分,也就是數據處理的部分,這里通過調試對recv,listen,accept等函數下斷點,通過跟蹤數據流來找到程序處理數據的位置。

這里是根據輸入數據的前四字節走入不同的處理函數。
變量dword_A2F90存放對應功能碼以及處理函數。

例如94 8e 05 00地址對應的是功能碼1的處理函數。
定位之后繼續對該程序代碼分析,發現其實一個TLV格式的報文,TLV 的意思就是Type 類型,Length 長度,Value 值。接下來就是對每個功能進行分析,來找出其中是否存在漏洞,這里需要耐心以及對功能的理解。
這里以0x1對應的功能為例,正常交互時,會輸出程序的公鑰。如下圖。

當我們設置長度為0xfffffff4的時候會導致服務端出現邏輯錯誤,進而無限循環不停向客戶端發送公鑰,此時如果關閉客戶端的連接就會導致程序產生SIGPIPE信號進而退出。

該漏洞的漏洞點在于沒有對輸入的長度進行驗證,也就是說不會驗證TLV中的L與V的長度是否相等。另一個則是程序的信號處理不夠完善,導致程序退出。至此一個簡單的拒絕服務漏洞就出現了。
而官方通過添加驗證數據長度的代碼進行修復漏洞。
總結
對我而言整個流程總體來說,確定目標,環境準備,漏洞挖掘。其中花的時間大部分在對程序的逆向分析上,一個程序實現的功能越多越復雜就越可能出現漏洞。最終拿了三個CVE,總體而言華碩的漏洞提交體驗還是不錯的。
