[系統安全] 四.OllyDbg動態分析工具基礎用法及Crakeme逆向破解

您可能之前看到過我寫的類似文章,爲什麼還要重複撰寫呢?只是想更好地幫助初學者瞭解病毒逆向分析和系統安全,更加成體系且不破壞之前的系列。因此,我重新開設了這個專欄,準備系統整理和深入學習系統安全、逆向分析和惡意代碼檢測,“系統安全”系列文章會更加聚焦,更加系統,更加深入,也是作者的慢慢成長史。換專業確實挺難的,逆向分析也是塊硬骨頭,但我也試試,看看自己未來四年究竟能將它學到什麼程度,漫漫長征路,偏向虎山行。享受過程,一起加油~

系統安全系列作者將深入研究惡意樣本分析、逆向分析、攻防實戰和Windows漏洞利用等,通過在線筆記和實踐操作的形式分享與博友們學習,希望能與您一起進步。前文普及了IDA Pro反彙編工具的基礎用法,並簡單講解一個EXE逆向工程解密實戰方法。這篇文章將詳細介紹OllyDbg的基礎用法和CrakeMe案例,逆向分析的“倚天屠龍”,希望對入門的同學有幫助。

話不多說,讓我們開始新的征程吧!您的點贊、評論、收藏將是對我最大的支持,感恩安全路上一路前行,如果有寫得不好的地方,可以聯繫我修改。基礎性文章,希望對您有所幫助,作者的目的是與安全人共同進步,加油~

作者的github資源:

前文分析:


聲明:本人堅決反對利用教學方法進行犯罪的行爲,一切犯罪行爲必將受到嚴懲,綠色網絡需要我們共同維護,更推薦大家瞭解它們背後的原理,更好地進行防護。


一.OllyDbg工具簡介

OllyDbg是一個新的動態追蹤工具,將IDA與SoftICE結合起來的思想,Ring 3級調試器,非常容易上手,是當今最爲流行的調試解密工具之一。它還支持插件擴展功能,是目前最強大的調試工具之一。

OllyDbg打開如下圖所示,包括反彙編窗口、寄存器窗口、信息窗口、數據窗口、堆棧窗口。

  • 反彙編窗口:顯示被調試程序的反彙編代碼,包括地址、HEX數據、反彙編、註釋
  • 寄存器窗口:顯示當前所選線程的CPU寄存器內容,點擊標籤可切換顯示寄存器的方式
  • 信息窗口:顯示反彙編窗口中選中的第一個命令的參數及跳轉目標地址、字符等
  • 數據窗口:顯示內存或文件的內容,右鍵菜單可切換顯示方式
  • 堆棧窗口:顯示當前線程的堆棧

在這裏插入圖片描述

下圖是打開EXE後顯示的界面。

在這裏插入圖片描述


下面簡單講解常用的快捷鍵調試方式。

F2
設置斷點,如下圖所示的紅色位置,程序運行到此處會暫停,再按一次F2鍵會刪除斷點。

在這裏插入圖片描述

F9
按下這個鍵運行程序,如果沒有設置相應的點,被調試的程序直接開始運行。

F8
單步步過,每按一次這個按鍵,將執行反彙編窗口中的一條指令,遇到CALL等子程序不進入其代碼。

在這裏插入圖片描述

F7
單步步入,功能通單步步過(F8)類似,區別是遇到CALL等子程序時會進入其中,進入後首先停留在子程序的第一條指令上。如下圖進入CALL子程序。

在這裏插入圖片描述

在這裏插入圖片描述

F4
運行到選定位置,即運行到光標所在位置處暫停。

CTRL+F9
執行到返回,按下此鍵會執行到一個返回指令時暫停,常用於從系統領空返回到我們調試的程序領空。

ALT+F9
執行到用戶代碼,從系統領空快速返回我們調試的程序領空。

在這裏插入圖片描述


二.OllyDbg分析Crakeme示例1

第一個案例是 《加密與解密》書中Crakeme v3.0的文件,需要解密用戶名和序列號。

在這裏插入圖片描述

點擊“Register now”按鈕,會有輸入錯誤相關的提示,如下圖所示。

在這裏插入圖片描述

OllyDbg動態分析的基本流程如下:

  • 通常拿到一個軟件先試着運行軟件,如果有幫助文檔查閱幫助文檔,熟悉軟件的基本用法,接着嘗試輸入錯誤的註冊碼,觀察錯誤提示。
  • 如果沒有輸入註冊碼的地方,要考慮是否是讀取註冊表或Key文件(程序讀取一個文件中的內容判斷是否註冊),這些可以用其他工具來輔助分析。
  • 如果都不是,原程序只是一個功能不全的試用版,那要註冊爲正式版需要手動寫代碼完善。
  • 如果需要輸入註冊碼,如上圖所示,則調用查殼軟件檢查程序是否加殼(如PeiD、FI),有殼的需要脫殼之後再調用OllyDbg分析調試,無殼的直接調用工具調試。

下面開始正式的分析。

第一步:調用PEiD檢測程序是否加殼。
反饋結果爲“Borland Delphi 4.0 - 5.0”,無殼Delphi編寫的文件。

在這裏插入圖片描述

第二步:運行CrakeMe V3.0文件,並點擊“Register now”,提示錯誤信息。
對話框提示錯誤信息“Wrong Serial, try again!”。

在這裏插入圖片描述

第三步:啓動OllyDbg軟件,選擇菜單“文件”,打開CrackMe3文件。
此時文件會停留在如下位置,雙擊註釋位置能添加自定義註釋。

在這裏插入圖片描述

第四步:在反彙編窗口右鍵鼠標,選擇“查找”->“所有參考文本字串”。

在這裏插入圖片描述

彈出如下圖所示的對話框。

在這裏插入圖片描述

第五步:右鍵選擇“查找文本”,輸入“Wrong”定位“Wrong Serial, try again!”位置。

在這裏插入圖片描述

如下圖所示,定位到“Wrong Serial”位置。

在這裏插入圖片描述

第六步:接着右鍵鼠標,點擊“反彙編窗口中跟隨”。

在這裏插入圖片描述

接着定位到如下圖所示位置。

在這裏插入圖片描述

第七步:選中該語句右鍵“查找參考”-:“選定地址”(快捷鍵Ctrl+R)。

在這裏插入圖片描述

彈出如下圖所示的“參考頁面”。

在這裏插入圖片描述

第八步:雙機上面的兩個地址(00440F79、00440F93),去到對應的位置。

在這裏插入圖片描述

在這裏插入圖片描述

在反彙編窗口中向上滾動窗口,可以看到核心代碼:

在這裏插入圖片描述

第九步:通過查看跳轉到“Wrong serial, try again”字符串的指令,可以查詢相應的程序。
在“調試選項”->“CPU”->勾選“顯示跳轉路徑”及“如跳轉未實現則顯示灰色路徑”和“顯示跳轉到選定命令的路徑”。

在這裏插入圖片描述

如下圖所示:

在這裏插入圖片描述

第十步:詳細分析反彙編代碼。
在下圖中,地址0040F2C處按下F2鍵設置斷點,接着按F9運行程序。

在這裏插入圖片描述

輸入“Test”和“754-GFX-IER-954”,點擊“Register now!”,顯示結果如下圖所示。

在這裏插入圖片描述

程序會在斷點處停止,同時提示剛纔輸入的內容。

在這裏插入圖片描述

輸出內容如下所示,其中內存地址02091CE0中輸入了剛纔的“Test”。

第十一步:左擊“ss:[0019F8FC]=02091CE0,(ASCII “Test”)”,右鍵選擇“數據窗口中跟隨數值”,會在數據窗口中看到輸入的內容。EAX=00000004 表示輸入內容的長度爲4個字符。

在這裏插入圖片描述

第十二步:調用F8按鍵和F7按鍵一步步分析代碼。
回到下面00440F2C這部分代碼,按下F8一步步運行,注意下面的核心代碼。

00440F2C  |.  8B45 FC       mov eax,[local.1]            ;  輸入的內容送到EAX,即"Test"
00440F2F  |.  BA 14104400   mov edx,crackme3.00441014    ;  ASCII "Registered User"
00440F34  |.  E8 F32BFCFF   call crackme3.00403B2C       ;  關鍵點:用按F7進入子程序
00440F39  |. /75 51         jnz Xcrackme3.00440F8C       ;  調走到這裏就錯誤:Wrong serial
...

在這裏插入圖片描述

第十三步:當F8運行到“00440F34 |. E8 F32BFCFF call crackme3.00403B2C”時,按下F7進入CALL子程序,此時光標停留在如下所示位置(00403B2C)。

在這裏插入圖片描述

這裏的PUSH ebx、PUSH esi等都是調用子程序保存堆棧時使用的命令,按F8一步步運行代碼。其核心解釋如下,是基礎的彙編語言:(參考看雪CCDebuger大神的《OllyDBG入門教程》)

在這裏插入圖片描述

重點:程序運行到如下圖所示界面時,可以看到“Test”和“Registered User”的比較。通過上面圖片的分析,我們知道用戶名必須爲“Registered User”。

在這裏插入圖片描述

第十四步:接着按F9鍵運行程序,出現錯誤對話框,點擊確定,重新在編輯框中輸入“Registered User”,再次點擊“Register now!”按鈕,分析調試程序。
注意,F12鍵爲暫停。

在這裏插入圖片描述

核心代碼如下,其中地址00440F34的CALL已經分析清楚,繼續F8執行下一步,知道第二個關鍵地方,即00440F51,按下F7進入子程序。注意:註釋內容的提示不一定存在,需要動態調試程序到寄存器查看對應的註冊碼,纔是正確的做法。

在這裏插入圖片描述

00440F34  |.  E8 F32BFCFF   call crackme3.00403B2C
00440F51  |.  E8 D62BFCFF   call crackme3.00403B2C

上面兩句代碼可以看到用戶名和註冊碼都是調用同一子程序,這個CALL分析方法和上面一樣。

在這裏插入圖片描述

第十五步:按F8調試該子程序,發現cmp比較兩個值是否相等,其中0044102C爲註冊碼內容。

在這裏插入圖片描述

第十六步:按F12暫停,再按F9重新運行,輸入正確的用戶名和密碼,解密成功。

  • Registered User
  • GFX-754-IER-954

在這裏插入圖片描述

難點:調試程序時如何核心代碼,比如這裏的CMP比較,同時彙編代碼也比較晦澀。


三.OllyDbg分析Crakeme示例2

這個案例是破解Crakeme中的Afkayas.1.EXE,這是典型的字符串序列破解程序,根據name的值推出serial。

第一步:通過PEiD檢查它無殼,VB編寫的。

第二步:OllyDbg工具打開Afkayas.1.EXE文件如下圖所示。

第三步:反彙編區域右鍵鼠標,選擇“查找”->“所有參考文本字串”。

第四步:在彈出的對話框中找到失敗的提示字符“You Get Wrong”,右鍵“反彙編窗口中跟隨”。

此時會回到代碼區,可以看到失敗和成果的字符串。

第五步:通常成功和失敗的反饋字符串相隔不遠,需要在之前判斷,如果輸入的serial正確則成功,否則失敗;接着向上找到調用字符串比較函數的入口點。

注意,這一步比較關鍵,但個人覺得需要長時間的經驗和實踐,才能準確定位。

彙編調用函數之前會先把參數入棧,然後用CALL指令調用函數。在字符串比較函數之前有一句 PUSH EAX 指令,可以推測這裏的EAX就是字符串的首地址。

第六步:在比較函數00402533處按下F2鍵設置斷點,接着按F9鍵執行,此時會彈出運行界面,我們輸入“Eastmount”和“12345678”,然後點擊OK按鈕。

此時程序停留在斷點處,右下角堆棧區顯示了提示的正確Serial。

第七步:輸入正確的用戶名和Serial,成果註冊。

  • Eastmount
  • AKA-877848

下面結合鬼手大神和海天一色大神的博文,簡單分析加密的基本邏輯,同時強烈推薦大家閱讀他們的文章,參見前面的參考文獻。這些逆向的經驗真不是一朝一夕就能獲取的,深知自己要學習和經歷的東西太多,你我一起加油。

基本流程如下:
serial = ‘AKA-’ + 逆序itoa(strlen(name) * 0x17CFB + name[0])

  • 求出了用戶名的長度
  • 將用戶名長度乘以0x17CFB得到結果 如果溢出則跳轉
  • 將結果再加上用戶名的第一個字符的ASCII
  • 將結果轉爲十進制
  • 將結果和AKA進行拼接,得到最後的序列號

下面分享一段Python的解密代碼。

# encoding:  utf-8

key = "AKA"
name = "Eastmount"

#獲取用戶名長度
nameLen = len(name)
print(u'獲取用戶名長度:')
print(nameLen)

#用戶名長度乘以0x17CFB得到結果
res = nameLen * 0x17CFB
print(u'用戶名長度乘以0x17CFB:')
print(res)

#將結果加上用戶名的第一個字符的ASCII
print(name[0], ord(name[0]))
res = res + ord(name[0])
print(u'結果加上用戶名第一個字符的ASCII:')
print(res)

#轉換爲十進制 省略

#拼接序列號
key = key + str(res)
print(u'最終結果:')
print(key)

定義不同的用戶名可以得到對應的Serial。


四.總結

寫到這裏,這篇基礎性文章就敘述完畢,網絡安全要學習的知識真的很多,涉及面很廣,包括彙編、網絡、操作系統、加密解密、C/C++、Python等。希望自己能慢慢進步,科研與實踐並重,也希望讀者喜歡這系列總結筆記。不喜勿噴,與你同行~

今天剛好CSDN粉絲破十萬,真心感謝大家這些年來的陪伴和支持,感恩認識您,也希望未來能繼續分享更高質量的文章,幫助更多人入門和解決爲題,寓教於樂,共勉!

在這裏插入圖片描述

2020年8月18新開的“娜璋AI安全之家”,主要圍繞Python大數據分析、網絡空間安全、人工智能、Web滲透及攻防技術進行講解,同時分享論文的算法實現。娜璋之家會更加系統,並重構作者的所有文章,從零講解Python和安全,寫了近十年文章,真心想把自己所學所感所做分享出來,還請各位多多指教,真誠邀請您的關注!謝謝。

在這裏插入圖片描述

(By:Eastmount 2020-12-22 星期二 晚上10點寫於武漢 https://blog.csdn.net/Eastmoun)


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章