概述
上篇文章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.label
和mmdt_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.label
和mmdt_feature.data
檔案拷貝到python_mmdt
的安裝路徑,命令如下:
- 拷貝特徵向量集檔案:
mmdt-copy mmdt_feature.data
- 拷貝特徵向量集對應標籤檔案:
mmdt-copy mmdt_feature.label
特別注意:
mmdt_feature.label
和mmdt_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演算法對特徵向量集合進行計算,提高基檢出率。