1. 程式人生 > >一個Python開源專案-哈勃沙箱原始碼剖析(下)

一個Python開源專案-哈勃沙箱原始碼剖析(下)

前言

上一篇中,我們講解了哈勃沙箱的技術點,詳細分析了靜態檢測和動態檢測的流程。本篇接著對動態檢測的關鍵技術點進行分析,包括strace,sysdig,volatility。volatility的介紹不會太深入,記憶體取證這部分的研究還需要繼續。

strace機制

上一篇講到了strace和ltrace都是基於ptrace機制,但是對ptrace機制和strace/ltrace是如何利用ptrace監控系統呼叫,沒有進行詳細的講解。

 

那什麼是ptrace機制呢?

 

ptrace機制是作業系統提供了一種標準的服務來讓程式設計師實現對底層硬體和服務的控制。

 

當一個程式需要作系統呼叫的時候,它將相關引數放進系統呼叫相關的暫存器,然後呼叫軟中斷0x80,這個中斷就像一個讓程式得以接觸到核心模式的視窗,程式將引數和系統呼叫號交給核心核心來完成系統呼叫的執行。


ptrace會在什麼時候出現呢?

 

在執行系統呼叫之前,核心會先檢查當前程序是否處於被“跟蹤”(traced)的狀態。如果是的話,核心暫停當前程序並將控制權交給跟蹤程序,使跟蹤程序得以察看或者修改被跟蹤程序的暫存器。

 

strace監控系統呼叫

 

下面就以strace為例,如下圖所示,在第2步和第3步是關鍵。

 

strace使用ptrace機制來檢測目標程序並“監聽”該程序的系統呼叫,strace可以在每次呼叫系統呼叫時中斷跟蹤的程序,捕獲呼叫,解碼它,然後繼續執行跟蹤的程序

 

大家可能知道,每次呼叫系統呼叫(例如,開啟,讀取,寫入,關閉)時,都需要從使用者級別到核心級別的轉換 - 這稱為上下文切換。這取決於CPU系列和型號,以不同的方式實現,但它往往復雜且相對較慢。

sysdig機制

 

sysdig是一個開源系統發掘工具,用於系統級別的勘察和排障,可以看作system(系統)+dig(挖掘)的組合。我們可以把它看作一系列傳統的 unix 系統工具的組合,主要包括:

  • strace:追蹤某個程序產生和接收的系統呼叫。

  • tcpdump:分析網路資料,監控原始網路通訊。

  • lsof:  列出開啟的檔案。

  • top:監控系統性能工具。

  • htop :互動式的程序瀏覽器,可以用來替換 top 命令。

  • iftop :主要用來顯示本機網路流量情況及各相互通訊的流量集合。

  • lua:一個小巧的指令碼語言。該語言的設計目的是為了嵌入應用程式中,從而為應用程式提供靈活的擴充套件和定製功能。

 

sysdig工作方式分成使用者空間和核心空間兩個部分,結構如下圖所示(附件畫圖畫的):

 

 

資料的捕獲流程分為如下5部分

  1. 在核心有一個元件叫 sysdig-probe,也可以把它稱為資料探頭,它通過跟蹤 linux 核心來進行資料抓獲。

  2. 事件緩衝器(event buffer)用來把儲存器對映到使用者空間。

  3. scap 元件:用來進行捕獲控制和轉儲檔案,以及資料的狀態採集。

  4. sinsp 元件:用來進行事件分析、執行鑿子(chisel),設定過濾和輸出格式化。

  5. 最後 sysdig 工具在命令列解析採集的資料。

 

從整體架構上來看,sysdig與libpcap / tcpdump / wireshark的架構非常相似,都是先捕獲大量的資料,然後使用過濾器獲取自己想要的資料。

 

希望大家注意到一個問題, sysdig-probe從核心捕獲的資料會非常大的,使用者空間裡的scapsinspsysdig元件能處理過來嗎?假如處理不過來,sysdig會採用什麼機制呢?sysdig會像strace一樣放慢程式速度嗎?

 

答案是否定的。在這種情況下,事件緩衝區填滿,sysdig-probe開始丟棄傳入的事件。因此,將丟失一些跟蹤資訊,但機器上執行的其他程序不會減慢速度,這是sysdig架構的關鍵優勢,意味著跟蹤開銷可預測。既然sysdig這麼強大,下面講解一下sysdig的基本用法。

 

sysdig 基本用法

 

我以ubuntu系統中的操作為例,直接在shell輸入sudo sysdig 就能開始捕獲系統資訊,執行後你會看到終端有持續不斷的輸出流。

 

$ sudo sysdig

 

因為系統每時每刻都有大量的系統呼叫產生,這樣是沒辦法看清更無法分析輸出資訊的,可以先使用 ctrl + c 來退出命令。輸出如下圖所示:

 

先來解釋一下它的輸出格式:

 

所有的輸入都是按照行來分割的,每行都是一條記錄,由多個列組成,預設的格式是:

 

%evt.num %evt.outputtime %evt.cpu %proc.name (%thread.tid) %evt.dir %evt.type %evt.info

 

各個欄位的含義如下

  • evt.num: 遞增的事件號

  • evt.time: 事件發生的時間

  • evt.cpu: 事件被捕獲時所在的 CPU,也就是系統呼叫是在哪個 CPU 執行的。比較上面的例子中,值 0 代表機器的第一個 CPU

  • proc.name: 生成事件的程序名字,也就是哪個程序在執行

  • thread.tid: 執行緒的 id,如果是單執行緒的程式,這也是程序的 pid

  • evt.dir: 事件的方向(direction),> 代表進入事件,< 代表退出事件

  • evt.type: 事件的名稱,比如 open、stat等,一般是系統呼叫

  • evt.args: 事件的引數。如果是系統呼叫,這些對應著系統呼叫的引數

 

過濾

 

完整的 sysdig 使用方法:

 

sysdig [option]...  [filter]

 

sysdig 的過濾功能很強大,不僅支援的過濾項很多,而且還能夠自由地進行邏輯組合。

 

過濾項

 

sysdig 的過濾器也是分成不同類別的,比如:

 

  • fd: 對檔案描述符(file descriptor)進行過濾,比如 fd 標號(fd.num)、fd 名字(fd.name)

  • process: 程序資訊的過濾,比如程序 id(proc.id)、程序名(proc.name)

  • evt: 事件資訊的過濾,比如事件編號、事件名

  • user: 使用者資訊的過濾,比如使用者 id、使用者名稱、使用者 home 目錄、使用者的登入 shell(user.shell)

  • syslog: 系統日誌的過濾,比如日誌的嚴重程度、日誌的內容

  • fdlist: poll event 的檔案描述符的過濾

 

完整的過濾器列表可以使用sysdig -l來檢視,比如可以檢視建立 TCP 連線的事件

 

sudo sysdig evt.type=accept

 

過濾器組合

 

過濾器除了直接的相等比較之外,還有其他操作符,包括=、!=、>=、>、<、<=、contains、in 和 exists

比如:

 

$ sysdig fd.name contains /etc

$ sysdig "evt.type in ( 'select', 'poll' )"

$ sysdig proc.name exists

 

多個過濾條件還可以通過 and、or 和 not 進行邏輯組合,比如:

 

$ sysdig "not (fd.name contains /proc or fd.name contains /dev)"

volatility簡單描述

 到這發現已經寫了4千多字,volatility這裡簡要描述一下,詳細的分析,等我之後對記憶體取證有了一個整體的框架再說。

 

 Volatility是一個Python編寫的跨平臺,用於記憶體分析的法證工具,其目的是為了在資料犯罪中提取易失性資料 ,也可以用來進行Rootkit的檢測和協助清除。Volatility分析主要依賴的是profile檔案,profile檔案是由兩部分合成。以linux為例,大致如下:

 

  1.  Linux的System.map檔案列出了詳細的系統呼叫(syscall),而kernel-header原始碼通過dwarfdump生成的module.dwarf檔案中會包含很多核心資料結構,將以上2個檔案打包為profile檔案。

  2. 再用這個profile檔案解析dump下來的實體記憶體,就很容易找到植入Rootkit的機器活動時的程序(linux_psaux)、網路通訊(linux_netstat)、活動檔案(linux_lsof)、驅動模組(linux_lsmod)等等

最後

關注公眾號:七夜安全部落格

  • 回覆【1】:領取 Python資料分析 教程大禮包
  • 回覆【2】:領取 Python Flask 全套教程
  • 回覆【3】:領取 某學院 機器學習 教程
  • 回覆【4】:領取 爬蟲 教程
  • 回覆【5】:領取 編譯原理 教程 
  • 回覆【6】:領取 滲透測試 教程 
  • 回覆【7】:領取 人工智慧數學基礎 教程

本文章屬於原創作品,歡迎大家轉載分享,禁止修改文章的內容。