Principle and Application of Md5 Extended Attack

Posted by shortysbest on Tue, 25 Jun 2019 21:11:45 +0200

In the process of doing CTF topic, we met with MD5 extension attack. Referring to several articles, we feel that there are some minor defects in writing. Then we send another article to understand MD5 extension attack. First of all, we need to understand the working principle of md5.

1) Working Principle of md5

Refer specifically to these two articles

http://blog.csdn.net/adidala/article/details/28677393 The implementation of the algorithm is incorrect

https://www.rfc-editor.org/rfc/pdfrfc/rfc1321.txt.pdf The algorithm is correct

The algorithm principle of md5 is shown in the following figure

The algorithm steps of Md5 are

1. Filling

Fill in the data, first add 0x80, then add 0x00 to make (data bytes + 8)% 64 = 0

2. Increase length

Put the length of the data in an 8-byte array and put the low byte in front. For example, the length of the data of 1,8 bytes is expressed as 00,000,000,000,01. The length value is converted into the low byte in front into 0,100,000,000,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,000,and add this data to the whole data

3. Round change

A group of 64 bytes is used for round transformation. In this group, 4 bytes are used as a unit and 16 digits are divided.

First prepare four 32-bit characters A, B, C and D, where A = 0x67452301 and B = 0xefcdab89

C = 0x98badcfe,D = 0x10325476, ABCD as seed, and 16 digits for a complex operation (see later), the result of the operation is A1 B1 C1 D1, A1B1 C1D1 as seed, then repeat the process of calculation to get AnBnCnDn.

4. Output hash value

Ans are arranged in a low byte order similar to the second step An'. Similarly, Bn, Cn and Dn are transformed in the same way. Simple splicing of An', Bn', Cn', Dn'is the final result.

Note: Here's a brief record of the correct complex algorithms

The algorithm in document 1 is wrong, and the correct algorithm is

Define several of these sub-algorithms

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)

//Constant Scale:

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)

//Complex algorithm is

        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)

        #first round

        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

        #Second round

        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

        #Third round

        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

        #Fourth round

        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 algorithm implementation python version see my_md5 function implementation in Section 3

Understanding the principle of md5 algorithm, let's start with an explanation of md5 extended attack

2) Md5 Attack Extension Attack

First of all, you can refer to this article.( http://www.freebuf.com/articles/web/69264.html This article will supplement this article.

From the principle of md5 algorithm, we can know that the ABCD calculated in each round will be the initial value of the next round. Assuming that we know the md5 value of a number x is y, where x is an unknown quantity, i.e. y=md5 (x), and the length of X is known, then we can carry out md5 extension attack, because we know that y is a simple combination of the ABCD values calculated in md5 (x), through the md5 algorithm. It is known that y = f (filling value of x + x), if we add x1, it is possible to calculate the filling value of Y'= f ((filling value of x + x + x1) + (filling value of x + x + x1). It should be that Y'can use AB transformed by y.

The CD value can be obtained by calculating again and again with the filling value of X1 + (filling value of X + X + filling value of x1).

The following figure illustrates the principle of the above algorithm.

Among them, label 1 is the original data x, label 2 bits the filling length of the original data x, label 3 represents the newly added data, label 4 is the filling and length of label 1, 2, 3. If we know a calculated hash value and the length of plaintext, we can construct the data of label 2, label 3, and calculate the function of unknown md5 value (such as server-side program). When we get the data of label 2 and label 3, we will automatically add the data of label 4, calculate label 1 and label 2 to produce ABCD, and then produce hash value. This hash value is predictable.

Attackers can calculate labels 3 and 4, and the hash value of local output calculated with ABCD as input is consistent with the hash value calculated by server.

The attacker's perspective is shown in the following figure.

1. Attackers provide data labeled 2, 3, and 4

2. The server calculates the location of label 2 just as ABCD is the known data.

3. The attacker succeeded in calculating hash values locally based on the data of labels 3 and 4 and ABCD values.

From the server's point of view, the attacker provides the data of label 2 and 3. The server calculates the data of label 4. At the same time, the server produces ABCD, and finds that the calculation is not completed. Then it runs md5 algorithm, and the new hash value calculated is consistent with the attacker's.

In summary, there are two conditions that need to be known in order to carry out such attacks.

1. The length of label 1 data.

2. The md5 value of label 1 data.

Finally, summarize the attack steps.

Step 1: Calculate the data of label 2 according to the length of label 1, provide the data of label 3, calculate the data of label 4 locally, and calculate the hash value after adding the data of label 3 and 4.

The second step: Send the calculated hash, and label 2, label 3 data, the attack succeeded.

 

3) Program presentation

Demonstrate the MD5 program written by python and the MD5 extended attack program

#-*- coding=utf-8 -*-
import math

def my_md5_extend(salt_hash,  salt_length, added_message):
    #Calculate the data to be filled in
    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]
    #The following data is used to add after payload
    added_data.extend(salt_length); #important
    #Print payload
    print ''.join(['%' + hex(item).replace('0x', '').rjust(2,'0') for item in added_data])
    
    #Add new data, then use the data already md5 to expand the calculation, and calculate a new hash value.
    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);
    
    #Use hash that has been calculated
    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 calculation
    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)
        
        #first round
        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
 
        #Second round
        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

        #Third round
        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

        #Fourth round

        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):
    #First step filling
    #mystring = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'
    myord =map(ord, mystring);#Convert to hexadecimal array
    myord_length = len(myord) * 8;
    myord.append(0x80);

    while (len(myord) * 8 + 64 )% 512 != 0:
        myord.append(0x00);


    #Step 2 Increase Length
    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)


    #Processing each 512 bits
    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)#Wrong Location

    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)
        
        #first round
        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
 
        #Second round
        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

        #Third round
        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

        #Fourth round

        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) Concluding remarks

When doing the ctf topic, we should strengthen the understanding of the principle and practice. The way of summarizing words can help us remember.

 

Reference:

[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

Topics: Lambda Python