作CTF題目的過程當中遇到了md5擴展攻擊,參考了幾篇文章,感受寫的都有些小缺陷,再發一篇文章,理解md5擴展攻擊首先須要瞭解md5的工做原理html
具體參考這兩篇文章python
http://blog.csdn.net/adidala/article/details/28677393,算法實現有誤web
https://www.rfc-editor.org/rfc/pdfrfc/rfc1321.txt.pdf,算法正確算法
md5的算法原理以下圖所示數組
Md5的算法步驟是服務器
一、填充app
將數據進行填充,首先添加0x80,接着添加0x00使得 (數據字節數 + 8)%64 = 0函數
二、增長長度spa
將數據的長度放入8字節的數組中,把低字節放到前面,例如長度爲1,8字節的數據長度表示爲00 00 00 00 00 00 00 01,把這個長度值轉化爲低字節在前面變成了01 00 00 00 00 00 00 00,將這個數據加入到總體的數據中。.net
三、進行輪次變換
以64個字節爲1組進行輪次變換,這一組中以4字節爲1個單位分紅16個數字。
首先準備A,B,C,D四個32位的字符,其中, A = 0x67452301,B = 0xefcdab89
,C = 0x98badcfe,D = 0x10325476, 將ABCD做爲種子,與16個數字進行一種複雜的運算(運算方式見後文),運算結果爲A1 B1 C1 D1,以A1 B1 C1 D1爲種子而後重複這個過程計算最後獲得AnBnCnDn
四、輸出hash值
將An進行相似於第二步的低字節順序的排列An’,同理對Bn,Cn,Dn進行一樣變換,An’,Bn’,Cn’,Dn’的簡單拼接就是最後結果。
注:這裏簡單記錄一下正確的複雜算法
文獻1中的算法是錯誤的,正確的算法是
定義其中幾個子算法 F = lambda x,y,z:((x&y)|((~x)&z)) G = lambda x,y,z:((x&z)|(y&(~z))) H = lambda x,y,z:(x^y^z) I = lambda x,y,z:(y^(x|(~z))) def shift(a, count): return (((a << count) | (a >> (32 -count)))&0xffffffff) 常量表: T_func = lambda i: int(4294967296*abs(math.sin(i))) & 0xffffffff T = [T_func(i) for i in xrange(1, 65)] T.insert(0 , 0) 複雜算法爲 INPUT_A = A INPUT_B = B INPUT_C = C INPUT_D = D M = [ (myord[i * 64 + j + 3] <<24) + (myord[i * 64 + j + 2] << 16 )+ (myord[i * 64 + j + 1] << 8) + (myord[i * 64 + j + 0] )\ for j in xrange(0, 64, 4)] def shift(a, count): return (((a << count) | (a >> (32 -count)))&0xffffffff) #第一輪 A = (B+ shift((A+F(B,C,D)+M[0]+T[1]) &0xffffffff,7) ) & 0xffffffff D = (A+shift((D+F(A,B,C)+M[1]+T[2]) &0xffffffff ,12) )& 0xffffffff C = (D+shift((C+F(D,A,B)+M[2]+T[3]) &0xffffffff,17) ) &0xffffffff B = (C+shift((B+F(C,D,A)+M[3]+T[4]) &0xffffffff,22) )&0xffffffff A = (B+shift((A+F(B,C,D)+M[4]+T[5]) &0xffffffff,7) )&0xffffffff D = (A+shift((D+F(A,B,C)+M[5]+T[6])&0xffffffff,12) )&0xffffffff C = (D+shift((C+F(D,A,B)+M[6]+T[7]) &0xffffffff,17) )&0xffffffff B = (C+shift((B+F(C,D,A)+M[7]+T[8]) &0xffffffff,22) )&0xffffffff A = (B+shift((A+F(B,C,D)+M[8]+T[9])&0xffffffff,7) )&0xffffffff D = (A+shift((D+F(A,B,C)+M[9]+T[10])&0xffffffff,12) )&0xffffffff C = (D+shift((C+F(D,A,B)+M[10]+T[11])&0xffffffff,17) )&0xffffffff B = (C+shift((B+F(C,D,A)+M[11]+T[12])&0xffffffff,22) )&0xffffffff A = (B+shift((A+F(B,C,D)+M[12]+T[13])&0xffffffff,7) )&0xffffffff D = (A+shift((D+F(A,B,C)+M[13]+T[14])&0xffffffff,12) )&0xffffffff C = (D+shift((C+F(D,A,B)+M[14]+T[15])&0xffffffff,17) )&0xffffffff B = (C+shift((B+F(C,D,A)+M[15]+T[16])&0xffffffff,22) )&0xffffffff #第二輪 A = (B+shift((A+G(B,C,D)+M[1]+T[17])&0xffffffff,5) )&0xffffffff D = (A+shift((D+G(A,B,C)+M[6]+T[18]) &0xffffffff,9) )&0xffffffff C = (D+shift((C+G(D,A,B)+M[11]+T[19])&0xffffffff,14) )&0xffffffff B = (C+shift((B+G(C,D,A)+M[0]+T[20])&0xffffffff,20) )&0xffffffff A = (B+shift((A+G(B,C,D)+M[5]+T[21])&0xffffffff,5) )&0xffffffff D = (A+shift((D+G(A,B,C)+M[10]+T[22])&0xffffffff,9) )&0xffffffff C = (D+shift((C+G(D,A,B)+M[15]+T[23])&0xffffffff,14) )&0xffffffff B = (C+shift((B+G(C,D,A)+M[4]+T[24])&0xffffffff,20) )&0xffffffff A = (B+shift((A+G(B,C,D)+M[9]+T[25])&0xffffffff,5) )&0xffffffff D = (A+shift((D+G(A,B,C)+M[14]+T[26])&0xffffffff,9) )&0xffffffff C = (D+shift((C+G(D,A,B)+M[3]+T[27])&0xffffffff,14) )&0xffffffff B = (C+shift((B+G(C,D,A)+M[8]+T[28])&0xffffffff,20) )&0xffffffff A = (B+shift((A+G(B,C,D)+M[13]+T[29])&0xffffffff,5) )&0xffffffff D = (A+shift((D+G(A,B,C)+M[2]+T[30])&0xffffffff,9) )&0xffffffff C = (D+shift((C+G(D,A,B)+M[7]+T[31])&0xffffffff,14) )&0xffffffff B = (C+shift((B+G(C,D,A)+M[12]+T[32])&0xffffffff,20))&0xffffffff #第三輪 A = (B+shift((A+H(B,C,D)+M[5]+T[33])&0xffffffff,4) )&0xffffffff D = (A+shift((D+H(A,B,C)+M[8]+T[34])&0xffffffff,11) )&0xffffffff C = (D+shift((C+H(D,A,B)+M[11]+T[35])&0xffffffff,16) )&0xffffffff B = (C+shift((B+H(C,D,A)+M[14]+T[36])&0xffffffff,23) )&0xffffffff A = (B+shift((A+H(B,C,D)+M[1]+T[37])&0xffffffff,4) )&0xffffffff D = (A+shift((D+H(A,B,C)+M[4]+T[38])&0xffffffff,11) )&0xffffffff C = (D+shift((C+H(D,A,B)+M[7]+T[39])&0xffffffff,16) )&0xffffffff B = (C+shift((B+H(C,D,A)+M[10]+T[40])&0xffffffff,23) )&0xffffffff A = (B+shift((A+H(B,C,D)+M[13]+T[41])&0xffffffff,4) )&0xffffffff D = (A+shift((D+H(A,B,C)+M[0]+T[42])&0xffffffff,11) )&0xffffffff C = (D+shift((C+H(D,A,B)+M[3]+T[43])&0xffffffff,16) )&0xffffffff B = (C+shift((B+H(C,D,A)+M[6]+T[44])&0xffffffff,23) )&0xffffffff A = (B+shift((A+H(B,C,D)+M[9]+T[45])&0xffffffff,4) )&0xffffffff D = (A+shift((D+H(A,B,C)+M[12]+T[46])&0xffffffff,11) )&0xffffffff C = (D+shift((C+H(D,A,B)+M[15]+T[47])&0xffffffff,16) )&0xffffffff B = (C+shift((B+H(C,D,A)+M[2]+T[48])&0xffffffff,23))&0xffffffff #第四輪 A = (B+shift((A+I(B,C,D)+M[0]+T[49])&0xffffffff,6) )&0xffffffff D = (A+shift((D+I(A,B,C)+M[7]+T[50])&0xffffffff,10) )&0xffffffff C = (D+shift((C+I(D,A,B)+M[14]+T[51])&0xffffffff,15) )&0xffffffff B = (C+shift((B+I(C,D,A)+M[5]+T[52])&0xffffffff,21) )&0xffffffff A = (B+shift((A+I(B,C,D)+M[12]+T[53])&0xffffffff,6) )&0xffffffff D = (A+shift((D+I(A,B,C)+M[3]+T[54])&0xffffffff,10) )&0xffffffff C = (D+shift((C+I(D,A,B)+M[10]+T[55])&0xffffffff,15) )&0xffffffff B = (C+shift((B+I(C,D,A)+M[1]+T[56])&0xffffffff,21) )&0xffffffff A = (B+shift((A+I(B,C,D)+M[8]+T[57])&0xffffffff,6) )&0xffffffff D = (A+shift((D+I(A,B,C)+M[15]+T[58])&0xffffffff,10) )&0xffffffff C = (D+shift((C+I(D,A,B)+M[6]+T[59])&0xffffffff,15) )&0xffffffff B = (C+shift((B+I(C,D,A)+M[13]+T[60])&0xffffffff,21) )&0xffffffff A = (B+shift((A+I(B,C,D)+M[4]+T[61])&0xffffffff,6) )&0xffffffff D = (A+shift((D+I(A,B,C)+M[11]+T[62])&0xffffffff,10) )&0xffffffff C = (D+shift((C+I(D,A,B)+M[2]+T[63])&0xffffffff,15) )&0xffffffff B = (C+shift((B+I(C,D,A)+M[9]+T[64])&0xffffffff,21))&0xffffffff A = (A + INPUT_A) & 0xffffffff B = (B + INPUT_B) & 0xffffffff C = (C + INPUT_C) & 0xffffffff D = (D + INPUT_D) & 0xffffffff
Md5算法實現python版本見第三節的中的my_md5函數實現
理解的md5算法的原理,下面開始講解md5擴展攻擊
首先能夠參考這篇文章(http://www.freebuf.com/articles/web/69264.html),本文將對這篇文章進行補充說明。
從md5算法原理能夠知道,每一輪次計算的ABCD將做爲下一輪次計算的初始值,假設咱們已知一個數字x的md5值爲y,其中x爲未知量,即y=md5(x),同時已知x的長度,那麼咱們就能進行md5擴展攻擊,由於咱們知道y爲md5(x)計算完畢後的ABCD值的簡單組合,經過md5的算法可知y = f(x + x的填充值),若是咱們增長x1,計算y’=f( (x + x的填充值+x1 ) + (x + x的填充值+x1 ) 的填充值 )則變得可能,應爲y’可使用y轉化的AB
CD值同(x1 + (x + x的填充值+x1 ) 的填充值)再進行一輪次的計算既能夠得出。
下圖闡述了上述算法原理
其中標號1爲原始數據x,標號2位原始數據x的填充長度,標號3表示新增長的數據,標號4爲標號1,2,3的填充和長度。若是咱們已知一個計算出來的hash值,同時知道明文的長度,則咱們能夠構造標號2的數據,標號3,計算未知數md5值的函數(如服務器端的程序),拿到咱們構造的標號2和標號3的數據,會自動添加標號4的數據,計算完標號1和和標號2產生ABCD,接着會產生hash值,這時這個hash值就是能夠預測。
攻擊者能夠計算出標號3和標號4,以ABCD做爲輸入進行計算本地產出的hash值和服務端計算出的hash值是一致的。
攻擊者的視角以下圖所示。
一、攻擊者提供標號2,標號3,標號4的數據
二、服務端計算到標號2的位置恰好爲ABCD這個已知數據
三、攻擊者在本地根據標號3和標號4的數據和ABCD值計算hash值攻擊成功
而服務端的視角是,攻擊者提供了標號2和標號3的數據,服務端計算了標號4的數據,同時服務端產出ABCD,發現沒有計算完成,接着運行md5算法,計算出的新的hash值和攻擊者一致。
綜上所述要想進行此類攻擊須要知道兩個條件
一、標號1數據的長度。
二、標號1數據的md5值。
最後總結一下攻擊步驟
第一步:根據標號1的長度計算標號2的數據,提供標號3的數據,本地計算標號4 的數據,並計算加上標號3和標號4數據後的hash值。
第二步:發送計算出來的hash,和標號2,標號3的數據,攻擊成功。
展現python編寫的MD5程序和md5擴展攻擊的程序
#-*- coding=utf-8 -*- import math def my_md5_extend(salt_hash, salt_length, added_message): #計算須要填充的數據 added_data = [0x80]; x = salt_length + 1; while (x + 8) % 64 != 0: x += 1; added_data.append(0x00); salt_length *= 8; salt_length = salt_length % (2 ** 64); salt_length = hex(salt_length); salt_length = salt_length[2:len(salt_length)-1].rjust(16, '0'); salt_length = [int(format(salt_length[i:i+2]), 16) for i in xrange(0, len(salt_length), 2)][::-1] #下面的數據用於加在payload後面 added_data.extend(salt_length); #important #打印payload print ''.join(['%' + hex(item).replace('0x', '').rjust(2,'0') for item in added_data]) #增長新加的數據,而後使用已經md5的數據進行擴展計算,計算出來一個新的hash值 myord = map(ord, added_message); myord.append(0x80); added_length = (x + 8 + len(added_message)) ; y = x + 8 + len(added_message) + 1; while (y + 8) % 64 != 0: y += 1; myord.append(0x00); added_length *= 8; added_length = added_length % (2 ** 64); added_length = hex(added_length); added_length = added_length[2:len(added_length)-1].rjust(16, '0'); added_length = [int(format(added_length[i:i+2]), 16) for i in xrange(0, len(added_length), 2)][::-1] myord.extend(added_length); #使用已經計算出來的hash myA, myB, myC, myD = ( int(salt_hash[i +6: i + 8] +salt_hash[i + 4: i + 6] +salt_hash[i + 2:i + 4] +salt_hash[i + 0 : i + 2], 16) for i in xrange(0, len(salt_hash), 8)); A = myA; B = myB; C = myC; D = myD; F = lambda x,y,z:((x&y)|((~x)&z)) G = lambda x,y,z:((x&z)|(y&(~z))) H = lambda x,y,z:(x^y^z) I = lambda x,y,z:(y^(x|(~z))) T_func = lambda i: int(4294967296*abs(math.sin(i))) & 0xffffffff T = [T_func(i) for i in xrange(1, 65)] T.insert(0 , 0) #進行hash計算 for i in xrange(0, len(myord) / 64): INPUT_A = A INPUT_B = B INPUT_C = C INPUT_D = D M = [ (myord[i * 64 + j + 3] <<24) + (myord[i * 64 + j + 2] << 16 )+ (myord[i * 64 + j + 1] << 8) + (myord[i * 64 + j + 0] )\ for j in xrange(0, 64, 4)] def shift(a, count): return (((a << count) | (a >> (32 -count)))&0xffffffff) #第一輪 A = (B+ shift((A+F(B,C,D)+M[0]+T[1]) &0xffffffff,7) ) & 0xffffffff D = (A+shift((D+F(A,B,C)+M[1]+T[2]) &0xffffffff ,12) )& 0xffffffff C = (D+shift((C+F(D,A,B)+M[2]+T[3]) &0xffffffff,17) ) &0xffffffff B = (C+shift((B+F(C,D,A)+M[3]+T[4]) &0xffffffff,22) )&0xffffffff A = (B+shift((A+F(B,C,D)+M[4]+T[5]) &0xffffffff,7) )&0xffffffff D = (A+shift((D+F(A,B,C)+M[5]+T[6])&0xffffffff,12) )&0xffffffff C = (D+shift((C+F(D,A,B)+M[6]+T[7]) &0xffffffff,17) )&0xffffffff B = (C+shift((B+F(C,D,A)+M[7]+T[8]) &0xffffffff,22) )&0xffffffff A = (B+shift((A+F(B,C,D)+M[8]+T[9])&0xffffffff,7) )&0xffffffff D = (A+shift((D+F(A,B,C)+M[9]+T[10])&0xffffffff,12) )&0xffffffff C = (D+shift((C+F(D,A,B)+M[10]+T[11])&0xffffffff,17) )&0xffffffff B = (C+shift((B+F(C,D,A)+M[11]+T[12])&0xffffffff,22) )&0xffffffff A = (B+shift((A+F(B,C,D)+M[12]+T[13])&0xffffffff,7) )&0xffffffff D = (A+shift((D+F(A,B,C)+M[13]+T[14])&0xffffffff,12) )&0xffffffff C = (D+shift((C+F(D,A,B)+M[14]+T[15])&0xffffffff,17) )&0xffffffff B = (C+shift((B+F(C,D,A)+M[15]+T[16])&0xffffffff,22) )&0xffffffff #第二輪 A = (B+shift((A+G(B,C,D)+M[1]+T[17])&0xffffffff,5) )&0xffffffff D = (A+shift((D+G(A,B,C)+M[6]+T[18]) &0xffffffff,9) )&0xffffffff C = (D+shift((C+G(D,A,B)+M[11]+T[19])&0xffffffff,14) )&0xffffffff B = (C+shift((B+G(C,D,A)+M[0]+T[20])&0xffffffff,20) )&0xffffffff A = (B+shift((A+G(B,C,D)+M[5]+T[21])&0xffffffff,5) )&0xffffffff D = (A+shift((D+G(A,B,C)+M[10]+T[22])&0xffffffff,9) )&0xffffffff C = (D+shift((C+G(D,A,B)+M[15]+T[23])&0xffffffff,14) )&0xffffffff B = (C+shift((B+G(C,D,A)+M[4]+T[24])&0xffffffff,20) )&0xffffffff A = (B+shift((A+G(B,C,D)+M[9]+T[25])&0xffffffff,5) )&0xffffffff D = (A+shift((D+G(A,B,C)+M[14]+T[26])&0xffffffff,9) )&0xffffffff C = (D+shift((C+G(D,A,B)+M[3]+T[27])&0xffffffff,14) )&0xffffffff B = (C+shift((B+G(C,D,A)+M[8]+T[28])&0xffffffff,20) )&0xffffffff A = (B+shift((A+G(B,C,D)+M[13]+T[29])&0xffffffff,5) )&0xffffffff D = (A+shift((D+G(A,B,C)+M[2]+T[30])&0xffffffff,9) )&0xffffffff C = (D+shift((C+G(D,A,B)+M[7]+T[31])&0xffffffff,14) )&0xffffffff B = (C+shift((B+G(C,D,A)+M[12]+T[32])&0xffffffff,20))&0xffffffff #第三輪 A = (B+shift((A+H(B,C,D)+M[5]+T[33])&0xffffffff,4) )&0xffffffff D = (A+shift((D+H(A,B,C)+M[8]+T[34])&0xffffffff,11) )&0xffffffff C = (D+shift((C+H(D,A,B)+M[11]+T[35])&0xffffffff,16) )&0xffffffff B = (C+shift((B+H(C,D,A)+M[14]+T[36])&0xffffffff,23) )&0xffffffff A = (B+shift((A+H(B,C,D)+M[1]+T[37])&0xffffffff,4) )&0xffffffff D = (A+shift((D+H(A,B,C)+M[4]+T[38])&0xffffffff,11) )&0xffffffff C = (D+shift((C+H(D,A,B)+M[7]+T[39])&0xffffffff,16) )&0xffffffff B = (C+shift((B+H(C,D,A)+M[10]+T[40])&0xffffffff,23) )&0xffffffff A = (B+shift((A+H(B,C,D)+M[13]+T[41])&0xffffffff,4) )&0xffffffff D = (A+shift((D+H(A,B,C)+M[0]+T[42])&0xffffffff,11) )&0xffffffff C = (D+shift((C+H(D,A,B)+M[3]+T[43])&0xffffffff,16) )&0xffffffff B = (C+shift((B+H(C,D,A)+M[6]+T[44])&0xffffffff,23) )&0xffffffff A = (B+shift((A+H(B,C,D)+M[9]+T[45])&0xffffffff,4) )&0xffffffff D = (A+shift((D+H(A,B,C)+M[12]+T[46])&0xffffffff,11) )&0xffffffff C = (D+shift((C+H(D,A,B)+M[15]+T[47])&0xffffffff,16) )&0xffffffff B = (C+shift((B+H(C,D,A)+M[2]+T[48])&0xffffffff,23))&0xffffffff #第四輪 A = (B+shift((A+I(B,C,D)+M[0]+T[49])&0xffffffff,6) )&0xffffffff D = (A+shift((D+I(A,B,C)+M[7]+T[50])&0xffffffff,10) )&0xffffffff C = (D+shift((C+I(D,A,B)+M[14]+T[51])&0xffffffff,15) )&0xffffffff B = (C+shift((B+I(C,D,A)+M[5]+T[52])&0xffffffff,21) )&0xffffffff A = (B+shift((A+I(B,C,D)+M[12]+T[53])&0xffffffff,6) )&0xffffffff D = (A+shift((D+I(A,B,C)+M[3]+T[54])&0xffffffff,10) )&0xffffffff C = (D+shift((C+I(D,A,B)+M[10]+T[55])&0xffffffff,15) )&0xffffffff B = (C+shift((B+I(C,D,A)+M[1]+T[56])&0xffffffff,21) )&0xffffffff A = (B+shift((A+I(B,C,D)+M[8]+T[57])&0xffffffff,6) )&0xffffffff D = (A+shift((D+I(A,B,C)+M[15]+T[58])&0xffffffff,10) )&0xffffffff C = (D+shift((C+I(D,A,B)+M[6]+T[59])&0xffffffff,15) )&0xffffffff B = (C+shift((B+I(C,D,A)+M[13]+T[60])&0xffffffff,21) )&0xffffffff A = (B+shift((A+I(B,C,D)+M[4]+T[61])&0xffffffff,6) )&0xffffffff D = (A+shift((D+I(A,B,C)+M[11]+T[62])&0xffffffff,10) )&0xffffffff C = (D+shift((C+I(D,A,B)+M[2]+T[63])&0xffffffff,15) )&0xffffffff B = (C+shift((B+I(C,D,A)+M[9]+T[64])&0xffffffff,21))&0xffffffff A = (A + INPUT_A) & 0xffffffff B = (B + INPUT_B) & 0xffffffff C = (C + INPUT_C) & 0xffffffff D = (D + INPUT_D) & 0xffffffff def show_result(A, B, C, D): result = ""; mya = [hex(A)[2:len(hex(A)[2:]) if hex(A).find('L') == -1 else -1].rjust(8, '0')[k:k+2] for k in xrange(0, 8, 2)][::-1] myb = [hex(B)[2:len(hex(B)[2:]) if hex(B).find('L') == -1 else -1].rjust(8, '0')[k:k+2] for k in xrange(0, 8, 2)][::-1] myc = [hex(C)[2:len(hex(C)[2:]) if hex(C).find('L') == -1 else -1].rjust(8, '0')[k:k+2] for k in xrange(0, 8, 2)][::-1] myd = [hex(D)[2:len(hex(D)[2:]) if hex(D).find('L') == -1 else -1].rjust(8, '0')[k:k+2] for k in xrange(0, 8, 2)][::-1] return ''.join(mya + myb + myc + myd) return show_result(A, B, C, D); print my_md5_extend('571580b26c65f306376d4f64e53cb5c7', 15 + len('adminadmin'), 'nb'); def my_md5(mystring): #第一步填充 #mystring = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz' myord =map(ord, mystring);#轉化成爲16進制的array myord_length = len(myord) * 8; myord.append(0x80); while (len(myord) * 8 + 64 )% 512 != 0: myord.append(0x00); #第二步增長長度 myord_length = myord_length % (2 ** 64); myord_length = hex(myord_length); myord_length = myord_length[2:len(myord_length)-1].rjust(16, '0'); myord_length = [int(format(myord_length[i:i+2]), 16) for i in xrange(0, len(myord_length), 2)][::-1] myord.extend(myord_length) #對每個512位作處理 A = 0x67452301 B = 0xefcdab89 C = 0x98badcfe D = 0x10325476 F = lambda x,y,z:((x&y)|((~x)&z)) G = lambda x,y,z:((x&z)|(y&(~z))) H = lambda x,y,z:(x^y^z) I = lambda x,y,z:(y^(x|(~z))) T_func = lambda i: int(4294967296*abs(math.sin(i))) & 0xffffffff T = [T_func(i) for i in xrange(1, 65)] T.insert(0 , 0)#錯誤的位置 for i in xrange(0, len(myord) / 64): INPUT_A = A INPUT_B = B INPUT_C = C INPUT_D = D M = [ (myord[i * 64 + j + 3] <<24) + (myord[i * 64 + j + 2] << 16 )+ (myord[i * 64 + j + 1] << 8) + (myord[i * 64 + j + 0] )\ for j in xrange(0, 64, 4)] def shift(a, count): return (((a << count) | (a >> (32 -count)))&0xffffffff) #第一輪 A = (B+ shift((A+F(B,C,D)+M[0]+T[1]) &0xffffffff,7) ) & 0xffffffff D = (A+shift((D+F(A,B,C)+M[1]+T[2]) &0xffffffff ,12) )& 0xffffffff C = (D+shift((C+F(D,A,B)+M[2]+T[3]) &0xffffffff,17) ) &0xffffffff B = (C+shift((B+F(C,D,A)+M[3]+T[4]) &0xffffffff,22) )&0xffffffff A = (B+shift((A+F(B,C,D)+M[4]+T[5]) &0xffffffff,7) )&0xffffffff D = (A+shift((D+F(A,B,C)+M[5]+T[6])&0xffffffff,12) )&0xffffffff C = (D+shift((C+F(D,A,B)+M[6]+T[7]) &0xffffffff,17) )&0xffffffff B = (C+shift((B+F(C,D,A)+M[7]+T[8]) &0xffffffff,22) )&0xffffffff A = (B+shift((A+F(B,C,D)+M[8]+T[9])&0xffffffff,7) )&0xffffffff D = (A+shift((D+F(A,B,C)+M[9]+T[10])&0xffffffff,12) )&0xffffffff C = (D+shift((C+F(D,A,B)+M[10]+T[11])&0xffffffff,17) )&0xffffffff B = (C+shift((B+F(C,D,A)+M[11]+T[12])&0xffffffff,22) )&0xffffffff A = (B+shift((A+F(B,C,D)+M[12]+T[13])&0xffffffff,7) )&0xffffffff D = (A+shift((D+F(A,B,C)+M[13]+T[14])&0xffffffff,12) )&0xffffffff C = (D+shift((C+F(D,A,B)+M[14]+T[15])&0xffffffff,17) )&0xffffffff B = (C+shift((B+F(C,D,A)+M[15]+T[16])&0xffffffff,22) )&0xffffffff #第二輪 A = (B+shift((A+G(B,C,D)+M[1]+T[17])&0xffffffff,5) )&0xffffffff D = (A+shift((D+G(A,B,C)+M[6]+T[18]) &0xffffffff,9) )&0xffffffff C = (D+shift((C+G(D,A,B)+M[11]+T[19])&0xffffffff,14) )&0xffffffff B = (C+shift((B+G(C,D,A)+M[0]+T[20])&0xffffffff,20) )&0xffffffff A = (B+shift((A+G(B,C,D)+M[5]+T[21])&0xffffffff,5) )&0xffffffff D = (A+shift((D+G(A,B,C)+M[10]+T[22])&0xffffffff,9) )&0xffffffff C = (D+shift((C+G(D,A,B)+M[15]+T[23])&0xffffffff,14) )&0xffffffff B = (C+shift((B+G(C,D,A)+M[4]+T[24])&0xffffffff,20) )&0xffffffff A = (B+shift((A+G(B,C,D)+M[9]+T[25])&0xffffffff,5) )&0xffffffff D = (A+shift((D+G(A,B,C)+M[14]+T[26])&0xffffffff,9) )&0xffffffff C = (D+shift((C+G(D,A,B)+M[3]+T[27])&0xffffffff,14) )&0xffffffff B = (C+shift((B+G(C,D,A)+M[8]+T[28])&0xffffffff,20) )&0xffffffff A = (B+shift((A+G(B,C,D)+M[13]+T[29])&0xffffffff,5) )&0xffffffff D = (A+shift((D+G(A,B,C)+M[2]+T[30])&0xffffffff,9) )&0xffffffff C = (D+shift((C+G(D,A,B)+M[7]+T[31])&0xffffffff,14) )&0xffffffff B = (C+shift((B+G(C,D,A)+M[12]+T[32])&0xffffffff,20))&0xffffffff #第三輪 A = (B+shift((A+H(B,C,D)+M[5]+T[33])&0xffffffff,4) )&0xffffffff D = (A+shift((D+H(A,B,C)+M[8]+T[34])&0xffffffff,11) )&0xffffffff C = (D+shift((C+H(D,A,B)+M[11]+T[35])&0xffffffff,16) )&0xffffffff B = (C+shift((B+H(C,D,A)+M[14]+T[36])&0xffffffff,23) )&0xffffffff A = (B+shift((A+H(B,C,D)+M[1]+T[37])&0xffffffff,4) )&0xffffffff D = (A+shift((D+H(A,B,C)+M[4]+T[38])&0xffffffff,11) )&0xffffffff C = (D+shift((C+H(D,A,B)+M[7]+T[39])&0xffffffff,16) )&0xffffffff B = (C+shift((B+H(C,D,A)+M[10]+T[40])&0xffffffff,23) )&0xffffffff A = (B+shift((A+H(B,C,D)+M[13]+T[41])&0xffffffff,4) )&0xffffffff D = (A+shift((D+H(A,B,C)+M[0]+T[42])&0xffffffff,11) )&0xffffffff C = (D+shift((C+H(D,A,B)+M[3]+T[43])&0xffffffff,16) )&0xffffffff B = (C+shift((B+H(C,D,A)+M[6]+T[44])&0xffffffff,23) )&0xffffffff A = (B+shift((A+H(B,C,D)+M[9]+T[45])&0xffffffff,4) )&0xffffffff D = (A+shift((D+H(A,B,C)+M[12]+T[46])&0xffffffff,11) )&0xffffffff C = (D+shift((C+H(D,A,B)+M[15]+T[47])&0xffffffff,16) )&0xffffffff B = (C+shift((B+H(C,D,A)+M[2]+T[48])&0xffffffff,23))&0xffffffff #第四輪 A = (B+shift((A+I(B,C,D)+M[0]+T[49])&0xffffffff,6) )&0xffffffff D = (A+shift((D+I(A,B,C)+M[7]+T[50])&0xffffffff,10) )&0xffffffff C = (D+shift((C+I(D,A,B)+M[14]+T[51])&0xffffffff,15) )&0xffffffff B = (C+shift((B+I(C,D,A)+M[5]+T[52])&0xffffffff,21) )&0xffffffff A = (B+shift((A+I(B,C,D)+M[12]+T[53])&0xffffffff,6) )&0xffffffff D = (A+shift((D+I(A,B,C)+M[3]+T[54])&0xffffffff,10) )&0xffffffff C = (D+shift((C+I(D,A,B)+M[10]+T[55])&0xffffffff,15) )&0xffffffff B = (C+shift((B+I(C,D,A)+M[1]+T[56])&0xffffffff,21) )&0xffffffff A = (B+shift((A+I(B,C,D)+M[8]+T[57])&0xffffffff,6) )&0xffffffff D = (A+shift((D+I(A,B,C)+M[15]+T[58])&0xffffffff,10) )&0xffffffff C = (D+shift((C+I(D,A,B)+M[6]+T[59])&0xffffffff,15) )&0xffffffff B = (C+shift((B+I(C,D,A)+M[13]+T[60])&0xffffffff,21) )&0xffffffff A = (B+shift((A+I(B,C,D)+M[4]+T[61])&0xffffffff,6) )&0xffffffff D = (A+shift((D+I(A,B,C)+M[11]+T[62])&0xffffffff,10) )&0xffffffff C = (D+shift((C+I(D,A,B)+M[2]+T[63])&0xffffffff,15) )&0xffffffff B = (C+shift((B+I(C,D,A)+M[9]+T[64])&0xffffffff,21))&0xffffffff A = (A + INPUT_A) & 0xffffffff B = (B + INPUT_B) & 0xffffffff C = (C + INPUT_C) & 0xffffffff D = (D + INPUT_D) & 0xffffffff def show_result(A, B, C, D): result = ""; mya = [hex(A)[2:len(hex(A)[2:]) if hex(A).find('L') == -1 else -1].rjust(8, '0')[k:k+2] for k in xrange(0, 8, 2)][::-1] myb = [hex(B)[2:len(hex(B)[2:]) if hex(B).find('L') == -1 else -1].rjust(8, '0')[k:k+2] for k in xrange(0, 8, 2)][::-1] myc = [hex(C)[2:len(hex(C)[2:]) if hex(C).find('L') == -1 else -1].rjust(8, '0')[k:k+2] for k in xrange(0, 8, 2)][::-1] myd = [hex(D)[2:len(hex(D)[2:]) if hex(D).find('L') == -1 else -1].rjust(8, '0')[k:k+2] for k in xrange(0, 8, 2)][::-1] return ''.join(mya + myb + myc + myd) return show_result(A, B, C, D);
在作ctf題目的時候增強對原理的理解,和動手實踐,文字總結的方式能夠幫助記憶。
【1】http://blog.csdn.net/adidala/article/details/28677393