逆向工程入门
逆向工程 REVERES
交流逆向工程相關知識 +Q1906661021
后續文章:https://blog.csdn.net/m0_46276093/article/details/121224223
首發于 Th0r安全公眾號
1.逆向工程簡介及發展方向
軟件逆向工程是一種探究應用程序內部組成結構及工作原理的技 術. 運用逆向分析技術, 窺探程序內部結構, 掌握其工作原理.
– 《逆向工程核心原理》
逆向工程,顧名思義,將已經完成的程序經行反編譯以找到其內部隱藏細節的過程,我們將其稱之為逆向工程
第一步,我們將通過各種信息收集工具,對要進行逆向分析的程序進行信息處理
第二步,我們將存在保護的目標程序經行去加密,并且備份其源文件
第三步,將目標程序拖入靜態分析或動態調試軟件中經行處理(代碼審計或debug)
第四步,對收集到的信息進行整合,給目標程序打補丁,實現我們的目的
在CTF比賽中
逆向工程是CTF比賽中一個重要的方向
涵蓋了Windows逆向,Linux逆向,Android逆向,密碼學逆向等諸多方面,對程序代碼進行審計,在關鍵的位置為程序打上補丁,繞過一些復雜的花指令,逆向工程無疑是最具技術含量的工作,但也因為其本身難度之高,一個好的逆向手是團隊中最稀缺的人才。
逆向工程還是pwn方向的前置知識儲備
所謂“知己知彼,百戰不殆”,如果說pwn是信息安全世界中最鋒利的武器,那逆向工程就是幫助它識破敵人弱點的銳利眼眸。在進行數據溢出攻擊之前,我們要用逆向工程的手法,分析目標程序,找到其關鍵弱點,一擊致命。我們可以說逆向是為pwn服務的工具,也可以說pwn是長了牙齒的逆向工程。
密碼學逆向的獨特之處
CTF中,有一部分逆向工程的題目,其本身流程并不復雜,但用到了高級的密碼學加密方式,我個人稱這種逆向題目為“密碼學逆向”,不需要你有很高的程序閱讀能力,但是要找出是哪種加密方式,有怎樣的特征值,卻是個極其艱巨的任務,所以在遇到這種題目的時候,逆向手往往要和密碼學方向合作或者自學密碼學。
以上三點也是比賽中逆向工程細分后,供大家選擇的三個方向:代碼審計逆向,PWN逆向,密碼學逆向
在現實生活中
破解軟件的基本原理
軟件的破解版,它們都是怎么來的?又是進行了怎樣的操作才把復雜的驗證機制無效化?
答案是逆向工程
在破解軟件時,需要借助各種方法,繞過軟件本身自帶的自我驗證機制,和通過后臺服務器的網絡驗證機制
給軟件打上補丁,白嫖free XD
病毒防范,“亡羊補牢”
殺毒軟件的病毒庫是怎么構建的?截獲病毒后該如何處理?
答案還是逆向工程
當電腦受到病毒入侵后,保留完整病毒樣本,并對他們進行功能和邏輯分析,找出其特征值,對其進行封裝隔離;找到其主要攻擊的位置預防下一次攻擊時可能的數據丟失。
雖是亡羊補牢,可能也為時未晚
2.主要逆向工具
各種逆向工具簡介
1.編碼轉換及解密工具
編碼轉換工具是信息安全中最常用的工具,因為題目所給出的“答案”為了迷惑我們,經常會使用編碼的方式,隱藏在大量垃圾信息中,防止被輕易發現,因此我們需要對某些有特定編碼規則的字符串經行編碼轉化。
解密工具,因為有密碼學逆向的存在,我們需要去熟悉某些特定的解密方法,并以軟件和網站來輔助我們的解密過程
2.文件類型及查殼
判斷文件類型及查殼工具能幫助我們在開始逆向進行必要的信息收集,幫助我們選擇正確的反編譯及反匯編工具
3.去保護
根據之前收集的信息,為之后的代碼審計做準備,使用相關工具和手段盡可能去除軟件的反編譯保護
4.靜態分析
靜態分析軟件一般采用線性掃描和遞歸遍歷的方法,將已經經過編譯器編譯過生成的可執行文件,反編譯成匯編代碼或偽C語言代碼,在靜態分析這個步驟中,我們將使用靜態分析軟件進一步深入收集目標程序的信息,對目標程序進行修改,理解目標程序的實現邏輯。靜態分析和動態調試是逆向工程的主體部分
5.動態調試
動態調試是逆向工程中的殺手锏,無論多復雜困難的題目,你都能在動態調試中找到解決它的辦法,但動態調試軟件同樣也是逆向工程中最難上手的軟件,通過對逆向深入的學習,當你能熟練地掌握匯編語言基礎和動態調試工具的使用后,你就是一個合格的逆向手了。
3.Windows逆向
Windows逆向工具
在開始講解Windows逆向的具體流程之前,我們先來了解一下我們需要用到的工具
CaptfEncoder
CaptfEncoder是一款跨平臺網絡安全工具套件,提供網絡安全相關編碼轉換、古典密碼、密碼學、特殊編碼等工具,并聚合各類在線工具
HexEdit
HexEditXP是一款實用的文本、代碼編輯工具,多用于二進制、十六進制文本的編輯操作,擁有編輯磁盤文件、編輯大型文件、顏色高亮、添加書簽以及對指定內容進行復制、粘貼、替換等操作,軟件還內置了腳本編輯器功能,方便開發者使用
ExeinfoPe
Exeinfo PE是一款查看PE文件信息的工具,可以查看EXE/DLL文件的編譯器信息、是否加殼、入口點地址、輸出表/輸入表等等PE信息,幫助開發人員對程序進行分析和逆向
die
Detect it Easy是一個多功能的PE-DIY工具,主要用于殼偵測。功能正日益完善,是不可多得的破解利器,支持文件直接拖放,可添加到右鍵菜單,非常方便!Die和peid一樣可以加載插件
FFI
File Format Identifier(超級巡警病毒分析)是一款查殼脫殼工具,同時也是一款病毒分析工具,它可以自動識別文件格式,使用超級巡警的格式識別引擎,集查殼、虛擬機脫殼、PE文件編輯、PE文件重建、導入表抓取(內置虛擬機解密某些加密導入表)、進程內存查看/DUMP、附加數據處理、文件地址轉換、PEID插件支持、MD5計算以及快捷的第三方工具利用等功能,適合病毒分析中對一些病毒木馬樣本進行系統處理。
IDA PRO
交互式反匯編器專業版(Interactive Disassembler Professional),人們常稱其為IDA Pro,或簡稱為IDA。是最棒的一個靜態反編譯軟件,為安全分析人士不可缺少的利器!IDA Pro是一款交互式的,可編程的,可擴展的,多處理器的,交叉Windows或Linux WinCE MacOS平臺主機來分析程序, 被公認為最好的花錢可以買到的逆向工程利器。IDA Pro已經成為事實上的分析敵意代碼的標準并讓其自身迅速成為攻擊研究領域的重要工具。它支持數十種CPU指令集其中包括Intel x86,x64,MIPS,PowerPC,ARM,Z80,68000,c8051等等。
X64DBG
x64dbg 是 Windows 下的 32 64 位調試器,類似 ollydbg
OllyDbg
IDA的使用
想要入門逆向工程,那最正統的路徑便是學習怎樣使用IDA這個軟件,并從這個過程中去學習反編譯的技巧和各種逆向方法
提前準備了一個簡單的C語言程序 reserve_codeblocks.exe,我們從它入手來學習IDA的使用
欸,先別著急,IDA有兩個版本,ida和ida64我們要用哪個來打開這個程序呢?
想進一步熟悉IDA的使用,我們要從題目入手進一步分析
BUUCTF : easyre(基礎)
BUUCTF : reverse_1(字符串中無flag)
BUUCTF : xor (編寫腳本)
s = ['f',0xA,'k',0xC,'w','&','O','.','@',0x11,'x',0xD,'Z',';','U',0x11,'p',0x19,'F',0x1F,'v','"','M','#','D',0xE,'g',6,'h',0xF,'G','2','O'] flag = 'f' for i in range(1,len(s)):if(isinstance(s[i],int)):s[i] = chr(s[i]) for i in range(1,len(s)):flag += chr(ord(s[i]) ^ ord(s[i-1]))#a^b=c 等于 a^c=bprint(flag)常見的加密算法
base64加密
base64主要是將輸入中的每3字節(共 24 bytes)按每 6 bytes分成一組,變成4個小于64的索引值,然后通過一個索引表得到4個可見字符。
char[] Base64Code ={ 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o','p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7','8', '9', '+', '/', '=' };索引表為一個64字節的字符串,如果在代碼中發現引用了這個索引表“ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/” ,那么基本上就可以確定使用了base64,此外,有一些變種的base64,主要是改變了這個索引表。
TEA算法
TEA算法是一種常見的分組加密算法,密鑰為 128 bytes位,明文為 64 bytes位,主要做了32輪變換,每輪變換都涉及移位和變換。TEA的源碼為:
static void tea_encrypt(uint32_t *v, uint32_t *k) {uint32_t v0 = v[0], v1 = v[1], sum = 0, i;uint32_t delta = 0x9e3779b9;uint32_t k0 = k[0], k1 = k[1], k2 = k[2], k3 = k[3];for (i = 0; i < tea_round; i++) {sum += delta;v0 += ((v1 << 4) + k0) ^ (v1 + sum) ^ ((v1 >> 5) + k1);v1 += ((v0 << 4) + k2) ^ (v0 + sum) ^ ((v0 >> 5) + k3);}v[0] = v0;v[1] = v1; }static void tea_decrypt(uint32_t *v, uint32_t *k) {uint32_t v0 = v[0], v1 = v[1], sum, i;sum = (tea_round == 16) ? 0xE3779B90 : 0xC6EF3720;uint32_t delta = 0x9e3779b9;uint32_t k0 = k[0], k1 = k[1], k2 = k[2], k3 = k[3];for (i = 0; i < tea_round; i++) {v1 -= ((v0 << 4) + k2) ^ (v0 + sum) ^ ((v0 >> 5) + k3);v0 -= ((v1 << 4) + k0) ^ (v1 + sum) ^ ((v1 >> 5) + k1);sum -= delta;}v[0] = v0;v[1] = v1; }對TEA的識別也比較容易,在TEA算法中有一個固定的常數 0x9e3779b9 或者 0x61c88647,出現這兩個特征值時可以以此確定TEA算法。
AES分組加密法
AES是常見的分組加密算法,其加解密流程如圖。
AES加密過程涉及4種操作:字節替代(SubBytes),行移位(ShiftRows),列混淆(MixColumns)和輪密鑰加(AddRoundKey)
其中,字節替代過程是通過S盒完成一個字節到另一個字節的映射,S盒和逆S盒具體如下:
如果發現程序中有S盒或者動態生成了S盒,則可以確定采用了AES加密。
RC4加密
RC4加密算法屬于流加密算法,包括初始化函數和加解密函數,函數代碼具體如下:
/* 初始化函數 */ void rc4_init(unsigned char*s,unsigned char*Data,unsigned long Len) {int i=0,j=0;//char k[256]={0};unsigned char k[256]={0};unsigned char tmp=0;for(i=0;i<256;i++){s[i]=i;k[i]=key[i%Len];}for(i=0;i<256;i++){j=(j+s[i]+k[i])%256;tmp=s[i];s[i]=s[j];//交換s[i]和s[j]s[j]=tmp;} } /* 加解密 */ void rc4_crypt(unsigned char*s,unsigned char*Data,unsigned long Len) {int i=0,j=0,t=0;unsigned long k=0;unsigned char tmp;for(k=0;k<Len;k++){i=(i+1)%256;j=(j+s[i])%256;temp=s[i];s[i]=s[j];//交換s[i]和s[j]s[j]=tmp;t=(s[i]+s[j])%256;Data[k]^=s[t];} }可以看出,初始化代碼對字符數組s進行了初始化賦值,且賦值分別遞增,之后又對s進行了256次交換操作。通過識別初始化代碼,可以判斷為RC4算法。
MD5消息摘要算法
MD5消息摘要算法,是一種被廣泛使用的密碼散列函數,可以產生一個128位的散列值,用于確保消息傳輸的完整性和一致性。MD5加密的函數大致如下:
MD5_CTX md5c; MD5Init(&md5c); MD5UpdaterString(&md5c,plain); MD5Final(digest,&md5c);其中,MD5Init會初始化四個稱作MD5鏈接變量的整型參數。因此如果看到這4個常數0x67452301,0xefcdab89,0x98badcfe,0x10325476,就可以懷疑該函數是否為MD5算法了。
MD5Init函數代碼如下:
void MD5Init(MD5_CTX *context)/* context */ {context->count[0]=context->count[1]=0;/* Load magic initialization constants. */context->state[0] = 0x67452301;context->state[1] = 0xefcdab89;context->state[2] = 0x98badcfe;context->state[3] = 0x10325476; }總結
- 上一篇: openjdk:8u22-jre-alp
- 下一篇: linux中的信号2——进程如何处理信号