두번째 문제는 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의 내용을 볼 수 있다.
위에서 구한 내용을 복사해서 빈칸에 넣으면
이렇게 문제를 해결했다고 뜬다.
이번 문제를 풀면서 바이트나 포인터에 대한 기본 개념이 부족하다는 것을 깨달았다. 시간이 나면 다시 한번 정리해봐야겠다.
'Security > pwnable.kr' 카테고리의 다른 글
[pwnable.kr] Toddler's Bottle - blackjack (0) | 2021.12.05 |
---|---|
[pwnable.kr] Toddler's Bottle - lotto (0) | 2021.11.28 |
[pwnable.kr] Toddler's Bottle - mistake (0) | 2021.11.21 |
[pwnable.kr] Toddler's Bottle - random (0) | 2021.11.15 |
[pwnable.kr] Toddler's Bottle - fd (0) | 2021.10.04 |
댓글