collision - 3 pt [writeup]
Daddy told me about cool MD5 hash collision today.
I wanna do something like that too!
ssh col@pwnable.kr -p2222 (pw:guest)
1. 파일 확인
col@ubuntu:~$ ls
col col.c flag
col@ubuntu:~$ cat col.c
#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;
}
메인부터 훑어보면 암호는 20자여야하고 해쉬코드(0x21DD09EC)와 패스워드 리턴값이 같아야한다. check_password(const char* p)에서 각 int의 크기인 4바이트 앞부터 데이터를 잘라 5번 res에 누적시킨다. 같은값을 5번 더해서 해쉬코드가 나오면 된다.
2. 결과 도출
res 값은 for문의 값을 5번 누적한 결과이다. res 값을 5로나누었을때 for에서 쓰인 데이터는 한번당 0x6C5CEC8이다. 이것을 다시 5로 곱하면 0x4가 부족하다. 데이터는 0x6C5CEC8 4개와 0x6C5CECC의 데이터를 더하는 것으로 가정하고 프로그램에 입력값으로 넣어주면 된다.
little endian을 따르고 있음으로 다음과 같은 순서대로 프로그램에 16진수로 데이터를 전달해주면 된다.
col@ubuntu:~$ ./col `python -c 'print "\xC8\xCE\xC5\x06"*4+"\xcc\xce\xc5\x06"'`
daddy! I just managed to create a hash collision :)
파이썬을 이용해서 16진수로 값을 전달했다. 프로그램에서 입력값으로 받으면 char로 인식하기에 주의가 필요하다.
3. flag
daddy! I just managed to create a hash collision :)