<menu id="guoca"></menu>
<nav id="guoca"></nav><xmp id="guoca">
  • <xmp id="guoca">
  • <nav id="guoca"><code id="guoca"></code></nav>
  • <nav id="guoca"><code id="guoca"></code></nav>

    用uboot“操控”某路由器設備

    VSole2022-07-16 16:10:45

    從uart 進入uboot shell

    某路由器設備拆開后定位到uart接口,將uart引腳通過TTL接入到電腦,路由器上電啟動,觀察啟動日志。

    Boot SPI NANDstart read bootheaderstart read secondbootnon secure bootJumpddr init enter, rate is 1333 mbpsddr size is 0x10000000U-Boot 2013.04 (Feb 14 2022 - 16:16:39)......eth0Hit 1 to upgrade software versionHit any key to stop autoboot:  1......*****************pc start*************************************echo 5000 > /proc/sys/vm/min_free_kbytes********************close console
    

    從上面設備的部分啟動日志可以看出,uboot shell可以被中斷,路由器上電后快速按任意鍵可進入。路由器啟動后關閉了console 控制臺,不能通過console登錄路由器。為了方便后續逆向工作,最好能進入路由器系統,但目前是console已關閉,且未發現telnet、ssh等服務,只能從uboot shell為切入點進一步分析。

    路由器reset,快速按下任意鍵進入boot shell,可以看到當前uboot shell支持的命令。

    => h?       - alias for 'help'base    - print or set address offsetbdinfo  - print Board Info structureboot    - boot default, i.e., run 'bootcmd'bootd   - boot default, i.e., run 'bootcmd'bootk   - boot kernelbootm   - boot application image from memorybootz   - boot Linux zImage image from memorycmp     - memory compareconinfo - print console devices and informationcp      - memory copydhcp    - boot image via network using DHCP/TFTP protocoldownver - upgrade software downloaded from TFTP serverecho    - echo args to consoleerase   - erase FLASH memoryfdt     - flattened device tree utility commandsflinfo  - print FLASH memory informationgo      - start application at address 'addr'gpiotest- gpiotest dir [num] [in/out]gpiotest value [num] [1/0]gpiotest gvalue [num]help    - print command description/usageimxtract- extract a part of a multi-imageitest   - return true/false on integer comparemcupg   -  multicast upgrademd      - memory displaymii     - MII utility commandsmtddebug- mtddebug operatemtest   - simple RAM read/write testmw      - memory write (fill)nand    - NAND sub-systemping    - send ICMP ECHO_REQUEST to network hostprintenv- print environment variablesprotect - enable or disable FLASH write protectionreset   - Perform RESET of the CPUrun     - run commands in an environment variablesaveenv - save environment variables to persistent storagesetenv  - set environment variablessleep   - delay execution for some timesnumber - Get or set serial number for zte boardstftp    - boot image via network using TFTP protocolversion - print monitor, compiler and linker versionwatchdog- watchdog reset && disablexmodem  - xmodem
    

    修改內核啟動參數

    printenv查看當前環境變量。

    => printenvbaudrate=115200bome=aclcle) root=/dev/mtdblock8 rw rootfstype=jffs2 mem=256M singlebootcmd=setenv bootargs console=$(console) root=/dev/mtdblock8 ro rootfstype=jffs2  mem=$(memsize);bootm 0x440001e0;bootdelay=1bootfile=uboot.binbootloaderfile=bootloader.binconsole=ttyAMA0,115200n8ethact=eth0ethaddr=00:41:71:00:00:50fileaddr=44000000filesize=13bfb78gatewayip=192.168.1.1ipaddr=192.168.1.1linuzfile=vmlinuz.binloadaddr=0x44000000memsize=256Mnand_erasesize=20000nand_oobsize=40nand_writesize=800netmask=255.255.255.0netretry=5serverip=192.168.1.100
    

    bootargs為內核啟動參數,這里沒有看到init參數,一般來說,通過設置init參數來指定內核啟動后第一個執行的腳本,可以嘗試設置init=/bin/sh進入linux shell。

    setenv bootcmd 'setenv bootargs console=$(console) root=/dev/mtdblock8 rw rootfstype=jffs2  mem=$(memsize) init=/bin/sh;bootm 0x440001e0;'
    

    用setenv修改bootcmd參數,保存環境變量。

    => saveSaving Environment to NAND...Erasing 0x180000 - 0x200000:,1560>!mtdpart=0x1,start=0x0,mtdpartoffset=0x180000,mtdPartsize=0x80000,length=0x80000        [Done]Writing to Nand:_,1455>!mtdpart=0x1,offset=0x0,mtdpartoffset=0x180000,mtdPartsize=0x80000,length=0x20000        [Done]
    

    bootm啟動失敗,這里報錯can't get kernel image!

    => bootm 0x440001e0Wrong Image Format for bootm commandERROR: can't get kernel image!
    

    網上下載一份u-boot-2013源碼,搜索can't get kernel image字符串,定位到關鍵代碼。

    uboot首先會檢測kernel的uimage頭部信息,不正確會輸出上面錯誤。kernel uimage是在kernel image前加上一段長度為64字節的頭,用于描述內核的版本、加載位置等信息 ,uimage魔數一般是0x27051956,很明顯0x440001e0地址的數據不符合,所以加載報錯。

    typedef struct image_header {    __be32        ih_magic;    /* Image Header Magic Number    */    __be32        ih_hcrc;    /* Image Header CRC Checksum    */    __be32        ih_time;    /* Image Creation Timestamp    */    __be32        ih_size;    /* Image Data Size        */    __be32        ih_load;    /* Data     Load  Address        */    __be32        ih_ep;        /* Entry Point Address        */    __be32        ih_dcrc;    /* Image Data CRC Checksum    */    uint8_t        ih_os;        /* Operating System        */    uint8_t        ih_arch;    /* CPU architecture        */    uint8_t        ih_type;    /* Image Type            */    uint8_t        ih_comp;    /* Compression Type        */    uint8_t        ih_name[IH_NMLEN];    /* Image Name        */} image_header_t;#define IH_MAGIC    0x27051956    /* Image Magic Number        */#define IH_NMLEN        32    /* Image Name Length        */
    

    => md.b 440001e0 100440001e0: ff d7 ff ff bf fe fd f7 7f ff 7f df 5f bd ff ff    ............_...440001f0: f6 a2 b7 f7 5f fe fe fe 77 f5 db ff 3f bf fa 76    ...._...w...?..v44000200: fc ed ef fd 7f ff ff fd 7b ee ff ee fd 7b ff 75    ........{....{.u44000210: 67 7d e8 bf ee ef ed a1 cd fb 63 fe 67 ee f7 9e    g}........c.g...44000220: f3 df af f5 ea ff f7 fb 78 77 ea fd df ff ef fb    ........xw......44000230: d3 dd e9 ff b3 3f e7 ef 76 f6 f6 ed cf b3 bd fb    .....?..v.......44000240: bf eb 97 fb 9f ef ff ef d9 59 b9 3e 5f 3f ff 32    .........Y.>_?.2
    

    正常情況下0x440001e0地址應該存放著kernel的uimage數據,這里不知什么原因kernel uimage未能正確加載到內存。這里嘗試手動從nand flash中讀取內核到內存中。

    0x000000000000-0x000008000000 : "whole flash"0x000000000000-0x000000200000 : "u-boot"0x000006800000-0x000006b00000 : "parameter tags"0x000000200000-0x000000700000 : "kernel0"0x000000700000-0x000000c00000 : "kernel1"0x000000c00000-0x000001400000 : "usercfg"0x000001400000-0x000001500000 : "others"0x000001500000-0x000001800000 : "wlan"0x000001800000-0x000003800000 : "rootfs0"0x000003800000-0x000005800000 : "rootfs1"0x000005800000-0x000006000000 : "framework"0x000006000000-0x000006800000 : "framework1"0x000006b00000-0x000008000000 : "apps"
    

    路由器正常啟動的日志中,可以看到nand flash的13個分區,其中0x000000200000-0x000000700000 、0x000000700000-0x000000c00000存放這kernel數據,其中一個應該是做備份用。

    nand dump查看nand flash中內核數據,uimage從0x2001e0開始。

    => nand dump 0x200000Page 00200000 dump:    99 99 99 99 44 44 44 44  55 55 55 55 aa aa aa aa    00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00    00 00 00 00 56 31 2e 30  2e 31 2e 32 32 30 33 31    35 2e 31 37 30 39 33 33  00 00 00 00 00 00 00 00    00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00    01 00 00 00 00 5a 64 01  17 58 24 00 e0 01 00 00    dc e0 50 82 00 00 3c 01  00 5a 24 00 d2 2c 67 09    00 00 20 00 00 00 50 00  00 00 80 01 00 00 00 02    00 00 70 00 00 00 50 00  00 00 80 03 00 00 00 02    5a 58 49 43 20 33 36 30  54 36 47 56 32 20 55 4e    49 20 56 31 2e 30 2e 31  2e 32 32 30 33 31 35 2e    31 37 30 39 33 33 00 00  00 00 00 00 00 00 00 00    00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00    00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00    00 00 04 00 00 5a 60 01  31 52 b8 ea 56 32 5f 56    32 2e 00 00 00 00 00 00  00 00 00 00 00 00 00 00    01 00 00 00 47 9b 29 1d  32 30 32 32 30 33 32 31    31 38 32 35 32 31 00 00  00 00 00 00 ff ff ff ff    ff ff ff ff 00 00 00 10  ff ff 01 00 56 31 2e 30    00 00 00 00 00 00 00 00  00 00 00 00 33 36 30 54    36 47 56 32 00 00 00 00  00 00 00 00 15 56 24 56    5a 58 30 31 03 30 00 00  00 e0 00 02 43 57 46 57    31 37 30 33 32 38 31 30  30 31 00 00 ff ff ff ff    ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff    ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff    ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff    ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff    ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff    ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff    ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff    27 05 19 56 3c 35 3b 72  62 38 52 83 00 24 57 d7    40 00 80 00 40 00 80 00  cc 1f fd e3 05 02 02 00    4c 69 6e 75 78 20 4b 65  72 6e 65 6c 20 49 6d 61
    

    使用nand read將nand flash中kernel分區數據加載到內存中,addr是ram的地址,off指的是nand flash的地址, size指要讀取nand flash的數據大小。

    nand read - addr off|partition size =>nand read 0x44000000 0x200000 500000NAND read: device 0 offset 0x200000, size 0x500000 5242880 bytes read: OK=> md.b 0x440001e0 60440001e0: 27 05 19 56 3c 35 3b 72 62 38 52 83 00 24 57 d7    '..V<5;rb8R..$W.440001f0: 40 00 80 00 40 00 80 00 cc 1f fd e3 05 02 02 00    @...@...........44000200: 4c 69 6e 75 78 20 4b 65 72 6e 65 6c 20 49 6d 61    Linux Kernel Ima44000210: 67 65 00 00 00 00 00 00 00 00 00 00 00 00 00 00    ge..............44000220: 00 00 a0 e1 00 00 a0 e1 00 00 a0 e1 00 00 a0 e1    ................44000230: 00 00 a0 e1 00 00 a0 e1 00 00 a0 e1 00 00 a0 e1    ................
    => bootm 0x440001e0## Booting kernel from Legacy Image at 440001e0 ...   Image Name:   Linux Kernel Image   Image Type:   ARM Linux Kernel Image (uncompressed)   Data Size:    2381783 Bytes = 2.3 MiB   Load Address: 40008000   Entry Point:  40008000   Verifying Checksum ... OK   Loading Kernel Image ... OKOK----------------------|-->setup versioninfo tag... Starting kernel ...
    

    再次bootm,成功啟動,但是當內核嘗試啟動我們添加的啟動參數init=/bin/sh時失敗了,未能成功進入linux shell,之后又重新用了默認啟動參數重啟。

    Set_Trap_Pkt_Pps_Limit is NULL.Set_Trap_Pkt_Pps_Limit is NULL.VFS: Mounted root (jffs2 filesystem) on device 31:9.Freeing unused kernel memory: 176K (c05b4000 - c05e0000)This architecture does not have kernel memory protection.Kernel panic - not syncing: Requested init /bin/sh; failed (error -2).CPU: 1 PID: 1 Comm: swapper/0 Not tainted 4.1.25 #2
    

    添加init參數未能成功啟動,后面嘗試修改文件系統,開啟console、修改root密碼,修改后的文件系統通過tftp上傳到設備。

    uboot tftp通信環境搭建

    uboot shell 支持tftp通信功能,這里先在ubuntu 18 PC機上安裝tftp服務。

    sudo apt install tftpd-hpa
    

    檢查tftpd-hpa服務是否正在運行。

    sudo systemctl status tftpd-hpa
    

     ftpd-hpa服務器的默認配置文件是/etc/default/tftpd-hpa。TFTP_DIRECTORY是TFTP服務器訪問目錄。 

    給TFTP_OPTIONS選項添加--create選項,否則無法創建新文件或將新文件上傳到 TFTP 服務器。

     

    修改/var/lib/tftpboot訪問屬性。

    chmod 777 /var/lib/tftp
    

    uboot shell環境變量中tftp的 serverip默認為192.168.1.100,這里我們直接將上面裝有tftp服務器的ubuntu的ip地址設為192.168.1.100。

    pc與路由器通過網線連接,從tftp服務器成功下載測試文件app.cgi到uboot,至此tftp通信環境已建立,下面修改文件系統上傳到uboot。

    修改文件系統進入linux shell

    已經從網上下載到了設備固件,另外通過uboot也可以從flash的rootfs分區dump出文件系統。當前想通過修改固件開啟console并修改登錄密碼,修改后的固件重新打包通過tftp上傳到uboot,最后在刷到nand flash的文件系統分區。

    前面了解到路由器正常啟動時,串口日志最后打印了close console,可見根文件系統啟動后直接關閉了console,導致不能通過串口登錄到linux shell。解包設備固件,在程序中搜索close console字符串,發現該字符串出現在/bin/cspd程序中。 

     

    找到關閉console的代碼,直接patch掉。開啟console后想要登錄進linux shell還需要知道用戶名、密碼,可以考慮直接將/etc/passwd文件中root用戶密碼字段置空,后面登錄時直接輸入用戶名root即可登錄。

    從上面的環境變量信息可以知道設備使用的是jffs2文件系統,將上面修改后的文件重新打包為jffs2格式,打包后的文件系統通過tftp下載到uboot,此時文件系統還只是在RAM中,斷電或者重啟后數據就會丟失,所以后面還需要將RAM中的文件系統數據用nand write命令寫入到nand flash的文件系統分區。

    mkfs.jffs2 -d ./fs_1/ -l -e 0x20000 -o jffs2.img --no-cleanmarkers
    

    通過上面步驟將修改后的文件系統刷入 nand flash文件系統分區后,重啟設備,成功開啟console,進入linux shell。

    telnet server 移植

    上面通過修改文件系統實現了從本地console進入到linux shell。設備默認沒有telnet服務,為了方便后續管理設備,考慮移植個telnet server到設備中。 

    查看固件中程序信息,發現程序是使用buildroot編譯,所以嘗試使用Buidroot 2017.05編譯一個帶有telnetd的busybox移植到設備。

    objdump -s --section=.comment Simulator
    

     https://buildroot.org/downloads/ 下載buildroot 2017.05版本。

    make menuconfig
    

    進入編譯配置界面。

     配置界面選項主要根據下圖固件中文件的信息,ARM 、ELF32、LSB、EABI5 等配置,ld-linux.so.3說明用的是glibc庫 。

    接著設置busybox相關選項,添加telnetd。

    make busybox-menuconfig
    

    以上設置完成后執行make進行編譯,編譯完成后在當前目錄會生成output文件夾,編譯好的busybox在output文件夾中,生成的telnetd是鏈接到busybox的,所以這里直接將生成的busybox移植到路由器即可。將編譯的busybox復制到固件文件系統/bin目錄并重命名為busybox2。

     在路由器文件系統自啟動目錄/etc/rcS.d下找個文件,加入busybox2 telnetd的啟動命令。

    上面修改完成后,重新將文件打包成jffs2文件系統,然后通過tftp下載到uboot,最后nand write寫入到nand flash文件系統,重啟設備,telnet服務會自動啟動,通過telnet客戶端成功連接到路由器,后續動態調試移植gdbserver也可使用類似方法。

    總結

    通過uart打斷uboot進入uboot shell,給內核啟動參數添加init未能成功啟動。根據啟動日志搜索關鍵字符串定位到關閉console的程序,patch二進制程序開啟console,修改root密碼,將修改后的文件重新打包通過tftp下載到uboot中,最后使用nand write寫入到nand flash文件系統分區,實現從本地console進入到linux shell。最后使用Buidroot編譯一個帶有telnetd的busybox移植到設備,實現telnet登錄到設備。

    tftpuboot
    本作品采用《CC 協議》,轉載必須注明作者和本文鏈接
    從uart 進入uboot shell某路由器設備拆開后定位到uart接口,將uart引腳通過TTL接入到電腦,路由器上電啟動,觀察啟動日志。從上面設備的部分啟動日志可以看出,uboot shell可以被中斷,路由器上電后快速按任意鍵可進入。為了方便后續逆向工作,最好能進入路由器系統,但目前是console已關閉,且未發現telnet、ssh等服務,只能從uboot shell為切入點進一步分析。
    本地提示登錄嘗試更改uboot啟動參數時,uboot設置了密碼。固件0xF40000位置使用dd命令分割固件,將該區域的文件系統文件使用binwalk解壓后,可得到以下文件系統內容。根文件系統結構在根文件系統下搜索”boot.sh”,確定boot.sh會在開機啟動。
    同時又在默認的系統環境下,通過pip安裝部署,大多數情況下,是不會出現問題。相關的依賴庫,在Python安裝之后,都是通過pip來安裝。但實際我們裝個python2.7版本的環境就基本滿足目前的需求。我們創建了一個叫做py27的虛擬環境。workonpy272.4 安裝Opencananrypip在安裝opencanary時,會自動安裝他所需求要的各種依賴,一般不出問題的話,一切都會順利安裝完成。
    TFTP(Trivial File Transfer Protocol,簡單文件傳輸協議)是TCP/IP協議族中的一個用來在客戶端與服務器之間進行簡單文件傳輸的協議,提供不復雜、開銷不大的文件傳輸服務。
    本文檔中的配置均是在實驗室環境下進行的配置和驗證,配置前設備的所有參數均采用出廠時的缺省配置。配置思路為了使路由器在重啟后使用新版本軟件,需要指定下次啟動時所用的主用啟動文件為升級后的軟件版本。Host的配置#配置Host的IP地址為192.168.100.14/24,使得與Router路由可達,具體配置方法略。#啟動Host上的TFTP服務器,設置TFTP服務器下載路徑等參數,并開啟服務。
    時光飛逝,轉眼間2021年已過大半,我們的“防火墻ALG技術”系列文章也已經更新到了第四期,之前推送的《防火墻ALG技術之安全策略》 《防火墻ALG技術之FTP協議穿墻術》 《防火墻ALG技術之TFTP協議穿墻術》 可點擊鏈接進行閱讀。本期介紹DNS協議穿越防火墻NAT,淺談個人理解與認知。
    今天實踐的是vulnhub的mattermost鏡像,下載地址, https://download.vulnhub.com/enumbox/Mattermost.7z, 用workstation導入成功,先做地址掃描, sudo netdiscover -r 192.168.137.0/24,
    web服務器經常需要從別的服務器獲取數據,如果獲取數據的服務器地址可控,攻擊者就可以通過web服務器自定義向別的服務器發出請求,本期我們聊一下ssrf漏洞原理和利用.快來一起看看吧
    在2016年,FLARE推出了一款用Python編寫的開源網絡分析工具FakeNet-NG。FakeNet-NG允許安全分析人員在單個Windows主機上使用標準或自定義協議來觀察網絡應用程序并與其進行交互,這對惡意軟件分析和逆向工程特別有用...
    Orange Cyberdefense最近發布的Security Navigator報告顯示,過去幾年針對工業控制系統(ICS)的攻擊迅速增加,其中大多數攻擊都是針對傳統IT系統攻擊的溢出。這個調查結果并不令人意外,因為新興的網絡風險管理方法正在導致OT和IT之間的日益融合。
    VSole
    網絡安全專家
      亚洲 欧美 自拍 唯美 另类