ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [pwnable.kr][Toddler's Bottle] 2. collision
    Wargame/pwnable.kr 2019. 7. 16. 02:37

    MD5 해시 충돌에 관한 문제이다.

     

    Toddler's Bottle - collision

     

    ID: col / PW: guest로 접속하여 파일을 확인해보았다.

     

    ls

     

    col의 소스코드를 확인해보자.

     

    cat col.c

    main을 먼저 보면, 인자가 20 bytes이어야 하고, hashcode와 check_password(인자)가 같아야 flag가 출력된다는 것을 알 수 있다.

     

    그렇다면 check_password 함수를 자세히 살펴보자.

     

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

    check_password 함수의 인자는 char형 포인터이다. 이렇게 받은 인자는 int형 포인터로 변환되어 ip라는 변수에 저장된다. 이는 곧 1 byte의 char형 변수가 4 bytes의 int형 변수로 변환된다는 뜻이므로, ip의 배열 내 1개의 원소는 p의 4 bytes 문자열과 대응된다.

    예를 들어 p = aaaabbbbccccdddd라고 한다면, ip[0] = aaaa, ip[1] = bbbb, ip[2] = cccc, ip[3] = dddd가 된다.

     

    앞의 main 함수에서 20 bytes 크기의 인자를 받으면, check_password 함수에서 해당 인자(ip)를 4 bytes씩 나눠서 저장하기 때문에 반복문은 5번 반복된다.

    따라서 check_password의 리턴값은 인자(ip)를 4 bytes씩 나눈 값들의 합이다.

     

    check_password의 리턴값과 0x21DD09EC이 같아야 flag가 출력된다. 따라서 20 bytes 크기의 인자값을 4 bytes씩 나누어 int형으로 모두 더한 값과 0x21DD09EC이 같도록 인자를 주어야 한다.

     

    0x21DD09EC = 0x6C5CEC8 * 4 + 0x6C5CECC

     

    0x21DD09EC를 5개의 숫자로 간단하게 나누면 위와 같이 된다. 이를 hex값 그대로 인자로 주면 인자의 총합이 0x21DD09EC가 되어 flag가 출력된다.

     

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

     

Designed by Tistory.