TeamT5 威脅分析師高峰會議程搶先看!門票欲購從速!
技術分析

從 Syn 樣本看邊緣裝置惡意程式:ARM Linux 逆向的分析挑戰

2025.10.16GSS & IR Team
Share:

前言:多架構環境下的威脅分析挑戰

近年來,隨著邊緣裝置(Edge Device)應用的普及,相關的資安威脅也逐漸被揭露。這類裝置涵蓋多種 CPU 架構,如 x86/64、ARM、MIPS、RISC-V、Xtensa 等,雖帶來彈性與成本優勢,卻同時增加了分析人員在逆向與惡意程式研究上的挑戰與學習門檻。
幾個月前,IR Team 成員在 VirusTotal 上注意到一系列以 “syn” 開頭命名的樣本,其中一個名為 synlsewb(MD5: 3a3d791232177f8cdf3e626f0f1cab9a)的檔案特別引人注意。這些樣本中,有部分被歸類為 ELF_PLEAD 後門家族。由於 Synology 系列設備常見於邊緣環境,且其產品採用了多種 CPU 架構(包含 Intel、AMD 與 ARM),因此這個樣本的出現顯得頗具代表性。
值得一提的是,synlsewb 為一個 ARM 架構的 ELF 執行檔,對於平時較少接觸非 x86 平台的研究者來說,是一個非常合適的 ARM 惡意樣本分析練習案例。透過這類樣本的研究,不僅能深入理解邊緣裝置威脅的多樣性,也能強化跨架構惡意程式分析的經驗與技術能力。

分析環境準備與初步觀察

成員花了些時間熟悉 ARM 指令集(ARM Instruction Set),內容以快速瀏覽為主——不必一次看懂全部,遇到不熟悉的指令可以回頭再查閱或透過 Google 查詢深入了解。
在實作上,本文使用 IDA Pro 開啟樣本,並以 Ctrl+E 跳至程式的原始進入點(entry / start 位址)。在該位置可以觀察到一條 BL(相當於 x86 的 CALL)指令,分支會跳到 sub_32C 子程式。
進入 sub_32C 函數後,可以按 F5 可以看到最後會跳到 off_21064() 的函數裡。

可以看到 off_21064() 是一個函數指標,會再跳到 sub_2D8 函數裡面。

在這個階段,可以觀察到程式中出現了 .init_proc 與 .term_proc 等區段,這通常代表程式已進入初始化與結束程序的設定階段。出現這些符號時,意味著執行流程距離 main 函式已相當接近。進一步分析可發現,程式的主要進入點(即 main 函式)對應到 sub_55C0(R0)。這個函式便是程式邏輯的核心所在,後續的行為分析與逆向重點也將集中於此。

由於 ARM 架構的指令執行採用 Pipeline(管線化)機制,程式計數器(PC)的實際行為與表面值存在一定偏移。整體流程可分為三個階段:抓取(Fetch,PC)、解碼(Decode,PC – 4) 與 執行(Execute,PC – 8)。

也就是說,當指令真正進入執行階段時,PC 的值其實已經超前了 8 byte(在 Thumb 模式 下則約為 4 byte)。因此,在這個位置進行位址運算時,最終計算出的 R0 會對應到 記憶體位址 0x21000 中的 DWORD 值,而該值正是指向 sub_55C0 的函式位址。
.text:000002E0                 LDR     R2, =(off_21000 - 0x2F4)    ; R2 = 21000-2F4
.text:000002E4                 LDR     R3, =(.init_proc_ptr - 0x21000)
.text:000002E8                 LDR     R0, =(off_21044 - 0x21000)    ; 21044-21000
.text:000002EC                 ADD     R2, PC, R2      ; R2 = PC + R2 = (2EC+8) + (21000-2F4) = 2F4 + 20D0C = 21000
.text:000002F0                 LDR     R3, [R2,R3]
.text:000002F4                 LDR     R0, [R2,R0]     ; [21000+(21044-21000)]
...
.got:00021044 off_21044       DCD sub_55C0            ; DATA XREF: sub_2D8+10↑o
.got:00021044                                         ; sub_2D8+1C↑r ...

函數識別與加密模組分析

進入 main 函數後,程式開始呼叫一連串的子函式。在這些子函式中,可以觀察到一些固定的常數值(magic number)。將這些常數值進行搜尋或比對,會發現它們與 SHA‑1 演算法的初始化常數(initial hash values)相符。

這些函數若以 IDA Pro 產生的 Pseudocode(C 語法反編譯)形式輸出,再交由 GPT 進行輔助分析,通常可以初步推測出程式的大致功能與行為邏輯。
不過,需要特別注意的是——這樣的推論僅供參考與方向判斷。由於反編譯結果可能受最佳化、編譯器特性或混淆技術影響,GPT 所給出的結論並非絕對準確,仍需結合實際的組合語言對照、記憶體操作與動態執行觀察(例如使用調試器或模擬器)進行驗證。
sub_4E08 它看起來像是某個雜湊演算法(例如 MD5、SHA1、或自訂訊息摘要)中的「最終收尾(final)」階段。
sub_1058 這是 AES 金鑰展開(Key Expansion)函數 的實作版本。

確認樣本為 TinyShell 變種

回到 sub_55C0 函數後,可以發現其結構相當熟悉——這種以 switch-case 判斷指令類型 的寫法,讓人聯想到過去分析過的 tinyshell 樣本。具體來說,switch-case 中的分支分別對應:
  • 1=GET_FILE:處理檔案下載/讀取
  • 2=PUT_FILE:處理檔案上傳/寫入
  • 3=RUNSHELL:啟動 shell 或遠端指令執行
點入 3 分支對應的子函式 sub_50F4 後,可進一步確認其為 shell 處理邏輯。結合之前觀察到的雜湊與加密特徵——如 SHA‑1 初始化常數 與 AES 金鑰展開/加密函式——可以相當確定,這個樣本正是 tinyshell。
簡單總結,即sub_55C0 是 tinyshell 的指令分派核心,其特徵包括 SHA‑1 雜湊、AES 加密處理,以及以 switch-case 判斷指令(GET_FILE、PUT_FILE、RUNSHELL)。這些線索對後續逆向分析與樣本行為推斷提供了明確的方向。

如果對照 tinyshell 的原始碼,可以發現 sub_F08 對應到程式中的 pel_server_init 函數。此函數在呼叫時帶入兩個參數,其中第二個參數 off_210BC 指向一個密碼(secret)字串。

要驗證樣本是否為原版 tinyshell,可以採用動態執行的方式觀察其行為。不過,需要注意目前的 Kali 系統是 x64 平台,而此惡意程式是 ARM 架構,因此必須透過模擬器來執行 ARM 指令集。
在這裡,只需安裝 qemu-user 就足夠,它可以模擬 ARM CPU,讓你直接執行 ARM ELF 程式。然而,為了確保環境完整,建議還是將相關 QEMU 模組全部安裝;因為在初步分析階段,你無法預先確定程式在執行時可能會依賴哪些功能或指令集擴充。
簡言之,qemu-user 提供了最基本的模擬能力,而完整安裝則能降低在動態分析過程中遇到錯誤或缺少依賴的風險。
sudo apt update
sudo apt install qemu-user qemu-system
sudo apt install gdb-multiarch

sudo apt install gcc-aarch64-linux-gnu g++-aarch64-linux-gnu
sudo apt install gcc-arm-linux-gnueabihf g++-arm-linux-gnueabihf
sudo apt install gcc-arm-linux-gnueabi g++-arm-linux-gnueabi

動態分析與模擬環境建置

apt-get 安裝好 qemu-user 後,即可在 x64 的 Kali 上直接執行該 ARM ELF 樣本。實際執行時會由 qemu-arm 模擬器在主機上執行該二進位,並使用本機資源(CPU / 網路 / 檔案系統)來模擬目標行為。執行過程中觀察到的網路行為——使用 netstat 檢查可發現該程式在本機監聽 TCP 63258 通訊埠,這表示該後門採取 被動 (passive) 的連線模式(等待遠端連入),而非主動發起外連。

進一步編譯 tsh 客戶端對該樣本進行連線測試;連線成功、互動行為與預期相符,進一步證實該樣本即為 tinyshell。這項動態驗證不僅補強了靜態分析(如 switch-case、SHA‑1/AES 特徵與初始化字串)所得出的推論,也直接證實該惡意程式為 tinyshell。

要在 x64 主機上對 ARM ELF 進行動態除錯,可以利用 qemu-arm 的 GDB server 模式。啟動時加上 -g 參數,qemu-arm 會在指定埠口開啟一個遠端 GDB 伺服器,供 IDA Pro(Remote GDB)或 gdb-multiarch 連線並做遠端除錯。

使用 gdb-multiarch 進行除錯時,可啟用 TUI(文字使用者介面)模式,以同時顯示程式碼、堆疊、暫存器與記憶體的文字視窗,便於在終端環境下進行交互式除錯。

同樣也可以使用 IDA Pro 進行除錯:在 IDA Pro 選單中,透過 Debugger 設定 Remote GDB Debugger,即可連線到遠端 GDB 伺服器進行動態分析。
在 IDA Pro 中,可透過選單 Debugger → Process Options… 進行除錯進程的設定。

在 IDA Pro 的 Remote GDB 設定中填入 Kali 主機的 IP 與 qemu-arm -g 指定的埠號,按下「確定」後按 F9 啟動程式進入除錯。

完成上述設定後,IDA Pro 會在程式的入口點暫停,等待使用者進行斷點設置、單步執行與控制流程追蹤。

由於已經確認樣本為 tinyshell,因此進行動態追蹤的價值有限,接下來可以專注於還原函數名稱。

建立與比對 FLIRT 簽章

在這裡,可使用 IDA Pro 的 FLIRT(Fast Library Identification and Recognition Technology) 功能來識別標準函式。然而,FLIRT signature 對 GCC 版本與編譯參數相當敏感。
最初若使用透過 apt-get 安裝的 cross compiler(如 gcc-arm-linux-gnueabi)編譯,會發現生成的 ELF 與對應的 .sig 檔案只能用於該 ELF,自行產生的 signature 無法通用。
若已下載 tinyshell 原始碼,可觀察其 Makefile,預設會使用 kali 內建的 gcc 與 strip 指令。若已安裝 cross compiler,建議將 Makefile 中的 CC 與 STRIP 改成自已安裝的版本,以編譯出對應於目標 ELF 架構的可用 signature。
┌──(kali㉿kali)-[~/arm
└─$ git clone https://github.com/creaktive/tsh.git; cd tsh

┌──(kali㉿kali)-[~/arm/tsh]
└─$ head -n 10 Makefile
#CC             = arm-linux-gnueabi-gcc
CC              = armv5l-linux-musleabi-gcc
RM              = rm -f
#STRIP          = arm-linux-gnueabi-strip
STRIP           = armv5l-linux-musleabi-strip
CFLAGS          = -O3 -W -Wall

TOOLCHAIN       = /var/toolchain/sys30

COMM            = pel.o aes.o sha1.o
其實這裡只需一行指令就能完成編譯,也可以直接使用 gcc,不必透過 Makefile。
使用 -g 參數可在編譯時加入除錯資訊;-c 則表示僅進行編譯(compile)而不做連結(link),因此不會產生 ELF 檔案。-c 與 -o 參數通常只能二選一。
此外,-O、-fno-inline、-fno-omit-frame-pointer 等編譯選項,也會影響最終 ELF 的結構與生成的 FLIRT signature,因此在還原函數名稱時必須特別注意這些參數對編譯結果的影響。
arm-linux-gnueabihf-gcc -O -W -Wall -static -o tshd pel.c aes.c sha1.c tshd.c -lutil -DLINUX 
arm-linux-gnueabihf-gcc -c -O -W -Wall -static pel.c aes.c sha1.c tshd.c -lutil -DLINUX 

arm-linux-gnueabi-gcc -O -W -Wall -static -o tshd pel.c aes.c sha1.c tshd.c -lutil -DLINUX 
arm-linux-gnueabi-gcc -c -O2 -W -Wall -static pel.c aes.c sha1.c tshd.c -lutil -DLINUX 

arm-linux-gnueabi-gcc -c -march=armv5te -mfloat-abi=soft -O2 -W -Wall -static pel.c aes.c sha1.c tshd.c -lutil -DLINUX

arm-linux-gnueabi-gcc -g -o tshd -march=armv5te -mfloat-abi=soft -fno-inline -fno-omit-frame-pointer -O1 -W -Wall -static pel.c aes.c sha1.c tshd.c -lutil -DLINUX 

armv5l-linux-musleabi-gcc -c -march=armv5te -mfloat-abi=soft -O2 -W -Wall -static pel.c aes.c sha1.c tshd.c -lutil -DLINUX

arm-linux-gnueabihf-gcc -march=armv5te -O -W -Wall -static -o tshd pel.c aes.c sha1.c tshd.c -lutil -DLINUX
嘗試了多種編譯參數組合仍未成功,最終只能透過 readelf 去分析 ELF 檔案,找出其相對應的編譯器版本,以便產生相符的 FLIRT signature 或進行函數名稱還原。

透過比對 ELF 檔案中的編譯器指紋,我鎖定到 GCC 11.2.1 (20211120)。進一步在網路上查證後,發現兩則具參考價值的資料:其一明確指出了 GCC 11.2.1 與編譯日期 20211120,暗示樣本作者可能就是使用這套 cross‑compiler 進行編譯。

其二為 Mandiant 的報告,描述在 FortiOS 中發現的一個 ELF 惡意程式,其編譯器版本同樣為 GCC 11.2.1 (20211120)。這兩則線索相互印證,提升了我對樣本編譯環境判定的信心。 (參考資料:Suspected Chinese Threat Actors Exploiting FortiOS Vulnerability (CVE-2022-42475))
在此,再下載了 armv5l-linux-musleabi-cross.tgz,解壓縮後設定環境變數,使系統能正確識別並使用解壓後的 cross compiler 工具鏈。
mkdir ~/gcc; cd gcc
wget https://github.com/troglobit/misc/releases/download/11-20211120/armv5l-linux-musleabi-cross.tgz
tar zxvf armv5l-linux-musleabi-cross.tgz
export PATH=~/gcc/armv5l-linux-musleabi-cross/bin:$PATH
export CROSS_COMPILE=armv5l-linux-musleabi-
export LD_LIBRARY_PATH=~/gcc/armv5l-linux-musleabi-cross/lib:$LD_LIBRARY_PATH
export ARCH=arm
編譯出的 tshd 與樣本 ELF 所顯示的 GCC 版本一致,證實了作者使用的編譯環境與我所配置的 cross compiler 相符。

之後就是一直改 gcc 的參數,收集特徵,再使用 pelf 取得 .o(object), .a(library) 特徵(可以一直累加),最後使用 sigmake 將 .pat 再轉成 .sig。
接下來的流程是持續調整 GCC 的編譯參數,收集函式特徵(FLIRT patterns),再使用 pelf 從 .o(object)或 .a(library)檔案提取特徵,可持續累加不同檔案的特徵。最後,利用 sigmake 將累積的 .pat 檔案轉換成 .sig,以便在 IDA Pro 中使用,完成函數名稱還原。

編譯產物可與原始樣本進行比對——例如檢查反組譯或指令序列是否相符——以驗證所用的編譯參數與工具鏈是否能重現原始二進位。

在 IDA Pro 中,透過 File → Load File → FLIRT Signature File… 選取並載入生成好的 .sig 檔案,即可套用 FLIRT signature 進行函數名稱還原。

載入 .sig 後,即可看到函數名稱被還原。gdb 與 Visual C++ 編譯出的結果類似:IDA Pro 會將使用者自訂撰寫的函數排列在最上方,而下方則列出標準函式庫或內建函數。

結論:從樣本分析到威脅歸屬

本文分析展示從零開始進行 ARM 架構惡意程式逆向的完整流程,涵蓋:
  • 指令集學習與 IDA Pro 操作
  • QEMU 模擬與動態偵錯
  • 函數簽章建立與比對
  • 核心加密模組判讀與行為確認

透過這些步驟,本文最終確認該樣本為 TinyShell ARM 版本變種,並成功建立分析環境與方法論。

參考資料

2025.10.16GSS & IR Team
Share:
為提供您最佳的服務體驗,本網站使用 Cookies。當您使用本網站,即表示您同意 Cookies 技術支援。更多資訊請參閱隱私權與Cookies使用政策。