본문 바로가기
Pwnable/Pwnable CTF

[Pwnable.kr] Toddler's Bottle_fd

by Y06 2021. 3. 17.

처음 들어가면 보이는 문제이다. 리눅스에서 'ssh fd@pwnable.kr -p2222' 로 접속하면 무언가 뜰 거 같다. 

 

 

비밀번호를 입력하라고 나오는데 비밀번호는 문제에서 'quest'라고 알려주었다.

 

 

ls 명령어를 사용해서 현재 디렉토리에 있는 내용을 확인한다. fd, fd.c, flag 파일이 있는 것을 볼 수 있다.

 

 

먼저 cat 명령어를 사용해서 fd.c 파일을 확인하였다. fd.c를 자세히 보면 fd 파일을 실행한 후 첫 번째로 넘기는 인자에서 0x1234만큼 빼준다. atoi 함수는 문자열을 정수로 변환하는 역할의 함수이다.

 

그 다음으로는 read 함수를 이용하여 fd, buf, 32를 확인한 후 strcmp로 buf 값이 LETMEWIN이면 플래그를 출력하는 방식인 문제이다.

 

리눅스 파일 스크립터는 일반 파일, 내/외부 장치 모두를 파일로 취급하는 리눅스에서 파일들에 접근해서 실행하기 위한 키의 역할을 수행한다. 이에 따라 Integer Value가 0,1,2일 때에 따라 입력, 출력, 에러 이벤트를 발생시킨다.

 

read 함수는 read(int fd(파일 디스크립터의 값), void *buf(수신한 데이터를 저장할 버퍼를 가리키는 포인터), buf(수신한 데이터를 저장할 버퍼를 가리키는 포인터)) 형태로 인자를 받고, 반환값으로 수신한 바이트 수(실패 시, -1)를 준다.

 

따라서 이 부분은 if 조건문 안에 strcmp(문자열 비교) 함수가 나오고 "LETMRWIN/n"과 buf를 비교한다. 이때 strcmp 앞에는 !가 있으므로 ctrcmp의 리턴 값은 0이 나와야 한다. 0은 두 게의 문자열이 같을 때 리턴된다.

 

우리는 fd 파일에 뭔가를 입력해야지 이 문제를 풀 수 있다. fd 값을 0이 되어야 한다. 고로 0x1234를 argv[1]에서 빼서 0이 나와야 한다면 argv[1]이 0x1234가 되어야 한다.

 

 

 

이는 10진수로 4660이기 때문에 그 뒤에 4660을 인자값으로 넘겨준다.

 

 

./fd 4660을 입력한 후 LETMEWIN을 입력하면 플래그 값이 나온다.

 

Flag: mommy! I think I know what a file descriptor is!!

 

 

문제를 풀었다.