分析 Linux ELF 惡意軟體 是做什麼的?
使用時機
- Linux 伺服器或容器遭到入侵,發現可疑的 ELF 二進位檔案時
- 分析 Linux Botnet(Mirai、Gafgyt、XorDDoS)、加密挖礦程式或勒索軟體時
- 調查針對雲端基礎設施、Docker 容器或 Kubernetes Pod 的惡意軟體時
- 逆向工程 Linux Rootkit 及核心模組時
- 分析編譯給 Linux x86_64、ARM 或 MIPS 架構的跨平台惡意軟體時
請勿使用於 Windows PE 二進位檔案分析;請改用 PEStudio、Ghidra 或 IDA 進行 Windows 惡意軟體分析。
前置需求
- 具備 Linux ELF 支援的 Ghidra 或 IDA,用於反組譯與反編譯
- 安裝了開發工具的 Linux 分析 VM(建議使用 Ubuntu 22.04)
- strace、ltrace 及 GDB,用於動態分析與除錯
- GNU binutils 中的 readelf、objdump 及 nm,用於靜態檢測
- Radare2,用於快速的二進位檔案分類與腳本化分析
- Docker,用於隔離的容器內惡意軟體執行
工作流程
步驟 1:識別 ELF 二進位檔案屬性
檢查 ELF 標頭及基本屬性:
# 檔案類型識別
file suspect_binary
# 詳細 ELF 標頭分析
readelf -h suspect_binary
# 區段標頭
readelf -S suspect_binary
# 程式標頭(區段)
readelf -l suspect_binary
# 符號表(若未被剝離)
readelf -s suspect_binary
nm suspect_binary 2>/dev/null
# 動態連結資訊
readelf -d suspect_binary
ldd suspect_binary 2>/dev/null # 僅在架構匹配時執行!
# 計算雜湊值
md5sum suspect_binary
sha256sum suspect_binary
# 檢查是否加殼/UPX
upx -t suspect_binary
# Python 為基礎的 ELF 分析
from elftools.elf.elffile import ELFFile
import hashlib
with open("suspect_binary", "rb") as f:
data = f.read()
sha256 = hashlib.sha256(data).hexdigest()
with open("suspect_binary", "rb") as f:
elf = ELFFile(f)
print(f"SHA-256: {sha256}")
print(f"類別: {elf.elfclass}-位元")
print(f"位元序: {'小端序' if elf.little_endian else '大端序'}")
print(f"機器架構: {elf.header.e_machine}")
print(f"類型: {elf.header.e_type}")
print(f"進入點: 0x{elf.header.e_entry:X}")
# 檢查是否被剝離
symtab = elf.get_section_by_name('.symtab')
print(f"已剝離: {'是' if symtab is None else '否'}")
# 區段熵分析
import math
from collections import Counter
for section in elf.iter_sections():
data = section.data()
if len(data) > 0:
entropy = -sum((c/len(data)) * math.log2(c/len(data))
for c in Counter(data).values() if c > 0)
if entropy > 7.0:
print(f" [!] 高熵區段: {section.name} ({entropy:.2f})")
步驟 2:提取字串與指標
搜尋嵌入的 IOC 與功能線索:
# ASCII 字串
strings suspect_binary > strings_output.txt
# 搜尋網路指標
grep -iE "(http|https|ftp)://" strings_output.txt
grep -iE "([0-9]{1,3}\.){3}[0-9]{1,3}" strings_output.txt
grep -iE "[a-zA-Z0-9.-]+\.(com|net|org|io|ru|cn)" strings_output.txt
# 搜尋 shell 指令
grep -iE "(bash|sh|wget|curl|chmod|/tmp/|/dev/)" strings_output.txt
# 搜尋加密挖礦指標
grep -iE "(stratum|xmr|monero|pool\.|mining)" strings_output.txt
# 搜尋 SSH/憑證竊取
grep -iE "(ssh|authorized_keys|id_rsa|shadow|passwd)" strings_output.txt
# 搜尋持續性機制
grep -iE "(crontab|systemd|init\.d|rc\.local|ld\.so\.preload)" strings_output.txt
# FLOSS 用於混淆字串(若可用)
floss suspect_binary
步驟 3:分析系統呼叫與函式庫使用
識別惡意軟體使用的系統呼叫與函式庫:
# 列出匯入的函式(動態連結)
readelf -r suspect_binary | grep -E "socket|connect|exec|fork|open|write|bind|listen"
# 在執行期間追蹤系統呼叫(僅在隔離 VM 中)
strace -f -e trace=network,process,file -o strace_output.txt ./suspect_binary
# 追蹤函式庫呼叫
ltrace -f -o ltrace_output.txt ./suspect_binary
# 主要的系統呼叫:
# 網路:socket, connect, bind, listen, accept, sendto, recvfrom
# 程序:fork, execve, clone, kill, ptrace
# 檔案:open, read, write, unlink, rename, chmod
# 持續性:inotify_add_watch(檔案監控)
步驟 4:使用 GDB 進行動態分析
除錯惡意軟體以觀察執行時行為:
# 使用 GDB 啟動二進位檔案
gdb ./suspect_binary
# 在關鍵函式設定中斷點
(gdb) break main
(gdb) break socket
(gdb) break connect
(gdb) break execve
(gdb) break fork
# 執行並分析
(gdb) run
(gdb) info registers # 檢視暫存器狀態
(gdb) x/20s $rdi # 檢查字串參數
(gdb) bt # 回溯
(gdb) continue
# 針對已剝離的二進位檔案,在進入點設定中斷點
(gdb) break *0x400580 # 來自 readelf 的進入點
(gdb) run
# 在執行期間監控網路連線
# 在另一個終端機中:
ss -tlnp # 列出監聽中的 socket
ss -tnp # 列出已建立的連線
步驟 5:使用 Ghidra 進行逆向工程
對 ELF 二進位檔案執行深層程式碼分析:
Ghidra 的 Linux ELF 分析:
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
1. 匯入:檔案 -> 匯入 -> 選擇 ELF 二進位檔案
- Ghidra 會自動偵測 ELF 格式與架構
- 接受預設的分析選項
2. 主要分析目標:
- main() 函式(若已剝離則為進入點)
- Socket 建立與連線函式
- 指令分派邏輯(對接收資料的 switch/case)
- 加密/編碼常式
- 持續性安裝程式碼
- 自我傳播/掃描函式
3. 針對 Mirai 類型的 Botnet,尋找:
- 暴力破解的憑證清單(telnet/SSH)
- 攻擊模組選擇(UDP flood、SYN flood、ACK flood)
- 掃描器模組(針對易受攻擊裝置的連接埠掃描)
- 殺手模組(終止競爭的 Botnet)
4. 針對加密挖礦程式,尋找:
- 礦池連線(stratum 協定)
- 錢包地址字串
- CPU/GPU 使用率函式
- 程序隱藏技術
步驟 6:分析 Linux 特有的持續性機制
檢查持續性機制:
# 檢查 LD_PRELOAD Rootkit
strings suspect_binary | grep "ld.so.preload"
# 寫入 /etc/ld.so.preload 的惡意軟體可掛載所有動態函式庫呼叫
# 檢查 crontab 持續性
strings suspect_binary | grep -i "cron"
# 檢查 systemd 服務建立
strings suspect_binary | grep -iE "systemd|\.service|systemctl"
# 檢查 init 腳本建立
strings suspect_binary | grep -iE "init\.d|rc\.local|update-rc"
# 檢查 SSH 金鑰注入
strings suspect_binary | grep -i "authorized_keys"
# 檢查核心模組(Rootkit)載入
strings suspect_binary | grep -iE "insmod|modprobe|init_module"
# 檢查程序隱藏
strings suspect_binary | grep -iE "proc|readdir|getdents"
關鍵概念
| 術語 | 定義 |
|---|---|
| ELF(Executable and Linkable Format) | Linux 可執行檔、共享函式庫與核心傾印的標準二進位格式,包含標頭、區段與區塊 |
| 已剝離二進位檔案 | 移除除錯符號的 ELF 二進位檔案,使得逆向工程更加困難,因為函式名稱已遺失 |
| LD_PRELOAD | Linux 環境變數,指定要在所有其他函式庫之前載入的共享函式庫;被 Rootkit 濫用以攔截系統函式庫呼叫 |
| strace | Linux 系統呼叫追蹤工具,記錄程序進行的所有系統呼叫與訊號,揭露檔案、網路與程序操作 |
| GOT/PLT | 全域偏移表(Global Offset Table)與程序連結表(Procedure Linkage Table);用於動態連結的 ELF 結構,可被劫持以進行函式掛載 |
| 靜態連結 | 將所有函式庫程式碼包含在內的二進位檔案編譯方式;常見於 IoT 惡意軟體,以便在沒有匹配共享函式庫的系統上執行 |
| Mirai | 大量出現的 Linux Botnet,透過 telnet 暴力破解入侵 IoT 裝置;原始碼外洩,導致出現許多變體 |
工具與系統
- Ghidra:美國國家安全局(NSA)逆向工程工具,完整支援 x86、x86_64、ARM、MIPS 等 Linux 架構的 ELF
- Radare2:開源逆向工程框架,提供命令列介面以進行快速的二進位檔案分析與腳本化
- strace:Linux 系統呼叫追蹤工具,用於觀察二進位檔案的行為,包括檔案、網路與程序操作
- GDB:GNU 除錯器,用於設定中斷點、檢查記憶體以及逐步執行 Linux 二進位檔案
- pyelftools:Python 函式庫,用於以程式化方式解析 ELF 檔案,以進行自動化分析流程
常見情境
情境:分析在已遭入侵的 Linux 伺服器上發現的加密挖礦程式
背景說明:一台雲端伺服器出現 100% CPU 使用率。調查發現 /tmp 目錄下有一個名稱可疑的未知二進位檔案正在執行。需分析該二進位檔案以確認其為加密挖礦程式,並識別攻擊者的錢包與礦池。
處理方式:
- 將二進位檔案複製到分析 VM 並計算 SHA-256 雜湊值
- 執行
file與readelf以識別架構與連結類型 - 提取字串並搜尋礦池地址(stratum+tcp://)及錢包地址
- 在沙盒中搭配 strace 執行,以觀察網路連線(礦池連線)
- 匯入 Ghidra 以識別挖礦演算法與組態提取
- 檢查持續性機制(crontab、systemd 服務、SSH 金鑰)
- 記錄所有 IOC,包括礦池地址、錢包、用於更新的 C2,以及持續性成品
注意事項:
- 在沙盒外對惡意軟體執行
ldd(ldd 可能執行二進位檔案中的程式碼) - 在嘗試 x86_64 執行前未檢查 ARM/MIPS 架構
- 遺漏伴隨的腳本檔案(.sh 檔案),這些檔案可能處理持續性與清理工作
- 忽略初始入侵向量(挖礦程式是如何部署的:SSH 暴力破解、網頁漏洞、容器逃逸)
輸出格式
LINUX ELF 惡意軟體分析報告
====================================
檔案: /tmp/.X11-unix/.rsync
SHA-256: e3b0c44298fc1c149afbf4c8996fb924...
類型: ELF 64-bit LSB executable, x86-64
連結方式: 靜態連結(所有函式庫已嵌入)
已剝離: 是
大小: 2,847,232 位元組
加殼程式: UPX 3.96(已解包以進行分析)
分類
家族: XMRig 加密挖礦程式(修改版)
變體: 具有 C2 更新機制的自訂建置
功能
[*] 透過 RandomX 演算法進行 XMR(門羅幣)挖礦
[*] 用於提交工作的 Stratum 礦池連線
[*] C2 回呼以取得組態更新
[*] 程序名稱偽裝(argv[0] = "[kworker/0:0]")
[*] 終止競爭對手程序(殺死其他挖礦程式)
[*] SSH 金鑰注入以重新取得存取權
網路指標
礦池: stratum+tcp://pool.minexmr[.]com:4444
C2 伺服器: hxxp://update.malicious[.]com/config
錢包: 49jZ5Q3b...門羅幣錢包地址...
持續性
[1] Crontab 條目:*/5 * * * * /tmp/.X11-unix/.rsync
[2] SSH 金鑰已新增至 /root/.ssh/authorized_keys
[3] Systemd 服務:/etc/systemd/system/rsync-daemon.service
[4] 已修改 /etc/ld.so.preload 以隱藏程序
程序隱藏
LD_PRELOAD: /usr/lib/.libsystem.so
掛載點: readdir() 以對 ls 隱藏 /tmp/.X11-unix/.rsync
掛載點: fopen() 以對 /proc/*/maps 讀取隱藏