本文節選自《揭秘家用路由器0day漏洞挖掘技術》一書,電子工業出版社,2015年8月上市
在前面的章節中,我們已經學習了如何從路由器固件中提取根文件系統,以及如何進行漏洞的分析和挖掘。從本章開始,我們會學習路由器硬件方面的一些基本知識。 通常我們都是通過路由器廠商獲取可用的固件,但并不是每一個路由器廠商都提供了固件下載,或者部分型號的產品沒有提供固件下載,這時我們就需要使用本章的技術,通過路由器硬件提供的接口將計算機與路由器主板連接,從當前的路由器中提取需要的數據。
本節我們來了解一下與路由器硬件相關的基礎知識。
FLASH也叫閃存,是路由器中常用的一種內存類型。它是可讀寫的存儲器,在系統重新啟動或關機之后仍能保存數據。FLASH中存放著當前正在使用的路由器操作系統等信息。 路由器的FLASH就像計算機的硬盤。我們的硬盤通常會被格式化成多個分區。同樣的原理,FLASH也被格式化為多個分區。通常情況下,FLASH分成4個區塊,其作用大致如下。
路由器的FLASH中存儲的數據對于我們進行路由器安全研究具有十分重要的意義。我們可以讀取NVRAM中的配置信息,以了解當前路由器中的敏感信息,還可以從FLASH中提取固件,然后運用前面學過的知識進行漏洞分析和挖掘。接下來,我們就給出從硬件中提取這些數據的一些思路。
通過接觸硬件進行數據提取的方法可謂多種多樣,通常情況下可以考慮以下3種方案。
路由器的串口對于開發人員來說是很有用的,通常可以用串口實現以下功能。
因此,這些功能對于我們進行路由器安全研究也具有相當大的益處。 在路由器中,我們要尋找的串口不是指通常所見的RS232,而是指UART(通用異步收發器),它是路由器設備中比較常見的一種接口。雖然RS-232和UART在協議方面是兼容的,但在電壓上卻不兼容。UART通常在3.3伏特進行操作,但也可運行在其他標準電壓(如5伏特、1.8伏特等)下。在后文中,凡是關于路由器串口的描述,在沒有特殊說明的情況下,都是指UART。 如下圖所示是Linksys WRT54G v2.2路由器主板上的串行接口。
下面我們使用基本的觀察法和萬用表從復雜的路由器主板中找出UART,并確定UART的每一個引腳的用途。由于UART的非標準化,這里演示的方法并非“放之四海而皆準”。本節以Linksys WRT54G v2路由器為例,其主板上一共有2個串口,接下來就演示一些基本的判定路由器串口的方法。 首先,我們通過肉眼觀察路由器主板上的引腳。一般來說,UART至少包含以下4個引腳。
也就是說,我們首先要注意在路由器主板上那些單行具有4~6個引腳的位置。但這種方法不一定在任何時候都有效,因為這些引腳的位置是由各個廠商設計的,沒有統一的標準。WRT54G路由器主板上的UART的位置如下圖所示。
通過觀察發現,“JP1”字樣的方框內是最符合URAT標志的WRT54G路由器主板的串口位置,在主板上已經標明了引腳的編號,以此來定位每一個引腳。 找到路由器串口以后,我們需要區分這些引腳的功能。這里給出以下兩種方法,通過這兩種方法的配合,可以快速識別每一個引腳的作用。
主板在印刷時都會遵循一些規律,這些規律可以幫助我們識別串口的引腳。
(1)VCC引腳的特點
VCC引腳通常被做成方形,如WRT54G路由器主板上的1號引腳。從路由器主板上可以看到較寬的走線,那么該引腳極有可能也是VCC引腳,如WRT54G路由器主板上的2號引腳。
(2)GND引腳的特點
GND引腳通常存在多條走線連接到周圍的地線(GND)。如下圖所示,將WRT54G路由器主板放大后,可以看到9號和10號引腳都有2條走線連接周圍的地線。
如果說在WRT54G路由器的主板上看起來還不是那么明顯,那么WRT120N路由器主板上的9號引腳就顯得尤為突出了,一共有8條較細的走線連接周圍的地線,如下圖所示。
通過目測法可以初步判斷WRT54G路由器主板上的1號和2號引腳為VCC引腳,9號和10號引腳為GND引腳,但是仍然存在6個引腳。在這6個引腳中,我們需要區分TXD引腳和RXD引腳。在剩余的6個引腳中,可以看到3號、4號、5號、6號這4個引腳分別有4條較細的走線連接,那么可以初步判斷TXD和RXD在這4個引腳當中。但遺憾的是,如果想知道哪個引腳是TXD引腳,哪個引腳是RXD引腳,使用目測法無法得出確切的答案。通過目測法僅僅是初步判斷,不能完全肯定,因此,我們需要通過下面的方法進行進一步的確定。
(1)測試GND引腳
將萬用表調到電阻測量的最小檔。這里最小為200歐姆,因此選擇電阻200歐姆檔位。然后,我們需要確定萬用表的兩只表筆應該放在哪些位置。通常金屬屏蔽是一個方便測試的接地點,因此,將一只表筆放在金屬屏蔽罩上,用另一只表筆分別接觸10個引腳,測試金屬屏蔽罩與串口的10個引腳,電阻為0的引腳即為GND引腳。 在WRT54G路由器的主板上有一塊金屬屏蔽外殼,將黑色探針(萬用表的負極探針)置于其上,然后使用另一根探針分別接觸10個需要測試的引腳,如下圖所示。
測試10個引腳之后發現,只有9號和10號引腳的電阻非常接近0,萬用表顯示電阻為00.2歐姆,如下圖所示。
在這里,萬用表電阻不為0的原因是萬用表自身的電阻就是40歐姆(00.2×200)。可以嘗試將兩只表筆短接來測試萬用表自身的電阻,如下圖所示。因此,這里測得WRT54G路由器主板串口的9號和10號引腳的電阻其實是0,也就是說,9號和10號引腳均為GND引腳。
(2)測試VCC
雖然VCC引腳對于我們使用路由器的串口是無關緊要的,但是確定VCC引腳可以排除它作為RXD引腳和TXD引腳的可能性,因此也是有必要的。在目測中,我們懷疑1號和2號引腳是VCC引腳,那么接下來我們就用萬用表來驗證這一猜測。 將萬用表量程放在直流電壓20伏特檔位上,給路由器上電(將路由器電源接通),從路由器啟動到系統完全啟動這段時間內觀察到電壓值基本穩定在3.30伏特,因此,1號和2號引腳為VCC引腳的猜想得到了驗證,如下圖所示。
(3)測試TXD引腳
當串行端口處于激活狀態并發送數據(否則無法測試出發送引腳)時,發送引腳是相當容易識別的。主板上的發送引腳被拉高到與VCC引腳相同的電壓,通常是3.3伏特。在有數據發送時,電壓將下降到0。當讀取的是一個不斷變化的直流電壓時,數字萬用表將顯示最終的平均采樣電壓。因此,如果萬用表顯示引腳電壓下降,表示該引腳有數據發送,由此可以判斷該引腳是TXD引腳。 在路由器中,引導程序、內核、系統的所有啟動信息都將被打印到串口,因此,我們測試TXD引腳的最佳時機就在系統啟動階段。我們在路由器系統啟動期間監控3號、4號、5號和6號這4個引腳,應該能夠很容易地識別哪些是發送引腳。 測試3號和4號引腳,發現其電壓在一段時間內保持在3.30伏特,如下圖所示。
接著,電壓便恢復到3.29伏特。 繼續測試,發現5號和6號引腳的特征與TXD引腳的特征不符,因此判斷3號和4號引腳為TXD引腳。 雖然這是識別發送引腳的一種有效方法,但值得注意的是,如果串行端口只發送少量數據,通過電壓波動判斷可能就不是那么準確了,這時我們需要使用示波器或邏輯分析儀捕獲發送引腳的數據活動。
(4)測試RXD引腳
準確地識別接收引腳是最困難的,因為它沒有十分有效的特征定義。通常我們通過測試找出TXD引腳,另一個引腳就是RXD引腳了。例如,在WRT54G路由器的主板上,5號和6號引腳就是RXD引腳。 經過上面的測試,我們基本上完成了對WRT54G路由器主板的引腳測試,2個串口(ttys0和ttys1)都已經找出來了。需要注意的是,并不是所有的路由器主板都有2個串口。 在WRT54G v2路由器的主板上有2個URAT接口,測試結果如表16-1所示。
表16-1
引腳 | 定義 | 引腳 | 定義 |
---|---|---|---|
1 | VCC(3.3V) 2.0 | 6 | RXD(ttyS0) |
2 | VCC(3.3V) 2.0 | 6 | RXD(ttyS0) |
3 | TXD(ttyS1) | 8 | NC |
4 | TXD(ttyS0) | 9 | GND |
5 | RXD(ttyS1) | 10 | GND |
在識別了串口的各個引腳之后,我們就可以通過一條USB轉UART適配器的TTL-232R-3V3線連接進行連接了。將UART適配器的USB接口端插入計算機的USB接口,將UART適配器連接到路由器串行端口中,使用方式如下。
接下來,我們開始進行硬件連接的準備工作。 首先,用排針或者將10個引腳的牛角座焊接到主板上,如下圖所示。
然后,按照上面給出的方法使用條線連接UART適配器和串口(使用靠近主板邊緣的ttyS0串行接口),如下圖所示。
連接好UART適配器和路由器串口以后,將UART適配器連接到計算機。由于本例是虛擬機環境,所以需要確認已經將TTL-232R-3V3適配器添加到虛擬機中,如下圖所示。
硬件方面的操作到這里基本上已經完成了,接下來,我們需要檢查串行端口的協議設置。串行端口有多種設置,但是在這里我們只需要完成波特率的設置即可。嘗試錯誤是識別波特率最快和最簡單的方法。因為串行端口通常用于顯示調試信息(即它們發送ASCII數據),并且只有少數可能頻率的波特率,所以我們可以循環逐一測試可能的波特率,直到輸出可理解的數據(如ASCII碼)時,就找到了當前串口的波特率。 在本書提供的下載鏈接中,baudrate.py有一個功能選項“-a”可以自動檢測波特率,使用方法如下。
[email protected]:~/soft$ sudo python baudrate.py -a
Starting baudrate detection on /dev/ttyUSB0, turn on your serial device now.
Press Ctl+C to quit.
@@@@@Baudrate: 9600 @@@@@@@
---snip---
@@@@@Baudrate: 115200 @@@@@@@
Detected baudrate: 115200
Save minicom configuration as:
這里我們檢測到WRT54G路由器主板的串口使用的波特率為115?200,但需要注意的是,在自動檢測的過程中,要保證串口有數據輸出,否則baudrate.py將無法準確檢測波特率。
在Linux環境下讀取路由器串口數據有以下幾種方法。
在知道路由器串口的波特率之后,我們可以直接運行本書下載鏈接中的miniterm.py。例如,知道波特率為115?200,運行如下命令。
[email protected]:~/soft$ sudo miniterm.py /dev/ttyUSB0 115200
--- Miniterm on /dev/ttyUSB0: 115200,8,N,1 ---
--- Quit: Ctrl+] | Menu: Ctrl+T | Help: Ctrl+T followed by Ctrl+H ---
此時,miniterm.py處于等待狀態。啟動路由器(接通電源),可以看到在Ubuntu終端已經打印了啟動信息,具體如下。
CFE version 1.0.37 for BCM947XX (32bit,SP,LE)
Build Date: Fri Feb 27 15:20:59 CST 2004 ([email protected])
Copyright (C) 2000,2001,2002,2003 Broadcom Corporation.
Initializing Arena.
Initializing Devices.
et0: Broadcom BCM47xx 10/100 Mbps Ethernet Controller 3.50.21.0
CPU type 0x29007: 200MHz
Total memory: 0x2000000 bytes (32MB)
Total memory used by CFE: 0x80334DC0 - 0x8043A310 (1070416)
Initialized Data: 0x80334DC0 - 0x80336F40 (8576)
BSS Area: 0x80336F40 - 0x80338310 (5072)
Local Heap: 0x80338310 - 0x80438310 (1048576)
Stack Area: 0x80438310 - 0x8043A310 (8192)
Text (code) segment: 0x80300000 - 0x8030F220 (61984)
Boot area (physical): 0x0043B000 - 0x0047B000
---snip---
在WRT54G路由器的啟動階段,按“Ctrl+C”組合鍵可以中止WRT54G路由器系統的啟動過程,進入CFE命令行模式,示例如下。
CFE version 1.0.37 for BCM947XX (32bit,SP,LE)
Build Date: Fri Feb 27 15:20:59 CST 2004 ([email protected])
Copyright (C) 2000,2001,2002,2003 Broadcom Corporation.
Initializing Arena.
Initializing Devices.
---snip---
Boot version: v2.3
The boot is CFE
mac_init(): Find mac [00:0F:66:AE:B4:DC] in location 1
Nothing...
Device eth0: hwaddr 00-0F-66-AE-B4-DC, ipaddr 192.168.1.1, mask 255.255.255.0
gateway not set, nameserver not set
Reading :: Failed.: Error
CFE>
輸入“help”可以查看當前支持的命令,具體如下。
CFE> help
Available commands:
et Broadcom Ethernet utility.
nvram NVRAM utility.
reboot Reboot.
flash Update a flash memory device
memtest Test memory.
f Fill contents of memory.
e Modify contents of memory.
d Dump memory.
u Disassemble instructions.
autoboot Automatic system bootstrap.
batch Load a batch file into memory and execute it
go Verify and boot OS image.
boot Load an executable file into memory and execute it
load Load an executable file into memory without executing it
save Save a region of memory to a remote file via TFTP
ping Ping a remote IP host.
arp Display or modify the ARP Table
ifconfig Configure the Ethernet interface
show devices Display information about the installed devices.
unsetenv Delete an environment variable.
printenv Display the environment variables
setenv Set an environment variable.
help Obtain help for CFE commands
For more information about a command, enter 'help command-name'
*** command status = 0
使用這些命令可以完成路由器CFE、FLASH、NVRAM的相關操作。這里我們以查看WRT54G路由器NVRAM配置信息中關于登錄頁面密碼的內容為例,命令如下。
CFE> nvram get http_passwd
admin
*** command status = 0
從返回的結果可以知道,這臺WRT54G路由器的Web管理功能的登錄密碼是“admin”。
在WRT54G路由器的啟動過程中,如果不使用“Ctrl+C”組合鍵,路由器就會正常啟動,啟動信息打印如下。
CFE version 1.0.37 for BCM947XX (32bit,SP,LE)
Build Date: Fri Feb 27 15:20:59 CST 2004 ([email protected])
Copyright (C) 2000,2001,2002,2003 Broadcom Corporation.
Initializing Arena.
Initializing Devices.
---snip---
gateway not set, nameserver not set
pppoe0 ifname=ppp0 ip=10.64.64.64 , netmask=255.255.255.255, gw=10.112.112.112
----------------------------------------------------------------------------
No interface specified. Quitting...
Hit enter to continue...
等待系統啟動完成,提示按“Enter”鍵繼續。按下“Enter”鍵,就可以進入Linux系統,提示如下。
BusyBox v0.60.0 (2005.07.12-09:08+0000) Built-in shell (msh)
Enter 'help' for a list of built-in commands.
#
此時,我們就可以使用命令管理路由器了。例如,查看運行在路由器上的Web服務器的動態庫鏈接地址,命令如下。
# ps |grep httpd
63 0 S httpd
147 0 S grep httpd
# cat /proc/63/maps|grep libc.so.0
2aac0000-2aac7000 r-xp 00000000 1f:02 1530 /lib/ld-uClibc.so.0
2ab06000-2ab07000 rw-p 00006000 1f:02 1530 /lib/ld-uClibc.so.0
2ad53000-2ad88000 r-xp 00000000 1f:02 1560 /lib/libc.so.0
2adc7000-2adc9000 rw-p 00034000 1f:02 1560 /lib/libc.so.0
可以看到,libc.so.0的加載基址為0x2ad53000。
在Windows環境下同樣可以連接路由器的串行端口,接下來我們就來看看如何使用Putty連接路由器的串行端口。 連接好適配器與串口以后,首先通過Windows的設備管理器查找適配器端口COM3,然后配置Putty,設置“Connect type”為“Serial”,將“Serial line”修改為“COM3”,設置波特率為115?200。配置好以上基本信息以后,單擊“Open”按鈕進行連接,啟動路由器,如下圖所示。如果要進入CFE命令行模式,只要在啟動過程中按“Ctrl+C”組合鍵即可。
通過路由器的串行端口可以獲得啟動信息。在CFE模式下可以利用CFE執行命令、操作NVRAM等。在對FLASH進行操作可以通過CFE更新固件。通過串行端口還可以獲得Shell管理系統。