python_mmdt:從0到1--實現簡單惡意程式碼分類器(二)

ddvv發表於2021-01-26

概述

上篇文章python_mmdt:一種基於敏感雜湊生成特徵向量的python庫(一)我們介紹了一種叫mmdt_hash(敏感雜湊)生成方法,並對其中的概念做了基本介紹。本篇,我們重點談談mmdt_hash的分類應用場景。

需求場景

設想這麼一個需求:有一批檔案需要判定是否屬於惡意檔案,並且需要給出惡意檔案所屬的家族型別。這個需求該怎麼高效處理呢?處理過程又該怎麼固化成我們自己的經驗呢?當以後面臨同樣的需求時,能否複用之前的結果呢?

我能想到的做法有以下三種:

  • 做法一:本地下載防毒軟體,使用防毒軟體對這批檔案進行掃描,檢視檢測結果。
  • 做法二:將這些檔案上傳到諸如Virustotal之類的檢測平臺,檢視檢測結果。
  • 做法三:隨機抽取樣本分析,判定為惡意的,則提取yara規則,利用yara規則對剩餘檔案進行掃描,未掃出的檔案繼續人工分析,繼續提yara規則,如此反覆,直到處理完成。

針對以上三種做法,分別討論其優點和缺點:

  • 做法一:
    • 優點:處理方式簡單快捷,誤報率極低,處理效率高
    • 缺點:單一殺軟漏報率可能較高;在Linux/MacOS上安裝、使用殺軟不方便;處理過程很難固化為經驗;有可能導致檔案洩漏(聯網使用殺軟雲查可能導致檔案被廠商收集)
  • 做法二:
    • 優點:適用Windows/Linux/MacOS平臺;檢測誤報率、漏報率都極低,結果豐富;處理效率高
    • 缺點:有聯網要求;有一定的程式碼開發工作;檔案百分百洩漏
  • 做法三:
    • 優點:處理過程天然可固化為經驗;適用任意平臺;適用隔離網路;經驗可積累,可複用;保證檔案安全性
    • 缺點:工作量極大,處理效率極低;

這裡的需求場景也許太過定製化,但還是有一定的代表性的。針對以上的需求場景,python_mmdt工具的分類演算法,可以很好的覆蓋上述場景。

使用python_mmdt的做法,具有以下優點

  • 處理方式簡單、快捷、處理效率高
  • 可打包為可執行檔案,附帶特徵向量,跨平臺適用Windows/Linux/MacOS
  • 無聯網要求,檔案保密性高
  • 處理過程可固化為經驗,經驗固化方式簡單,處理結果複用方便
  • mmdt_hash大小固定,儲存佔用空間小

當然,有三個缺點不能不提:

  • 準確率可能較低(依賴於判定分值的設定)
  • 漏報率可能較高(依賴於判定分值的設定)
  • 部分檔案的mmdt_hash值沒有意義,不能用作分類規則。

因此,可以在不同的場景使用不同的判定分值,判定分值越高,準確率越高;判定分值越低,漏報率越低。

程式碼專案地址

  • python_mmdt
  • 版本:0.1.3
  • 特性:實現簡單分類器,專案附帶基礎敏感雜湊特徵庫,可實現惡意樣本匹配

基本介紹

使用pip安裝python_mmdt之後,會向系統中新增如下命令:

  • mmdt-hash:計算指定檔案的mmdt_hash
  • mmdt-std:計算mmdt_hash的標準差,用於衡量mmdt_hash的好壞
  • mmdt-compare:比較兩個檔案的相似度
  • mmdt-gen:利用已知樣本集,生成基於mmdt_hash的特徵向量集合
  • mmdt-filter:對生成的的特徵向量集合,進行過濾,移除相同的特徵向量
  • mmdt-filter-simple:對生成的特徵向量集,進行簡單過濾(去重),適用與簡單分類器
  • mmdt-classify:對未知樣本集進行分類處理,輸出分類結果

基本命令使用

1. 計算檔案的mmdt_hash

計算單個檔案mmdt_hash

  • 輸入引數1:檔案路徑
  • 螢幕輸出:mmdt_hash的值
  • 檔案輸出:無
# ➜ mmdt-hash APT28_1
#   5D58573C:B39A90BCDCB4D491BEC74B207AE5FE39
$ mmdt-hash $file

簡單分類的mmdt_hash結構如:index_hash:value_hash:冒號前的是敏感雜湊索引,:冒號後的是敏感雜湊真值。敏感雜湊索引用於快速定位相似雜湊,敏感雜湊真值用於計算兩個mmdt_hash之間的相似度。

2. 計算mmdt_hash的標準差

計算單個mmdt_hash值的標準差

  • 輸入引數1:單個mmdt_hash
  • 螢幕輸出:mmdt_hash值的標準差
  • 檔案輸出:無
# ➜ mmdt-std 5D58573C:B39A90BCDCB4D491BEC74B207AE5FE39
#   standard deviation: 45.333946
$ mmdt-std $mmdt_hash_str

mmdt_hash值的標準差,用於衡量生成的mmdt_hash的好壞。從大量統計結果看,當標註差低於10.0左右時,計算生成的mmdt_hash
的有效性太差,不能有效表示原始檔案。

3. 計算兩個檔案的相似度

計算兩個檔案的相似度,輸入2個檔案路徑,輸出

  • 輸入引數1:檔案1路徑
  • 輸入引數2:檔案2路徑
  • 螢幕輸出:兩個檔案的相似度
  • 檔案輸出:無
# ➜ mmdt-compare APT28_1 APT28_2
#   0.9929302916167373
$ mmdt-compare $file1 $file2

計算兩個輸入檔案的相似度,相似度本質採用歐幾里得距離衡量。計算兩個mmdt_hash的歐幾里得距離,並歸一化,計算得到相似度。

4. 生成特徵向量集合

生成基於mmdt_hash的特徵向量集合

  • 輸入引數1:已知樣本集的路徑
  • 輸入引數2:已知樣本集的標籤檔案路徑
  • 螢幕輸出:生成特徵向量過程資訊
  • 檔案輸出:當前資料夾生成兩個檔案,mmdt_feature.labelmmdt_feature.data
# ➜ mmdt-gen APT28 apt28.tags
#   ...
#   process: APT28_3, 22
#   process: APT28_4, 23
#   end gen mmdt set.
# ➜ ll mmdt_feature.*
#   -rw-r--r--  1 ddvv  staff   703B  1 16 10:34 mmdt_feature.data
#   -rw-r--r--  1 ddvv  staff   133B  1 16 10:34 mmdt_feature.label
$ mmdt-gen $file_path $file_tag

遍歷指定檔案目錄,計算該目錄下所有檔案的mmdt_hash,並從標籤檔案中讀取對應標籤,生成標籤索引,記錄到特徵向量集合中。輸入的標籤檔案採用檔名,標籤的csv格式儲存。

5. 特徵向量過濾

對生成的特徵向量集合進行過濾處理

  • 輸入引數1:特徵向量集合檔案
  • 輸入引數2:過濾條件的標準差下限
  • 螢幕輸出:過濾特徵向量過程資訊
  • 檔案輸出:覆蓋輸入的特徵向量集合檔案路徑
# ➜ mmdt-filter mmdt_feature.data 10.0
#   start filter mmdt set.
#   old len: 23
#   new len: 21
#   end filter mmdt set.
# ➜ ll mmdt_feature.*
#   -rw-r--r--  1 ddvv  staff   689B  1 16 10:39 mmdt_feature.data
#   -rw-r--r--  1 ddvv  staff   133B  1 16 10:34 mmdt_feature.label
$ mmdt-filter $mmdt_feature_file_name $dlt

特徵向量集合的一般過濾方法,計算特徵向量集合中mmdt_hash值的標準差,移除標準差小於10.0的mmdt_hash。如前所說,標準差小於10.0的mmdt_hash有效性很低,無法使用。

6. 簡單分類器特徵向量過濾

對生成的基於mmdt_hash特徵向量集合進行適配簡單分類器(去重)過濾處理

  • 輸入引數1:特徵向量集合檔案
  • 螢幕輸出:過濾特徵向量過程資訊
  • 檔案輸出:覆蓋當前路徑的mmdt_feature.data檔案
# ➜ mmdt-filter-simple mmdt_feature.data
#   start filter mmdt set.
#   old len: 21
#   new len: 21
#   end filter mmdt set.
# ➜ ll mmdt_feature.*
#   -rw-r--r--  1 ddvv  staff   689B  1 16 10:39 mmdt_feature.data
#   -rw-r--r--  1 ddvv  staff   133B  1 16 10:34 mmdt_feature.label
$ mmdt-filter-simple $mmdt_feature_file_name

簡單分類演算法的特定過濾方式,移除完全相同的特徵向量,並覆蓋原始特徵向量集合。

7. 分類器的使用

對指定檔案或資料夾進行分類識別

  • 輸入引數1:目標檔案路徑或資料夾路徑
  • 輸入引數2:相似度下限,可選,預設0.95
  • 輸入引數3:分類器型別,可選,預設1,簡單分類器
  • 螢幕輸出:分類過程結果輸出
  • 檔案輸出:無

重要,需要將生成的mmdt_feature.labelmmdt_feature.data檔案拷貝到python_mmdt的安裝路徑,命令如下:

  • 拷貝特徵向量集檔案:mmdt-copy mmdt_feature.data
  • 拷貝特徵向量集對應標籤檔案:mmdt-copy mmdt_feature.label

特別注意:

  • mmdt_feature.labelmmdt_feature.data檔名不可更改
  • 當缺失mmdt_feature.data檔案時,分類器預設是用python_mmdt的特徵向量集
  • 當缺失mmdt_feature.label檔案時,分類器仍可以工作,但是判定結果僅輸出是否識別檔案,而不會輸出對應的判定標籤
# ➜ mmdt-classify . 0.8 1
#   ...
#   ./APT28_5,1.000000,group_apt28,39.660364
#   ./APT28_2,0.992930,group_apt28,44.917703
#   ./APT28_23,1.000000,group_apt28,39.682770
#   ...
# 注意:缺失mmdt_feature.label檔案時,只會輸出是否匹配,而不會輸出對應標籤
# ➜ mmdt-classify . 0.8 1
#   ...
#   ./APT28_5,1.000000,matched_0,39.660364
#   ./APT28_2,0.992930,matched_0,44.917703
#   ./APT28_23,1.000000,matched_0,39.682770
#   ...
$ mmdt-classify $file_or_path $sim_value $classify_type

python_mmdt的核心功能,實現未知樣本的快速識別。mmdt-classify . 0.8 1表示對當前目錄下的檔案進行分類,分類判定分值設定為0.8,分類演算法採用1(簡單分類演算法)。

結束

本篇主要介紹了python_mmdt的一種簡單分類應用。在實際使用簡單分類器時,python_mmdt會將特徵向量集合轉成簡單分類特徵庫,通過查詢相等的索引雜湊,計算對應mmdt_hash的相似度,滿足判定分值,則返回判定結果。利用python_mmdt,可以實現自動特徵的提取、積累、複用,通過不斷的積累,期待實現“見過即可查”的目標。

如果惡意程式碼分析人員,可以共建一個mmdt_hash特徵向量庫,一定可以大大方便惡意程式碼分析這件事。設想一下,每個特徵向量20個位元組,1億條特徵向量的集合大小也就2G左右,1億條特徵向量可以檢出的惡意程式碼數量可能達到上百億,上千億,提供的保護覆蓋面就廣闊的多了。更重要的,共享的mmdt_hash值也不會導致原始檔案資訊的洩漏,但卻能提供非常有價值的資訊。

另外,目前python_mmdt直接對壓縮包型別的檔案計算敏感雜湊,其mmdt_hash值常常不可用,後續會嘗試對壓縮包進行解壓縮,計算實際檔案。當前使用雜湊索引匹配的的方式,雖然效率高,但是漏報率也高。後續會嘗試使用KNN演算法對特徵向量集合進行計算,提高基檢出率。

相關文章