MD5碰撞試驗

wajiez發表於2024-10-30

作業題目

本次實驗主要是加深大家對MD5碰撞及其原理的理解,使用SEED實驗環境中的工具及程式語言,完成以下任務:

  1. 使用md5collgen生成兩個MD5值相同的檔案,並利用bless十六進位制編輯器檢視輸出的兩個檔案,描述你觀察到的情況;
  2. 參考Lab3_task2.c的程式碼,生成兩個MD5值相同但輸出不同的兩個可執行檔案。
  3. 參考Lab3_task3.c的程式碼,生成兩個MD5值相同但程式碼行為不相同的可執行檔案。
  4. 回答問題:透過上面的實驗,請解釋為什麼可以做到不同行為的兩個可執行檔案具有相同的MD5值?

實驗步驟及結果

A.

test

生成一個名為test測試txt檔案,往裡面存入字串“hello”,使用md5collgen生成兩個檔案out1.bin,out2.bin.

這兩個檔案不同,但md5值相同。

md5演算法以64個位元組為一組來處理輸入,用bless檢視out1.bin,out2.bin:

test2

test3

可以發現,輸入不足64個位元組(或不是64的倍數)時,md5collgen會給輸入自動補零

用test2.txt再測試,test2.txt中有63個字元,加上結束符,一共64個位元組作為輸入。

test4

用bless再檢視md5collgen生成的檔案outfile1.bin,這次沒有補零。

test5

檢視out1.bin和outfile1.bin的內容:

捕獲

可以發現,除了我們寫到txt裡的內容,md5collgen又加入了一些東西使生成的兩個檔案內容不同但md5值相同

用bless開啟out1.bin檢視:

test7

可以發現,這段加入的內容一共128個位元組。

在out1.bin和out2.bin中,加入相同的字串“world”:

test8

發現兩個檔案md5值仍然相同,所以,在兩個md值相同的檔案中分別加入相同的內容,新的兩個檔案md5值仍然相同。

B.

透過A實驗得到的3個技巧可以完成B實驗。

修改程式碼(方便確定陣列內容所在位置):

aaa

編譯c程式碼為task2:

task2

用bless開啟task2,找到陣列內容開始的位置在檔案的第12320個位元組處。task3

要保證最後得到的是可執行的檔案,就要保證md5collgen的輸入是64位元組的倍數(不能自動補零)。

所以,取task2前12352個位元組為prefix,留出128個位元組的位置(md5collgen會在生成檔案的末尾加上128個位元組),取第12480個位元組後的內容為suffix。

task4

啊1

用prefix作為md5collgen的輸入,生成兩個md5值相同的檔案o1.bin,o2.bin。

task7

取出這兩個檔案的後128個位元組為P,Q。

task5

將prefix,P/Q,suffix合併為pro1/pro2,執行,pro1和pro2輸出內容不同,md5值相同。

啊2

也可以用o1.bin和o2.bin直接和suffix拼接:

啊3

兩種方法得到的可執行檔案相同:

呼哈2

完善task3程式碼,x和y內容相同就執行良性程式碼,內容不相同就執行惡性程式碼:

捕獲捕獲2

編譯c程式碼為task3:

3.1

用bless檢視task3,找到陣列開始的位置(12320)

3.2

用前12352個位元組作為md5cllgen輸入,得到o1.bin,o2.bin:

3.3

用bless檢視o1.bin:

3.11

發現陣列內容對應o1.bin最後160個位元組(陣列x前面的一部分)。

五米五米

取這最後160個位元組為P。

從task3中取第12480後的全部位元組為suffix:

3.7

用bless檢視suffix:

3.10

將suffix分割成三部分,a1(陣列x剩下的部分),中間部分(陣列y前面的一部分,和P位元組相同),a2(檔案剩餘全部):

無標題

3.12

不1

將中間部分替換為P,得到新的suffix_f:

3.12

再將suffix_f分別與o1.bin和o2.bin拼接,得到pro1,pro2。

遺憾

pro1,pro2行為不相同,md5值卻相同。

D.

md5的輸出是128bit的值,一共有2的128次方種不同的可能,但md5的輸入卻是無限可能的,所以,不同的輸入資料也可以對映到相同的md5值上。

對於兩個可執行檔案,我們只改變對應程式碼中陣列內容的部分,而不改變程式碼結構,再利用if判斷陣列內容來選擇不同的行為,這樣就可以使它們md5值相同但行為不同了。

相關文章