-
[pwnable.kr][Toddler's Bottle] 2. collisionWargame/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 :) 'Wargame > pwnable.kr' 카테고리의 다른 글
[pwnable.kr][Toddler's Bottle] 6. random (0) 2019.07.26 [pwnable.kr][Toddler's Bottle] 5. passcode (0) 2019.07.19 [pwnable.kr][Toddler's Bottle] 4. flag (0) 2019.07.18 [pwnable.kr][Toddler's Bottle] 3. bof (0) 2019.07.17 [pwnable.kr][Toddler's Bottle] 1. fd (0) 2019.07.15