<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>

    【技術分享】IoT固件分析入門

    VSole2021-07-19 18:01:03

     

    把前段時間GitHub 上 star 了的一個項目學一遍,地址:IoT_Sec_Tutorial

    訪問慢的話,gitee上也有鏡像可看

    Update:感覺算是一個很不錯的IoT固件分析入門教程,今天收到《路由器0day》后在路上粗略地看了下目錄,除了沒有涉及到硬件外,這個教程差不多把固件分析的起始工作都涉及到了(至于是不是 a bit out of date 就另當別論,不過總的來說也還好⑧)

    01 準備

    因為kali是剛上大學的時候裝的,現在都出到2021了,我的版本還是2019,所以先升級一波

    echo "deb http://http.kali.org/kali kali-rolling main non-free contrib" | sudo tee /etc/apt/sources.listsudo apt update && sudo apt -y full-upgrade[ -f /var/run/reboot-required ] && sudo reboot -f
    

    更新完后可以查看一下系統版本:

    grep VERSION /etc/os-release
    

    更新系統時間(我的時間好像之前一直都不對orz)

    apt-get install -y ntpdaterm -rf etc/localtimecp /usr/share/zoneinfo/Asia/Shanghai /etc/localtimentpdate -u ntp.api.bz
    

    切換shell(為啥升級后zsh沒有直接變成默認orzz)

    先查看系統中有幾種shell:

    cat /etc/shells
    

    kali自帶了zsh,直接切換就行了:

    cp -i /etc/skel/.zshrc ~/chsh -s /bin/zsh
    

    zsh配合oh-my-zsh比較好用,安裝:

    wget https://github.com/robbyrussell/oh-my-zsh/raw/master/tools/install.sh -O - | sh
    

    添加全路徑顯示:

    gedit ~/.oh-my-zsh/themes/robbyrussell.zsh-theme#然后把%{$fg[cyan]%}%c%{$reset_color%}的%c改為[$PWD]
    

    如果想用別的桌面系統:

    update-alternatives --config x-session-manager
    

     


    02 提取固件

    之前用過binwalk,但大多都是在misc題目里處理壓縮文件、圖片啥的,沒有仔細看過binwalk的命令其實除了binwalk之外,還有其他的固件分析/提取工具,在GitHub上用“firmware analysis”之類的關鍵詞能查到
    

    給了個華碩RT-N300路由器的固件,binwalk直接提取即可。

    提取出來發現沒有進行加密(…16年,這也太不安全了吧orz,不過現在基本都有了

    可以看到這個路由器用的是squashfs文件系統

    其中squashfs-root可用于分析了

    文件系統是操作系統的重要組成部分,是操作運行的基礎。不同的路由器使用的文件系統格式不盡相同。根文件系統會被打包成當前路由器所使用的文件系統格式,然后組裝到固件中。路由器希望文件系統越小越好,所以這些文件系統中各種壓縮格式隨處可見。
    Squashfs是一個只讀格式的文件系統,具有超高壓縮率,其壓縮率最高可達34%。當系統啟動后,會將文件系統保存在一個壓縮過的文件系統文件中,這個文件可以使用換回的形式掛載并對其中的文件進行訪問,當進程需要某些文件時,僅將對應部分的壓縮文件解壓縮。
    Squashfs文件系統常用的壓縮格式有GZIP、LZMA、LZO、XZ(LZMA2)。路由器的根文件系統通常會按照Squashfs文件系統常用壓縮格式中的一種進行打包,形成一個完整的Squashfs文件系統,然后與路由器操作系統的內核一起形成更新固件。
    由于squashFS可以在不需要解壓的情況下直接掛載,因此有許多應用場景,例如:1、安裝Linux時用的live cd2、小型嵌入式設備中的rootfs。rootfs一般以壓縮好的形式存放在ROM中,如果開機時把整個rootfs都解壓到內存里再讀取,對于ROM和RAM容量一般都很小的小型嵌入式設備來說性價比太低。
    

    Binwalk命令選項

    常規選項:

    提取選項:

    Diff:

    文件簽名:

    熵值:

    Raw Compression:

    如何手動提取固件

    squashfs文件系統頭部特征較多,有sqsh、hsqs、qshs、shsq、hsqt、tqsh、sqlz。我們用hexdump搜索特征在文件中的地址

    hexdump:一個二進制文件的查看工具,可轉為OCT、DEC、HEX進制查看

    得到如下搜索結果

    hsqs位于文件的0xe20c0,用dd命令截取出固件:

    注:dd命令中skip指定的值只能為十進制。用shell轉換進制可以使用:$((BASE#NUM))

    得到了一個squashfs格式的文件

    用unsquashfs解壓得到squashfs-root,即用binwalk提取出的同名文件。

    如果遇到binwalk之類的工具無法提取的情況,大多都是經過混淆,需要進一步處理

    Binwalk如何進行提取:

    通過maigc特征集與文件進行比對,但識別效率比file命令高多了

    特征集:https://github.com/ReFirmLabs/binwalk/tree/62e9caa164/src/binwalk/magic

    識別過程主要使用libmagic庫的4個函數:

    magic_t magic_open(int flags);//創建并返回一個magic cookie指針。
    void magic_close(magic_t cookie);//關閉magic簽名數據庫并釋放所有使用過的資源。
    const char *magic_buffer(magic_t cookie,const void *buffer,size_t len);//讀取buffer中指定長度的數據并與magic簽名數據庫進行對比,返回對比結果描述。
    Int magic_load(magic_t cookie,const char *filename);//從filename指定文件加載magic簽名數據庫,Binwalk把多個magic簽名文件組合到一個臨時文件中用于加載
    

     03 靜態分析

    給了個從Dlink固件里提取的樣本,打開發現被加密了,得爆破。

    kali自帶了一些關于壓縮文件的工具,比如生成字典用的crunch、rsmangler,爆破用的frackzip等,這些工具用法都不難

    crunch:Kali使用crunch生成密碼字典 – 青檬小棧

    直接用frackzip破解,(根據教程的提示)得到密碼beUT9Z

    解壓得到以下文件

    .mbn:高通的一套用于加載網絡環境的文件(modem software configuration)

    .yaffs2:針對NAND芯片設計的嵌入式文件系統,可用unyaffs提取

    unyaffs提取yaffs2

    核心應該是2K-mdm-image-mdm9625.yaffs2,不確定的話可以把三個.yaffs2都提取了(然后就該復習一下嵌入式系統的目錄結構了)

    接下來查看配置文件,有可能從配置文件中發現敏感信息

    其中的inadyn-mt.conf文件引起了我們注意,這是no-ip應用的配置文件,no-ip就是一個相當于花生殼的東西,可以申請動態域名

    cat 一看,果然no-ip的用戶名和密碼都出現了(這么明顯真的難以置信)

    接下來使用firmwalker來自動化遍歷

    Firmwalker:

    A simple bash script for searching the extracted ormounted firmware file system.

    It will search through the extracted or mounted firmwarefile system for things of interest such as:

    • etc/shadowand etc/passwd
    • list out theetc/ssl directory
    • search forSSL related files such as .pem, .crt, etc.
    • search forconfiguration files
    • look forscript files
    • search forother .bin files
    • look forkeywords such as admin, password, remote, etc.
    • search forcommon web servers used on IoT devices
    • search forcommon binaries such as ssh, tftp, dropbear, etc.
    • search forURLs, email addresses and IP addresses
    • Experimentalsupport for making calls to the Shodan API using the Shodan CLI

    (其實就相當于一個遍歷查找后綴、內容的批處理腳本)

    使用腳本獲得所有可能可以利用的文件(建議進入腳本目錄執行)

    除了配置文件外,分析存在風險的二進制程序也很重要。

    在etc/init.d目錄下存放啟動時運行的程序和腳本,其中有一個叫start_appmgr,mgr一般指固件的主控。查看腳本:

    把appmgr拖到ida

    憑借一點點pwn的經驗,我們發現了一個backdoor

    這個漏洞被收錄到CVE-2016-10178:Multiple vulnerabilities found in the Dlink DWR-932B (backdoor, backdoor accounts, weak WPS, RCE …) – IT Security Research by Pierre (pierrekim.github.io)

    即向192.168.1.1:39889發送HELODBG可以直接getshell(不太清楚為啥是39889端口,靜態看了好久沒看出來,猜測是跟下圖和label_66有關)

    update:用Ghidra搜到了

    這個漏洞確實明顯2333

    這個固件還有好幾個漏洞,太拉了吧Orz…

     


    04

    動態分析

    QEMU和Firmadyne

    QEMU這個模擬器想必都不陌生,一個近乎能夠模擬所有硬件設備的軟件;倒是第一次聽說Firmadyne這個工具,查了一下是一個基于QEMU的分析平臺,包含模擬、固件提取、調試等功能,但似乎支持的硬件設備較少?orz

    部署Firmadyne

    Tutorial里用的是attifyti提供的Ubuntu 14(因為作者說部署這玩意太麻煩了),但Firmadyne的作者在項目的某個issue里說了句“Ubuntu 14 也太早了”之類的話,于是打算自己部署一下Also,如果想用直接用attifyti的AttifyOS,https://github.com/adi0x90/attifyos,目前的系統基于Ubuntu18.04,官方的下載地址在谷歌網盤
    

    準備

    因為涉及到GitHub上一些項目的下載,網絡不太好的話可能需要一些幫助:

    clash on kali:下載clash并運行:https://github.com/Dreamacro/clash/releases導入節點:wget -O ~/.config/clash/config.yaml  clash_url
    配置代理:gsettings set org.gnome.system.proxy mode 'manual'gsettings set org.gnome.system.proxy.http port 7890gsettings set org.gnome.system.proxy.http host '127.0.0.1'gsettings set org.gnome.system.proxy.socks port 7891gsettings set org.gnome.system.proxy.socks host '127.0.0.1'gsettings set org.gnome.system.proxy ignore-hosts "['localhost', '127.0.0.0/8', '::1']"\
    進行配置,訪問:http://clash.razord.top/
    

    ** 注:以下繞了好多彎,最后也沒成功,用了AttifyOS ?????

    【方案1】安裝Firmadyne

    apt-get install qemu-system-arm qemu-system-mips qemu-system-x86 qemu-utilsapt-get install busybox-static fakeroot git dmsetup kpartx netcat-openbsd nmap python-psycopg2 python3-psycopg2 snmp uml-utilities util-linux vlangit clone --recursive https://github.com/firmadyne/firmadyne.gitcd ./firmadyne./download.sh
    

    配置Postgresql:

    # 安裝數據庫sudo apt-get install postgresql# 創建用戶,注意要設置密碼為 firmadynesudo -u postgres createuser -P firmadyne# 創建數據庫sudo -u postgres createdb -O firmadyne firmware# 初始化數據庫sudo -u postgres psql -d firmware < ./firmadyne/database/schema
    

    如果出現如下錯誤

    could not connect to database template1: could not connect to server: No such file or directory.
    Is the server running locally and accepting
    connections on Unix domain socket “var/run/postgresql/.s.PGSQL.5432”?

    有可能是沒有初始化數據庫(至少我是因為這個),用如下方法解決:

    # 設置postgres用戶的密碼passwd postgres
    # 創建postgresql的文件夾sudo mkdir /datasudo chmod o+w /datasu - postgresmkdir /data/postgresqlmkdir /data/postgresql/data
    # postgres用戶初始化數據庫/usr/lib/postgresql/13/bin/initdb -D /data/postgresql/data
    # 啟動數據庫/usr/lib/postgresql/13/bin/pg_ctl -D /data/postgresql/data -l logfile start
    #查看是否監聽了端口(結果應類似下圖)netstat -nlp |grep 5432
    參考:https://www.cnblogs.com/0x200/p/14026460.html
    

    接下來應該就能按照官方的Usage來使用了(沒試):firmadyne: Platform for emulation and dynamic analysis of Linux-based firmware

    【方案2】安裝firmware-analysis-plus

    因為用Firmadyne直接進行調試比較麻煩,所以用了FAP這個項目。

    這是個國人寫的中文項目,沒啥好說的:liyansong2018/firmware-analysis-plus: 開源固件仿真平臺,使用 firmadyne 一鍵模擬固件 (github.com)

    安裝作者提供的binwalk的時候一直報錯(kali2021 & ubuntu18 both),導致一直卡在提取固件的步驟(emmmm哪位大哥部署成功后教我一下)

    對此提了個issue

    【方案3】AttifyOS

    這個方法比較穩,自己部署也太折磨人了(外加考試周給娃弄傻了)

    注:密碼是attify

    模擬執行固件

    模擬固件運行:

    通過192.168.0.50即可訪問固件

    調試固件

    這個部分用到了Damn Vulnerable Router Firmware這個項目,大小400M+,建議上gitee clone

    安裝以下工具:

    sudo apt install gdb-multiarchwget -q -O- https://github.com/hugsy/gef/raw/master/scripts/gef.sh | shsudo pip3 install capstone unicorn keystone-engine
    

    進入DVRF/Firmware/,用binwalk提取DVRF_v03.bin

    提取出來的目錄里有個文件夾pwnable,里面存放著漏洞程序示例,選取stack_bof_01程序進行實驗,程序的源代碼可以在DVRF/Pwnable Source/Intro/里查看

    首先用reasdelf查看程序架構

    !

    (順手試了一下checksec,這里居然有裝?)

    拷貝qwmu-mipsel-static到固件根目錄:

    cp (which qemu-mipsel-static) .
    

    用qemu虛擬運行stack_bof_01:

    以調試的方式啟動程序,并在1234端口進行監聽:

    sudo chroot . ./qemu-mipsel-static -g 1234 ./pwnable/Intro/stack_bof_01
    

    打開一個新的shell,運行以下命令:

    gdb-multiarch pwnable/Intro/stack_bof_01# 設置架構set architecture mips
    #設置調試端口target remote 127.0.0.1:1234
    

    創建trash觸發溢出:

    pattern create 300
    

    帶上它重新進行調試

    gdb attach后繼續讓程序運行,觸發vul

    接下來就直接ret2system,但經過嘗試后發現,如果直接把跳轉地址設置為后門函數dat_shell的起始地址0x400950會觸發異常

    查看函數匯編代碼(MIPS…看不懂的話可以邊看邊學一波,MIPS 通用寄存器_flyingqr的專欄-CSDN博客_mips寄存器;MIPS匯編指令集 – 深海之炎 – 博客園 ;MIPS的匯編指令 · 語雀 )

    調試中發現,當執行到0x400970時,gp寄存器指向了不可訪問的地址

    而gp的值是由上一條指令得到的

    本來執行后v0要指向 指向__DT_MIPS_BASE_ADDRESS的指針

    簡單來說就是強行跳轉到backdoor之后,因為t9(默認在運行中指向當前函數的起始地址)沒有發生改變,導致在執行0x400970時產生異常訪問

    但可以發現(其實是按照exp來推…)main函數中的gp在-0x7fe4后剛好指向PTR__DT_MIPS_BASE_ADDRESS*(猜測原因是源代碼中后門函數在main函數后面且沒有被調用,導致編譯時認為main函數和后門函數的 gp和表的偏移 相等)

    于是得到

    update:

    main函數中

    所以gp在函數執行完畢后依舊指向的是基地址表

    感覺對于mips程序的分析,Ghidra比IDA好用些

    從這題也能看出mips和x86、x64的不同之處,除了這種特殊情況外,大多數情況下還是應該尋找gadget來進行跳轉改變t9寄存器

    這一節就到這,DVRF這個項目還設計了一些別的漏洞程序可以再進行分析

     05 解密固件

    訪問dlink的ftp服務器獲得幾個DIR-882的固件(圖中選中的文件),時間跨度為2017~2020年

    ftp://ftp2.dlink.com/PRODUCTS/DIR-882/REVA/
    

    解壓得到固件和對應的版本說明

    加密固件發布方案

    一般來說,有三種發布固件的方案

    • 出廠時未加密,解密例程在高版本固件v1.1中給出,為后續的加密固件做準備
    • 對于這個方案,我們可以通過解密v1.1來獲得解密例程
    • 出廠時的固件已經加密,供應商決定更改高版本固件的加密方式,并發布了包含解密例程的未加密中間版本v1.2
    • 這一方案與上面那個類似
    • 出廠時的固件已經加密,供應商決定更改高版本固件的加密方式,并發布了包含解密例程的使用原加密方式加密的過渡版本v1.3
    • 這種方案對獲取解密例程的難度較大,可從硬件中直接提取固件或對發布的v1.3進行分析

    DIR-882的固件發布方案為第一種,示意圖如下

    雖然個人認為第三種方案才是較為常見的,但教程中并沒有講到。猜測除了從硬件中提取外,還可以通過模擬器模擬然后進行patch或拿頭還原

    解密過程

    用binwalk分析最新和最早的兩個固件

    經過binwalk分析,FW104B02正是存在解密程序的中間版本(從文件名也能看出)

    對于判斷固件是否被加密/混淆還可以使用之前提到的binwalk -E 來查看文件各個區域的熵值

    提取該固件

    binwalk -eM DIR882A1_FW104B02_Middle_FW_Unencrypt.bin
    

    在最終目錄下搜索找到imgdecrypt,從名字看出是下個版本固件的解密例程

    可以靜態分析程序的解密算法,也可以直接運行程序來對加密固件進行解密。

    在本地運行時依舊需要借助qemu-mipsel-static模擬器,使用方法和上一節的模擬過程類似,不表。

    利用imgdecrypt還可以還原出ftp服務器上提供的最新的固件,所以可能后續版本和Dlink其它型號的路由器也能用這個程序還原固件?Orz

     06 修復固件運行環境

    有一些固件因為硬件依賴等原因導致qemu和firmadyne之類的軟件無法正確模擬

    比如下面這個

    ftp://ftp2.dlink.com/PRODUCTS/DIR-605L/REVA/DIR-605L_FIRMWARE_1.13.ZIP

    模擬固件運行的實質其實就是把固件的Web程序跑起來,而模擬失敗則說明Web程序運行出錯了,我們接下來就要看看Web程序報錯的原因以及如何修復運行環境。

    嘗試運行固件

    首先binwalk提取固件,進入文件系統目錄squashfs-root-0

    找到web服務程序Boa

    Boa程序是一個輕量級的web服務器程序,常見于嵌入式系統中。dlink就是在boa開源代碼的基礎上新增了很多功能接口以實現路由器上的不同功能。boa程序的路徑為/bin/boa,同時我們發現在/etc/boa路徑下還有個boa的密碼配置文件,我們可以直接獲取到boa加密后的密碼。

    用qemu-mips-static運行,結果產生了段錯誤

    mips 是32位大端字節序
    mipsel 是32位小端字節序

    分析錯誤并修復

    注:APMIB 是個Realtek的玩意(原來realtek還有做路由器相關的東西…)
    • apmib_init(), 從 flash 讀出 mib 值寫入 RAM —Realtek apmib library @ 邱小新の工作筆記
    有些CVE(如CVE-2019-19823)就跟APMIB有關 —TOTOLINK and other Realtek SDK based routers – full takeover (sploit.tech)
    MIB:management information base,與SNMP有關,可在維基里進一步了解:Management information base – Wikipedia

    由于沒有flash,導致讀mib失敗

    拖到反編譯工具中分析。先定位到字符串“Initialize AP MIB failed!”的位置。注意到在輸出這個字符串前有個調用APMIB初始化的跳轉,在此下斷點,IDA遠程調試

    QEMU的遠程調試不需要gdbserver,-g 指定端口,ida 遠程調試選項指定相應端口就行

    簡單調試后發現,程序進入APMIB初始化函數后將返回值賦給v0,返回后對返回值進行判斷。(跟著教程做完后,發現其實用靜態分析看的就很明顯,但多調試總是沒有壞處的嘛)

    跳轉回去的位置在這:

    我們先試試看把原來的跳轉patch一下能不能運行正常固件boa。

    有以下兩個可行方案:

    1、hxd(或其他二進制編輯器),把benz(0x14,不為0跳轉)改為beqz(0x10,為0跳轉)

    這個方法比較直接,定位到指令后把0x14改為0x10即可

    2、Ghidra,把bne改為beq(Ghidra中反編譯出的原指令為bne)

    如何用Ghidra進行patch并保存:

    • 下載python腳本ghidra_SavePatch 并放到Ghidra存放python腳本的目錄(找不到目錄的話,如圖)
    • 按照下圖導入腳本。
    • patch
    • 光標放在更改的指令,在script manager里運行腳本。

    參考:Patching Binaries With Ghidra – RangeForce

    不用ida的原因:

    把patch保存到文件中時,發現報錯,稍微搜了一下,依然不知道是啥原因orz

    418228: has no file mapping (original: 14 patched: 10)…skipping…

    再次運行試試,發現又報錯了:

    再放到Ghidra里分析,依舊通過字符串定位錯誤觸發點。

    兩個函數(調用的地方位于websAspInit)里的報錯由open函數造成(圖為create_chklist_file(),但兩個報錯類似,均為一開始打開某個文件出錯)

    用IDA調試發現報錯后仍然繼續運行,異常發生在執行apmib_get()時:

    具體在0x4084c9b0時,把[0+v0]里的值賦給v1,而0x1001明顯是一個訪問不了的地址

    查一下apmib_get是干啥的。似乎是用來獲取硬件配置信息,但我們要想讓固件跑起來可以不需要這個。那么直接把獲得apmib_get入口后的跳轉語句nop掉

    重新嘗試運行

    固件會一直嘗試朝 ioctl(設備驅動的控制接口)發送0x89f0(應該是一個SIOCDEVPRIVATE),我們模擬的固件并不支持,但沒啥大影響。(用Google搜一下“Unsupported ioctl: cmd=0x89f0”可以找到一些蠻有意思的東西2333)

    關于ioctl:ioctl()函數詳解_shanshanpt的專欄-CSDN博客

    查看報錯的頁面(用vim看代碼舒服一些),嗯,前端的東西:

    從文件名可以猜到是個跟路由器界面語言選擇有關的文件。

    文件不長,注意到有個函數跟語言和硬件有關:

    那么我們可以不讓它運行到這個頁面。

    查找調用了*LangSelect.asp的頁面,發現只有一個first.asp

    直接修改,重新運行完事

    這個固件成功運行后可以順便看一看這個洞: (CVE-2018-20057)D-Link DIR-619L&605L 命令注入漏洞 – Wiki ,直接用了后門

    這節的錯誤解決方法均通過修改指令,《路由器0day》書中的方法是偽造.so來劫持函數,也值得一學:分析固件第一步

    07 結束

    純初學者,如果有啥地方寫的不到位或者出錯了,還請指出

    程序調試加密芯片
    本作品采用《CC 協議》,轉載必須注明作者和本文鏈接
    某視頻app的學習記錄
    2022-01-03 16:58:52
    這個看見有人說有個版本開始不能截了,我這邊一直都是換證書的,沒感覺有影響,估計我下的是盜版,碰到再看了。先新建一個自己的測試app,接著的工作就是搬代碼了,直接導出所有的反編譯代碼
    截住 APP 重打包就一定程度上防止了病毒的傳播。如果 PermissionGroup 的屬性為空,會導致權限定義無效,且其他 APP 無法使用該權限。
    安卓工具總結
    2021-10-14 08:39:34
    JRE:Java Runtime Environment是Java運行時環境,包含了java虛擬機,java基礎類庫安裝過程:1)雙擊啟動安裝程序2)默認安裝路徑3)jre路徑選擇4)配置環境變量JAVA_HOME. 這里介紹幾款不錯的安卓模擬器。
    一. 應用層隧道技術1. ssh隧道建立雙向安全隧道將其他TCP端口的通信通過SSH連接轉發用SSH作為傳輸層協議,對流量自動加解密突破防火墻訪問規則的限制SSH本地端口轉發本機偵聽端口
    Web安全常見漏洞修復建議
    Windows安全工具錦集
    2023-01-07 11:03:54
    解決了OD對64位應用程序調試上的缺陷:下載地址:https://x64dbg.com/#startdnSpy一款針對.NET程序的開源逆向程序的工具。還能設置斷點,修改請求和響應的數據,模擬弱網絡環境。支持插件擴展:下載地址:https://www.telerik.com/download/fiddlerMicrosoftNetwork Monitor只支持Windows平臺的網絡數據分析工具,提供了一個專業的網路實時流量圖形界面,擁有識別和監控超過300種網絡協議的能力:下載地址:https://www.microsoft.com/en-us/download/details.aspx?
    VSole
    網絡安全專家
      亚洲 欧美 自拍 唯美 另类