collision

{"author": ["ret2basic"]}

Challenge

Daddy told me about cool MD5 hash collision today. I wanna do something like that too!

ssh col@pwnable.kr -p2222 (pw:guest)

Code Review

#include <stdio.h>
#include <string.h>
unsigned long hashcode = 0x21DD09EC;
unsigned long check_password(const char* p){
        int* ip = (int*)p;
        int i;
        int res=0;
        for(i=0; i<5; i++){
                res += ip[i];
        }
        return res;
}

int main(int argc, char* argv[]){
        if(argc<2){
                printf("usage : %s [passcode]\n", argv[0]);
                return 0;
        }
        if(strlen(argv[1]) != 20){
                printf("passcode length should be 20 bytes\n");
                return 0;
        }

        if(hashcode == check_password( argv[1] )){
                system("/bin/cat flag");
                return 0;
        }
        else
                printf("wrong passcode.\n");
        return 0;
}

The program takes 5 4-byte hex numbers as argv[1] and it calls check_password(). If the sum of these 5 hex numbers equals 0x21DD09EC then the program prints out the flag.

Solution

We need to find 5 integers in hex that sum to 0x21dd09ec. The naive idea is to divide 0x21dd09ec by 5. It won't work because 0x21dd09ec isn't divisible by 5. But, following from this logic, we could find a solution using the formula:

Here we have 0x21dd09ec // 5 = 0x6c5cec8, so residue = 0x21dd09ec - 0x6c5cec8 * 4 = 0x6c5cecc. Since the convertion is done by int* ip = (int*)p (pointer, not string), we should use little-endian in argv[1].

Exploit

Last updated