Pwnable.kr - collision

1 minute read

Challenge description:

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

#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;
}

This challenge takes a 20 bytes passcode as input then checks it against some hashcode, if it’s the same we get the flag.

The checking function casts the input to an integer and loops over it 4 bytes at a time (integer is 4 bytes).

So to solve this challenge we need to enter 5 numbers add up to 0x21DD09EC (the hashcode value).

0x21DD09EC / 5 = 0x06C5CEC8 + remainder 0x4, we can add the remainder to any of the 5 numbers.

One thing to remember is that values are stored in memory in little endian form (higher bytes are stored in lower memory addresses), so if we need to enter the value 0x41424344 it will be 0x44434241. We can use python pwn tools to do this for us.

Solution:

#solve.py

from pwn import *

hashcode = 0x21DD09EC
num = hashcode // 5
remainder = hashcode % 5

buf = ""
buf += p32(num)	# p32() converts to little endian
buf += p32(num)
buf += p32(num)
buf += p32(num)
buf += p32(num + remainder)

print(buf)
col@pwnable:~$ ./col $(python2 /tmp/solve.py)
daddy! I just managed to create a hash collision :)

Flag: daddy! I just managed to create a hash collision :)