본문 바로가기
Security/pwnable.kr

[pwnable.kr] Toddler's Bottle - collision

by 단월໒꒱ 2021. 10. 10.

두번째 문제는 collision 문제이다.

 

 

 

 

문제를 누르면 위와 같은 창이 뜬다. 이번 문제는 MD5 hash collision에 대한 문제 같다.

 

일단 하라는대로 따라가보자.

맨 밑에 있는 명령어를 통해 pwnable.kr에 접속해준다.

 

 

 

 

비밀번호는 guest라고 했으므로 password에 guest를 입력한다.

 

 

 

 

접속이 완료되면 위와 같은 화면이 뜬다.

 

 

 

 

ls를 이용해서 무슨 파일이 있나 살펴보았다. 우리가 원하는 건 flag인데 아직 접근할 수 없기 때문에 먼저 확인이 가능한 col.c를 먼저 살펴보기로 했다.

 

 

 

 

저번 문제보다 훨씬 긴 코드를 볼 수 있다. 해결 방법을 찾기 위해 먼저 위의 코드를 해석해보자.

unsigned long 타입의 hashcode에 0x21DD09EC가 저장돼있다.

check_password 함수에서는 4바이트 크기를 가진 값을 5번 더해주고 이 값을 리턴한다.

밑에 main 함수에서 flag를 확인하기 위해서는 check_password 함수를 거친 argv[1]가 hashcode와 같으면 flag를 보여주도록 되어있다. argv[1]의 길이가 20 바이트인 것도 알 수 있다.

(이 부분 나중에 다시 확인해보도록 하자... 포인터나 바이트 아직 잘 모른다...)

 

 

 

먼저 0x21DD09EC가 10진수로 얼마인지 알아봤다. 16진수인 0x21DD09EC를 10진수로 바꿔주면 568134124가 된다.

 

 

 

 

위의 568134124를 5로 나누면 113626824가 나온다.

 

 

 

 

 

하지만 113626824에 5를 곱하면 568134124에서 4가 부족한 값이 나오는 것을 확인할 수 있다.

따라서 113626824를 4번 곱해준 뒤 나머지 한 수는 여기에 4를 더한 113626828을 더해주면 값을 맞출 수 있다.

다시 16진수로 변환하면 113626824는 06C5CEC8이고 113626828은 06C5CECC이다.

 

 

 

 

이런 식으로 여러가지 넣어봤는데 안 돼서 찾아보니까 여기서 리틀 엔디안 방식을 이용했다고 한다.

그렇기 때문에 06C5CEC8 같은 경우 C8CEC506 이런 식으로 거꾸로 해줘야 한다는 것이다.

 

 

 

 

하지만 그렇게 해도 잘 안 됐다. 찾아보니까 파이썬 인터프리터를 이용해서 값을 입력해야한다고 한다.

 

 

 

 

찾아본 방식대로 값을 입력해주니 다행히 성공했고 이렇게 맞는 값을 입력하면 우리가 원하던 flag의 내용을 볼 수 있다.

 

 

 

 

위에서 구한 내용을 복사해서 빈칸에 넣으면

 

 

 

 

이렇게 문제를 해결했다고 뜬다.

 

 

이번 문제를 풀면서 바이트나 포인터에 대한 기본 개념이 부족하다는 것을 깨달았다. 시간이 나면 다시 한번 정리해봐야겠다.

댓글