Skip to content

Instantly share code, notes, and snippets.

@diogogmt
Created February 9, 2013 05:23
Show Gist options
  • Save diogogmt/4743976 to your computer and use it in GitHub Desktop.
Save diogogmt/4743976 to your computer and use it in GitHub Desktop.
Reversing md5 hashes
#include <stdio.h>
#define T_MASK ((md5_word_t)~0)
#define T1 0xd76aa478
#define T2 0xe8c7b756
#define T3 0x242070db
#define T4 0xc1bdceee
#define T5 0xf57c0faf
#define T6 0x4787c62a
#define T7 0xa8304613
#define T8 0xfd469501
#define T9 0x698098d8
#define T10 0x8b44f7af
#define T11 0xffff5bb1
#define T12 0x895cd7be
#define T13 0x6b901122
#define T14 0xfd987193
#define T15 0xa679438e
#define T16 0x49b40821
#define T17 0xf61e2562
#define T18 0xc040b340
#define T19 0x265e5a51
#define T20 0xe9b6c7aa
#define T21 0xd62f105d
#define T22 0x02441453
#define T23 0xd8a1e681
#define T24 0xe7d3fbc8
#define T25 0x21e1cde6
#define T26 0xc33707d6
#define T27 0xf4d50d87
#define T28 0x455a14ed
#define T29 0xa9e3e905
#define T30 0xfcefa3f8
#define T31 0x676f02d9
#define T32 0x8d2a4c8a
#define T33 0xfffa3942
#define T34 0x8771f681
#define T35 0x6d9d6122
#define T36 0xfde5380c
#define T37 0xa4beea44
#define T38 0x4bdecfa9
#define T39 0xf6bb4b60
#define T40 0xbebfbc70
#define T41 0x289b7ec6
#define T42 0xeaa127fa
#define T43 0xd4ef3085
#define T44 0x04881d05
#define T45 0xd9d4d039
#define T46 0xe6db99e5
#define T47 0x1fa27cf8
#define T48 0xc4ac5665
#define T49 0xf4292244
#define T50 0x432aff97
#define T51 0xab9423a7
#define T52 0xfc93a039
#define T53 0x655b59c3
#define T54 0x8f0ccc92
#define T55 0xffeff47d
#define T56 0x85845dd1
#define T57 0x6fa87e4f
#define T58 0xfe2ce6e0
#define T59 0xa3014314
#define T60 0x4e0811a1
#define T61 0xf7537e82
#define T62 0xbd3af235
#define T63 0x2ad7d2bb
#define T64 0xeb86d391
#define STR_SIZE 6
// If the string has 4 chars, it has a size of 32 bits
// X is a unsigned int pointer, it points to 32 bit chuncks of data
// X[0] will be the whole 4 byte string
// the byte right after the string has the value 0x80, which was translating to 128 since the first nibble is 0 and the second is 8
// a byte with the second nibble as 8 is the decimal 128 --> 1000 0000
// the formula for X_14 is STR_SIZE << 3 as long the string has less than 32 bytes
// after that the formula is (STR_SIZE - 32) << 3 and X_15 will be 1
#define X_14 (STR_SIZE << 3)
/* Round 1. */
/* Let [abcd k s i] denote the operation
a = b + ((a + F(b,c,d) + X[k] + T[i]) <<< s).
*/
/* Do the following 16 operations. */
// For the first operation the values of a,b,c,d are static
// ~b == d
// Still need to run some calculations and read the md5 RFC to understand what's going on
// For now all we know is that we can replace the first set of calculations by d
// t = a + ((b & c) | (~b & d)) + x_0 + T1; a = ((t << 7) | (t >> (25))) + b; \
#define ROUND_1 \
t = a + (c) + x_0 + T1; a = ((t << 7) | (t >> (25))) + b; \
t = d + ((a & b) | (~a & c)) + x_1 + T2; d = ((t << 12) | (t >> (20))) + a; \
t = c + ((d & a) | (~d & b)) + T3; c = ((t << 17) | (t >> (15))) + d; \
t = b + ((c & d) | (~c & a)) + T4; b = ((t << 22) | (t >> (10))) + c; \
t = a + ((b & c) | (~b & d)) + T5; a = ((t << 7) | (t >> (25))) + b; \
t = d + ((a & b) | (~a & c)) + T6; d = ((t << 12) | (t >> (20))) + a; \
t = c + ((d & a) | (~d & b)) + T7; c = ((t << 17) | (t >> (15))) + d; \
t = b + ((c & d) | (~c & a)) + T8; b = ((t << 22) | (t >> (10))) + c; \
t = a + ((b & c) | (~b & d)) + T9; a = ((t << 7) | (t >> (25))) + b; \
t = d + ((a & b) | (~a & c)) + T10; d = ((t << 12) | (t >> (20))) + a; \
t = c + ((d & a) | (~d & b)) + T11; c = ((t << 17) | (t >> (15))) + d; \
t = b + ((c & d) | (~c & a)) + T12; b = ((t << 22) | (t >> (10))) + c; \
t = a + ((b & c) | (~b & d)) + T13; a = ((t << 7) | (t >> (25))) + b; \
t = d + ((a & b) | (~a & c)) + T14; d = ((t << 12) | (t >> (20))) + a; \
t = c + ((d & a) | (~d & b)) + X_14 + T15; c = ((t << 17) | (t >> (15))) + d; \
t = b + ((c & d) | (~c & a)) + T16; b = ((t << 22) | (t >> (10))) + c; \
/* Round 2. */
/* Let [abcd k s i] denote the operation
a = b + ((a + G(b,c,d) + X[k] + T[i]) <<< s).
*/
/* Do the following 16 operations. */
#define ROUND_2 \
t = a + ((b & d) | (c & ~d)) + x_1 + T17; a = ((t << 5) | (t >> (27))) + b; \
t = d + ((a & c) | (b & ~c)) + T18; d = ((t << 9) | (t >> (23))) + a; \
t = c + ((d & b) | (a & ~b)) + T19; c = ((t << 14) | (t >> (18))) + d; \
t = b + ((c & a) | (d & ~a)) + x_0 + T20; b = ((t << 20) | (t >> (12))) + c; \
t = a + ((b & d) | (c & ~d)) + T21; a = ((t << 5) | (t >> (27))) + b; \
t = d + ((a & c) | (b & ~c)) + T22; d = ((t << 9) | (t >> (23))) + a; \
t = c + ((d & b) | (a & ~b)) + T23; c = ((t << 14) | (t >> (18))) + d; \
t = b + ((c & a) | (d & ~a)) + T24; b = ((t << 20) | (t >> (12))) + c; \
t = a + ((b & d) | (c & ~d)) + T25; a = ((t << 5) | (t >> (27))) + b; \
t = d + ((a & c) | (b & ~c)) + X_14 + T26; d = ((t << 9) | (t >> (23))) + a; \
t = c + ((d & b) | (a & ~b)) + T27; c = ((t << 14) | (t >> (18))) + d; \
t = b + ((c & a) | (d & ~a)) + T28; b = ((t << 20) | (t >> (12))) + c; \
t = a + ((b & d) | (c & ~d)) + T29; a = ((t << 5) | (t >> (27))) + b; \
t = d + ((a & c) | (b & ~c)) + T30; d = ((t << 9) | (t >> (23))) + a; \
t = c + ((d & b) | (a & ~b)) + T31; c = ((t << 14) | (t >> (18))) + d; \
t = b + ((c & a) | (d & ~a)) + T32; b = ((t << 20) | (t >> (12))) + c; \
/* Round 3. */
/* Let [abcd k s t] denote the operation
a = b + ((a + H(b,c,d) + X[k] + T[i]) <<< s).
*/
/* Do the following 16 operations. */
#define ROUND_3 \
t = a + (b ^ c ^ d) + T33; a = ((t << 4) | (t >> (28))) + b; \
t = d + (a ^ b ^ c) + T34; d = ((t << 11) | (t >> (21))) + a; \
t = c + (d ^ a ^ b) + T35; c = ((t << 16) | (t >> (16))) + d; \
t = b + (c ^ d ^ a) + X_14 + T36; b = ((t << 23) | (t >> (9))) + c; \
t = a + (b ^ c ^ d) + x_1 + T37; a = ((t << 4) | (t >> (28))) + b; \
t = d + (a ^ b ^ c) + T38; d = ((t << 11) | (t >> (21))) + a; \
t = c + (d ^ a ^ b) + T39; c = ((t << 16) | (t >> (16))) + d; \
t = b + (c ^ d ^ a) + T40; b = ((t << 23) | (t >> (9))) + c; \
t = a + (b ^ c ^ d) + T41; a = ((t << 4) | (t >> (28))) + b; \
t = d + (a ^ b ^ c) + x_0 + T42; d = ((t << 11) | (t >> (21))) + a; \
t = c + (d ^ a ^ b) + T43; c = ((t << 16) | (t >> (16))) + d; \
t = b + (c ^ d ^ a) + T44; b = ((t << 23) | (t >> (9))) + c; \
t = a + (b ^ c ^ d) + T45; a = ((t << 4) | (t >> (28))) + b; \
t = d + (a ^ b ^ c) + T46; d = ((t << 11) | (t >> (21))) + a; \
t = c + (d ^ a ^ b) + T47; c = ((t << 16) | (t >> (16))) + d; \
t = b + (c ^ d ^ a) + T48; b = ((t << 23) | (t >> (9))) + c; \
/* Round 4. */
/* Let [abcd k s t] denote the operation
a = b + ((a + I(b,c,d) + X[k] + T[i]) <<< s).
*/
/* Do the following 16 operations. */
#define ROUND_4 \
t = a + (c ^ (b | ~d)) + x_0 + T49;\
a = ((t << 6) | (t >> (26))) + b; \
\
t = d + (b ^ (a | ~c)) + T50;\
d = ((t << 10) | (t >> (22))) + a; \
\
t = c + (a ^ (d | ~b)) + X_14 + T51;\
c = ((t << 15) | (t >> (17))) + d; \
\
t = b + (d ^ (c | ~a)) + T52;\
b = ((t << 21) | (t >> (11))) + c; \
\
t = a + (c ^ (b | ~d)) + T53;\
a = ((t << 6) | (t >> (26))) + b; \
\
t = d + (b ^ (a | ~c)) + T54;\
d = ((t << 10) | (t >> (22))) + a; \
\
t = c + (a ^ (d | ~b)) + T55;\
c = ((t << 15) | (t >> (17))) + d; \
\
t = b + (d ^ (c | ~a)) + x_1 + T56;\
b = ((t << 21) | (t >> (11))) + c; \
\
t = a + (c ^ (b | ~d)) + T57;\
a = ((t << 6) | (t >> (26))) + b; \
\
t = d + (b ^ (a | ~c)) + T58;\
d = ((t << 10) | (t >> (22))) + a; \
\
t = c + (a ^ (d | ~b)) + T59;\
c = ((t << 15) | (t >> (17))) + d; \
\
t = b + (d ^ (c | ~a)) + T60;\
b = ((t << 21) | (t >> (11))) + c; \
\
t = a + (c ^ (b | ~d)) + T61;\
a = ((t << 6) | (t >> (26))) + b; \
\
t = d + (b ^ (a | ~c)) + T62;\
d = ((t << 10) | (t >> (22))) + a; \
printf("Original value:\n");\
printf("c: 0x%x\n", c);\
t = c + (a ^ (d | ~b)) + T63;\
c = ((t << 15) | (t >> (17))) + d; \
// t = b + (d ^ (c | ~a)) + T64;\
// b = ((t << 21) | (t >> (11))) + c; \
int main (void) {
unsigned int a, b, c, d;
unsigned int t;
int x_0 = 0;
int x_1;
char cached_ascii_code_1 = 0;
char cached_ascii_code_2 = 0;
char cached_ascii_code_3 = 0;
char cached_ascii_code_4 = 0;
char cached_ascii_code_5 = 0;
x_0 |= cached_ascii_code_1 << 8;
x_0 |= cached_ascii_code_2 << 16;
x_0 |= cached_ascii_code_3 << 24;
x_1 = cached_ascii_code_4;
x_1 |= cached_ascii_code_5 << 8;
// Add padding bit
x_1 |= 0x80 << 16;
a = 0x67452301;
b = 0xefcdab89;
c = 0x98badcfe;
d = 0x10325476;
ROUND_1
ROUND_2
ROUND_3
ROUND_4
printf("\nHash results:\n");
printf("a: 0x%x\n", a);
printf("b: 0x%x\n", b);
printf("c: 0x%x\n", c);
printf("d: 0x%x\n", d);
printf("\n\nStart reversing:\n");
c -= d;
c = (c << 17 | c >> 15);
c -= (a ^ (d | ~b)) + 0 + T63;
printf("c: 0x%x\n", c);
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment