본문 바로가기
Security/pwnable.kr

[pwnable.kr] Toddler's Bottle - mistake

by 단월໒꒱ 2021. 11. 21.

이번에 풀 문제는 mistake 문제이다.

 

 

 

 

대충 읽어보니 무언가 실수가 있는 것 같은데 힌트가 operator priority라는 걸 보면 연산 우선순위에 관한 실수인 것 같다.

 

일단 매번 하던 것처럼 pwnable.kr에 접속해서 password인 guest를 입력해준다.

 

 

 

 

접속에 성공했다.

 

 

 

 

ls -l 명령어를 통해 파일을 살펴보니 저런 파일들이 있는 걸 확인할 수 있다.

flag에 접근할 권한이 없으니 먼저 mistake.c 파일을 열어서 내용을 확인해보았다.

 

 

 

 

쭉 훑어보면 크게 어려운 부분은 없다.

다만, 앞서 언급한대로 연산자 순서에 주목해서 코드를 확인해보니 힌트대로 연산 순서가 애매해보이는 부분이 있다.

 

 

 

 

 

위의 두 부분이었는데,  일단 차근차근 살펴보도록 하자.

 

 

첫번째 부분을 보면, open 함수의 반환값이 fd에 입력되고 이 fd와 0을 비교하는 듯 하지만 사실 연산자의 우선순위를 고려해보면 그런 순서대로 연산되지 않는 걸 알 수 있다.

비교 연산자인 <은 산술 연산자 = 보다 우선순위가 높다.

따라서 위의 코드에서 open 함수의 반환값을 먼저 0과 비교한 뒤 비교한 값을 fd에 저장된다.

위에서 ls -l 명령어로 파일들을 확인해 본 결과 password 파일이 있고 정상적으로 열리는 것으로 보아 양수를 반환한다.

이 반환값을 0과 비교하면 거짓이므로 fd에는 0(false)가 저장된다.

 

 

두번째 부분을 보면 마찬가지로 산술 연산자 =과 비교 연산자 >의 연산 순위를 살펴봐야 한다.

read 함수를 보는데 위의 부분에서 fd가 0임을 확인하였으므로 이는 표준입력을 뜻한다.

따라서 사용자로부터 pw_buf 값을 입력 받게 된다.

 

 

위의 전체 코드를 살펴보면 pw_buf2를 입력 받는 부분이 있다.

scanf 함수로 pw_buf2를 입력 받은 뒤 이 값을 xor해준다.

 

 

요약하자면, 사용자로부터 pw_buf와 pw_buf2를 입력 받은 후 pw_buf2를 xor 연산을 한 값을 pw_buf2에 저장하는데, 이 pw_buf와 pw_buf2를 비교했을 때 그 값이 같으면 flag를 보여준다.

 

 

 

 

위에서 설명했듯이 무엇을 입력하든 pw_buf 값과 pw_buf2를 xor한 값이 같으면 flag를 볼 수 있기 때문에 아무거나 입력해주도록 하자.

mistake 파일을 실행시킨 뒤 일단 1111111111을 입력했다.

이 1111111111은 pw_buf에 저장되는데, 어떤 값을 xor한 값이 1111111111이 되려면 그 어떤 값은 0000000000이 되어야 한다.

따라서 input password에 0000000000을 입력하여 pw_buf2 부분에 0 10개를 넣어준다.

그러면 위의 화면처럼 flag의 내용을 볼 수 있다.

 

 

 

 

위에서 구한 flag 내용을 복사해서 붙여넣으면 

 

 

 

 

위의 화면처럼 문제를 해결했다고 뜬다.

댓글