天天看點

路由器固件安全分析技術(一)

前言

本文可作為路由器安全的入門學習教程,一起學習從零基礎從搭建環境開始入門路由器固件安全分析的技術。

搭建環境篇

示範系統:debian 3.16.0-4-686-pae

本篇重在示範路由器固件分析及運作環境,而對于工具各參數将不詳細闡述其用法,這裡隻要能夠成功搭建起來即可。

由于binwalk,qemu等工具目前隻能在linux環境下運作,又比如需要wine運作32位IDA程式。故綜合各方面,建議安裝32位debian發行版本。

在安裝各工具及依賴前更新/etc/apt/source.list,添加一行:deb http://us.archive.ubuntu.com/ubuntu saucy main universe,接着sudo apt-get update。以及安裝build-essential:sudo apt-get install build-essential,它能夠解決安裝過程的複雜的依賴問題。

1.IDA pro

由于路由器提取的根檔案系統有符号連結,在Windows下容易造成符号連結丢失,故在linux中安裝IDA Pro,同時linux原生版本的IDA pro網上的版本過舊,是以采取wine運作Windows IDA Pro。安裝wine,通過在終端輸入如下指令:

選擇在/opt目錄下建立目錄ida将Windows IDA Pro下所有檔案一概都拷貝到該檔案夾下。

路由器固件安全分析技術(一)

同時idaq.exe和idaq64.exe均為32位可執行檔案,這裡也是安裝32位Debian的原因。

由于後續會使用到IDA Pro的IDAPython插件,故還需要下載下傳https://www.dllme.com/dll/download/14091/python27.dll(該下載下傳位址來源于網絡),并放置到ida根目錄下。同時啟動idaq.exe以如下方式啟動:`export PYTHONPATH=/usr/lib/python2.7 && wine idaq`,當然可以寫入/usr/bin中,以該腳本方式啟動。

路由器固件安全分析技術(一)

最後,對路由器分析還需要一些IDA插件的支援,terminal中輸入git clone https://github.com/devttys0/ida.git,将整個目錄中的py檔案拷貝到/opt/ida/plugins中。此時啟動後能夠看到插件的生效如MIPS ROP Finder。

路由器固件安全分析技術(一)

2.BinWalk

如kali中安裝帶有BinWalk,但是由于缺少依賴依賴,故無法對固件進行解包,先使用git進行下載下傳:git clone https://github.com/devttys0/binwalk.git。

此時,僅可以對固件進行簡單的掃描操作。

路由器固件安全分析技術(一)

安裝依賴可以通過binwalk根目錄下的INSTALL.md依次進行安裝或者以root身份運作deps.sh。

通過執行binwalk -Me 固件檔案作為判斷依賴是否安裝成功的依據。

路由器固件安全分析技術(一)

3.qemu

qemu為模拟處理器的軟體,通過git進行下載下傳:git clone git://git.qemu-project.org/qemu.git。進入qemu下載下傳目錄。

執行如下指令

成功後進行配置并編譯安裝:sudo ./configure --static&&sudo make&&sudo make install。

對某固件bin目錄下非符号連結的檔案進行file指令,判斷其指令集類型。

說明為mips小端格式(little endian),小端格式也可見固件分析篇一節。

在提取檔案系統的bin目錄中直接執行qemu-mipsel ls,将會報找不到庫檔案的錯誤。這其實是因為需要定位根目錄到提取出檔案系統的根目錄中。

路由器固件安全分析技術(一)

将qemu-mispel拷貝到目前目錄,為更改執行目錄做準備,之後接着執行ls指令,可以看到能夠将mipsel指令集的ls運作起來了。

路由器固件安全分析技術(一)

4.交叉編譯環境

後續過程中,涉及到編譯編寫存在漏洞的mips可執行檔案及編寫mips可用的shellcode,故需要在linux上搭建交叉編譯環境。

完成下載下傳及解壓後,執行如下指令。

出現如下界面

路由器固件安全分析技術(一)

以MIPS小端格式為例,進入target options->target architecture選擇mips(little endian),target options->target architecture variant設定為MIPS。

路由器固件安全分析技術(一)

進入toolchain将kernel headers中将其改為對應機器的核心版本。

路由器固件安全分析技術(一)

由于測試機為3.16,故修改為低于此版本的headers。

路由器固件安全分析技術(一)

執行sudo make進行編譯,成功後在buildroot目錄的/output/host/usr/bin下出現mipsel-linux-gcc。

路由器固件安全分析技術(一)

同樣,可以編寫hello world程式使用mipsel-linux-gcc進行編譯後,使用qemu-mipsel進行運作,其中mipsel-linux-gcc用法與gcc一緻,讀者可以自行運作一下。

5.系統環境網絡配置

之前,已經通過qemu成功執行了一個mips程式,qemu還有一種模拟整個系統的模式。現在配置qemu虛拟機中的網絡環境。

後續步驟來源于參考資料,未能掌握這樣配置的原因,但暫且按部就班進行操作。

向/etc/network/interfaces添加如下内容:

在/etc/qemu-ifup中寫入如下内容:

儲存退出後使用chmod a+x為其加上可執行屬性。輸入sudo service networking restart重新開機網絡使設定生效。sudo ifdown eth0&sudo ifup br0。此時示範環境的網絡情況如下:

路由器固件安全分析技術(一)

現在,需要下載下傳核心檔案和磁盤鏡像。進入people.debian.org/~aurel32/qemu/即可,小端格式MIPS則為下載下傳vmlinux-2.6.32-5-4kc-malta和debian_squeeze_mipsel_standard.qcow2。

執行如下指令。

進入後預設密碼為root/root,登入後編輯/etc/network/interfaces,加入如下内容:

ifup eth1 啟用eth1接口,現在mips虛拟機網絡資訊如下圖。

路由器固件安全分析技術(一)

至此,常用的路由器固件分析工具均已搭建且配置完畢。

指令分析篇

為了不在分析固件的過程中,避免反複說明同一類問題的情況,本篇将會把涉及的mips彙編指令及特性等相關内容進行彙總加以說明。

目前,路由器多為使用mips32指令集的linux,掌握mips32彙編在逆向分析路由器固件中顯得格外重要。總體來說,其屬于risc精簡指令集,每條指令為4位元組定長。

1.寄存器

mips32中存在32個通用寄存器,每個寄存器長度均為32位,具體可見下表。

路由器固件安全分析技術(一)

除了通用寄存器,還有幾個特殊寄存器\$pc(程式計數器),\$hi(乘法高位存放,除法餘數存放),\$lo(乘法低位存放,除法商存放)。

2.常見指令

mips32指令編碼類型:

(1)6bit 操作碼+5bit源操作數+5bit第二源操作數+5bit目的操作數+5bit位移量+6bit函數位

(2)6bit操作碼+5bit源操作數+5bit第二源操作數+16bit立即數

(3)6bit操作碼+26bit位址

算術類:

因為受到risc指令定長的影響,對于mips32來說所有操作數不能使用記憶體尋址方式。對于add(i)(u)/sub(i)(u)加減類操作使用3個操作數,對于使用立即數的運算立即數大小不能超過16bit的表示。div/mul指令由于結果儲存在特殊寄存器\$hi和\$lo中,是以使用2個操作數即可。

load/store類:

load對應其彙編指令中l開頭的指令如lb,lw,la等等,作用為将尋址内容或是立即數讀入寄存器。相應地,store為s開頭如sb,sw等等将制定長度内容存入記憶體位址中。

跳轉指令:

均為無條件跳轉。j target為跳轉到target表示的位址,jr \$reg如jr \$ra常常被用于函數傳回,jal target代表junp and link将下一指令位置存入\$ra并跳轉到$ra。 其使用(3)型指令,故可以尋址26bit位址即256mb。

分支跳轉指令:

b target無條件跳轉到target,beq \$reg1,\$reg2,target為\$reg1=\$reg2時跳轉到target。同樣地,beq後的eq可以被替換包括lt(小于),le(小于等于),ne(不等于),ge(大于等于),gt(大于)。

syscall:

完成系統調用,\$v0存放系統調用号,一般情況下,\$a0-\$a3存放參數,系統調用傳回時\$v0存放傳回值,如若出錯則在\$a3中存放錯誤編号。

3.特性

尋址方式:

包括立即數尋址,寄存器尋址,寄存器相對尋址(寄存器和16位立即數相加後尋址),pc相對尋址:pc寄存器和16位立即數左移2位後運算尋址。

記憶體表示方法:

正如環境搭建出現的mipsel(little-endian),這裡以舉例方式來說明。如0x12345678早大端和小端方式存放的差別。從低位址到高位址表示大端存放位元組為0x12,0x34,0x56,0x78,小端方式從低位址到高位址為0x780x56,0x34,0x12。

流水線特性:

也被稱為分支延遲槽 ,與時鐘周期等有關,如jal在完成函數調用前jal的後一條指令已經被執行。

後門分析篇

本節将通過逆向分析一個實際路由器後門漏洞問題,在此同時鞏固指令分析篇的知識。

2014-02-10,CNCERT在http://www.cert.org.cn/publish/main/9/2014/20140429121938383684464/20140429121938383684464_.html 一文中通報了多個路由器的後門漏洞,其中包括D-LINK路由器的一個後門漏洞。

路由器固件安全分析技術(一)

首先,需要将固件的檔案系統提取出來,使用環境搭建中安裝的binwalk工具進行提取。輸入指令:binwalk -Me DIR100_v5.0.0EUb3_patch02.bix,其中-e代表根據配置檔案從固件中提取檔案系統,-M代表根據進行遞歸提取。

成功提取後,進入提取檔案系統目錄 的bin目錄下。同時,由于該後門的描述為:攻擊者通過修改User-Agent 值為“xmlset_roodkcableoj28840ybtide”(沒有引号)即可繞過路由器Web認證機制取得背景管理權限。故推測該後門與路由器的web server程式有關,在該目錄下對檔案名作為簡單的判斷依據,故對webs檔案進行逆向分析。

根據file指令得知其為大端mips32格式的可執行檔案。

根據公告資訊得知,在IDA Pro字元串視窗搜尋字元串:xmlset_roodkcableoj28840ybtide。

路由器固件安全分析技術(一)

根據交叉引用位置發現該字元串被出現在alpha_auth_check函數中。

路由器固件安全分析技術(一)

可以看到這個字元串和$s0+0xd0處内容當strcmp比對成功,則會v1=1,轉入loc_423edc。

路由器固件安全分析技術(一)

這裡也就是check成功的傳回值。也就是之前設定的1。

路由器固件安全分析技術(一)

而s0就是a0,傳遞的第一個參數。

路由器固件安全分析技術(一)

依次向上找調用處。

路由器固件安全分析技術(一)
路由器固件安全分析技術(一)
路由器固件安全分析技術(一)

函數簡化的為調用流程httpd_parse_request->alpha_httpd_parse_request->alpha_auth_check。在httpd_parse_request中看到結構體0xd0偏移處 的設定。這裡對應user-agent域的内容。這裡驗證了确實是user-agent為該值進行驗證。

路由器固件安全分析技術(一)

繼續看上層函數會判斷alpha_auth_check傳回值與-1的值。同時注意這裡延遲槽的處理。

路由器固件安全分析技術(一)

成功傳入http_request_t*内容等調用do_xgi處理請求。

路由器固件安全分析技術(一)

驗證不通過則重定向到/public/login.htm。

路由器固件安全分析技術(一)

這一步驗證了為該特殊值通過驗證不會被重定向到登入頁面的情況。最終确定該後門漏洞細節與描述一緻。

漏洞利用基礎篇

1.基本溢出原理

本篇将介紹如何編寫基礎功能的shellcode中的payload,如ctf pwn中常常會使用到的執行/bin/sh。因本篇做基礎技術介紹,至于其他更為複雜的payload編寫及實際二進制漏洞利用将在後續依次介紹。

mips與x86函數調用存在比較大的差别,從如下幾點進行描述。

葉子函數:内部不再調用其他函數的函數稱為葉子函數,相反稱為非葉子函數。

先來分析如超過4個參數傳遞的非葉子函數調用。

高位址到低位址依次為目前函數的寄存器備份和局部變量,參數x-參數1(參數4-參數1預留),目前函數傳回用的位址,調用函數的寄存器備份及局部變量。。。。。。依次類推。葉子函數和非葉子函數根據之前的描述可知其決定如何傳回到上層函數。故讨論覆寫傳回位址問題時需要分開讨論。

路由器固件安全分析技術(一)

由于這裡的non_leaf會調用strcpy是以其是一個非葉子函數,可以看到var_4位置是傳回\$ra存放的位置。而var_20是strcpy的目的位址,這裡存在棧溢出漏洞是可以覆寫掉var_4控制傳回位址 的。

對于葉子函數,這類情況傳回位址不會暫存在棧中,是以其通過$ra進行函數傳回。此時就需要滿足溢出空間足夠,來覆寫上層函數存放傳回位址的區域,因為上層函數必定是一個非葉子函數。

2.基本payload編寫方法

在mips32-linux的payload編寫,不可避免的使用到syscall系統調用。正如固件分析篇中所描述的,\$v0作為系統調用号,$a0-\$a3作為傳遞參數。

首先,不同系統調用對應不同的系統調用号及參數,故需要完成确定系統調用号的工作。為了确定系統号,進入使用者的buildroot目錄(為搭建環境中的交叉編譯安裝目錄),如進入/home/tophant/buildroot/output/build/linux-headers-3.12.74/usr/include/asm,檢視unistd.h頭檔案,示範的對應大端mips-libnux的頭檔案,不過對于小端mips-linux來說應該保持一緻。如下為該 檔案的簡單片段。

可知,對于mips32來說syscall的功能号範圍為4000到4348。比如#define NR_execve (NR_Linux + 11)代表execve的調用号為4011。

那麼,現在便動手編寫一個運作linux shell的payload,對應linux中的函數為execve。首先通過man檢視該函數的簡要說明,以便确定系統調用時的參數。

可知,隻需要向filename填充"/bin/sh"來完成,argv,envp填寫NULL即可。

如下為使用mips32彙編語言編寫的代碼。

.section .text代表為代碼段;.globl shellcode_execve代表程式主函數入口根據shellcode_execve辨別;.set noreorder與流水線機制相關,為了代碼被重新編排故加上本句宏.

shellcode_execve使用jal指令,這将會把alpha的運作時位址存入\$ra中,目的為能夠動态定位到variables辨別的位址初,避免不同運作環境下的不同位址問題,也被稱為代碼重定位技術。而nop一句為流水線機制留白。addiu \$a0,\$ra,20為定位到variables,\$ra運作時為alpha的位址,而mips32為risc,指令為定長4位元組,可以計算出到該字元串的距離4x5=20,接着就是參數2,3設定,現設定為NULL。最後完成調用号為4011(execve)的系統調用,最後緊跟/bin/sh字元串。

編譯并連結使用如下指令,同樣用到交叉編譯工具buildroot。

路由器固件安全分析技術(一)

該mips32彙編編寫已結被成功運作。現在需要将編寫的shellcode提取出來。首先通過readelf讀取節頭表。

路由器固件安全分析技術(一)

可以看到起始于0x4000d0,大小為0x30。進入ida在反彙編視窗找到對應位置,單擊0x4000d0,進入hex-view。

路由器固件安全分析技術(一)

灰色區域就是待提取的shellcode。

例如存在使用strcpy的溢出漏洞,完整的payload将會被\x00截斷,故需要将\x00壞字元剔除。

如上彙編指令均需要被調整為不帶\x00的指令。

​根據參考,jal alpha調整為li \$a2,0x1111;bltzal \$a2,alpha2這樣保證alpha在目前調整連結的上方不會因為payload長度原因導緻跳轉高8位為0x00。

nop指令在x86下為\x90,而在mips32下為\x00\x00\x00\x00,是以使用不影響payload運作的無效指令替代nop,lui \$a1,0x0101。

\x14\x00\xe4\x27一句中可以看到低2位元組和調整堆棧位置大小有關。是以通過先加一個16進制的3位數,再相應前去對應大小即可,同時保證不含\x0001103。如addiu \$a0,\$ra,1025,addiu \$a0,\$a0,-1001。

li \$a1,0調整為slti \$a1,\$zero,-1,因為0寄存器總小于1,\$a1一定會被置為0。同理調整 li \$a2,0為slti \$a2,\$zero,-1。

最後,重構payload需要調整重定位的偏移。

路由器固件安全分析技術(一)

可以觀察到所有的\x00都被剔除了。至此以\x00為壞字元的修正過程完畢。

路由器固件安全分析技術(一)

以上均是shellcode的編寫技術的基礎概覽,在實際運用中還需要根據特定條件進行一定的轉換。

參考資料

1.揭秘家用路由器0day漏洞挖掘技術——吳少華

2.詳細的路由器漏洞分析環境搭建教程——伐秦

3.Reported Vulnerability - D-Link routers authenticate administrative access using specific User-Agent string

繼續閱讀