標籤:

用於學習惡意軟體分析的最佳編程語言

譯文聲明本文是翻譯文章,文章原作者MalwareTech,文章來源:

原文地址:malwaretech.com/2018/03

在過去,許多人會經常問我一個問題:「我想要入門惡意軟體分析和逆向工程領域,應該學習什麼編程語言?」為了回答這個問題,我將詳細講解我認為最適合的前三種語言,希望大家可以通過閱讀本文找到自己認為最有用的語言。在本文中,我將重點討論本地惡意軟體(也就是不需要Java、Python或.NET等框架就能直接運行的惡意軟體),因為這是最常用的類型,如果能夠理解了這一類型,那麼對其他類型的惡意軟體也就變得輕車熟路。本文將不會涉及物聯網或移動惡意軟體的相關內容,因為我對這一領域並沒有太多的經驗。

第三名:Python

Python是一種具有多種用途的語言,當我需要快速完成某些工作時,我會選擇使用Python語言。雖然其他幾種語言的開發速度很快,但我發現Python具有可讀性高、可快速開發、易於學習的優點。由於Python是一種解釋型語言,所以解釋器可以為我們完成不同操作系統之間的所有轉換,因此我們僅需要編寫一次代碼就可以一勞永逸,而我們的代碼可以在任何操作系統上運行。儘管我是一位Linux伺服器的忠實粉絲,但我還是使用Windows作為日常主要使用的操作系統。因此,如果能在我的Windows上面編寫並測試代碼,然後在完成後將其上傳到伺服器上,這樣就會特別方便,而不再需要嘗試通過PuTTY終端開發和測試代碼。

惡意軟體分析

我最喜歡的一個Python的用途就是快速複製惡意軟體的組件,以便更好地理解其工作方式,並獲得惡意軟體自身的介面,從而實現更快速的分析。我的TrickBot工具包就是一個很好的例子,它能有助於解決逆向模塊化惡意軟體時所遇到的一些問題。

我在研究TrickBot的過程中,遇到的一個主要問題就是它會使用被黑客入侵的伺服器來控制惡意軟體,當然,其中大部分伺服器都會很快就關閉。在獲得新樣本後的幾天之內,所有硬編碼的控制伺服器都會發生死機,並且樣本開始失效。在對惡意軟體所使用的加密和解密代碼進行分析之後,我可以編寫一個簡單的Python腳本,該腳本可以允許我解密並修改任何TrickBot的配置文件,我通過這些文件來編輯主配置文件,並為其指定新的控制伺服器,這些控制伺服器是其他惡意軟體分析者在網路上發布的。

我寫的另一個腳本是用於命令與控制的基礎結構介面,該腳本可以幫助我在不運行惡意二進位文件的前提下,就能獲取到命令、有效載荷以及新的伺服器地址。如果我們非常注重個人主機的風險防範,那麼可能不希望在連接到互聯網的系統上運行惡意軟體。相反,通過Python來離線分析惡意軟體並重新實現需要訪問互聯網的代碼,這是非常有意義的。我們可以完全控制惡意軟體的功能,使其不再發送真實數據,甚至是發送蜜罐憑據。

調試器擴展

通常,分析任務往往是枯燥、無聊的,並且需要耗費大量的時間,所以如果能識別這些任務並使其自動化完成,那麼將會非常有幫助。我所使用的每個調試器和反彙編器都有自己的內置語言腳本,但如果我們使用多個調試器或反彙編器,那麼恐怕就需要學習大量不同的腳本語言,這是沒有意義的。但幸運的事,幾乎所有的調試器或反彙編器都支持Python。

以前我寫過一篇文章,主要講解了如何使用Python實現任務的自動化,在文章中我是以IDA Pro為例的。在我的分析中,我使用了Python對Dridex系列進行自動解密、評論和轉儲加密字元串。此外,我還展示了如何使用它來處理只能在調用時才能解析的問題,這樣使得靜態分析更為簡單。

在上面的示例中,腳本會遍歷Dridex二進位文件中的每個加密字元串。然後進行解密,並轉儲每個字元串,在這過程中不需要運行惡意軟體。

任務自動化

Python以其擁有大量可下載的庫而聞名,它實現了各種不同的功能,可以讓用戶無需從頭開始編寫代碼,就能夠在計算機上高效地自動執行幾乎任何任務。使用Python進行任務自動化,不僅僅適用於惡意軟體的分析,對其他許多方面的工作都很有用。我編寫過腳本來檢查命令與控制域、在VirusTotal上傳或查詢文件、載入用於分析惡意軟體的虛擬機等。Python是編程界的瑞士軍刀,值得我們對其進行學習,並用於分析惡意軟體。

第二名:C

對於作者而言,C語言是我在12歲開始學習相關技術之後,第一個熟練掌握的編程語言。由於我的夢想是成為一名程序員,因此我學習C的初衷並不是想研究逆向工程,也沒有想到我學到的知識會在如今作為惡意軟體分析工作的基礎。儘管我並不會堅持讓你掌握C語言,但我會在本文中提出如何閱讀和理解的相關建議,這對於惡意軟體分析來說是有所幫助的。

查看官方文檔

即使對於一個經驗豐富的逆向工程師,有時也會遇到不熟悉的某個惡意軟體代碼中的函數調用。如果想要了解該函數的功能、參數、如何對其初始化、返回什麼結果,那麼最好的方法就是調出文檔並進行閱讀。

例如,我們在Windows和Linux文檔中查看「connect」函數。

在這兩種環境下,函數的定義都是用C語言寫成的(儘管左邊的MSDN文檔中說是C++,但實際上就是C語言)。在C中,傳遞給函數的每個參數都有一個「類型」,它只是指定其所包含的數據類型(數字/文本/二進位數據)。在示例中,第三個參數都是「sockaddr」類型,這是一個常見的C語言中的類型。如果能了解「sockaddr」是什麼,我們就能夠知道它需要什麼數據、如何對其進行引用以及如何對其進行解釋。由於「sockaddr」是一個結構,我們必須首先查找sockaddr的定義,找到它的數據類型,然後查找每個單獨的數據類型,這實際上也是學習C語言的過程。MSDN中也經常提供示例C語言代碼,來解釋一個函數中的用法,閱讀這些代碼是了解函數之間關係的一種快速而有效的途徑。

無官方文檔的情況

對於像Microsoft Windows這樣的閉源操作系統,就有很多沒有記錄的數據結構和功能,其原因通常是它們不應該被除微軟之外的任何人使用。這些數據結構和功能通常被稱為Windows內部機制。惡意軟體開發者喜歡濫用內部機制來繞過安全控制,或者是為了迷惑惡意軟體分析師。為了了解其內部結構,儘管我們可以對操作系統自身進行逆行工程,但該過程耗時過多且異常困難。然而,如果我們掌握了C,就有一個更快的方式。

(1) ReactOS源代碼

ReactOS是一個用C語言編寫的開源操作系統,旨在與Windows Server 2003可執行文件相兼容。為了保證與Windows二進位文件的兼容性,開發人員必須對NT 5.2(用於Windows 2000、Windows Server 2003和Windows XP的Windows操作系統核心版本)進行逆向工程並重新實現,因此許多Windows中的相關機制都可以通過ReactOS來了解。由於Windows XP仍然佔有較大的市場份額,因此惡意軟體開發者仍然會為了使他們的惡意軟體兼容XP,而付出很多的努力,所以我們很難看到不支持5.2內核的惡意軟體。就我個人而言,我藉助ReactOS源代碼來了解Windows內部知識,這樣我就可以在真正的Windows操作系統上成功使用它了。

(2) Windows研究內核

Windows Research Kernel(WRK)是微軟為研究人員提供的NTOS內核源代碼的一個子集,其中包含大部分核心內核的源代碼,但也有一部分內容被刪除。儘管WRK僅包含Windows的內核部分,但它仍然可以用於幫助我們理解非內核的惡意軟體,因為內核的某些部分經常被Rookie濫用的「Native API」暴露給用戶級應用程序。最初,WRK很難獲得,只作為各種計算機科學研究計劃的一部分提供給經過認證的大學,但從那時開始,一些舊版本陸續被發布到GitHub,因此微軟決定公開發布。儘管WRK不像ReactOS那樣完整,但它還是具有一些優點,例如包含64位Windows內核的代碼,並且它是由Microsoft編寫的實際代碼,並不是通過逆向工程而製作的副本。

泄露的惡意軟體

要了解惡意軟體工作模式並在逆向工程中讀取實際惡意軟體的源代碼,最好的方法之一就是閱讀真實惡意軟體的源代碼。顯然,惡意軟體開發者並不會輕易公開源代碼,所以我們不可能獲得大部分惡意軟體的源代碼。但是,一些龐大的惡意軟體家族的源代碼會在某個時間節點被披露(例如Zeus、Mirai、Carberp、ISFB、Rovnix)。大部分泄漏的惡意軟體源代碼都可以在GitHub找到,但我建議最好避免下載這些代碼,因為其中可能會存在感染計算機的威脅。請注意,在某些國家,擁有惡意代碼甚至可能違反法律。

IDA Pro偽代碼

帶有反編譯器的完整版IDA Pro中有一個選項,可以將程序集顯示為「偽代碼」,這會導致它提供與程序集相匹配的代碼。

雖然IDA偽代碼在技術上並不是100%有效的C語言代碼,其中有著細微的差別,但對於任何能閱讀C語言的人來說,該偽代碼都是清晰可讀的。偽代碼可以讓我們快速了解代碼的功能,可以有效節省時間。

第一名:彙編語言

彙編語言(ASM)是每一位逆向工程師的工具箱中最重要的一個工具,它是機器碼的人類可讀版本,是計算機CPU實際理解的唯一語言。任何在沒有解釋器的情況下在計算機上運行的代碼,都必須被編譯成機器代碼,機器代碼是一組0、1指令,該指令告訴CPU要做什麼。像C、C++、GoLang、Pascal和Haskell這樣的語言,都會被編譯(翻譯)成機器代碼,因此大多數軟體(包括惡意軟體在內)都可以使用反編譯器(將機器代碼翻譯成人類可讀版本的彙編語言)。如果你能夠很好地閱讀彙編語言,那麼就不需要使用高級語言,直接可以分析彙編語言的代碼。同樣,這一技能在惡意軟體分析之外的很多地方都非常有用。

然而,因為彙編語言只是一個人類可讀版本的機器代碼,由於不僅僅有一種機器代碼,所以也不僅僅存在一種彙編語言。不同類型的CPU會接受不同類型的指令,當你學習彙編語言時,其實只是在學習CPU所支持的指令內容(稱為指令集)。在學習彙編語言之前,我們應該首先選擇要學習的彙編語言指令集。目前,有兩個在傳統計算機上非常常見。

i386

英特爾Inter 80386,簡稱為i386,是x86指令集的32位版本,幾乎用於所有的32位桌面計算機、伺服器和筆記本電腦之中。運行Windows、Linux或Mac的計算機,如果是32位的,那麼CPU就很可能是基於i386。由於這是最常見的指令集,因此如果有人在說到「彙編」時,可能就是在指i386。

當Microsoft開始設計64位操作系統時,他們遇到了很大的麻煩,因為他們需要確保32位(i386)應用程序仍然可以正常工作。目前,大多數Windows惡意軟體開發者只編寫32位惡意軟體,因為它可以同時在32和64位操作系統上運行。即使在64位Windows上,大多數惡意軟體仍然是基於i386,因此這也是我推薦的指令集

x86_64

這是x86的64位版本,也是現代計算機中較為常見的指令集。由於x86系列中的體系結構都保持了強大的向後兼容性,因此所有x86_64 CPU都可以執行i386指令,而大多數64位指令與i386指令非常相似,因此首先學習i386彙編,然後再學習x86_64是有意義的,因為x86_64指令集本質上包括i386。

雖然64位Windows可以運行i386應用程序,但其他操作系統並不支持,因此所有本地代碼都必須是x86_64。更高級的Windows惡意軟體系列通常會在64位Windows上部署64位版本的代碼,並且所有內核模式函數都是64位的,因此x86_64彙編語言對於了解i386也是非常有價值的。

結論

如果此前沒有程序設計經驗,要轉型成為惡意軟體逆向工程師並不是很容易,但學習編程的這一過程能有非常多的收穫。如果我們掌握編程語言(特別是彙編和C語言等),那麼就可以更快地學習其他語言,並能更好地掌握計算機的工作原理。編程是市場化程度最高的一個計算機相關技能,即使最後沒有成為惡意軟體分析師,我們也可以藉助該語言進行編程,所以希望大家不要覺得為了開始分析惡意軟體而學習一種程序設計語言是非常麻煩的行為。

本文是翻譯文章,文章原作者MalwareTech,文章來源:

原文地址:malwaretech.com/2018/03


推薦閱讀:

Gold Dragon:針對冬奧會的惡意軟體

TAG:惡意軟體 |