官术网_书友最值得收藏!

1.4 Crack小實驗

在開始講述漏洞利用原理之前,本節先用一個非常簡單的破解小實驗來幫助大家復習一下前面所講述的概念和工具,消除對二進制文件本能的恐懼。

下面是一段用于密碼驗證的C代碼:

    #include <stdio.h>
#define PASSWORD "1234567"
int verify_password (char *password)
{
        int authenticated;
        authenticated=strcmp(password,PASSWORD);
        return authenticated;
}
main()
{
        int valid_flag=0;
        char password[1024];
        while(1)
        {
            printf("please input password:    ");
            scanf("%s",password);
            valid_flag = verify_password(password);
            if(valid_flag)
            {
               printf("incorrect password!\n\n");
            }
            else
            {
              printf("Congratulation! You have passed the verification!\n");
               break;
            }
        }
}

如圖1.4.1所示,我們必須輸入正確的密碼“1234567”才能得到密碼驗證的確認,跳出循環。看到程序源碼后不難發現,程序是提示密碼錯誤請求再次輸入,還是提示密碼正確跳出循環,完全取決于main函數中的if判斷。

圖1.4.1 程序運行情況

如果我們能在.exe文件中找到if判斷對應的二進制機器代碼,將其稍作修改,那么即使輸入錯誤的密碼,也將通過驗證!本節實驗就帶領大家來完成這樣一件事情,這實際上是一種最簡單的軟件破解,也被稱為“爆破”。

題外話:軟件破解技術是自成體系的另一門安全技術,其關鍵在于在調試時巧妙地設置斷點,尋找關鍵代碼段。本例的破解方法有很多,比如直接在PE中搜索密碼、crack子函數等,在此只舉其中一個來介紹。這個實驗的目的在于練習使用工具,復習前面的概念,而并非真正研究破解技術。

實驗環境如表1-4-1所示。

表1-4-1 實驗環境

說明:如果完全采用實驗指導所推薦的實驗環境,將精確地重現指導中所有的細節,包括動態調試時的內存地址和靜態調試的文件偏移地址;否則,一些地址可能需要重新調試來確定。

首先打開IDA,并把由VC 6.0得到的.exe文件直接拖進IDA,稍等片刻,IDA就會把二進制文件翻譯成質量上乘的反匯編代碼。

如圖1.4.2所示,默認情況下,IDA會自動識別出main函數,并用類似流程圖的形式標注出函數內部的跳轉指令。如果按F12鍵,IDA會自動繪制出更加專業和詳細的函數流程圖,如圖1.4.3所示。

圖1.4.2 IDA的流程圖界面1

圖1.4.3 IDA的流程圖界面2

在IDA的圖形顯示界面中,用鼠標選中程序分支點,也就是我們要找的對應于C代碼中的if分支點,按空格鍵切換到匯編指令界面,如圖1.4.4所示。

圖1.4.4 用IDA定位破解點

光標仍然顯示高亮的這條匯編指令就是剛才在流程圖中看到的引起程序分支的指令??梢钥吹竭@條指令位于PE文件的.text節,并且IDA已經自動將該指令的地址換算成了運行時的內存地址VA:0040106E。

現在關閉IDA,換用OllyDbg進行動態調試來看看程序到底是怎樣分支的。用OllyDbg把PE文件打開,如圖1.4.5所示。

圖1.4.5 加載PE文件

OllyDbg在默認情況下將程序中斷在PE裝載器開始處,而不是main函數的開始。如果您有興趣,可以按F8鍵單步跟蹤,看看在main函數被運行之前,裝載器都做了哪些準備工作。一般情況下,main函數位于GetCommandLineA函數調用后不遠處,并且有明顯的特征:在調用之前有3次連續的壓棧操作,因為系統要給main傳入默認的argc、argv等參數。找到main函數調用后,按F7鍵單步跟入就可以看到真正的代碼了,如圖1.4.6所示。

圖1.4.6 定位main函數

我們也可以按快捷鍵Ctrl+G直接跳到由IDA得到的VA:0x0040106E處查看那條引起程序分支的關鍵指令,如圖1.4.7所示。

圖1.4.7 定位if分支

選中這條指令,按F2鍵下斷點,成功后,指令的地址會被標記成不同顏色。

按F9鍵讓程序運行起來,這時候控制權會回到程序,OllyDbg暫時掛起。到程序提示輸入密碼的Console界面隨便輸入一個錯誤的密碼,回車確認后,OllyDbg會重新中斷程序,收回控制權,如圖1.4.8所示。

圖1.4.8 破解前的狀態

密碼驗證函數的返回值將存在EAX寄存器中,if()語句通過以下兩條指令實現。

TEST EAX,EAX
JE XXXXX

也就是說,EAX中的值為0時,跳轉將被執行,程序進入密碼確認流程;否則跳轉不執行,程序進入密碼重輸的流程。由于現在輸入的是錯誤密碼,所以可以在預執行區看到提示:“Jump is not taken”。

如果我們把JE這條指令的機器代碼修改成JNE(非0則跳轉),那么整個程序的邏輯就會反過來:輸入錯誤的密碼會被確認,輸入正確的密碼反而要求重新輸入!當然,把

TEST EAX, EAX

指令修改成

XOR EAX, EAX

也能達到改變程序流程的目的,這時不論正確與否,密碼都將被接受。

雙擊JE這條指令,將其修改成JNE,單擊“Assemble”按鈕將其寫入內存,如圖1.4.9所示。

圖1.4.9 破解后的狀態

OllyDbg將匯編指令翻譯成機器代碼后寫入內存。原來內存中的機器代碼74(JE)現在變成了75(JNE)。此外,在預執行區中的提示也發生了變化,提示跳轉將要發生,也就是說,在修改了一個字節的內存數據后,錯誤的密碼也將跳入正確的執行流程!后面您可以單步執行,看看程序是不是如我們所料執行了正確密碼才應該執行的指令。

上面只是在內存中修改程序,我們還需要在二進制文件中也修改相應的字節。這就要用到第2章講到的內存地址VA與文件地址之間的對應關系了。

用LordPE打開.exe文件,查看PE文件的節信息,如圖1.4.10所示。

圖1.4.10 計算文件偏移地址

我們已經知道跳轉指令在內存中的地址是VA=0x0040106E,按照第2章VA與文件地址的換算公式:

文件偏移地址=虛擬內存地址(VA)-裝載基址(Image Base)-節偏移

= 0x0040106E-0x00400000-(0x00001000-0x00001000)

= 0x106E

也就是說,這條指令在PE文件中位于距離文件開始處106E字節的地方。用UltraEdit按照二進制方式打開crack_me.exe文件,如圖1.4.11所示。

圖1.4.11 修改PE文件

按快捷鍵Ctrl+G,輸入0x106E直接跳到JE指令的機器代碼處,如圖1.4.12所示。

圖1.4.12 修改PE文件

將這一個字節的74(JE)修改成75(JNE),保存后重新運行可執行文件,如圖1.4.13所示。原本正確的密碼“1234567”現在反而提示錯誤了。

圖1.4.13 成功破解密碼驗證

主站蜘蛛池模板: 定襄县| 阿拉尔市| 桐乡市| 明溪县| 同德县| 南溪县| 华安县| 山阴县| 恩平市| 辽源市| 蓝田县| 贵溪市| 三穗县| 新余市| 开远市| 寿光市| 大姚县| 耒阳市| 杂多县| 元氏县| 天门市| 娄底市| 吴堡县| 阳曲县| 大城县| 鄂温| 宁武县| 金山区| 衡阳县| 漳平市| 诸暨市| 兴城市| 拉孜县| 新竹县| 兴隆县| 东至县| 淳安县| 嫩江县| 泽州县| 九龙县| 遂川县|