pwnable.kr의 두번째 문제인 collision이다. 저번과 같이 linux환경에서 접속해주었다.
( ssh col@pwnable.kr -p2222 , password : guest )
접속했면 본격적으로 문제를 풀어보기 위해 역시 ls -l로 파일을 확인했다 역시 실행파일인 col파일과 소스코드인 col.c와 flag파일이 있었다.
우린 이제 저 flag파일을 실행시키기위해 끙끙 앓아야 한다. ( 문제풀이를 보기전까지는 말이다. )
우선 우리가 쓸 수 있는 것은 실행파일과 소스코드 뿐이니 소스코드를 먼저 봐야겠다.
# 소스코드 ( .c , .cpp , .python ) 들은 cat명령어로 볼 수 있다.
우리는 문제를 풀어야 하기에 한번 살펴봤다.
우선 소스코드를 해석해보자면 long형으로 hashcode라는 변수안에 0x21DD09EC값을 넣어서 저장한다.
그 뒤 long형식으로 check_password라는 함수를 선언하고 그 안에 배열 인자를 받아서 5번동안 반복하며 인자로 받아온 배열의 순서대로 res라는 변수에 더해준 뒤 res변수를 반환한다.
다음으로 제일 중요한 main함수를 보았다.
입력인자( argc )의 배열을 2개까지 받는 필터와 입력받는 byte크기가 20byte여야 하고, 처음에 선언한 hashcode와 check_password에 배열의 2번째 값을 넣어서 반환된 값을 비교해서 같으면 flag를 실행해준다.
그렇다면 이제 우리가 주목해야 할 것은 hashcode의 값이다.
hashcode의 값은 0x21DD09EC인데, check_password에서 5번 값을 더해주어 반환하기 때문에 더했을 때 0x21DD09EC가 되는 값을 인자로 넣어주어야 한다.
그렇기 때문에 계산기님이 필요하다. 바로 계산기를 켜서 5로 나누어주었다.
이제 값이 나왔으니 페이로드를 짜주자...라고 하기 전에 한번 저 값에 5를 곱해줘서 원래의 값을 만들어보겠다.
그런데 어라? 황당한 결과가 나왔다. 원래의 값보다 4가 적은 값이 나왔다. ( 16진수로 C = 12 이기 떄문에 4차이가 남 )
그 이유는 우리가 나눗셈을 할 때의 나머지 값 때문이다. 우리가 보통 나눗셈을 할 때 12를 5로 나눈다고 해보자 그럼 답으로 2...2가 나올 것이다. 5를 3번곱하면 나눌 값 ( 12 )를 넘어버리기 때문이다.
따라서 원래의 값을 얻으려면 나눈 값 ( 6C5CEC8 ) * 4 + ( 나눈 값 ( 6C5CEC8 ) +4 )를 해주어야 한다.
# 결과적으로 6C5CEC8 * 4 + 6C5CECC 값이다.
그럼 이제 페이로드를 짜 보자 ( python을 이용해서 만들었다. )
인자로 주어야 하기 때문에 실행 파일 ( ./col ) 뒤에 페이로드를 적어주어야 한다.
payload = `python -c ' print "\xC8\xCE\xC5\x06"*4+"\xCC\xCE\xC5\x06"'`
payload에서 6C5CEC8값을 \x형식으로 거꾸로 쓴 이유는 터미널에서 리틀 엔디안 방식을 사용하기 때문이다.
리틀 엔디안 방식은 많이 쓰는 방식이기 떄문에 가능하면 리틀 엔디안 방식을 검색해 보길 바란다.
flag : daddy! I just managed to create a hash collision :)
'Hacking > Pwnable' 카테고리의 다른 글
[ pwnable.kr ] random 문제 풀이 (0) | 2019.09.04 |
---|---|
[ pwnable.kr ] passcode 문제풀이 (0) | 2019.08.30 |
[ pwnable.kr ] flag 문제풀이 (0) | 2019.08.30 |
[ pwnable.kr ] bof 문제풀이 (2) | 2019.08.28 |
[ pwnable.kr ] fd 문제풀이 (0) | 2019.08.23 |