본문 바로가기
포너블(pwnable)/CTF(pwnable.kr)

[Toddler's Bottle] collision 문제풀이

by LIZ0904 2021. 3. 20.
반응형

문제

오늘의 문제는 위와 같다!

여기서 hash collision(해시 충돌)이라는 단어가 나온다.

Hash Collision(해시 충돌)이란, 다른 값을 넣었을 때 같은 값이 나오는 것을 의미한다. 오늘 문제의 핵심은 해시 충돌이다! 

 

문제 접속

ssh col@pwnable.kr -p2222를 쳐서 문제에 접속해보자!

 

ls -l

ls -l 명령을 이용해 현재 디렉터리에 있는 파일의 목록을 봤다. cat 명령을 사용해 flag를 확인해봤지만, 어김없이 Permission denied가 뜬다.

 

cat col.c

col.c 파일의 내용을 보면 위와 같다. main함수 먼저 확인을 해보자!

 

main 함수

첫번째 if문에서 인자값의 개수가 2개 미만이면 프로그램이 종료된다는 것을 알 수 있다.

두번째 if문에서는 인자값 argv[1]의 길이가 20byte여야 함을 알 수 있다.

세번째 if문에서 hashcode와 chech_password 함수 결과값을 비교한 뒤, /bin/cat flag 명령을 실행한다. argv[1]의 문자열을 check_password() 함수의 인자로 하여, 그 반환값을 hashcode랑 비교한다.

 

check_password 함수

check_password 함수부분을 살펴보자. const char* p, 즉 문자열을 인자로 받는다. int형 포인터 변수 ip에 p의 주소값을 넣고, int형 변수 rest에 ip[0]~ip[4]의 값을 더한 값을 넣는다. int형 포인터의 크기는 4byte이기 때문에 4byte 단위로 5개이 문자열을 더한다고 할 수 있다.

argv[1]에 hashcode의 값을 5로 나누어 그 값을 5번 연속하여 입력하면 될 것이다.

 

hashcode/5

hashcode의 값 0x21DD09EC를 5로 나누면 0x6C5CEC8이 나온다.

6C5CEC8*5

검산을 위해 다시 6C5CEC8을 5로 곱해보면 hashcode의 값 0x21DD09EC이 아닌 0x21DD09E8이 나온다. 

21DD09EC-21DD09E8

hashcode와 0x21DD09E8의 차를 보면 4가 나온다.

 

그럼 6C5CEC8d을 4번 더한 뒤, 마지막 연산, 즉 argv[4]의 부분에 6C5CEC8+4를 입력하면 hashcode과 같은 값이 입력될 것이다.

 

이렇게 어떤 값을 넣어도 0x21DD09E8(hashcode)가 나오게 되면, if문이 실행되면서 문제가 풀린다. 이 부분에서 hash collision(해시 충돌)이 발생돼 문제에서 언급한 대로 해시 충돌 응용 문제를 풀 수 있게 되는 것이다!

 

 

정답

4byte씩 5개의 값을 넣어 20byte에 맞췄다.

main 함수의 첫번째 if문의 argc>2의 조건을 만족했고,

두번째 if문의 argv[1]을 20byte에 맞췄고.

세번째 if문의 hashcode==check_password()의 조건을 만족했다.

정답을 입력하게 되면 /bin/cat flag 명령이 실행되면서 flag가 뜬다.

 

※리눅스에서 파이썬을 통해 c프로그램의 인자를 넘겨주기 위해, python에서 -c 옵션을 사용했다.

 

 

성공

flag를 입력하면 성공!!!

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

반응형

댓글