<span id="7ztzv"></span>
<sub id="7ztzv"></sub>

<span id="7ztzv"></span><form id="7ztzv"></form>

<span id="7ztzv"></span>

        <address id="7ztzv"></address>

            原文地址:http://drops.wooyun.org/tips/4523

            0x00 背景與簡介


            這篇文章主要講了如何在模擬環境下調試設備固件。

            作者:Zach Cutlip

            原文鏈接:http://shadow-file.blogspot.gr/2015/01/dynamically-analyzing-wifi-routers-upnp.html。

            在分析嵌入式設備的固件時,只采用靜態分析方式通常是不夠的。你需要實際執行你的分析目標來觀察它的行為。在嵌入式Linux設備的世界里,很容易把一個調試器放在目標硬件上進行調試。如果你能在自己的系統上運行二進制文件,而不是拖著硬件做分析, 將會方便很多。這就需要用QEMU進行仿真。

            接下來的一系列文章,我將專注于Netgear的一個比較流行的無線路由器,對其UPnP守護進程進行逆向分析。這篇文章將介紹如何在系統仿真環境下運行守護進程,以便可以通過調試器對其進行分析。

            0x01 先決條件


            首先,建議你讀一下我的工作區以及所使用的工具的描述。這里是鏈接http://shadow-file.blogspot.com/2013/12/emulating-and-debugging-workspace.html。

            你需要一個MIPS Linux的模擬環境。對于這一點,建議讀者查看我之前的搭建QEMU的帖子。http://shadow-file.blogspot.com/2013/05/running-debian-mips-linux-in-qemu.html

            你還需要一個MIPS Linux的交叉編譯器。我不會詳細描述交叉編譯器的建立過程,因為它們一團糟。有時候,你需要較舊的工具鏈,而其他時候,你需要較新的工具鏈。最好使用uClibc buildroot project(http://buildroot.uclibc.org/)同時建立big endian和little endian的MIPS Linux工具鏈。除此之外,每當我發現其他交叉編譯工具鏈時,我都會保存他們。類似D-Link和Netgear公司發布GPL版本tarballs是舊工具鏈的好來源。

            一旦你有了目標架構的交叉編譯工具鏈,你需要為目標建立GDB調試器。你至少需要適合目標架構的被靜態編譯的gdbserver。如果要使用GDB進行遠程調試,你需要編譯GDB,以便在你的本地機器架構(如X86-64)上運行,來對目標架構(如MIPS或mipsel體系結構)進行調試。同樣,我也不會去討論這些工具的構建,如果你建立了你的工具鏈,這應該很容易了。

            后面我將描述如何使用IDA Pro來進行遠程調試。但是,如果你想使用gdb,可以看看我的MIPS gdbinit文件:https://github.com/zcutlip/gdbinit-mips

            0x02 模擬一個簡單的二進制


            假設你已經建立了上述工具,并能正常工作,你現在應該能夠通過SSH進入您的模擬MIPS系統。正如我在Debian MIPS QEMU文章中所述,我喜歡連接QEMU的接口到VMWare的NAT接口,這樣就能夠用我的Mac通過SSH來接入,而不需要先登陸我的Ubuntu虛擬機。這也可以讓我通過NFS將我的Mac工作區掛載到QEMU系統。這樣,無論我工作在主機環境中,或是Ubuntu中,還是在QEMU中,我都在用相同的工作區。

            [email protected]:~ (130) $ ssh [email protected]
            [email protected]'s password:
            Linux debian-mipsel 2.6.32-5-4kc-malta #1 Wed Jan 12 06:13:27 UTC 2011 mips
            
            [email protected]:~# mount
            /dev/sda1 on / type ext3 (rw,errors=remount-ro)
            malastare:/Users/share/code on /root/code type nfs (rw,addr=192.168.127.1)
            [email protected]:~#cd code
            [email protected]:~/code#
            

            一旦登陸到模擬系統,cd到從設備的固件中提取的文件系統中。你應該能夠chroot到固件的根文件系統。需要使用chroot,因為目標二進制是和固件的庫鏈接的,很可能不能跟Debian的共享庫一起工作。

            [email protected]:~#cd code/wifi-reversing/netgear/r6200/extracted-1.0.0.28/rootfs/
            [email protected]:[email protected]e ./bin/ls
            ./bin/ls: symbolic link to `busybox'
            [email protected]:[email protected]e ./bin/busybox
            ./bin/busybox: ELF 32-bit LSB executable, MIPS, MIPS32 version 1 (SYSV), dynamically linked (uses shared libs), stripped
            [email protected]:[email protected]oot . /bin/ls -l /bin/busybox
            -rwxr-xr-x    1 10001    80         276413 Sep 20  2012 /bin/busybox
            [email protected]:~/code/wifi-reversing/netgear/r6200/extracted-1.0.0.28/rootfs#
            

            在上面的例子中,我已切換到所提取的文件系統的根目錄中。然后使用file命令,我了解到busybox是little endian MIPS可執行文件。然后,chroot到提取根目錄,并運行bin/ls,它是busybox的符號鏈接。

            如果試圖簡單的通過“chroot .”來地啟動一個shell,將無法正常工作。因為你的默認shell是bash,而大多數嵌入式設備沒有bash。

            [email protected]:[email protected]oot . chroot: failed to run command `/bin/bash': No such file or directory [email protected]:~/code/wifi-reversing/netgear/r6200/extracted-1.0.0.28/rootfs#

            相反,你可以chroot并執行bin / sh:

            [email protected]:[email protected]oot . /bin/sh
            
            BusyBox v1.7.2 (2012-09-20 10:26:08 CST) built-in shell (ash)
            Enter 'help' for a list of built-in commands.
            
            #
            #
            #exit
            [email protected]:~/code/wifi-reversing/netgear/r6200/extracted-1.0.0.28/rootfs#
            

            0x03 硬件解決方法


            即使有了必要的工具,建立了仿真環境且工作正常,你仍然可能遇到障礙。雖然QEMU在模擬核心芯片組包括CPU上都做的很不錯,但是QEMU往往不能提供你想運行的二進制程序需要的硬件。如果你試圖模仿一些簡單的像/bin/ls的程序,通常能夠正常工作。但更復雜的東西,如肯定有特定的硬件依賴的UPnP守護程序,QEMU就不能夠滿足。尤其對于管理嵌入式系統硬件的程序更是這樣,例如打開或關閉無線適配器。

            你將遇到的最常見問題是在運行系統服務,如Web服務器或UPnP守護進程時,缺乏NVRAM。非易失性RAM通常是包含配置參數的設備快速存儲器的一個分區。當一個守護進程啟動時,它通常會嘗試查詢NVRAM,獲取其運行時配置信息。有時一個守護進程會查詢NVRAM的幾十甚至上百個參數。

            為了解決在模擬條件下缺乏NVRAM的問題,我寫了一個叫nvram-faker的庫。當你運行二進制程序時,應該使用LD_PRELOAD對nvram-faker庫進行預加載。它會攔截通常由libnvram.so提供的nvram_get()調用。nvram-faker會查詢你提供的一個INI風格的配置文件,而不是試圖查詢NVRAM。

            附帶的README提供更完整的說明。這里有一個鏈接:https://github.com/zcutlip/nvram-faker

            即使解決了NVRAM問題,該程序可能會假設某些硬件是存在的。如果硬件不存在,該程序可能無法運行,或者即便它運行了,行為可能也與在其目標硬件上運行時有所不同。在這種情況下,你可能需要修補二進制文件。采用二進制補丁的情況各不相同。這取決于期望什么硬件,以及它不存在時的行為是什么。如果硬件缺失,你可能需要修補一個被執行到的條件分支。也可能需要修補針對特殊設備的ioctl()調用,如果你想將其替代為針對常規文件的讀取和寫入時。這里我將不談論修補的細節,但在我的BT HomeHub文章以及44CON的相應講座中進行了討論。

            這里是這些資源的鏈接:http://shadow-file.blogspot.com/2013/09/44con-resources.html

            0x04 附加調試器


            一旦在QEMU中運行了二進制程序,就可以附加調試器了。當然你需要gdbserver。同樣,這個工具應該適合目標架構并被靜態編譯,因為你會在chroot下運行它。你需要將它復制到提取的文件系統的根目錄中。

            # ./gdbserver
            Usage: gdbserver [OPTIONS] COMM PROG [ARGS ...]
            gdbserver [OPTIONS] --attach COMM PID
            gdbserver [OPTIONS] --multi COMM
            
            COMM may either be a tty device (for serial debugging), or
            HOST:PORT to listen for a TCP connection.
            
            Options:
              --debug               Enable general debugging output.
            --remote-debug        Enable remote protocol debugging output.
            --version             Display version information and exit.
              --wrapperWRAPPER --  Run WRAPPER to start new programs.
              --once                Exit after the first connection has closed.
            #
            

            你可以將gdbserver附加到正在運行的進程,或者用它來直接執行二進制程序。如果你需要調試只發生一次的初始化程序,你可以選擇后者。

            另一方面,你可能要等到守護進程被創建。據我所知沒有辦法讓IDA跟蹤創建的進程(forked processes)。你需要單獨的附加到它們。如果采用這種方式,你可以在chroot外,附加到已經運行的進程。

            以下shell腳本將在chroot下執行upnpd。如果DEBUG設置為1,它會附加在upnpd上,并在1234端口上暫停等待遠程調試會話。

            #!bash
            ROOTFS="/root/code/wifi-reversing/netgear/r6200/extracted-1.0.0.28/rootfs"
            chroot$ROOTFS /bin/sh -c "LD_PRELOAD=/libnvram-faker.so /usr/sbin/upnpd"
            
            #Give upnpd a bit to initialize and fork into the background.
            sleep 3;
            
            if [ "x1" = "x$DEBUG" ];
            then
            
            $ROOTFS/gdbserver --attach 0.0.0.0:1234 $(pgrepupnpd)
            fi
            

            你可以在recvfrom()調用之前創建一個斷點,然后當你向upnpd發送M-SEARCH包時,驗證調試器斷點。

            enter image description here

            然后,在IDA的Debugger菜單中的Process選項中設置“主機名”為你的QEMU系統的IP地址,并設置端口為gdbserver正在監聽的端口。我用的是1234。

            enter image description here

            接受設置,然后通過IDA的CTRL+8熱鍵連接到遠程調試會話。再次按Ctrl+8繼續執行。你應該能夠發送一個M-SEARCH包1,可以看到調試器命中斷點。

            enter image description here

            顯然還有很多需要探索,也會遇到有很多這里未提及的情況,但希望這可以讓你開始。

            我推薦Craig Heffner用于UPnP分析的miranda工具:https://code.google.com/p/miranda-upnp/

            <span id="7ztzv"></span>
            <sub id="7ztzv"></sub>

            <span id="7ztzv"></span><form id="7ztzv"></form>

            <span id="7ztzv"></span>

                  <address id="7ztzv"></address>

                      亚洲欧美在线