Md5擴展攻擊的原理和應用

作CTF題目的過程當中遇到了md5擴展攻擊,參考了幾篇文章,感受寫的都有些小缺陷,再發一篇文章,理解md5擴展攻擊首先須要瞭解md5的工做原理html

1)md5的工做原理

具體參考這兩篇文章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擴展攻擊

2)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的數據,攻擊成功。

 

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);

 

4)結語

在作ctf題目的時候增強對原理的理解,和動手實踐,文字總結的方式能夠幫助記憶。

 

參考文獻:

【1】http://blog.csdn.net/adidala/article/details/28677393

【2】https://www.rfc-editor.org/rfc/pdfrfc/rfc1321.txt.pdf

【3】http://www.freebuf.com/articles/web/69264.html

相關文章
相關標籤/搜索