PWNable collision
http://pwnable.kr/index.php
writeup을 보면 MD5의 해시 충돌의 사용해 푸는 문제라는 힌트가 주어진다. 이제 저기에 나온 ssh로 접속해서 파일들을 확인했다.
MD5란 MD5(Message-Digest algorithm 5)는 128비트 암호화 해시 함수이다. 해시 함수는 임의 길이를 가진 문자열을 입력받아 고정된 길이의 해쉬값을 출력한다. 말 그대로 함수를 생각하며 되는데 해쉬함수의 문제점은 충돌이 일어날 수 있다는 것이다. 즉, 특정 해쉬값을 나오게 하는 값이 하나가 아닐경우 해시 충돌이 일어났다고 말한다.
col.c라는 파일이 보인다. 코드를 읽기 위해 cat명령어를 사용해 살펴봤다.
if(입력한 단어의 수가 2개 미만)--> printf("usage: ~~")
if (입력한 2번째 단어가 20바이트가 아니라면) --> printf("passcode~~")
if (hashcode 와 check_password(두번째 단어)의 반환값이 같다면) --> 성공!!
그외의 경우 --> printf("wrong passcode.")
col.c를 해석하면 다음과 같다. 성공을 하기 위해서는 hashcode의 값과 check_password(argv[1])의 밪환값이 같아야 하는데 hashcode는 처음에 0x21DD09EC라고 초기화 돼있다. check_password()함수는 전달받은 인자를 정수형으로 바꿔서 5번에 걸쳐 더한 다음 그 총 합을 반환한다. 따라서 이 값이 0x21DD09EC와 같으면 된다.
그럼 16진수 21DD09EC를 5 로 나누면 몫은 6C5CEC8이 나오고 나머지가 4이므로 4번은 6C5CEC8이고 한 번은 6C5CECC이여야 한다. 이 5번은 다 더하면 원하는 숫자 0x21DD09EC가 나온다.
$는 실행 파일의 인자로 ()안에 있는 문자를 넣어준다는 의미이다. 파이썬을 사용해서 입력해 주는데 리틀 엔디언 방식이기 때문에 숫자를 뒤쪽부터 잘라서 입력해준다. 여기서 리틀 엔디안이란 엔디언의 한 방식이다. 엔디언은 컴퓨터 메모리와 같은 1차원 공간에 여러개의 연속된 대상을 배열하는 걸 의미한다. 바이트를 배열하는 방식을 바이트 오더라고 한다. 엔디언은 최상위 바이트부터 하위주소에 넣는 빅 엔디안과 최하위바이트부터 하위주소에 넣는 리틀 엔디안이 있다. 빅 엔디언은 사람이 숫자를 쓰는 방식과 또같아 보이지만 리틀 엔디안은 숫자를 바이트 단위로 쪼개서 뒤에서 부터 쓴다고 생각하면된다.
입력된 명령어를 보면 6C5CE8 과 6C5CECC를 바이트 단위로 나눈 후 뒤 부터 써준것을 볼 수 있다.
이렇게 입력해주면 성공!
참고:
http://nobilitycat.tistory.com/entry/pwnablekr-collision
https://ko.wikipedia.org/wiki/%ED%95%B4%EC%8B%9C_%EC%B6%A9%EB%8F%8C
https://seed.kisa.or.kr/iwt/ko/intro/EgovHashFunction.do
https://ko.wikipedia.org/wiki/%EC%97%94%EB%94%94%EC%96%B8
http://skmagic.tistory.com/160
http://pwnable.kr/index.php
writeup을 보면 MD5의 해시 충돌의 사용해 푸는 문제라는 힌트가 주어진다. 이제 저기에 나온 ssh로 접속해서 파일들을 확인했다.
MD5란 MD5(Message-Digest algorithm 5)는 128비트 암호화 해시 함수이다. 해시 함수는 임의 길이를 가진 문자열을 입력받아 고정된 길이의 해쉬값을 출력한다. 말 그대로 함수를 생각하며 되는데 해쉬함수의 문제점은 충돌이 일어날 수 있다는 것이다. 즉, 특정 해쉬값을 나오게 하는 값이 하나가 아닐경우 해시 충돌이 일어났다고 말한다.
col.c라는 파일이 보인다. 코드를 읽기 위해 cat명령어를 사용해 살펴봤다.
if(입력한 단어의 수가 2개 미만)--> printf("usage: ~~")
if (입력한 2번째 단어가 20바이트가 아니라면) --> printf("passcode~~")
if (hashcode 와 check_password(두번째 단어)의 반환값이 같다면) --> 성공!!
그외의 경우 --> printf("wrong passcode.")
col.c를 해석하면 다음과 같다. 성공을 하기 위해서는 hashcode의 값과 check_password(argv[1])의 밪환값이 같아야 하는데 hashcode는 처음에 0x21DD09EC라고 초기화 돼있다. check_password()함수는 전달받은 인자를 정수형으로 바꿔서 5번에 걸쳐 더한 다음 그 총 합을 반환한다. 따라서 이 값이 0x21DD09EC와 같으면 된다.
그럼 16진수 21DD09EC를 5 로 나누면 몫은 6C5CEC8이 나오고 나머지가 4이므로 4번은 6C5CEC8이고 한 번은 6C5CECC이여야 한다. 이 5번은 다 더하면 원하는 숫자 0x21DD09EC가 나온다.
$는 실행 파일의 인자로 ()안에 있는 문자를 넣어준다는 의미이다. 파이썬을 사용해서 입력해 주는데 리틀 엔디언 방식이기 때문에 숫자를 뒤쪽부터 잘라서 입력해준다. 여기서 리틀 엔디안이란 엔디언의 한 방식이다. 엔디언은 컴퓨터 메모리와 같은 1차원 공간에 여러개의 연속된 대상을 배열하는 걸 의미한다. 바이트를 배열하는 방식을 바이트 오더라고 한다. 엔디언은 최상위 바이트부터 하위주소에 넣는 빅 엔디안과 최하위바이트부터 하위주소에 넣는 리틀 엔디안이 있다. 빅 엔디언은 사람이 숫자를 쓰는 방식과 또같아 보이지만 리틀 엔디안은 숫자를 바이트 단위로 쪼개서 뒤에서 부터 쓴다고 생각하면된다.
입력된 명령어를 보면 6C5CE8 과 6C5CECC를 바이트 단위로 나눈 후 뒤 부터 써준것을 볼 수 있다.
이렇게 입력해주면 성공!
참고:
http://nobilitycat.tistory.com/entry/pwnablekr-collision
https://ko.wikipedia.org/wiki/%ED%95%B4%EC%8B%9C_%EC%B6%A9%EB%8F%8C
https://seed.kisa.or.kr/iwt/ko/intro/EgovHashFunction.do
https://ko.wikipedia.org/wiki/%EC%97%94%EB%94%94%EC%96%B8
http://skmagic.tistory.com/160
댓글
댓글 쓰기