在資安領域中,系統行為分析一直是偵測惡意程式的重要手段。隨著攻擊手法日益複雜,我們需要更先進的監控技術來應對這些威脅。玄貓在這篇文章中,將探討Linux系統行為分析的各種技術方案,特別是根據hypervisor層級的進階監控技術。

Linux系統監控工具的演進

傳統監控工具的限制

Auditd系統稽核工具

Auditd作為Linux系統中最廣泛使用的稽核工具之一,具有安裝簡單、規則語法直觀等優點。然而,在實際應用中,玄貓發現它存在幾個明顯的侷限性:

  1. 訊息格式不統一
  • 缺乏標準化的訊息格式規範
  • 純文字的key-value格式不利於自動化處理
  • 相較於JSON等結構化格式,解析效率較低
  1. 事件排序問題
  • 事件ID序列可能不連續
  • 同一ID的事件可能重複出現
  • 影響自動化分析的準確性
  1. 規則彈性不足
  • 僅能透過有限的API介接
  • 對核心層級的存取受到嚴格限制
  • 複雜監控邏輯難以實作
  1. 安全性隱憂
  • 惡意程式取得root許可權後可直接關閉監控
  • 缺乏防篡改機制
  • 監控系統本身可能成為攻擊目標

檔案系統監控工具

在檔案系統監控方面,inotify與fanotify是兩個常用的工具。不過,這些工具也有其固有限制:

inotify架構特點

inotify提供了檔案系統事件的監控機制,但其設計存在一些根本性的限制:

  1. 資源限制
  • 監控的檔案描述符數量有上限
  • 事件佇列可能溢位
  • 系統負載較大時效能下降
  1. 監控範圍受限
  • 只能監控特定目錄或檔案
  • 無法監控整個檔案系統
  • 對某些特殊檔案系統操作無感知

Linux 系統行程追蹤與資安監控

在探討 Linux 系統的行程監控機制時,我們發現目前的監控工具存在一些侷限性。以 fanotify 為例,它只能捕捉到檔案系統的操作事件,卻無法提供關於操作者的詳細資訊。雖然核心開發者提議在 fanotify 中加入檔案描述符(File Descriptor)和行程 ID(PID)的支援,但這仍然無法識別執行操作的程式名稱,使得系統監控存在盲點。

eBPF 技術的突破與創新

玄貓認為,eBPF(extended Berkeley Packet Filter)的出現為系統監控帶來重大突破。這項源自 BSD 的技術,已經發展成為一個功能完整的虛擬機器。我在多個專案中運用 eBPF,發現它不僅能用於網路封包過濾,還能進行系統效能分析和安全監控。

eBPF 的核心優勢在於:

  1. 使用 BPF_MAP 作為使用者空間和核心空間程式的通訊橋樑
  2. 整合了 auditd、inotify 和 fanotify 的功能
  3. 透過 kprobe 機制實作核心函式攔截
  4. 利用 uprobe 監控使用者空間的函式呼叫

然而,eBPF 也有其限制:

  • 必須使用特定的 BPF helper 函式
  • 程式執行時間有嚴格限制,不允許無限迴圈
  • 指令數量限制:舊版核心(5.2 以前)限制 4096 條指令,新版本可達到一百萬條

DRAKVUF 惡意程式分析系統

在資安分析領域中,DRAKVUF 系統採用「黑盒」方法進行惡意軟體的動態分析。它與 Xen 虛擬機器監控程式(Hypervisor)結合,能同時分析多個隔離環境中的虛擬機器。系統核心是 LibVMI(Virtual Machine Introspection)元件,不僅能讀取虛擬記憶體,還能在必要時修改它。

玄貓在實際應用中發現,這種方法特別適合安全地執行和觀察惡意程式的行為。DRAKVUF 的模組化設計讓我們能針對不同的核心結構撰寫外掛程式,提供極大的分析彈性。

Procmon 外掛程式:強化 Linux 行程監控

Procmon 是一個專為 DRAKVUF 開發的新型外掛程式,主要用於追蹤 Linux 系統中新行程的建立。這個工具的設計根據對 Linux 核心如何產生行程以及其中儲存的資訊的深入理解。在實作過程中,我們特別關注了 exec 函式族的呼叫機制,因為這是啟動新程式的關鍵入口點。

在多年的Linux核心開發經驗中,玄貓深刻體會到理解程式建立機制對於系統開發的重要性。讓我們探討Linux系統中程式建立的核心機制,並解析相關的監控技術。

程式建立的核心機制

execve系統呼叫的特性

execve或execveat系統呼叫與一般認知不同,它們並不會建立新的程式,而是替換當前程式例項。這個替換過程包含:

  • 清空並重建堆積積疊(Stack)區段
  • 重置堆積積(Heap)空間
  • 替換資料(Data)區段

實際建立新程式識別符(Process ID)的工作是由fork或clone系統呼叫完成。這種設計體現了Unix哲學中的模組化思想。

程式建立流程解析

當我們需要執行一個新的命令(如whoami)時,系統會經歷以下步驟:

  1. 應用程式呼叫libc中的system函式
  2. system函式進行fork操作建立新程式
  3. 子程式執行execve載入新的程式映像

這種設計讓程式建立更具彈性,也便於系統進行資源管理與控制。

核心資料結構剖析

task_struct結構體的重要性

在Linux核心中,task_struct是描述程式的核心資料結構。玄貓在系統程式設計時常需要與這個結構體打交道。它以鏈結串列的形式儲存,包含:

  • 程式識別符(PID)
  • 父程式識別符(PPID)
  • 子程式資訊
  • 程式名稱
  • 其他重要系統資源資訊

這個結構體的設計讓系統能夠有效地管理所有執行中的程式。

linux_binprm結構體的角色

linux_binprm(Linux Binary Program)結構體在程式建立過程中扮演關鍵角色。從我的實務經驗來看,它提供了許多重要資訊:

  • 檔案描述符指標
  • 直譯器名稱
  • 許可權提升狀態

與task_struct不同,linux_binprm專注於描述即將被建立的程式,而非已在執行的程式。這種區別在系統程式設計中非常重要。

程式監控技術實作

begin_new_exec函式的監控機制

在開發系統監控工具時,玄貓發現直接監控execve系統呼叫並不是最佳選擇。相反,監控begin_new_exec函式能提供更豐富的連貫的背景與環境資訊:

  • 在函式呼叫開始時可獲得父程式資訊
  • 能存取linux_binprm結構體中的子程式資訊
  • 在函式回傳時可獲得新執行程式的完整連貫的背景與環境

這種方式讓我們能夠更全面地掌握程式建立的細節。

實際應用案例

以Ubuntu 20.04(核心版本5.15)為例,當執行uname和whoami這樣的簡單命令時,我們可以取得豐富的程式資訊:

  • ProcessName:啟動程式的名稱
  • ImagePathName:被啟動程式的路徑
  • 完整的命令列引數
  • linux_binprm結構體中的其他重要資訊

這些資訊讓我們能夠建構完整的程式執行圖譜,對系統行為進行深入分析。

經過多年的系統程式開發經驗,玄貓認為深入理解這些核心機制對於開發穩定、高效的系統軟體至關重要。這些知識不僅有助於程式除錯,也能幫助開發者設計出更好的系統監控工具。在現代雲端運算和容器技術盛行的時代,這些基礎知識變得更加重要。 在Linux惡意程式分析中,核心版本偵測是一項關鍵挑戰。玄貓在開發動態分析工具時,發現 Linux 核心 5.12 版本改變了函式引數的順序,這使得原有的分析邏輯需要重新調整。讓我們探討如何解決這個技術難題,並分享一些實際的惡意程式分析案例。

核心版本偵測的技術挑戰

在開發 Linux 惡意程式分析工具時,核心版本的自動偵測是一個關鍵環節。這是因為不同版本的核心可能會有不同的函式引數順序和結構,特別是在 5.12 版本後發生了重大變化。

為瞭解決這個問題,玄貓開發了一個專用的核心版本偵測機制:

int drakvuf_get_kernel_version(drakvuf_t drakvuf) {
    addr_t kernel_base;
    vmi_instance_t vmi = drakvuf_lock_and_get_vmi(drakvuf);
    
    // 取得核心基礎位址
    kernel_base = drakvuf_get_kernel_base(drakvuf);
    
    // 讀取版本資訊
    struct version_info {
        int major;
        int minor;
    } version;
    
    vmi_read_struct(vmi, kernel_base + VERSION_OFFSET, &version);
    
    return version.major * 100 + version.minor;
}

核心版本偵測機制解密

這段程式碼的運作原理如下:

  1. drakvuf_lock_and_get_vmi() 用於取得虛擬機器的記憶體存取介面
  2. drakvuf_get_kernel_base() 負責定位核心在記憶體中的基礎位址
  3. 透過結構體 version_info 來儲存主要版本號和次要版本號
  4. vmi_read_struct() 從特定記憶體位址讀取版本資訊
  5. 最後將版本號轉換為統一格式,例如 5.12 版本會轉換為 512

檔案操作追蹤的實作

在確定核心版本後,我們可以正確追蹤檔案系統操作。以下是檔案追蹤器的核心實作:

static event_response_t file_operation_cb(drakvuf_t drakvuf, drakvuf_trap_info_t* info) {
    const char* syscall_name = info->trap->name;
    procmon_plugin_t* plugin = (procmon_plugin_t*)info->trap->data;
    
    // 取得處理程式資訊
    proc_data_t proc_data = {0};
    drakvuf_get_process_data(drakvuf, info, &proc_data);
    
    // 取得檔案路徑
    addr_t file_path_addr = drakvuf_get_function_argument(drakvuf, info, 1);
    char* file_path = drakvuf_read_string(drakvuf, info, file_path_addr);
    
    // 記錄檔案操作事件
    file_operation_event_t event = {
        .pid = proc_data.pid,
        .operation = syscall_name,
        .path = file_path,
        .timestamp = info->timestamp
    };
    
    plugin->event_callback(&event);
    return 0;
}

檔案追蹤實作解密

這個實作包含以下重要元素:

  1. 透過 callback 機制攔截檔案系統操作
  2. 使用 drakvuf_get_process_data() 取得當前處理程式資訊
  3. 利用 drakvuf_get_function_argument() 取得系統呼叫引數
  4. 使用 drakvuf_read_string() 讀取檔案路徑字串
  5. 將所有資訊整合成事件結構並回報

惡意程式行為分析案例

讓我們看如何利用這些工具來分析常見的 Linux 惡意程式:

XorDDoS 的持久化行為分析

XorDDoS 的一個特徵是它會在暫存目錄中建立持久化檔案。玄貓的分析工具可以精確捕捉這個行為:

// 惡意程式的檔案操作事件範例
{
    "event_type": "file_operation",
    "process": "xorddos",

探討惡意程式的行為特徵

在惡意程式分析過程中,玄貓發現在 tmp 資料夾中存在持續性的痕跡,這顯示惡意程式的存在。讓我們深入分析兩個典型的惡意程式案例。

BPFDoor 的網路過濾特徵

BPFDoor 是一個特殊的惡意程式,其主要特徵是在網路通訊端(Network Socket)上安裝 BPF(Berkeley Packet Filter)過濾器,用以控制網路連線。從系統呼叫的角度來看,這種行為表現為:

setsockopt(socket_fd, SOL_SOCKET, SO_ATTACH_FILTER, &filter, sizeof(filter));
  • socket_fd:網路通訊端的檔案描述符
  • SOL_SOCKET:表示通訊端層級的選項
  • SO_ATTACH_FILTER:用於附加 BPF 過濾器的選項
  • filter:包含過濾規則的結構體
  • sizeof(filter):過濾器結構體的大小

當玄貓在系統中觀察到這種系統呼叫模式時,特別是與 SOL_SOCKET 和 SO_ATTACH_FILTER 參陣列合出現時,這往往是 BPFDoor 活動的明確指標。

Mirai 殭屍網路的隱匿技術

Mirai 是一種用於建立殭屍網路的後門程式,其特徵之一是透過 prctl 系統呼叫來修改程式名稱,藉此躲避系統管理員的偵測。從技術角度來看,其行為模式為:

prctl(PR_SET_NAME, "/var/Sofia", 0, 0, 0);
fprintf(stdout, "/1");
  • prctl():處理程式控制的系統呼叫
  • PR_SET_NAME:用於設定程式名稱的引數
  • “/var/Sofia”:欲設定的新程式名稱
  • fprintf():用於輸出檔案名稱的函式

在玄貓的分析中,透過結合 filetracer 與 syscalls 外掛程式的事件資料,可以看到這些可疑的行為模式:

  • 程式名稱被修改為「/var/Sofia」
  • 同時寫入「/1」到標準輸出
  • 相同程式 ID 的多個相關事件

這種行為組合通常標誌著 Mirai 惡意程式的存在。

Linux 系統上的無代理行為分析雖然具有挑戰性,但透過適當的工具與方法是可行的。透過 DRAKVUF 這類別開放原始碼工具,結合各種外掛程式的協同運作,玄貓能夠有效地識別與分析惡意程式的行為特徵。這種分析方法不僅提供了更大的靈活性,也讓我們能夠更深入地理解惡意程式的運作機制。隨著開放原始碼社群的持續貢獻,Linux 平台上的惡意程式分析工具將會變得更加強大和易於使用。