<menu id="guoca"></menu>
<nav id="guoca"></nav><xmp id="guoca">
  • <xmp id="guoca">
  • <nav id="guoca"><code id="guoca"></code></nav>
  • <nav id="guoca"><code id="guoca"></code></nav>

    【技術分享】如何編寫有效的Yara特征

    VSole2021-07-20 16:11:57

    概述

    筆者在去年夏天學習和分析CobaltStrike時編寫了一篇yara入門的文章,算是填坑,在此文中記錄下一些常見的編寫思路。

     

    PDB路徑

    PDB文件是在程序編譯時產生的,它記錄了程序的符號表,通過PDB,我們可以很方便對目標程序進行調試。

    #程序編譯時分為Private Build和Public Build。#private build 表示開發人員在自己的電腦上進行coding和build,此時編譯后的程序和pdb在相同的路徑下。#Public build  表示開發人員在公用的電腦上進行build,在這種情況下,還需一個symbol server以存儲所有程序的pdb,當用戶程序報錯,debugger才能根據symbol server自動找到報錯程序所對應的pdb,加載符號以方便程序員進行調試
    

    pdb信息一定是和生成的程序同名的,若生成的程序名為: normal.exe 那么對應的pdb一定為: normal.pdb。

    當調試器加載目標進程的pdb時,調試器首先會嘗試查找與程序同名的pdb文件,若成功找到目標pdb,調試器則會檢查嵌入到PDB和目標進程中的GUID是否匹配,匹配則成功加載,不匹配則加載失敗。由于GUID計算時會使用時間因子,所以pdb和程序總是一一對應的。

    還是以上面的簡單代碼為例,在加載pdb之后,可以最大程度的還原符號表,提升分析效率

    了解了pdb的作用和基本原理之后,下面來看看在樣本查殺和hunting中pdb發揮的作用。

    #需要稍微區分下hunting和查殺的區別#通常在樣本hunting時可以將特征寫的寬泛一些,因為hunting的目的是盡可能的根據當前的信息去尋找更多的樣本,在這種情況下,是允許誤報并且可以由特征編寫人員去人工判定誤報的。#而查殺,也就是惡意代碼查殺方向,對特征的要求會比較高,通常不能接受誤報,特征編寫人員需要把握好查殺率和誤報率之間的平衡。
    

    一般來說,在分析中遇到的pdb信息有如下幾類

    1、普通pdb名,可完全匹配pdb,以pdb信息作為查殺條件。

    2、以pdb路徑中的部分信息作為過濾條件,快速過濾掉不相干樣本。

    3、無字面意義pdb,如文件名稱為隨機字符串,此類pdb最好不好選做特征,否則將會變成單殺特征。

    4、帶人名/盤符/路徑/日期/等信息的有價值pdb,此類pdb有可能是攻擊者不小心留下來的,價值較高。

    5、誤導性pdb,有的pdb信息不僅無用,還會誤導分析人員。

    普通pdb

    以最近又異常活躍的Dridex為例,筆者在分析其中一個樣本時發現樣本中保留的pdb信息如下:

    這里只是一個孤零零的pdb名稱,并無路徑信息,且此pdb名稱并無實際意義,在vt上對此信息進行檢索,能查到大批相關樣本(從文件大小可以看出這些樣本其實是相同的,可能只修改了極少的字節所以有了不同的md5,這里只是用它們舉一個簡單的例子)

    關于Dridex相關的樣本,MalawareBazaar上面倒是又不少,這里剛好可以借助其進行練習。筆者之前根據bazaar提供的API接口寫了個簡單的腳本用于批量查詢樣本并獲取基本信息,效果如下

    免費注冊bazaar之后將會得到一個APIkey,將自己的APIkey填充到下面的腳本中即可,調用方式為:

    python3 get_bazaar_samples_info.py

    比如要得到上面csv中的內容,輸入

    python3 get_bazaar_samples_info.py Dridex 10

    import sysimport requestsimport osimport jsonimport csvimport datetime
    
    def getbaseinfo(tag,limit):    getdate = datetime.datetime.now().strftime('%Y-%m-%d')    csvFileName = getdate + "_" + tag + '.csv'    f = open(csvFileName,'w',newline='',encoding='utf-8')    csv_writer = csv.writer(f)    csv_writer.writerow(['sha256_hash','md5_hash','first_seen','file_name','file_size','file_type','signature','tags','clamav'])
        headers = {'API-KEY':'your API key'}    data = {        'query':'get_taginfo',        'tag':''+tag+'',        'limit':''+limit+''    }    response = requests.post('https://mb-api.abuse.ch/api/v1/', data=data,headers=headers)    json_response = json.loads(response.content)    samples_info  = json_response['data']    for sample in samples_info:        hash256 = sample['sha256_hash']        md5 = sample['md5_hash']        first_seen = sample['first_seen']        file_name = sample['file_name']        file_size = sample['file_size']        file_type = sample['file_type']        signature = sample['signature']        tags = sample['tags']        intelligence = sample['intelligence']        if 'clamav' in intelligence.keys():            clamav = intelligence['clamav']        else:            clamav = ""        csv_writer.writerow([hash256,md5,first_seen,file_name,file_size,file_type,signature,tags,clamav])    f.close()    # print(json_response['data'][0]['md5_hash'])if __name__ == '__main__':    if len(sys.argv) < 3:        print("Usage: python3 get_bazaar_samples_info.py  ")        quit()    tag = sys.argv[1]    limit = sys.argv[2]    getbaseinfo(tag,limit)
    

    同樣的,也可以根據bazaar提供的API接口完善腳本,實現查詢之后自動從bazaar上下載樣本并解壓到本地。

    樣本下載回來之后,按照大小排序,可以看到一共有三類樣本,分別是162kb大小、160kb大小和159kb大小。三類樣本對應的pdb信息分別是 Gsp.pdb、fffp4.pdb、Gsp.pdb

    此時,光通過fffp4.pdb這個信息已經不足以匹配完我們視野范圍內的Dridex樣本了,這也是光以pdb信息作為特征點的一個局限性:通用性較差,很有可能查不了代碼沒怎么改變的變種樣本。

    通過pdb過濾

    上面樣本遇到的fffp4.pdb,通過google引擎檢索之后只有6條相關結果,且出來的結果都是沙箱相關的檢測報告,點進去發現對應的樣本的確是屬于Dridex的惡意樣本,因此可以考慮以fffp4.pdb作為一條特征。

    但是更多的時候,我們可能在樣本中會遇到名字普普通通的pdb名稱,此時再用pdb作為特征就明顯不合適。以ebb83160e97ea11f46057a92f16e37ec樣本為例,該樣本所包含的pdb名稱為debug.pdb

    debug.pdb這個名字較為常見,此時若是以該名字作為特征明顯不合適,但是這里可以注意到,一般情況下,正常程序的pdb信息是完整路徑,而不是像這個樣本中孤零零的一個文件名。所以正常程序的debug.pdb前面應該是路徑中的斜杠而不是00,因此可以加上00在vt上進行connect搜索:

    搜索結果返回回來全是惡意程序,但這并不意味著可以直接以這段hex作為特征,我們將搜索結果限制在報毒數小于10可以看到就出現了一些白樣本

    因此,此類pdb可以作為一個篩選過濾條件。

    再來看看另一批樣本,原始樣本中的pdb信息如下

    在只有一個樣本或是一批相同樣本的情況下比較難利用此pdb信息做文章,筆者在分析和關聯之后,定位到了同源,但是擁有不同pdb的樣本,信息如下

    經過簡單的關聯分析之后,很快可以得到結論,該家族的樣本binIE\MiniIE2.pdb 的信息不會變,前面的盤符和code_路徑有可能改變,但若只匹配binIE\MiniIE2.pdb 還是有一定幾率的誤報,所以可以以該段hex數據作為過濾條件,加上部分的實際代碼抑制誤報。

    無意義pdb

    嚴格意義上來講,上面提到的fffp4.pdb也算是無意義pdb,因為將該pdb信息寫成yara特征,掃描回來的樣本必然是大同小異的,或者說代碼段幾乎完全相同,在這種情況下,看似是pdb信息起了作用,實際上隨便取一段代碼的opcode做特征效果也一樣。

    還有一種筆者認為的無意義pdb是隨機字符串pdb,如下所示:

    此類pdb沒有路徑等信息,基本上只會出現一次,就算通過該信息關聯到了樣本,情況和上面的fffp4.pdb也大致相同。

    高價值pdb

    “高價值”pdb信息通常出現在高級威脅追蹤與分析中。

    以BITTER為例,部分樣本殘留了pdb信息:

    C:\Users\ARAGON\Documents\Visual Studio 2008\Projects\DownWin32\Release\DownWin32.pdb

    C:\Users\UserA\Documents\Visual Studio 2008\Projects\Artra\Release\Artra.pdb

    雖然此類樣本pdb信息不相同,代碼也相差甚遠,但是pdb的命名風格卻較為相似。

    C:\Users{UserName}\Documents\Visual Studio 2008\Projects{demoName}\Release{DemoName}.pdb

    從上面兩個樣本來看,可變部分是上面橙色標記的幾個值,但是這里不妨猜測,Visual Studio的版本后面也會變,所以可以編寫一條正則特征,用于檢測包含了下面這種模式pdb的樣本

    C:\Users{UserName}\Documents\Visual Studio {2008}\Projects{demoName}\Release{DemoName}.pdb

    后面的樣本也能佐證這條特征的合理性:

    繼續分析,還能看到有的樣本中加入了時間因子,這里的28Nov應該是表示11月28,我們可以對比分析作者信息不相同的樣本,慢慢找到BITTER中不同人員的分工,以及他們的共用代碼。

    錯誤pdb

    一個典型的錯誤pdb是msf框架所生成的meterpreter的payload。

    #常見的msf馬有兩種#一類是patch入口點,創建線程執行shell code之后跳轉到原始的入口點繼續執行。#一類是將入口點完全替換為msf的shellcode,此類樣本會直接通過多個跳轉動態解密執行。
    

    msf默認生成的meterpreter樣本尾部有一個pdb路徑叫做:C:\local0\asf\release\build-2.2.14\support\Release\ab.pdb

    這里的pdb其實不是msf自身的pdb,而是Apache提供的性能檢測工具ab.exe的pdb信息。

    patch ab.exe是msf的常見手法,通常來說,msf生成的meterpreter還會保留ab.exe的版本信息,筆者暫未閱讀過msf的源碼,所以猜測起初可能是為了增加樣本的免殺性,但是目前在免殺方面已經沒什么效果,可能可以迷惑一下初級的樣本分析人員

    雖然這里的pdb路徑不在正常的位置的,IDA載入文件時也不會提醒加載pdb,但是yara作為全文掃的引擎,不能指定pdb出現的位置,為了避免誤報,所以不能取這樣的pdb作為特征。

    關于PDB,暫時說這么多,總的來說,樣本中殘留的pdb信息有時可以比較好的幫助我們完成溯源、關聯等工作。但是不適合作為特征,可以在yara中作為一個可選條件。

     

    互斥體

    和pdb一樣,互斥體大多數時候并不能直接作為查殺特征甚至是hunting特征,只是在深入分析某個組織,構建TTPS時可以起到一定的作用。

    大多數惡意軟件感染計算機之后會通過計劃任務、開機啟動注冊表、啟動項等方式實現本地持久化,但是像計劃任務啟動這種方式有可能會倒是程序多開,過多的進程名可能會引起用戶或運維人員的注意,為了避免此類情況,攻擊者有時候會創建互斥體以保證樣本在主機上只有一個實例運行。

    惡意軟件常見的互斥體有以下幾類

    1、獲取當前的計算機基本信息計算出一個ID,以該ID作為互斥體名

    2、硬編碼在代碼中的互斥體名,如程序名、C2地址、地名、小說人物名、隨機亂碼名

    3、仿冒正常程序的互斥體名。

    互斥體取名相對來說比較”困難”,為了避免不同版本的惡意軟件感染同一個主機并在主機上同時運行,攻擊者通常需要選用多個版本同時適用的互斥體名。

    比較直接的做法是獲取用戶主機的計算機名、用戶名等信息通過固定的算法生成一個ID用于標識受害者主機,這個ID可以作為互斥體名,同時也可以作為請求頭中的id,發送上線標識包。

    還有一個簡單的做法是以請求域名作為互斥體名稱,這樣可以保證,與同一個C2通信的樣本不會重復運行。

    不過大部分的惡意軟件開發者會選擇實用隨機字符串作為互斥體名,這可能是他們沒有考慮版本更新方面的問題,也有可能是有意為之。

    隨機字符串

    以Clop勒索軟件為例(7edc821c3b46e85f262a96182ed2de86),樣本運行后會在線程中創建名為

    FSKJHFOJKW#^^^66^6

    的互斥體,經過搜索引擎和VT可得知該互斥體名為隨機生成,并無實際意義,所以不能作為樣本特征。

    以Clipper家族的樣本為例,同一批樣本,代碼結構很相似,但是創建的互斥體名也是不同的,這里的互斥體名也是通過隨機字符生成,不能作為特征點或是關聯分析的關鍵點。

    請求域名

    以05690a450fea902744c9f7560a999267樣本為例,樣本運行后,會創建名為

    qq2009.3322.org

    的互斥體名

    通過VT也可以看到,的確有很多樣本請求了該域名

    因此,類似于這種以域名作為互斥體名的樣本,是可以考慮直接以互斥體名(域名)作為特征的,但是這個特征說是查互斥體名,其實也是查域名,通用性相對來說也較差。

    偽裝

    在上面講pdb的時候講到了有的惡意軟件會偽裝正常軟件的pdb信息以迷惑用戶,互斥體也不例外。

    以e6fcdc19924db03a6c2c026c7992344b樣本為例,樣本運行后會創建名為chromiumUndate的互斥體名。

    這里的互斥體名很明顯是仿冒了Chromium更新程序名,此外,攻擊者還仿冒了Chromium的版本信息

    并且特意保留了仿冒Chromium的pdb信息,希望通過這三層信息迷惑用戶或是迷惑初級分析人員

    此類樣本的特征是相對危險的,在提取時需要格外注意。

    計算生成

    通過收集本地主機信息計算ID作為互斥體名的一般是高級威脅所涉及的樣本。

    這里又會分為兩類

    1、 直接在樣本中獲取指定信息,計算,然后生成互斥體名。

    2、 上一階段的樣本獲取信息并計算ID傳入到C2,C2根據此ID生成對應的樣本。

    通過這種方式,較難根據互斥體名進行溯源或是主動關聯其他樣本,但是我們可以收集和記錄,在遇到該家族其他樣本時進行被動關聯。

    關于此類互斥體名,已經脫離了靜態特征的范疇,在此節中不進行深入討論

    互斥體pdb
    本作品采用《CC 協議》,轉載必須注明作者和本文鏈接
    筆者在去年夏天學習和分析CobaltStrike時編寫了一篇yara入門的文章,算是填坑,在此文中記錄下一些常見的編寫思路。
    殺軟淺析
    2021-11-18 13:08:56
    本文將和大家一起淺析常見的殺軟,如有不足之處還請師傅們指出,謝謝大家。
    DarkBit勒索軟件分析
    2023-05-15 09:10:03
    json內容包括:文件大小限制:最小為25MB,最大為6GB,不同大小的文件被分成不同的部分,每個部分的大小也不相同。如 1000MB 到 4000MB 的大小的文件,被分為3部分,每部分大小不超過 10000 字節。DarkBit 會單獨加密這些較小的部分中的每一個,而不是一次加密整個文件。文件擴展名限制:排除特定的文件擴展名。利用 Go_Parser 解析 runtime 庫,把生成map文件導入到 x64dbg 檢測處理器是否為
    創建子線程,休眠 2147367705ms后殺死當前主進程。嘗試解析“microsoft.com”的ip,如果解析不成功則殺死進程。一些反調試的操作。通過子線程獲取一些系統信息包括系統的bios版本,核心名等,在system32目錄下寫入文件并創建系統服務通過遍歷進程列表找到進程中到的指定程序,然后通過發送代碼直接到指定驅動程序,實際釋放為gmer64.sys程序。
    EasyPersistent是一個用于windows系統上權限維持的Cobalt Strike CNA 腳本。腳本整合了一些常用的權限維持方法,使用反射DLL模塊可使用API對系統服務、計劃任務等常見權限維持方法進行可視化操作。使用時請注意HKLM和HKCU位置,x86和x64的不同;
    新發現的與越南威脅行為者相關的惡意軟件通過 LinkedIn 網絡釣魚活動以用戶為目標,竊取數據和管理員權限以獲取經濟利益。
    本次一共截獲了兩個和KingSqlZ組織有關的可疑樣本。
    誰在調試我的代碼?
    2022-01-10 07:07:45
    反調試策略方案
    勒索病毒的深度分析
    VSole
    網絡安全專家
      亚洲 欧美 自拍 唯美 另类